Fonction pour convertir le numéro de colonne en lettre?

143

Quelqu'un a-t-il une fonction Excel VBA qui peut renvoyer la ou les lettres de colonne à partir d'un nombre?

Par exemple, entrer 100 devrait renvoyer CV.

mezamorphique
la source
4
Consultez cette question: stackoverflow.com/questions/10106465/…
Francis Dean
@FrancisDean c'est l'inverse de cette question qui cherche l'adresse du nombre
brettdj
2
@brettdj La réponse liée montre à la fois nombre à lettre et lettre à nombre.
Francis Dean
2
@FrancisDean juste point, j'ai regardé le titre de la question dans le lien vers plutôt que la réponse acceptée
brettdj

Réponses:

211

Cette fonction renvoie la lettre de colonne pour un numéro de colonne donné.

Function Col_Letter(lngCol As Long) As String
    Dim vArr
    vArr = Split(Cells(1, lngCol).Address(True, False), "$")
    Col_Letter = vArr(0)
End Function

code de test pour la colonne 100

Sub Test()
    MsgBox Col_Letter(100)
End Sub
Brettdj
la source
9
Vous pouvez ajouter le (0)à la fin de la commande Fractionner si vous souhaitez vous enregistrer une déclaration de variable et une ligne de code supplémentaire. par exempleCol_letter = Split(Cells(1, lngCol).Address(True, False), "$")(0)
Caltor
3
C'est tout à fait correct, mais j'ai pensé qu'il était plus lisible d'utiliser plusieurs lignes.
brettdj
6
Pourquoi s'embêter avec les paramètres booléens dans cette situation. Tu peux le faire:............................................. ......v = Split(Cells(1, lngCol).Address, "$")(1)
Excel Hero
1
Bien que ce soit très ancien, j'ai un ajout mineur - vérifier d'abord si le nombre est positif, sinon vous rencontrez des erreurs. si lngcol <= 0 alors
Selkie
1
Lorsque vous utilisez VBS, n'oubliez pas qu'il .Cellss'agit d'une propriété d'Excel, ce qui signifie que vous devez utiliser <excel_object>.Cells(). Sinon, vous obtiendrez une erreur d'incompatibilité de type.
Stevoisiak
88

Si vous préférez ne pas utiliser d'objet range:

Function ColumnLetter(ColumnNumber As Long) As String
    Dim n As Long
    Dim c As Byte
    Dim s As String

    n = ColumnNumber
    Do
        c = ((n - 1) Mod 26)
        s = Chr(c + 65) & s
        n = (n - c) \ 26
    Loop While n > 0
    ColumnLetter = s
End Function
robartsd
la source
1
Vous ne savez pas pourquoi vous avez publié une méthode plus longue avec une boucle sur la base de Si vous préférez ne pas utiliser un objet range:
brettdj
29
@brettdj Je peux imaginer plusieurs raisons: 1) cette méthode est environ 6 fois plus rapide par mes tests 2) elle ne nécessite pas d'accès à l'API Excel 3) elle a probablement une empreinte mémoire plus petite. EDIT: Aussi, je ne sais pas pourquoi j'ai commenté une réponse de plus d'un an: S
Blackhawk
6
Il y a cependant un inconvénient à l'augmentation de la vitesse. L'utilisation de l'objet range génère une erreur si vous transmettez un numéro de colonne non valide. Cela fonctionne même si quelqu'un utilise toujours Excel 2003. Si vous avez besoin de ce type d'exception, utilisez la méthode de plage. Sinon, bravo à robartsd.
Engineer Toast
6
IF ColumnNumber <= Columns.Countserait préférable d'éviter les hypothèses autour des versions.
brettdj
1
Une autre raison d'utiliser ce code est si vous n'êtes pas en VBA mais en VB, .net, etc.
Maury Markowitz
46

Quelque chose qui fonctionne pour moi est:

Cells(Row,Column).Address 

Cela vous renverra la référence du format $ AE $ 1.

Damian Fennelly
la source
1
Cela ne répond pas à la question.
Pochmurnik le
33

Je suis surpris que personne n'ait suggéré: ** <code> </code> <code> Colonnes (</code> *** <code> Index des colonnes </code> *** <code>) .Address </code> <code> </code> **

  • Par exemple: MsgBox Columns( 9347 ).Address renvoie ** <code> $ MUM: $ MUM </code> ** .

