webentwicklung-frage-antwort-db.com.de

So konvertieren Sie eine Spaltennummer (zB 127) in eine Excel-Spalte (zB AA)

Wie konvertiert man eine numerische Zahl in einen Excel-Spaltennamen in C #, ohne dass die Automatisierung den Wert direkt aus Excel bezieht.

Excel 2007 hat einen möglichen Bereich von 1 bis 16384, also der Anzahl der unterstützten Spalten. Die resultierenden Werte sollten in Form von Excel-Spaltennamen sein, z. A, AA, AAA usw.

425
robertkroll

So mache ich es:

private string GetExcelColumnName(int columnNumber)
{
    int dividend = columnNumber;
    string columnName = String.Empty;
    int modulo;

    while (dividend > 0)
    {
        modulo = (dividend - 1) % 26;
        columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
        dividend = (int)((dividend - modulo) / 26);
    } 

    return columnName;
}
819
Graham

Wenn dies in Excel ohne VBA erforderlich ist, können Sie Folgendes tun:

=SUBSTITUTE(ADDRESS(1;colNum;4);"1";"")

dabei steht colNum für die Spaltennummer

Und in VBA:

Function GetColumnName(colNum As Integer) As String
    Dim d As Integer
    Dim m As Integer
    Dim name As String
    d = colNum
    name = ""
    Do While (d > 0)
        m = (d - 1) Mod 26
        name = Chr(65 + m) + name
        d = Int((d - m) / 26)
    Loop
    GetColumnName = name
End Function
54
vzczc

Sorry, das ist Python statt C #, aber zumindest sind die Ergebnisse korrekt

def ColIdxToXlName(idx):
    if idx < 1:
        raise ValueError("Index is too small")
    result = ""
    while True:
        if idx > 26:
            idx, r = divmod(idx - 1, 26)
            result = chr(r + ord('A')) + result
        else:
            return chr(idx + ord('A') - 1) + result


for i in xrange(1, 1024):
    print "%4d : %s" % (i, ColIdxToXlName(i))
20
RoMa

Möglicherweise müssen Sie beide Arten konvertieren, z. B. von einer Excel-Spaltenadresse wie AAZ in eine Ganzzahl und von einer beliebigen Ganzzahl in Excel. Die beiden folgenden Methoden werden genau das tun. Angenommen, die 1-basierte Indizierung, das erste Element in Ihren "Arrays" ist die Elementnummer 1 . Hier gibt es keine Größenbeschränkung. Daher können Sie Adressen wie ERROR verwenden. Das wäre die Spaltennummer 2613824 ...

public static string ColumnAdress(int col)
{
  if (col <= 26) { 
    return Convert.ToChar(col + 64).ToString();
  }
  int div = col / 26;
  int mod = col % 26;
  if (mod == 0) {mod = 26;div--;}
  return ColumnAdress(div) + ColumnAdress(mod);
}

public static int ColumnNumber(string colAdress)
{
  int[] digits = new int[colAdress.Length];
  for (int i = 0; i < colAdress.Length; ++i)
  {
    digits[i] = Convert.ToInt32(colAdress[i]) - 64;
  }
  int mul=1;int res=0;
  for (int pos = digits.Length - 1; pos >= 0; --pos)
  {
    res += digits[pos] * mul;
    mul *= 26;
  }
  return res;
}
17
Arent Arntzen

In meinem ersten Beitrag habe ich einen Fehler entdeckt, also habe ich mich entschieden, mich hinzusetzen und die Mathematik zu machen. Was ich fand, ist, dass das Zahlensystem, das zum Identifizieren von Excel-Spalten verwendet wird, kein Basis-26-System ist, wie es von einer anderen Person gepostet wurde. Betrachten Sie Folgendes in Basis 10. Sie können dies auch mit den Buchstaben des Alphabets tun.

Leerzeichen: ......................... S1, S2, S3: S1, S2, S3
.................................... 0, 00, 000: .. A, AA AAA
.................................... 1, 01, 001: .. B, AB AAB
....................................…,…,…:……,… ,…
.................................... 9, 99, 999: .. Z, ZZ ZZZ
Gesamtzustände im Raum: 10, 100, 1000: 26, 676, 17576
Staaten insgesamt: ............... 1110 ................ 18278

Excel nummeriert die Spalten in den einzelnen alphabetischen Räumen anhand der Basis 26. Sie können sehen, dass die Zustandsraumprogression im Allgemeinen a, a ^ 2, a ^ 3,… für einige Basis a ist und die Gesamtzahl der Zustände a + a ist ^ 2 + a ^ 3 +…. 

