Função para converter o número da coluna em letra?

143

Alguém tem uma função VBA do Excel que pode retornar a (s) letra (s) da coluna de um número?

Por exemplo, digitar 100 deve retornar CV.

mezamórfico
fonte
4
Verifique esta questão: stackoverflow.com/questions/10106465/…
Francis Dean
@FrancisDean que é o reverso desta questão que está procurando o endereço a partir do número
brettdj
2
@brettdj A resposta vinculada mostra número para letra e letra para número.
22615 Francis Dean
2
@FrancisDean fair point, olhei para o título da pergunta no link e não para a resposta aceita
brettdj

Respostas:

211

Essa função retorna a letra da coluna para um determinado número de coluna.

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

código de teste para a coluna 100

Sub Test()
    MsgBox Col_Letter(100)
End Sub
brettdj
fonte
9
Você pode adicionar o (0)final do comando Split se desejar salvar uma declaração de variável e uma linha de código extra. por exemplo,Col_letter = Split(Cells(1, lngCol).Address(True, False), "$")(0)
Caltor
3
Isso está correto, mas achei mais legível usar várias linhas.
brettdj
6
Por que se preocupar com os parâmetros booleanos nessa situação? Você consegue fazer isso:............................................. ......v = Split(Cells(1, lngCol).Address, "$")(1)
Excel herói
1
Embora isso seja muito antigo, tenho uma pequena adição - verificando primeiro se o número é positivo, pois, caso contrário, você encontrará erros. se lngcol <= 0 então
Selkie
1
Ao usar o VBS, lembre-se de que .Cellsé uma propriedade do Excel, o que significa que você precisa usar <excel_object>.Cells(). Caso contrário, você receberá um erro de incompatibilidade de tipo.
Stevoisiak
88

Se você preferir não usar um objeto de intervalo:

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
fonte
1
Não está claro por que você postou um método mais longo com um loop com base em Se você preferir não usar um objeto de intervalo:
brettdj
29
@brettdj Eu posso imaginar várias razões: 1) esse método é 6x mais rápido nos meus testes 2) não requer acesso à API do Excel 3) presumivelmente possui uma menor pegada de memória. Edição: Além disso, não sei por que comentei uma resposta com mais de um ano: S
Blackhawk
6
Porém, há uma desvantagem no aumento da velocidade. O uso do objeto range gera um erro se você passar um número de coluna inválido. Funciona mesmo se alguém ainda estiver usando o Excel 2003. Se você precisar desse tipo de exceção, siga o método range. Caso contrário, parabéns para robartsd.
Engenheiro brinde
6
IF ColumnNumber <= Columns.Countseria melhor evitar suposições sobre versões.
brettdj
1
Outra razão para usar esse código é que se você não está em VBA, mas em VB, .net, etc.
Maury Markowitz
46

Algo que funciona para mim é:

Cells(Row,Column).Address 

Isso retornará a referência de formato $ AE $ 1 para você.

Damian Fennelly
fonte
1
Isso não responde à pergunta.
Pochmurnik
33

Estou surpreso que ninguém tenha sugerido: ** <code> </code> <code> Colunas (</code> *** <code> Índice da coluna </code> *** <code>) .Address </code> <code> </code> **

  • Por exemplo: MsgBox Columns( 9347 ).Address retorna ** <code> $ MUM: $ MUM </code> ** .

Para retornar SOMENTE a (s) letra (s) da coluna :Split((Columns(Column Index).Address(,0)),":")(0)

  • Por exemplo: MsgBox Split((Columns( 2734 ).Address(,0)),":")(0) retorna ** <code> DAD </code> ** .

  Mais exemplos


ashleedawg
fonte
Este funciona para mim no Office 365: string col = Worksheet.Columns [column] .Address; retornar col.Substring (col.IndexOf (":") + 2); Por alguma razão, outras expressões, como Range = Worksheet.Cells [1, coluna], estavam lançando erros (na chamada Cells ou quando tentei usar o endereço, não consigo lembrar - desculpe - quais linhas estavam sendo lançadas nas quais casos específicos.)
Sam Azer
19

Apenas mais uma maneira de fazer isso. A resposta de Brettdj me fez pensar nisso, mas se você usar esse método, não precisará usar uma matriz variante, poderá ir diretamente para uma string.

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

ou pode torná-lo um pouco mais compacto com esse

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

Observe que isso depende de você referenciar a linha 1 no objeto de células.

OSUZorba
fonte
18