Pour renvoyer UNIQUEMENT la (les) lettre (s) de la colonne :Split((Columns(Column Index).Address(,0)),":")(0)

  • Par exemple: MsgBox Split((Columns( 2734 ).Address(,0)),":")(0) renvoie ** <code> DAD </code> ** .

  Plus d'exemples


ashleedawg
la source
Celui-ci fonctionne pour moi dans Office 365: string col = Worksheet.Columns [column] .Address; return col.Substring (col.IndexOf (":") + 2); Pour une raison quelconque, d'autres expressions, telles que Range = Worksheet.Cells [1, column], envoyaient des erreurs (soit dans l'appel Cells, soit lorsque j'ai essayé de prendre l'adresse, je ne me souviens pas - désolé - quelles lignes ont été jetées dans lesquelles cas spécifiques.)
Sam Azer
19

Encore une façon de le faire. La réponse de Brettdj m'a fait penser à cela, mais si vous utilisez cette méthode, vous n'avez pas besoin d'utiliser un tableau variant, vous pouvez accéder directement à une chaîne.

ColLtr = Cells(1, ColNum).Address(True, False)
ColLtr = Replace(ColLtr, "$1", "")

ou peut le rendre un peu plus compact avec ce

ColLtr = Replace(Cells(1, ColNum).Address(True, False), "$1", "")

Notez que cela dépend de votre référence à la ligne 1 dans l'objet Cellules.

OSUZorba
la source
18

Et une solution utilisant la récursivité:

Function ColumnNumberToLetter(iCol As Long) As String

    Dim lAlpha As Long
    Dim lRemainder As Long

    If iCol <= 26 Then
        ColumnNumberToLetter = Chr(iCol + 64)
    Else
        lRemainder = iCol Mod 26
        lAlpha = Int(iCol / 26)
        If lRemainder = 0 Then
            lRemainder = 26
            lAlpha = lAlpha - 1
        End If
        ColumnNumberToLetter = ColumnNumberToLetter(lAlpha) & Chr(lRemainder + 64)
    End If

End Function
Nikolay Ivanov
la source
Couper-coller parfait pour convertir des nombres supérieurs à 676. Merci!
David Krider
1
Le reste ne peut jamais être supérieur à 26 alors pourquoi pas un entier plutôt qu'un long?
Caltor
10
@Caltor À moins que vous n'ayez un but spécial pour utiliser un Integer, comme appeler une API qui en demande un par exemple, vous ne devriez jamais choisir un Integer sur un Long. VBA est optimisé pour les Longs. VBA traite Longs plus rapidement que les nombres entiers.
Excel Hero
1
@ExcelHero Je ne le savais pas. Cependant, un Long ne prend-il pas plus de mémoire qu'un Integer?
Caltor le
6
@Caltor En effet, un Long fait 32 bits, tandis qu'un Integer vaut 16. Mais cela n'a pas d'importance dans l'informatique moderne. Il y a 25 ans ... ça comptait beaucoup. Mais aujourd'hui (même il y a 15 ans), la différence est totalement sans conséquence.
Excel Hero
9

Ceci est disponible en utilisant une formule:

=SUBSTITUTE(ADDRESS(1,COLUMN(),4),"1","")

et ainsi peut également être écrit comme une fonction VBA comme demandé:

Function ColName(colNum As Integer) As String
    ColName = Split(Worksheets(1).Cells(1, colNum).Address, "$")(1)
End Function
Alistair Collins
la source
8

Ceci est une version de la réponse de robartsd (avec la saveur de la solution en une ligne de Jan Wijninckx ), utilisant la récursivité au lieu d'une boucle.

Public Function ColumnLetter(Column As Integer) As String
    If Column < 1 Then Exit Function
    ColumnLetter = ColumnLetter(Int((Column - 1) / 26)) & Chr(((Column - 1) Mod 26) + Asc("A"))
End Function

J'ai testé cela avec les entrées suivantes:

1   => "A"
26  => "Z"
27  => "AA"
51  => "AY"
702 => "ZZ"
703 => "AAA" 
-1  => ""
-234=> ""
Alexanderbird
la source
2
Je viens de remarquer que c'est essentiellement la même chose que la solution de Nikolay Ivanov, ce qui rend la mienne un peu moins nouvelle. Je vais le laisser car il montre une approche légèrement différente pour quelques détails
alexanderbird
Bonne solution pour deux raisons: n'utiliser aucun objet (tel que plage, cellule, etc.); définition très compacte.
aimé.par.Jesus
8

Le code de robertsd est élégant, mais pour le rendre à l'épreuve du temps, changez la déclaration de n en type long