Angenommen, Sie möchten die Gesamtzahl der Zustände A in den ersten N Leerzeichen ermitteln. Die Formel dafür ist A = (a) (a ^ N - 1)/(a-1). Dies ist wichtig, weil wir den Raum N suchen müssen, der unserem Index K entspricht. Wenn ich herausfinden möchte, wo K im Zahlensystem liegt, muss ich A durch K ersetzen und nach N suchen. Die Lösung ist N = log { Basis a} (A (a-1)/a + 1). Wenn ich das Beispiel von a = 10 und K = 192 verwende, weiß ich, dass N = 2.23804…. Dies sagt mir, dass K am Anfang des dritten Feldes liegt, da es etwas größer als zwei ist.

Der nächste Schritt besteht darin, herauszufinden, wie weit wir uns im aktuellen Bereich befinden. Um dies herauszufinden, subtrahieren Sie von K das A, das unter Verwendung des Stockwerks von N erzeugt wird. In diesem Beispiel beträgt der Stock von N zwei. Also ist A = (10) (10 ^ 2 - 1)/(10-1) = 110, wie erwartet, wenn Sie die Zustände der ersten beiden Räume kombinieren. Dies muss von K abgezogen werden, da diese ersten 110 Zustände bereits in den ersten beiden Feldern berücksichtigt worden wären. Damit bleiben uns 82 Staaten. In diesem Zahlensystem ist die Darstellung von 192 in der Basis 10 also 082. 

Der C # -Code, der einen Basisindex von Null verwendet, lautet

    private string ExcelColumnIndexToName(int Index)
    {
        string range = string.Empty;
        if (Index < 0 ) return range;
        int a = 26;
        int x = (int)Math.Floor(Math.Log((Index) * (a - 1) / a + 1, a));
        Index -= (int)(Math.Pow(a, x) - 1) * a / (a - 1);
        for (int i = x+1; Index + i > 0; i--)
        {
            range = ((char)(65 + Index % a)).ToString() + range;
            Index /= a;
        }
        return range;
    }

// Alte Post

Eine nullbasierte Lösung in C #.

    private string ExcelColumnIndexToName(int Index)
    {
        string range = "";
        if (Index < 0 ) return range;
        for(int i=1;Index + i > 0;i=0)
        {
            range = ((char)(65 + Index % 26)).ToString() + range;
            Index /= 26;
        }
        if (range.Length > 1) range = ((char)((int)range[0] - 1)).ToString() + range.Substring(1);
        return range;
    }
13
John

Einfach mit Rekursion.

public static string GetStandardExcelColumnName(int columnNumberOneBased)
{
  int baseValue = Convert.ToInt32('A');
  int columnNumberZeroBased = columnNumberOneBased - 1;

  string ret = "";

  if (columnNumberOneBased > 26)
  {
    ret = GetStandardExcelColumnName(columnNumberZeroBased / 26) ;
  }

  return ret + Convert.ToChar(baseValue + (columnNumberZeroBased % 26) );
}
9
Peter
int nCol = 127;
string sChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string sCol = "";
while (nCol >= 26)
{
    int nChar = nCol % 26;
    nCol = (nCol - nChar) / 26;
    // You could do some trick with using nChar as offset from 'A', but I am lazy to do it right now.
    sCol = sChars[nChar] + sCol;
}
sCol = sChars[nCol] + sCol;

Update: Der Kommentar von Peter ist richtig. Das ist was ich für das Schreiben von Code im Browser bekomme. :-) Meine Lösung wurde nicht kompiliert, es fehlte der am weitesten links stehende Buchstabe und der Aufbau der Zeichenfolge in umgekehrter Reihenfolge - alles jetzt behoben.

Abgesehen von den Fehlern konvertiert der Algorithmus im Wesentlichen eine Zahl von Basis 10 in Basis 26.

Update 2: Joel Coehoorn ist richtig - der obige Code gibt AB für 27 zurück. Wenn es sich um eine echte Basis 26-Nummer handelt, wäre AA gleich A und die nächste Nummer nach Z wäre BA.

int nCol = 127;
string sChars = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string sCol = "";
while (nCol > 26)
{
    int nChar = nCol % 26;
    if (nChar == 0)
        nChar = 26;
    nCol = (nCol - nChar) / 26;
    sCol = sChars[nChar] + sCol;
}
if (nCol != 0)
    sCol = sChars[nCol] + sCol;
9
Franci Penov

Diese Antwort ist in JavaScript:

function getCharFromNumber(columnNumber){
    var dividend = columnNumber;
    var columnName = "";
    var modulo;

    while (dividend > 0)
    {
        modulo = (dividend - 1) % 26;
        columnName = String.fromCharCode(65 + modulo).toString() + columnName;
        dividend = parseInt((dividend - modulo) / 26);
    } 
    return  columnName;
}
8
MaVRoSCy

..Und in PHP umgewandelt:

function GetExcelColumnName($columnNumber) {
    $columnName = '';
    while ($columnNumber > 0) {
        $modulo = ($columnNumber - 1) % 26;
        $columnName = chr(65 + $modulo) . $columnName;
        $columnNumber = (int)(($columnNumber - $modulo) / 26);
    }
    return $columnName;
}
7
Stephen Fuhry