E uma solução usando recursão:

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
fonte
Recortar e colar perfeito para converter números maiores que 676. Obrigado!
David Krider
1
O restante nunca pode ter mais de 26 anos. Por que não um número inteiro e não longo?
Caltor
10
@Caltor A menos que você tenha um propósito especial para usar um número inteiro, como chamar uma API que exija um por exemplo, você nunca deve escolher um número inteiro em vez de um longo. O VBA é otimizado para Longs. Processos VBA Longs mais rápido que Inteiros.
Excel Hero
1
@ExcelHero Eu não sabia disso. Mas um Long não ocupa mais memória que um Inteiro?
Caltor
6
@Caltor De fato, um Long tem 32 bits, enquanto um Inteiro é 16. Mas isso não importa na computação moderna. 25 anos atrás ... isso importava muito. Mas hoje (até 15 anos atrás) a diferença é totalmente irrelevante.
Excel Hero
9

Isso está disponível usando uma fórmula:

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

e também pode ser gravado como uma função VBA, conforme solicitado:

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

Esta é uma versão da resposta de robartsd (com o sabor da solução de uma linha de Jan Wijninckx ), usando recursão em vez de um loop.

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

Eu testei isso com as seguintes entradas:

1   => "A"
26  => "Z"
27  => "AA"
51  => "AY"
702 => "ZZ"
703 => "AAA" 
-1  => ""
-234=> ""
alexanderbird
fonte
2
Acabei de notar que isso é essencialmente o mesmo que a solução de Nikolay Ivanov, que torna a minha um pouco menos nova. Vou deixá-lo porque mostra uma abordagem um pouco diferente para algumas das minúcias
alexanderbird
Boa solução por dois motivos: não usar nenhum objeto (como intervalo, célula etc.); definição muito compacta.
precisa saber é o seguinte
8

O código de robertsd é elegante, mas para torná-lo à prova de futuro, altere a declaração de n para digitar long

Caso você queira uma fórmula para evitar macro, aqui está algo que funciona até a coluna 702, inclusive

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

onde A1 é a célula que contém o número da coluna a ser convertida em letras.

Jan Wijninckx
fonte
7

ÚLTIMA ATUALIZAÇÃO : Por favor, ignore a função abaixo, o @SurasinTancharoen conseguiu me alertar que está quebrado n = 53.
Para aqueles que estão interessados, aqui estão outros valores quebrados logo abaixo n = 200:

Certos valores de

Por favor, use a função @brettdj para todas as suas necessidades. Até funciona para o Microsoft Excel mais recente número máximo de colunas: 16384deve fornecerXFD

insira a descrição da imagem aqui

FIM DA ATUALIZAÇÃO


A função abaixo é fornecida pela 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

Fonte: Como converter números de colunas do Excel em caracteres alfabéticos

APLICA-SE A

  • Microsoft Office Excel 2007
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Excel 97 Standard Edition
mtbink.com
fonte
2
Para referência, isso ocorre com conjuntos de colunas maiores, pois Chr () não lida bem com grandes números.
Azuvector 18/10
2
Isso tem um erro. Tente ConvertToLetter (53), que deveria ter sido 'BA', mas falhará.
Surasin Tancharoen
@SurasinTancharoen Muito obrigado por observar esta falha. Eu nunca pensei que a Microsoft forneceria uma função quebrada, pois eles mesmos criaram o Microsoft Excel. Vou abandonar esta função a partir de agora e vai usar @brettdj função que até mesmo corrigir até mais recente número máximo Microsoft Excel de limite de colunaCol_Letter(16384) = "XFD"
mtbink.com
4
E de onde vem essa "divisão por 27"? A última vez que verifiquei, há 26 letras. É por isso que esse código quebra.
ib11 28/05
5

Esta é uma função baseada na resposta de @ DamienFennelly acima. Se você me der um joinha, dê uma joinha também! : P

Function outColLetterFromNumber(iCol as Integer) as String
    sAddr = Cells(1, iCol).Address
    aSplit = Split(sAddr, "$")
    outColLetterFromNumber = aSplit(1)
End Function
BrettFromLA
fonte
2
Bom, mas como é diferente da resposta aceita?
Ioannis
@loannis Baseei o meu na resposta de DamianFennelly, e não na resposta aceita. Mas sim, a minha se parece muito com a resposta aceita, exceto uma linha é dividida em duas para torná-la mais legível.
BrettFromLA
3

Existe uma maneira muito simples de usar o poder do Excel: Use Range.Cells.Addressproperty, desta maneira:

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

Isso retornará o endereço da coluna desejada na linha 1. Faça o seguinte 1:

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

Observe que é tão rápido e poderoso que você pode retornar endereços de coluna que existem!

Substitua lngRowo número da coluna desejada usando a Selection.Columnpropriedade!

flaviomorgado
fonte
2

Aqui está um liner simples que pode ser usado.

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

Funcionará apenas para uma designação de coluna de 1 letra, mas é bom para casos simples. Se você precisar trabalhar com designações exclusivas de duas letras, use o seguinte:

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