Si vous souhaitez qu'une formule évite les macros, voici quelque chose qui fonctionne jusqu'à la colonne 702 incluse

=IF(A1>26,CHAR(INT((A1-1)/26)+64),"")&CHAR(MOD(A1-1,26)+65)

où A1 est la cellule contenant le numéro de colonne à convertir en lettres.

Jan Wijninckx
la source
7

DERNIÈRE MISE À JOUR : Veuillez ignorer la fonction ci-dessous, @SurasinTancharoen a réussi à m'alerter qu'elle est interrompue n = 53.
Pour ceux qui sont intéressés, voici d'autres valeurs cassées juste en dessous n = 200:

Certaines valeurs de

Veuillez utiliser la fonction @brettdj pour tous vos besoins. Cela fonctionne même pour la dernière limite du nombre maximal de colonnes de Microsoft Excel: 16384devrait donnerXFD

entrez la description de l'image ici

FIN DE MISE À JOUR


La fonction ci-dessous est fournie par Microsoft:

Function ConvertToLetter(iCol As Integer) As String
   Dim iAlpha As Integer
   Dim iRemainder As Integer
   iAlpha = Int(iCol / 27)
   iRemainder = iCol - (iAlpha * 26)
   If iAlpha > 0 Then
      ConvertToLetter = Chr(iAlpha + 64)
   End If
   If iRemainder > 0 Then
      ConvertToLetter = ConvertToLetter & Chr(iRemainder + 64)
   End If
End Function

Source: Comment convertir les numéros de colonne Excel en caractères alphabétiques

S'APPLIQUE À

  • Microsoft Office Excel 2007
  • Édition standard de Microsoft Excel 2002
  • Édition standard de Microsoft Excel 2000
  • Microsoft Excel 97 Édition Standard
mtbink.com
la source
2
Pour référence, cela émet avec des ensembles de colonnes plus grands car Chr () ne gère pas bien les grands nombres.
Azuvector
2
Cela a un bug. Essayez ConvertToLetter (53) qui aurait dû être «BA» mais cela échouera.
Surasin Tancharoen
@SurasinTancharoen Merci beaucoup d'avoir noté cette faille. Je n'ai jamais pensé que Microsoft fournirait une fonction cassée car c'est eux qui ont créé Microsoft Excel eux-mêmes. J'abandonnerai cette fonction à partir de maintenant et utiliserai la fonction @brettdj qui corrige même jusqu'au dernier nombre maximal de colonnes Microsoft ExcelCol_Letter(16384) = "XFD"
mtbink.com
4
Et d'où vient cette «division par 27»? La dernière fois que j'ai vérifié, il y avait 26 lettres. C'est pourquoi ce code se brise.
ib11
5

Ceci est une fonction basée sur la réponse de @ DamienFennelly ci-dessus. Si vous me donnez un coup de pouce, donnez-lui un coup de pouce aussi! : P

Function outColLetterFromNumber(iCol as Integer) as String
    sAddr = Cells(1, iCol).Address
    aSplit = Split(sAddr, "$")
    outColLetterFromNumber = aSplit(1)
End Function
BrettFromLA
la source
2
Bien, mais en quoi est-ce différent de la réponse acceptée?
Ioannis
@loannis J'ai basé la mienne sur la réponse de DamianFennelly, pas celle acceptée. Mais oui, la mienne ressemble beaucoup à la réponse acceptée, sauf qu'une ligne est divisée en deux pour la rendre plus lisible.
BrettFromLA
3

Il existe un moyen très simple d'utiliser Excel Power: utilisez la Range.Cells.Addresspropriété, de cette façon:

strCol = Cells(1, lngRow).Address(xlRowRelative, xlColRelative)

Cela renverra l'adresse de la colonne souhaitée sur la ligne 1. Prenez-la du 1:

strCol = Left(strCol, len(strCol) - 1)

Notez qu'il est si rapide et puissant que vous pouvez renvoyer des adresses de colonnes qui existent même!

Remplacez lngRowle numéro de colonne souhaité en utilisant la Selection.Columnpropriété!

flaviomorgado
la source
2

Voici une simple doublure qui peut être utilisée.

ColumnLetter = Mid(Cells(Row, LastColA).Address, 2, 1)

Cela ne fonctionnera que pour une désignation de colonne d'une lettre, mais c'est bien pour les cas simples. Si vous en avez besoin pour fonctionner uniquement pour les désignations de 2 lettres, vous pouvez utiliser ce qui suit:

