558 votes

Comment convertir un numéro de colonne (par exemple 127) en une colonne Excel (par exemple AA) ?

Comment convertir un nombre numérique en un nom de colonne Excel en C# sans utiliser l'automatisation en obtenant la valeur directement d'Excel.

Excel 2007 a une plage possible de 1 à 16384, qui est le nombre de colonnes qu'il prend en charge. Les valeurs obtenues doivent être sous la forme de noms de colonnes Excel, par exemple A, AA, AAA, etc.

2 votes

Sans oublier qu'il existe des limites dans le nombre de colonnes disponibles. Par exemple, * Excel 2003 (v11) va jusqu'à IV, 2^8 ou 256 colonnes). * Excel 2007 (v12) va jusqu'à XFD, 2^14 ou 16384 colonnes.

1 votes

0 votes

Cette question est étiquetée C# et excel. Je signale cette question comme étant dépassée, parce que nous vivons en 2016 et qu'il y a EPPLUS . Une bibliothèque C# couramment utilisée pour créer des feuilles de calcul Excel avancées sur le serveur. Qui est mise à disposition sous : GNU Library General Public License (LGPL). En utilisant EPPlus, vous pouvez facilement obtenir la chaîne Column.

1054voto

Graham Points 5475

Voici comment je fais :

private string GetExcelColumnName(int columnNumber)
{
    string columnName = "";

    while (columnNumber > 0)
    {
        int modulo = (columnNumber - 1) % 26;
        columnName = Convert.ToChar('A' + modulo) + columnName;
        columnNumber = (columnNumber - modulo) / 26;
    } 

    return columnName;
}

76 votes

Ce code fonctionne bien. Il suppose que la colonne A est la colonne numéro 1. J'ai dû faire un changement rapide pour tenir compte du fait que mon système utilise la colonne A comme numéro de colonne 0. J'ai changé la ligne int dividend en int dividend = numéro de colonne + 1 ; Keith.

0 votes

Vous pourriez probablement rendre cette opération légèrement plus rapide en supprimant les concaténations de chaînes et en utilisant un StringBuilder. Je travaille avec OpenXML, j'ai donc besoin de toute la vitesse possible. +1 cependant, c'est correct.

16 votes

@Jduv vient de l'essayer en utilisant StringBuilder . Cela prend environ deux fois plus de temps. Il s'agit d'une chaîne très courte (3 caractères maximum - Excel 2010 va jusqu'à la colonne XFD), donc 2 concaténations de chaîne maximum. (J'ai utilisé 100 itérations de traduction des entiers 1 à 16384, c'est-à-dire les colonnes Excel A à XFD, comme test).

67voto

vzczc Points 4923

Si quelqu'un a besoin de faire cela dans Excel sans VBA, voici un moyen :

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

où colNum est le numéro de la colonne

Et en 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

2 votes

Exemple : =SUBSTITUTE(TEXT(ADDRESS(1,1000,4),""), "1","")

0 votes

Oui, j'utilise Excel dans une région où ; est utilisé à la place de , pour séparer les arguments des fonctions dans Excel. Merci de me l'avoir signalé.

2 votes

Je l'ai fait sans la fonction TEXTE. À quoi sert la fonction TEXT ?

28voto

RoMa Points 401

Désolé, c'est du Python au lieu du C#, mais au moins les résultats sont corrects :

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))

0 votes

Oui j'ai downVoté, ne postez pas Python quand la question est C#. Et oui, plus de gens devraient le faire.

5 votes

Le titre de la question n'implique pas C#, donc beaucoup de gens peuvent venir ici qui n'attendent pas C#. Donc, merci de partager en Python !

14voto

John Points 71

J'ai découvert une erreur dans mon premier message, alors j'ai décidé de m'asseoir et de faire les calculs. J'ai découvert que le système numérique utilisé pour identifier les colonnes d'Excel n'est pas un système en base 26, comme l'a indiqué une autre personne. Considérez ce qui suit en base 10. Vous pouvez également le faire avec les lettres de l'alphabet.