Isso funcionará independentemente de qual coluna dentro da sua linha de código para a célula localizada na linha X, na coluna Y:

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

Se você possui uma célula com nome definido exclusivo "Cellname":

Mid(Cells(1,val(range("Cellname").Column)).Address, 2, instr(2,Cells(1,val(range("Cellname").Column)).Address,"$")-2)
Codeplayer
fonte
1

A solução do brettdj funciona de maneira fantástica, mas se você se deparar com uma solução potencial pela mesma razão que eu, pensei que ofereceria minha solução alternativa.

O problema que eu estava tendo era rolar para uma coluna específica com base na saída de uma função MATCH (). Em vez de converter o número da coluna em paralelo à letra da coluna, optei por alternar temporariamente o estilo de referência de A1 para R1C1. Dessa forma, eu poderia simplesmente rolar para o número da coluna sem ter que mexer com uma função VBA. Para alternar facilmente entre os dois estilos de referência, você pode usar este código VBA:

Sub toggle_reference_style()

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

End Sub
Will Ediger
fonte
1

Para avançar na resposta brettdj, aqui é necessário tornar a entrada do número da coluna opcional. Se a entrada do número da coluna for omitida, a função retornará a letra da coluna da célula que chama para a função. Eu sei que isso também pode ser alcançado usando apenas ColumnLetter(COLUMN()), mas achei que seria bom se ele pudesse entender isso de maneira inteligente.

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

A desvantagem dessa função é que ela seria muito, muito ligeiramente mais lenta que a resposta de brettdj por causa do IFteste. Mas isso pode ser sentido se a função for usada repetidamente por uma quantidade muito grande de vezes.

Rosetta
fonte
1

Aqui está uma resposta tardia, apenas para uma abordagem simplista usando Int()e Ifno caso de colunas de 1 a 3 caracteres:

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
fonte
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
fonte
1

Aqui, uma função simples em 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
fonte
1

Essa fórmula fornecerá a coluna com base em um intervalo (ou seja, A1 ), em que o intervalo é uma única célula. Se um intervalo de várias células for fornecido, ele retornará a célula superior esquerda. Observe que as duas referências de célula devem ser as mesmas:

MID (CÉLULA ("endereço", A1 ), 2, PESQUISA ("$", CÉLULA ("endereço", A1 ), 2) -2) -2)

Como funciona:

CELL ("property", "range") retorna um valor específico do intervalo, dependendo da propriedade usada. Nesse caso, o endereço da célula. A propriedade address retorna um valor $ [col] $ [linha], ou seja, A1 -> $ A $ 1. A função MID analisa o valor da coluna entre os símbolos $.

Thom
fonte
0

Maneira fácil de obter o nome da coluna

Sub column()

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

End Sub

Espero que ajude =)

cristobal
fonte
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.
fonte
0

Estou atrasado para a festa aqui, mas quero contribuir com outra resposta que ninguém mais tenha abordado ainda que não envolva matrizes. Você pode fazer isso com uma simples manipulação de strings.

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

Depois de inserir a entrada no formato $A$1, use a Midfunção, inicie na posição 2 para contabilizar a primeira e $, em seguida, você encontrará onde a segunda $aparece na cadeia usando InStre, em seguida, subtraia 2 para contabilizar essa posição inicial.

Isso oferece o benefício de ser adaptável para toda a gama de colunas possíveis. Portanto, ColLetter(1)devolve "A" e ColLetter(16384)devolve "XFD", que é a última coluna possível para a minha versão do Excel.

SandPiper
fonte
-1

A letra da coluna do número da coluna pode ser extraída usando a fórmula seguindo as etapas
1. Calcule o endereço da coluna usando a fórmula ADDRESS
2. Extraia a letra da coluna usando as funções MID e FIND

Exemplo:
1. ADDRESS (1000,1000,1)
resulta $ ALL $ 1000
2 . = Resultados MID (F15,2, FIND ("$", F15,2) -2)
TODOS os F15 que contêm o resultado da etapa 1

De uma vez, podemos escrever
MID (ADDRESS (1000,1000,1), 2, FIND ("$", ENDEREÇO ​​(1000,1000,1), 2) -2)

Bhanu Sinha
fonte
-1

isto é apenas para REFEDIT ... geralmente use código uphere versão em breve ... fácil de ser lido e entendido / use 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
fonte
-2

que tal apenas converter para o número ascii e usar Chr () para converter novamente em uma letra?

col_letter = Chr (Selection.Column + 96)

beef_supreme
fonte
-6

Aqui está outra maneira:

{

      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
fonte
1
Não é necessário criar uma string listando as letras do alfabeto. A ASCII basicamente fez isso por nós.
Caltor