ColumnLetter = Mid(Cells(Row, LastColA).Address, 2, 2)
Syd B
la source
2

Cela fonctionnera quelle que soit la colonne à l'intérieur de votre ligne de code pour la cellule située dans la ligne X, dans la colonne Y:

Mid(Cells(X,Y).Address, 2, instr(2,Cells(X,Y).Address,"$")-2)

Si vous avez une cellule avec un nom unique défini "Cellname":

Mid(Cells(1,val(range("Cellname").Column)).Address, 2, instr(2,Cells(1,val(range("Cellname").Column)).Address,"$")-2)
Joueur de code
la source
1

La solution de brettdj fonctionne à merveille, mais si vous rencontrez cela comme une solution potentielle pour la même raison que moi, j'ai pensé que je proposerais ma solution alternative.

Le problème que j'avais était de faire défiler jusqu'à une colonne spécifique en fonction de la sortie d'une fonction MATCH (). Au lieu de convertir le numéro de colonne en sa lettre de colonne parallèle, j'ai choisi de basculer temporairement le style de référence de A1 à R1C1. De cette façon, je pourrais simplement faire défiler jusqu'au numéro de colonne sans avoir à utiliser une fonction VBA. Pour basculer facilement entre les deux styles de référence, vous pouvez utiliser ce code VBA:

Sub toggle_reference_style()

If Application.ReferenceStyle = xlR1C1 Then
  Application.ReferenceStyle = xlA1
Else
  Application.ReferenceStyle = xlR1C1
End If

End Sub
Will Ediger
la source
1

Poursuivant la réponse brettdj, voici de rendre l'entrée du numéro de colonne facultative. Si l'entrée du numéro de colonne est omise, la fonction renvoie la lettre de colonne de la cellule qui appelle la fonction. Je sais que cela peut également être réalisé en utilisant simplement ColumnLetter(COLUMN()), mais j'ai pensé que ce serait bien s'il pouvait intelligemment le comprendre.

Public Function ColumnLetter(Optional ColumnNumber As Long = 0) As String
    If ColumnNumber = 0 Then
        ColumnLetter = Split(Application.Caller.Address(True, False, xlA1), "$")(0)
    Else
        ColumnLetter = Split(Cells(1, ColumnNumber).Address(True, False, xlA1), "$")(0)
    End If
End Function

Le compromis de cette fonction est qu'elle serait très très légèrement plus lente que la réponse de brettdj à cause du IFtest. Mais cela peut être ressenti si la fonction est utilisée à plusieurs reprises pendant un très grand nombre de fois.

Rosetta
la source
1

Voici une réponse tardive, juste pour une approche simpliste utilisant Int()et Ifdans le cas de colonnes de 1 à 3 caractères:

Function outColLetterFromNumber(i As Integer) As String

    If i < 27 Then       'one-letter
        col = Chr(64 + i)
    ElseIf i < 677 Then  'two-letter
        col = Chr(64 + Int(i / 26)) & Chr(64 + i - (Int(i / 26) * 26))
    Else                 'three-letter
        col = Chr(64 + Int(i / 676)) & Chr(64 + Int(i - Int(i / 676) * 676) / 26)) & Chr(64 + i - (Int(i - Int(i / 676) * 676) / 26) * 26))
    End If

    outColLetterFromNumber = col

End Function
ib11
la source
1
Function fColLetter(iCol As Integer) As String
  On Error GoTo errLabel
  fColLetter = Split(Columns(lngCol).Address(, False), ":")(1)
  Exit Function
errLabel:
  fColLetter = "%ERR%"
End Function
Krzysztof
la source
1

Ici, une fonction simple en Pascal (Delphi).

function GetColLetterFromNum(Sheet : Variant; Col : Integer) : String;
begin
  Result := Sheet.Columns[Col].Address;  // from Col=100 --> '$CV:$CV'
  Result := Copy(Result, 2, Pos(':', Result) - 2);
end;
Jordi
la source
1

Cette formule donnera la colonne basée sur une plage (par exemple, A1 ), où plage est une seule cellule. Si une plage multicellulaire est donnée, elle renverra la cellule en haut à gauche. Remarque, les deux références de cellule doivent être identiques:

MID (CELL ("adresse", A1 ), 2, RECHERCHE ("$", CELL ("adresse", A1 ), 2) -2)

Comment ça fonctionne:

CELL ("propriété", "plage") renvoie une valeur spécifique de la plage en fonction de la propriété utilisée. Dans ce cas, l'adresse de la cellule. La propriété address renvoie une valeur $ [col] $ [row], c'est-à-dire A1 -> $ A $ 1. La fonction MID analyse la valeur de la colonne entre les symboles $.