Ich bin überrascht, dass alle Lösungen bisher entweder Iteration oder Rekursion enthalten.

Hier ist meine Lösung, die in konstanter Zeit läuft (keine Schleifen). Diese Lösung funktioniert für alle möglichen Excel-Spalten und überprüft, ob die Eingabe in eine Excel-Spalte umgewandelt werden kann. Mögliche Spalten liegen im Bereich [A, XFD] oder [1, 16384]. (Dies ist abhängig von Ihrer Version von Excel)

private static string Turn(uint col)
{
    if (col < 1 || col > 16384) //Excel columns are one-based (one = 'A')
        throw new ArgumentException("col must be >= 1 and <= 16384");

    if (col <= 26) //one character
        return ((char)(col + 'A' - 1)).ToString();

    else if (col <= 702) //two characters
    {
        char firstChar = (char)((int)((col - 1) / 26) + 'A' - 1);
        char secondChar = (char)(col % 26 + 'A' - 1);

        if (secondChar == '@') //Excel is one-based, but modulo operations are zero-based
            secondChar = 'Z'; //convert one-based to zero-based

        return string.Format("{0}{1}", firstChar, secondChar);
    }

    else //three characters
    {
        char firstChar = (char)((int)((col - 1) / 702) + 'A' - 1);
        char secondChar = (char)((col - 1) / 26 % 26 + 'A' - 1);
        char thirdChar = (char)(col % 26 + 'A' - 1);

        if (thirdChar == '@') //Excel is one-based, but modulo operations are zero-based
            thirdChar = 'Z'; //convert one-based to zero-based

        return string.Format("{0}{1}{2}", firstChar, secondChar, thirdChar);
    }
}
7
user2023861

Gleiche Implementierung in Java 

public String getExcelColumnName (int columnNumber) 
    {     
        int dividend = columnNumber;   
        int i;
        String columnName = "";     
        int modulo;     
        while (dividend > 0)     
        {        
            modulo = (dividend - 1) % 26;         
            i = 65 + modulo;
            columnName = new Character((char)i).toString() + columnName;        
            dividend = (int)((dividend - modulo) / 26);    
        }       
        return columnName; 
    }  
6
Balaji.N.S