Espace : .........................S1, S2, S3 : S1, S2, S3
....................................0, 00, 000 :.. A, AA, AAA
....................................1, 01, 001 :.. B, AB, AAB
.................................... ..., ..., ... :.. ..., ..., ...
....................................9, 99, 999 :.. Z, ZZ, ZZZ
Total des états dans l'espace : 10, 100, 1000 : 26, 676, 17576
Total des États : ...............1110................18278

Excel numérote les colonnes dans les différents espaces alphabétiques en utilisant la base 26. Vous pouvez voir qu'en général, la progression de l'espace d'état est a, a^2, a^3, pour une certaine base a, et le nombre total d'états est a + a^2 + a^3 + .

Supposons que l'on veuille trouver le nombre total d'états A dans les N premiers espaces. La formule pour le faire est A = (a)(a^N - 1 )/(a-1). Cette formule est importante car nous devons trouver l'espace N qui correspond à notre indice K. Si je veux savoir où se situe K dans le système numérique, je dois remplacer A par K et résoudre N. La solution est N = log{base a} (A (a-1)/a +1). Si je prends l'exemple de a = 10 et K = 192, je sais que N = 2,23804 . Cela m'indique que K se trouve au début du troisième espace puisqu'il est un peu plus grand que deux.

L'étape suivante consiste à déterminer exactement à quelle distance dans l'espace actuel nous nous trouvons. Pour cela, il faut soustraire de K le A généré en utilisant le plancher de N. Dans cet exemple, le plancher de N est de deux. Donc, A = (10)(10^2 - 1)/(10-1) = 110, comme on peut s'y attendre lorsque l'on combine les états des deux premiers espaces. Cela doit être soustrait de K parce que ces 110 premiers états auraient déjà été pris en compte dans les deux premiers espaces. Il nous reste donc 82 états. Ainsi, dans ce système numérique, la représentation de 192 en base 10 est 082.

Le code C# utilisant un indice de base de zéro est le suivant

    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;
    }

//Old Post

Une solution à base de zéro en 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;
    }

1 votes

Ooh je ne sais pas pourquoi mais j'aime cette solution. Rien de fantaisiste, juste une bonne utilisation de la logique... un code facilement lisible pour tous les niveaux de programmeurs. Une chose cependant, je crois que c'est la meilleure pratique pour spécifier une chaîne vide en C# comme string range = string.Empty ;

0 votes

Oui, très bonne explication. Mais pourriez-vous également préciser que ce n'est pas non plus la base 27 ? Votre explication le montre lorsqu'elle est étudiée, mais une mention rapide en haut de page pourrait faire gagner du temps à quelques autres personnes.

10voto

Franci Penov Points 45358
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;

Mise à jour : Peter Le commentaire de l'auteur est juste. C'est ce qui arrive quand on écrit du code dans le navigateur :-) Ma solution ne compilait pas, il lui manquait la lettre la plus à gauche et elle construisait la chaîne de caractères dans l'ordre inverse - tout est maintenant corrigé.

Les bogues mis à part, l'algorithme consiste essentiellement à convertir un nombre de la base 10 à la base 26.

Mise à jour 2 : Joel Coehoorn a raison - le code ci-dessus retournera AB pour 27. S'il s'agissait d'un vrai nombre en base 26, AA serait égal à A et le nombre suivant après Z serait 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;

0 votes

Le code ne compile pas (sCol non initialisé). S'il le fait, il ne donnera pas la bonne réponse.

6 votes

CETTE RÉPONSE EST FAUSSE. La base 26 n'est pas suffisante. Pensez à ce qui se passe lorsque vous passez de Z à AA. Si A est équivalent au chiffre 0, alors c'est comme si vous alliez de 9 à 00. Si c'est le chiffre 1, c'est comme si on passait de 9 à 11.

5 votes

Je ne suis pas clair après les mises à jour... est-ce que l'un des algorithmes est maintenant correct ? Et si oui, lequel, le second ? J'éditerais ceci et le rendrais évident pour la postérité....

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X