Thom
la source
0

Un moyen simple d'obtenir le nom de la colonne

Sub column()

cell=cells(1,1)
column = Replace(cell.Address(False, False), cell.Row, "")
msgbox column

End Sub

J'espère que ça aide =)

Cristobal
la source
0
Sub GiveAddress()
    Dim Chara As String
    Chara = ""
    Dim Num As Integer
    Dim ColNum As Long
    ColNum = InputBox("Input the column number")

    Do
        If ColNum < 27 Then
            Chara = Chr(ColNum + 64) & Chara
            Exit Do
        Else
            Num = ColNum / 26
            If (Num * 26) > ColNum Then Num = Num - 1
            If (Num * 26) = ColNum Then Num = ((ColNum - 1) / 26) - 1
            Chara = Chr((ColNum - (26 * Num)) + 64) & Chara
            ColNum = Num
        End If
    Loop

    MsgBox "Address is '" & Chara & "'."
End Sub
Chetan V.
la source
0

Je suis donc en retard à la fête ici, mais je veux apporter une autre réponse que personne d'autre n'a encore abordée et qui n'implique pas de tableaux. Vous pouvez le faire avec une simple manipulation de chaîne.

Function ColLetter(Col_Index As Long) As String

    Dim ColumnLetter As String

    'Prevent errors; if you get back a number when expecting a letter, 
    '    you know you did something wrong.
    If Col_Index <= 0 Or Col_Index >= 16384 Then
        ColLetter = 0
        Exit Function
    End If

    ColumnLetter = ThisWorkbook.Sheets(1).Cells(1, Col_Index).Address     'Address in $A$1 format
    ColumnLetter = Mid(ColumnLetter, 2, InStr(2, ColumnLetter, "$") - 2)  'Extracts just the letter

    ColLetter = ColumnLetter
End Sub

Une fois que vous avez l'entrée dans le format $A$1, utilisez la Midfonction, commencez à la position 2 pour tenir compte du premier $, puis vous trouvez où le second $apparaît dans la chaîne en utilisant InStr, puis soustrayez 2 pour tenir compte de cette position de départ.

Cela vous donne l'avantage d'être adaptable à toute la gamme de colonnes possibles. Par conséquent, ColLetter(1)rend "A", et ColLetter(16384)rend "XFD", qui est la dernière colonne possible pour ma version Excel.

Bécasseau
la source
-1

La lettre de colonne du numéro de colonne peut être extraite à l'aide de la formule en suivant les étapes
1. Calculez l'adresse de la colonne à l'aide de la formule ADDRESS
2. Extrayez la lettre de la colonne à l'aide des fonctions MID et FIND

Exemple:
1. ADDRESS (1000,1000,1)
results $ ALL $ 1000
2 . = MID (F15,2, FIND ("$", F15,2) -2)
résultats ALL en supposant que F15 contient le résultat de l'étape 1

En une seule fois, nous pouvons écrire
MID (ADDRESS (1000,1000,1), 2, FIND ("$", ADRESSE (1000,1000,1), 2) -2)

Bhanu Sinha
la source
-1

ceci n'est que pour REFEDIT ... utilisez généralement le code uphere sous peu la version ... facile à lire et à comprendre / il utilise poz de $

Private Sub RefEdit1_Change()

    Me.Label1.Caption = NOtoLETTER(RefEdit1.Value) ' you may assign to a variable  var=....'

End Sub

Function NOtoLETTER(REFedit)

    Dim First As Long, Second As Long

    First = InStr(REFedit, "$")                 'first poz of $
    Second = InStr(First + 1, REFedit, "$")     'second poz of $

    NOtoLETTER = Mid(REFedit, First + 1, Second - First - 1)   'extract COLUMN LETTER

End Function
Gabriel V
la source
-2

qu'en est-il simplement de la conversion au nombre ascii et de l'utilisation de Chr () pour reconvertir en lettre?

col_letter = Chr (Colonne de sélection + 96)

boeuf_supreme
la source
-6

Voici une autre façon:

{

      Sub find_test2()

            alpha_col = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,W,Z" 
            MsgBox Split(alpha_col, ",")(ActiveCell.Column - 1) 

      End Sub

}
Mike Powell
la source
1
Pas besoin de créer une chaîne listant les lettres de l'alphabet. L'ASCII a essentiellement fait cela pour nous.
Caltor