Ein bisschen spät im Spiel, aber hier ist der Code, den ich verwende (in C #):

private static readonly string _Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static int ColumnNameParse(string value)
{
    // assumes value.Length is [1,3]
    // assumes value is uppercase
    var digits = value.PadLeft(3).Select(x => _Alphabet.IndexOf(x));
    return digits.Aggregate(0, (current, index) => (current * 26) + (index + 1));
}
5
Kelly L

Ich wollte meine statische Klasse verwenden, die ich benutze, um zwischen Col-Index und Col-Label zu wechseln. Ich verwende eine modifizierte akzeptierte Antwort für meine ColumnLabel-Methode

public static class Extensions
{
    public static string ColumnLabel(this int col)
    {
        var dividend = col;
        var columnLabel = string.Empty;
        int modulo;

        while (dividend > 0)
        {
            modulo = (dividend - 1) % 26;
            columnLabel = Convert.ToChar(65 + modulo).ToString() + columnLabel;
            dividend = (int)((dividend - modulo) / 26);
        } 

        return columnLabel;
    }
    public static int ColumnIndex(this string colLabel)
    {
        // "AD" (1 * 26^1) + (4 * 26^0) ...
        var colIndex = 0;
        for(int ind = 0, pow = colLabel.Count()-1; ind < colLabel.Count(); ++ind, --pow)
        {
            var cVal = Convert.ToInt32(colLabel[ind]) - 64; //col A is index 1
            colIndex += cVal * ((int)Math.Pow(26, pow));
        }
        return colIndex;
    }
}

Verwenden Sie dies wie ...

30.ColumnLabel(); // "AD"
"AD".ColumnIndex(); // 30
5
t3dodson

Fügen Sie einfach eine einfache zweizeilige C # -Implementierung mit Rekursion ein, da alle Antworten hier viel komplizierter erscheinen als notwendig.

/// <summary>
/// Gets the column letter(s) corresponding to the given column number.
/// </summary>
/// <param name="column">The one-based column index. Must be greater than zero.</param>
/// <returns>The desired column letter, or an empty string if the column number was invalid.</returns>
public static string GetColumnLetter(int column) {
    if (column < 1) return String.Empty;
    return GetColumnLetter((column - 1) / 26) + (char)('A' + (column - 1) % 26);
}
5
Extragorey

Nachdem ich mir alle mitgelieferten Versionen angesehen hatte, ging ich hinunter, um eine selbst zu machen, indem ich Rekursion verwendete.

Hier ist meine vb.net-Version:

Function CL(ByVal x As Integer) As String
    If x >= 1 And x <= 26 Then
        CL = Chr(x + 64)
    Else
        CL = CL((x - x Mod 26) / 26) & Chr((x Mod 26) + 1 + 64)
    End If
End Function
5
user932708

wenn Sie es nur für eine Zellenformel ohne Code wünschen, hier eine Formel dafür:

IF(COLUMN()>=26,CHAR(ROUND(COLUMN()/26,1)+64)&CHAR(MOD(COLUMN(),26)+64),CHAR(COLUMN()+64))
4
Matt Lewis

In Delphi (Pascal):

function GetExcelColumnName(columnNumber: integer): string;
var
  dividend, modulo: integer;
begin
  Result := '';
  dividend := columnNumber;
  while dividend > 0 do begin
    modulo := (dividend - 1) mod 26;
    Result := Chr(65 + modulo) + Result;
    dividend := (dividend - modulo) div 26;
  end;
end;
4
JRL
private String getColumn(int c) {
    String s = "";
    do {
        s = (char)('A' + (c % 26)) + s;
        c /= 26;
    } while (c-- > 0);
    return s;
}

Es ist nicht genau die Basis 26, es gibt keine 0 im System. Wenn ja, würde auf 'Z' 'BA' folgen, nicht 'AA'.

3
rubberduckie

In Perl für eine Eingabe von 1 (A), 27 (AA) usw.

sub Excel_colname {
  my ($idx) = @_;       # one-based column number
  --$idx;               # zero-based column index
  my $name = "";
  while ($idx >= 0) {
    $name .= chr(ord("A") + ($idx % 26));
    $idx   = int($idx / 26) - 1;
  }
  return scalar reverse $name;
}
2
Myforwik

JavaScript-Lösung

/**
 * Calculate the column letter abbreviation from a 1 based index
 * @param {Number} value
 * @returns {string}
 */
getColumnFromIndex = function (value) {
    var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
    var remainder, result = "";
    do {
        remainder = value % 26;
        result = base[(remainder || 26) - 1] + result;
        value = Math.floor(value / 26);
    } while (value > 0);
    return result;
};
2
Ally

Verfeinern der ursprünglichen Lösung (in C #):

public static class ExcelHelper
{
    private static Dictionary<UInt16, String> l_DictionaryOfColumns;

    public static ExcelHelper() {
        l_DictionaryOfColumns = new Dictionary<ushort, string>(256);
    }

    public static String GetExcelColumnName(UInt16 l_Column)
    {
        UInt16 l_ColumnCopy = l_Column;
        String l_Chars = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String l_rVal = "";
        UInt16 l_Char;


        if (l_DictionaryOfColumns.ContainsKey(l_Column) == true)
        {
            l_rVal = l_DictionaryOfColumns[l_Column];
        }
        else
        {
            while (l_ColumnCopy > 26)
            {
                l_Char = l_ColumnCopy % 26;
                if (l_Char == 0)
                    l_Char = 26;

                l_ColumnCopy = (l_ColumnCopy - l_Char) / 26;
                l_rVal = l_Chars[l_Char] + l_rVal;
            }
            if (l_ColumnCopy != 0)
                l_rVal = l_Chars[l_ColumnCopy] + l_rVal;

            l_DictionaryOfColumns.ContainsKey(l_Column) = l_rVal;
        }

        return l_rVal;
    }
}
2
ShloEmi

Hier ist eine Actionscript-Version:

private var columnNumbers:Array = ['A', 'B', 'C', 'D', 'E', 'F' , 'G', 'H', 'I', 'J', 'K' ,'L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];

    private function getExcelColumnName(columnNumber:int) : String{
        var dividend:int = columnNumber;
        var columnName:String = "";
        var modulo:int;

        while (dividend > 0)
        {
            modulo = (dividend - 1) % 26;
            columnName = columnNumbers[modulo] + columnName;
            dividend = int((dividend - modulo) / 26);
        } 

        return columnName;
    }
2
Rob

Ein anderer VBA-Weg

Public Function GetColumnName(TargetCell As Range) As String
    GetColumnName = Split(CStr(TargetCell.Address), "$")(1)
End Function
2
Paul Ma

Dies ist eine Javascript-Version gemäß dem Code von Graham

function (columnNumber) {
    var dividend = columnNumber;
    var columnName = "";
    var modulo;

    while (dividend > 0) {
        modulo = (dividend - 1) % 26;
        columnName = String.fromCharCode(65 + modulo) + columnName;
        dividend = parseInt((dividend - modulo) / 26);
    }

    return columnName;
};
1
Kevin

Ich versuche dasselbe in Java zu tun ....__ Ich habe folgenden Code geschrieben:

private String getExcelColumnName(int columnNumber) {

    int dividend = columnNumber;
    String columnName = "";
    int modulo;

    while (dividend > 0)
    {
        modulo = (dividend - 1) % 26;

        char val = Character.valueOf((char)(65 + modulo));

        columnName += val;

        dividend = (int)((dividend - modulo) / 26);
    } 

    return columnName;
}

Sobald ich es mit columnNumber = 29 ausgeführt habe, gibt es das Ergebnis = "CA" (anstelle von "AC") Gibt es irgendwelche Kommentare, die mir fehlen? Aber als ich die Antwort des Graham sah, bin ich wenig verwirrt ....

1
Hasan

Dies ist die Frage, die von allen anderen sowie von Google weitergeleitet wird. Ich poste dies hier.

Viele dieser Antworten sind korrekt, aber für einfache Situationen zu umständlich, beispielsweise wenn Sie nicht über 26 Spalten haben. Wenn Sie Zweifel haben, ob Sie in doppelte Zeichensäulen gehen, ignorieren Sie diese Antwort. Wenn Sie sich jedoch sicher sind, dass Sie dies nicht tun, können Sie dies in C # so einfach wie folgt tun:

public static char ColIndexToLetter(short index)
{
    if (index < 0 || index > 25) throw new ArgumentException("Index must be between 0 and 25.");
    return (char)('A' + index);
}

Heck, wenn Sie sich sicher sind, was Sie übergeben, können Sie die Validierung sogar entfernen und diese Inline verwenden:

(char)('A' + index)

Dies wird in vielen Sprachen sehr ähnlich sein, sodass Sie es bei Bedarf anpassen können.

Auch hier gilt nur dann, wenn Sie zu 100% sicher sind, dass Sie nicht mehr als 26 Spalten haben werden.

1

Sorry, das ist Python statt C #, aber zumindest sind die Ergebnisse korrekt

def Excel_column_number_to_name(column_number):
    output = ""
    index = column_number-1
    while index >= 0:
        character = chr((index%26)+ord('A'))
        output = output + character
        index = index/26 - 1

    return output[::-1]


for i in xrange(1, 1024):
    print "%4d : %s" % (i, Excel_column_number_to_name(i))

Bestanden diese Testfälle:

  • Spaltennummer: 494286 => ABCDZ 
  • Spaltennummer: 27 => AA
  • Spaltennummer: 52 => AZ
1
DataEngineer

Obwohl ich zu spät komme, ist Grahams Antwort alles andere als optimal. Insbesondere müssen Sie nicht die Variable modulo verwenden, ToString() aufrufen und (int) cast anwenden. Wenn man bedenkt, dass in den meisten Fällen in der C # -Welt Sie mit der Nummerierung von 0 beginnen würden, hier meine Überarbeitung:

public static string GetColumnName(int index) // zero-based
{
    const byte BASE = 'Z' - 'A' + 1;
    string name = String.Empty;

    do
    {
        name = Convert.ToChar('A' + index % BASE) + name;
        index = index / BASE - 1;
    }
    while (index >= 0);

    return name;
}
1
Herman Kan

Mit diesen Codes kann eine bestimmte Nummer (Indexstart von 1) in eine Excel-Spalte umgewandelt werden.

    public static string NumberToExcelColumn(uint number)
    {
        uint originalNumber = number;

        uint numChars = 1;
        while (Math.Pow(26, numChars) < number)
        {
            numChars++;

            if (Math.Pow(26, numChars) + 26 >= number)
            {
                break;
            }               
        }

        string toRet = "";
        uint lastValue = 0;

        do
        {
            number -= lastValue;

            double powerVal = Math.Pow(26, numChars - 1);
            byte thisCharIdx = (byte)Math.Truncate((columnNumber - 1) / powerVal);
            lastValue = (int)powerVal * thisCharIdx;

            if (numChars - 2 >= 0)
            {
                double powerVal_next = Math.Pow(26, numChars - 2);
                byte thisCharIdx_next = (byte)Math.Truncate((columnNumber - lastValue - 1) / powerVal_next);
                int lastValue_next = (int)Math.Pow(26, numChars - 2) * thisCharIdx_next;

                if (thisCharIdx_next == 0 && lastValue_next == 0 && powerVal_next == 26)
                {
                    thisCharIdx--;
                    lastValue = (int)powerVal * thisCharIdx;
                }
            }

            toRet += (char)((byte)'A' + thisCharIdx + ((numChars > 1) ? -1 : 0));

            numChars--;
        } while (numChars > 0);

        return toRet;
    }

Mein Unit-Test:

    [TestMethod]
    public void Test()
    {
        Assert.AreEqual("A", NumberToExcelColumn(1));
        Assert.AreEqual("Z", NumberToExcelColumn(26));
        Assert.AreEqual("AA", NumberToExcelColumn(27));
        Assert.AreEqual("AO", NumberToExcelColumn(41));
        Assert.AreEqual("AZ", NumberToExcelColumn(52));
        Assert.AreEqual("BA", NumberToExcelColumn(53));
        Assert.AreEqual("ZZ", NumberToExcelColumn(702));
        Assert.AreEqual("AAA", NumberToExcelColumn(703));
        Assert.AreEqual("ABC", NumberToExcelColumn(731));
        Assert.AreEqual("ACQ", NumberToExcelColumn(771));
        Assert.AreEqual("AYZ", NumberToExcelColumn(1352));
        Assert.AreEqual("AZA", NumberToExcelColumn(1353));
        Assert.AreEqual("AZB", NumberToExcelColumn(1354));
        Assert.AreEqual("BAA", NumberToExcelColumn(1379));
        Assert.AreEqual("CNU", NumberToExcelColumn(2413));
        Assert.AreEqual("GCM", NumberToExcelColumn(4823));
        Assert.AreEqual("MSR", NumberToExcelColumn(9300));
        Assert.AreEqual("OMB", NumberToExcelColumn(10480));
        Assert.AreEqual("ULV", NumberToExcelColumn(14530));
        Assert.AreEqual("XFD", NumberToExcelColumn(16384));
    }
1
S_R

Bereits mehr als 30 Lösungen, aber hier ist meine einzeilige C # -Lösung ...

public string IntToExcelColumn(int i)
{
    return ((i<16926? "" : ((char)((((i/26)-1)%26)+65)).ToString()) + (i<2730? "" : ((char)((((i/26)-1)%26)+65)).ToString()) + (i<26? "" : ((char)((((i/26)-1)%26)+65)).ToString()) + ((char)((i%26)+65)));
}
1
AlishahNovin

Hier ist meine super späte Implementierung in PHP. Dies ist rekursiv. Ich habe es geschrieben, bevor ich diesen Beitrag gefunden habe. Ich wollte sehen, ob andere dieses Problem bereits gelöst hatten ...

public function GetColumn($intNumber, $strCol = null) {

    if ($intNumber > 0) {
        $intRem = ($intNumber - 1) % 26;
        $strCol = $this->GetColumn(intval(($intNumber - $intRem) / 26), sprintf('%s%s', chr(65 + $intRem), $strCol));
    }

    return $strCol;
}
1
Gordon Freeman

Prägnant und elegant Ruby Version:

def col_name(col_idx)
    name = ""
    while col_idx>0
        mod     = (col_idx-1)%26
        name    = (65+mod).chr + name
        col_idx = ((col_idx-mod)/26).to_i
    end
    name
end
0
Iwan B.

NodeJS-Implementierung:

/**
* getColumnFromIndex
* Helper that returns a column value (A-XFD) for an index value (integer).
* The column follows the Common Spreadsheet Format e.g., A, AA, AAA.
* See https://stackoverflow.com/questions/181596/how-to-convert-a-column-number-eg-127-into-an-Excel-column-eg-aa/3444285#3444285
* @param numVal: Integer
* @return String
*/
getColumnFromIndex: function(numVal){
   var dividend = parseInt(numVal);
   var columnName = '';
   var modulo;
   while (dividend > 0) {
      modulo = (dividend - 1) % 26;
      columnName = String.fromCharCode(65 + modulo) + columnName;
      dividend = parseInt((dividend - modulo) / 26);
   }
   return columnName;
},

Dank Konvertieren Sie das Excel-Spaltenalphabet (z. B. AA) in die Zahl (z. B. 25) . Und umgekehrt:

/**
* getIndexFromColumn
* Helper that returns an index value (integer) for a column value (A-XFD).
* The column follows the Common Spreadsheet Format e.g., A, AA, AAA.
* See https://stackoverflow.com/questions/9905533/convert-Excel-column-alphabet-e-g-aa-to-number-e-g-25
* @param strVal: String
* @return Integer
*/
getIndexFromColumn: function(val){
   var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', i, j, result = 0;
   for (i = 0, j = val.length - 1; i < val.length; i += 1, j -= 1) {
      result += Math.pow(base.length, j) * (base.indexOf(val[i]) + 1);
   }
   return result;
}
0
Rob Sawyer

Eine andere Lösung:

private void Foo()
{
   l_ExcelApp = new Excel.ApplicationClass();
   l_ExcelApp.ReferenceStyle = Excel.XlReferenceStyle.xlR1C1;
   // ... now reference by R[row]C[column], Ex. A1 <==> R1C1, C6 <==> R3C6, ...
}

mehr dazu hier - Zellreferenzierung in Excel für alle! von Dr Nitin Paranjape

0
ShloEmi

Ich musste diese Arbeit heute nur machen, meine Implementierung verwendet Rekursion:

private static string GetColumnLetter(string colNumber)
{
    if (string.IsNullOrEmpty(colNumber))
    {
        throw new ArgumentNullException(colNumber);
    }

    string colName = String.Empty;

    try
    {
        var colNum = Convert.ToInt32(colNumber);
        var mod = colNum % 26;
        var div = Math.Floor((double)(colNum)/26);
        colName = ((div > 0) ? GetColumnLetter((div - 1).ToString()) : String.Empty) + Convert.ToChar(mod + 65);
    }
    finally
    {
        colName = colName == String.Empty ? "A" : colName;
    }

    return colName;
}

Dies betrachtet die Zahl als Zeichenfolge, die Methode und die Zahlen, die mit "0" beginnen (A = 0).

0
Madison Tobal

Eine weitere VBA-Antwort sah - dies kann in Excel-vba mit einer 1-Zeilen-UDF:.

Function GetColLetter(ByVal colID As Integer) As String
    GetColLetter = Split(Cells(1, colID).Address, "$")(1)
End Function
0
Sam

Hier ist, was es wert ist, Grahams Code in Powershell:

function ConvertTo-ExcelColumnID {
param (
    [parameter(Position = 0,
        HelpMessage = "A 1-based index to convert to an Excel column ID. e.g. 2 => 'B', 29 => 'AC'",
        Mandatory = $true)]
    [int]$index
);

[string]$result = '';
if ($index -le 0 ) {
    return $result;
}

while ($index -gt 0) {
    [int]$modulo = ($index - 1) % 26;
    $character = [char]($modulo + [int][char]'A');
    $result = $character + $result;
    [int]$index = ($index - $modulo) / 26;
}

return $result;

}

0
user1098928

Verwenden Sie dies in VB.Net 2005:

Private Function ColumnName(ByVal ColumnIndex As Integer) As String

   Dim Name As String = ""

   Name = (New Microsoft.Office.Interop.Owc11.Spreadsheet).Columns.Item(ColumnIndex).Address(False, False, Microsoft.Office.Interop.Owc11.XlReferenceStyle.xlA1)
   Name = Split(Name, ":")(0)

   Return Name

End Function
0
user121385

Die meisten vorherigen Antworten sind korrekt. Hier ist eine weitere Möglichkeit, die Spaltennummer in Excel-Spalten umzuwandeln. Die Lösung ist ziemlich einfach, wenn wir dies als Basisumwandlung betrachten. Wandeln Sie einfach die Spaltennummer in Basis 26 um, da nur 26 Buchstaben vorhanden sind ..__ So können Sie dies tun: 

Schritte:

  • setzen Sie die Spalte als Quotienten

  • subtrahieren Sie eins von der Quotientenvariablen (vom vorherigen Schritt), da wir auf ascii table enden müssen, wobei 97 a ist.

  • durch 26 teilen und den Rest erhalten.

  • +97 zu rest hinzufügen und in char konvertieren (da 97 in der ASCII - Tabelle "a" ist)
  • quotient wird zum neuen Quotienten/26 (da wir möglicherweise 26 Spalten überschreiten)
  • fahren Sie damit fort, bis der Quotient größer als 0 ist, und geben Sie das Ergebnis zurück

hier ist der Code, der das tut :)

def convert_num_to_column(column_num):
    result = ""
    quotient = column_num
    remainder = 0
    while (quotient >0):
        quotient = quotient -1
        remainder = quotient%26
        result = chr(int(remainder)+97)+result
        quotient = int(quotient/26)
    return result

print("--",convert_num_to_column(1).upper())
0
grepit
public static string ConvertToAlphaColumnReferenceFromInteger(int columnReference)
    {
        int baseValue = ((int)('A')) - 1 ;
        string lsReturn = String.Empty; 

        if (columnReference > 26) 
        {
            lsReturn = ConvertToAlphaColumnReferenceFromInteger(Convert.ToInt32(Convert.ToDouble(columnReference / 26).ToString().Split('.')[0]));
        } 

        return lsReturn + Convert.ToChar(baseValue + (columnReference % 26));            
    }
0
Daniel

Danke für die Antworten hier !! Ich habe mit diesen Hilfsfunktionen für die Interaktion mit der Google Sheets-API gearbeitet, an der ich in Elixir/Phoenix arbeite

hier ist, was ich kam (könnte wahrscheinlich etwas zusätzliche Validierung und Fehlerbehandlung verwenden)

In Elixir:

def number_to_column(number) do
  cond do
    (number > 0 && number <= 26) ->
      to_string([(number + 64)])
    (number > 26) ->
      div_col = number_to_column(div(number - 1, 26))
      remainder = rem(number, 26)
      rem_col = cond do
        (remainder == 0) ->
          number_to_column(26)
        true ->
          number_to_column(remainder)
      end
      div_col <> rem_col
    true ->
      ""
  end
end

Und die Umkehrfunktion: 

def column_to_number(column) do
  column
    |> to_charlist
    |> Enum.reverse
    |> Enum.with_index
    |> Enum.reduce(0, fn({char, idx}, acc) ->
      ((char - 64) * :math.pow(26,idx)) + acc
    end)
    |> round
end

Und einige Tests:

describe "test Excel functions" do
  @excelTestData [{"A", 1}, {"Z",26}, {"AA", 27}, {"AB", 28}, {"AZ", 52},{"BA", 53}, {"AAA", 703}]

  test "column to number" do
    Enum.each(@excelTestData, fn({input, expected_result}) ->
      actual_result = BulkOnboardingController.column_to_number(input)
      assert actual_result == expected_result
    end)
  end

  test "number to column" do
    Enum.each(@excelTestData, fn({expected_result, input}) ->
      actual_result = BulkOnboardingController.number_to_column(input)
      assert actual_result == expected_result
    end)
  end
end
0
phlare

So würde ich es in Python machen. Der Algorithmus wird unten erklärt:

alph = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z')
def labelrec(n, res):
    if n<26:
        return alph[n]+res
    else:
        rem = n%26
        res = alph[rem]+res
        n = n/26-1
        return labelrec(n, res)

Die Funktion labelrec kann mit der Nummer und einer leeren Zeichenfolge aufgerufen werden:

print labelrec(16383, '')

Deshalb funktioniert es: Wenn Dezimalzahlen auf dieselbe Weise wie Excel-Arbeitsblattspalten geschrieben würden, würde die Zahl 0-9 normal geschrieben, aber 10 würde '00' und dann 20 '10' und so weiter. Einige Zahlen zuordnen:

0 - 0

9 - 9

10 - 00 Uhr

20 - 10

100 - 90

110 - 000

1110 - 0000

Das Muster ist also klar. Wenn an der Stelle der Einheit eine Zahl kleiner als 10 ist, entspricht ihre Darstellung der Zahl selbst. Andernfalls müssen Sie die verbleibende Zahl anpassen, indem Sie sie um 1 subtrahieren und erneut rekursieren. Sie können anhalten, wenn die Anzahl weniger als 10 beträgt.

Die gleiche Logik wird für die Nummern der Basis 26 in der obigen Lösung angewendet.

P.S. Wenn Sie möchten, dass die Zahlen bei 1 beginnen, rufen Sie dieselbe Funktion für die Eingangsnummer auf, nachdem Sie sie um 1 verringert haben.

0
lambdapilgrim

Wenn Sie die Zelle progmatisch referenzieren möchten, erhalten Sie viel besser lesbaren Code, wenn Sie die Cells-Methode eines Arbeitsblatts verwenden. Statt einer traditionellen Zellreferenz wird ein Zeilen- und Spaltenindex verwendet. Es ist der Offset-Methode sehr ähnlich.

0
pipTheGeek

(Mir ist klar, dass sich die Frage auf C # bezieht. Wenn jedoch jemand mit Java dasselbe tun muss, kann Folgendes hilfreich sein.

Es stellt sich heraus, dass dies mit der Klasse "CellReference" in Jakarta POI problemlos möglich ist. Die Konvertierung kann auch auf zwei Arten erfolgen.

// Convert row and column numbers (0-based) to an Excel cell reference
CellReference numbers = new CellReference(3, 28);
System.out.println(numbers.formatAsString());

// Convert an Excel cell reference back into digits
CellReference reference = new CellReference("AC4");
System.out.println(reference.getRow() + ", " + reference.getCol());
0
Ian

F # -Version jedes Weges

let rec getExcelColumnName x  = if x<26 then int 'A'+x|>char|>string else (x/26-1|>c)+ c(x%26)

verzeihung der Minimierung, arbeitete an einer besseren Version von https://stackoverflow.com/a/4500043/57883


.__ und die entgegengesetzte Richtung:

// return values start at 0
let getIndexFromExcelColumnName (x:string) =
    let a = int 'A'
    let fPow len i =
        Math.Pow(26., len - 1 - i |> float)
        |> int

    let getValue len i c = 
        int c - a + 1 * fPow len i
    let f i = getValue x.Length i x.[i]
    [0 .. x.Length - 1]
    |> Seq.map f
    |> Seq.sum
    |> fun x -> x - 1
0
Maslow

Ich verwende dieses in VB.NET 2003 und es funktioniert gut ...

Private Function GetExcelColumnName(ByVal aiColNumber As Integer) As String
    Dim BaseValue As Integer = Convert.ToInt32(("A").Chars(0)) - 1
    Dim lsReturn As String = String.Empty

    If (aiColNumber > 26) Then
        lsReturn = GetExcelColumnName(Convert.ToInt32((Format(aiColNumber / 26, "0.0").Split("."))(0)))
    End If

    GetExcelColumnName = lsReturn + Convert.ToChar(BaseValue + (aiColNumber Mod 26))
End Function
0
Manuel

Ziel-C-Implementierung:

-(NSString*)getColumnName:(int)n {
     NSString *name = @"";
     while (n>0) {
     n--;
     char c = (char)('A' + n%26);
     name = [NSString stringWithFormat:@"%c%@",c,name];
     n = n/26;
  }    
     return name;

}

Schnelle Implementierung:

func getColumnName(n:Int)->String{
 var columnName = ""
 var index = n
 while index>0 {
     index--
     let char = Character(UnicodeScalar(65 + index%26))
     columnName = "\(char)\(columnName)"
     index = index / 26
 }
 return columnName

}

Die Antwort basiert auf: https://stackoverflow.com/a/4532562/2231118

0
bpolat