Función para convertir el número de columna a letra?

143

¿Alguien tiene una función Excel VBA que pueda devolver las letras de la columna de un número?

Por ejemplo, ingresar 100 debería regresar CV.

mezamórfico
fuente
44
Mira esta pregunta: stackoverflow.com/questions/10106465/…
Francis Dean
@FrancisDean que es el reverso de esta pregunta que busca la dirección del número
brettdj
2
@brettdj La respuesta vinculada muestra tanto número a letra como letra a número.
Francis Dean
2
@FrancisDean punto justo, miré el título de la pregunta en el enlace en lugar de la respuesta aceptada
brettdj

Respuestas:

211

Esta función devuelve la letra de la columna para un número de columna dado.

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 prueba para la columna 100

Sub Test()
    MsgBox Col_Letter(100)
End Sub
brettdj
fuente
9
Puede agregarlo (0)al final del comando Dividir si desea guardar una declaración de variable y una línea de código adicional. Por ejemploCol_letter = Split(Cells(1, lngCol).Address(True, False), "$")(0)
Caltor
3
Eso es bastante correcto, pero pensé que era más legible usar varias líneas.
brettdj
66
¿Por qué molestarse con los params booleanos en esta situación? Puedes hacerlo:............................................. ......v = Split(Cells(1, lngCol).Address, "$")(1)
Excel Hero
1
Si bien esto es muy antiguo, tengo una adición menor: verificar primero si el número es positivo, ya que de lo contrario te encontrarás con errores. si lngcol <= 0 entonces
Selkie
1
Cuando use VBS, recuerde que .Cellses una propiedad de Excel, lo que significa que debe usarla <excel_object>.Cells(). De lo contrario, obtendrá un error de tipo no coincidente.
Stevoisiak
88

Si prefiere no usar un objeto de rango:

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
fuente
1
No está claro por qué publicó un método más largo con un bucle en función de Si prefiere no usar un objeto de rango:
brettdj
29
@brettdj Puedo imaginar varias razones: 1) este método es aproximadamente 6 veces más rápido según mis pruebas 2) no requiere acceso a la API de Excel 3) presumiblemente tiene una huella de memoria más pequeña. EDITAR: Además, no estoy seguro de por qué comenté una respuesta de más de un año: S
Blackhawk
66
Sin embargo, hay un inconveniente en el aumento de la velocidad. El uso del objeto de rango arroja un error si pasa un número de columna no válido. Funciona incluso si alguien sigue usando Excel 2003. Si necesita ese tipo de excepción, vaya con el método de rango. De lo contrario, felicitaciones a robartsd.
Ingeniero Toast
66
IF ColumnNumber <= Columns.CountSería mejor evitar suposiciones en torno a las versiones.
brettdj
1
Otra razón para usar este código es si no estás en VBA sino en VB, .net, etc.
Maury Markowitz,
46

Algo que funciona para mí es:

Cells(Row,Column).Address 

Esto le devolverá la referencia de formato $ AE $ 1.

Damian Fennelly
fuente
1
Esto no responde la pregunta.
Pochmurnik
33

Me sorprende que nadie sugirió: ** <code> </code> <code> Columnas (</code> *** <code> Column Index </code> *** <code>) .Dirección </code> <code> </code> **

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

Para devolver SOLO las letras de la columna :Split((Columns(Column Index).Address(,0)),":")(0)

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

  Más ejemplos


ashleedawg
fuente
Este me funciona en Office 365: string col = Worksheet.Columns [column] .Address; return col.Substring (col.IndexOf (":") + 2); Por alguna razón, otras expresiones, como Range = Worksheet.Cells [1, columna], arrojaban errores (ya sea en la llamada de Celdas o cuando intenté tomar la dirección, no recuerdo, lo siento, qué líneas se tiraron en qué casos específicos.)
Sam Azer
19

Solo una forma más de hacer esto. La respuesta de Brettdj me hizo pensar en esto, pero si usa este método no tiene que usar una matriz variante, puede ir directamente a una cadena.

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

o puede hacerlo un poco más compacto con esto

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

Tenga en cuenta que esto depende de que haga referencia a la fila 1 en el objeto de celdas.

OSUZorba
fuente
18

Y una solución usando recursividad:

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
fuente
Corta y pega perfecto para convertir números mayores que 676. ¡Gracias!
David Krider
1
El resto nunca puede ser más de 26, ¿por qué no un número entero en lugar de largo?
Caltor
10
@Caltor A menos que tenga un propósito especial para usar un Integer, como llamar a una API que exige uno, por ejemplo, nunca debe elegir un Integer en lugar de un Long. VBA está optimizado para Longs. VBA procesa Longs más rápido que Integers.
Excel Hero
1
@ExcelHero No lo sabía. Sin embargo, ¿un Long no requiere más memoria que un Integer?
Caltor
66
@Caltor De hecho, un Long es de 32 bits, mientras que un Integer es de 16. Pero eso no importa en la informática moderna. Hace 25 años ... importaba mucho. Pero hoy (incluso hace 15 años) la diferencia es totalmente intrascendente.
Excel Hero
9

Esto está disponible mediante el uso de una fórmula:

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

y también se puede escribir como una función VBA según lo solicitado:

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

Esta es una versión de la respuesta de robartsd (con el sabor de la solución de una línea de Jan Wijninckx ), utilizando la recursividad en lugar de un bucle.

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

He probado esto con las siguientes entradas:

1   => "A"
26  => "Z"
27  => "AA"
51  => "AY"
702 => "ZZ"
703 => "AAA" 
-1  => ""
-234=> ""
alexanderbird
fuente
2
Acabo de notar que esto es esencialmente lo mismo que la solución de Nikolay Ivanov, lo que hace que la mía sea un poco menos novedosa. Lo dejaré arriba porque muestra un enfoque ligeramente diferente para algunas de las minucias
alexanderbird
Buena solución por dos razones: no usar ningún objeto (como rango, celda, etc.); Definición muy compacta.
loved.by.Jesus
8

código de robertsd es elegante, pero para que sea a prueba de futuro, cambie la declaración de n para escribir largo

En caso de que desee una fórmula para evitar macros, aquí hay algo que funciona hasta la columna 702 inclusive

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

donde A1 es la celda que contiene el número de columna que se convertirá en letras.

Jan Wijninckx
fuente
7

ÚLTIMA ACTUALIZACIÓN : ignore la función a continuación, @SurasinTancharoen logró alertarme de que no funciona n = 53.
Para aquellos que estén interesados, aquí hay otros valores rotos a continuación n = 200:

Ciertos valores de

Utilice la función @brettdj para todas sus necesidades. Incluso funciona para el último límite máximo de columnas de Microsoft Excel: 16384debería darXFD

ingrese la descripción de la imagen aquí

FIN DE ACTUALIZACIÓN


Microsoft proporciona la siguiente función:

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

Fuente: Cómo convertir números de columnas de Excel en caracteres alfabéticos

SE APLICA A

  • Microsoft Office Excel 2007
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Excel 97 Standard Edition
mtbink.com
fuente
2
Como referencia, esto vomita con conjuntos de columnas más grandes ya que Chr () no maneja bien los números grandes.
Azuvector
2
Esto tiene un error. Pruebe ConvertToLetter (53) que debería haber sido 'BA' pero será un error.
Surasin Tancharoen
@SurasinTancharoen Muchas gracias por notar esta falla. Nunca pensé que Microsoft proporcionaría una función rota, ya que ellos mismos crearon Microsoft Excel. A partir de ahora abandonaré esta función y usaré la función @brettdj que incluso corrige hasta el último número máximo de límite de columna de Microsoft ExcelCol_Letter(16384) = "XFD"
mtbink.com
44
¿Y de dónde demonios viene este "dividir entre 27"? Lo último que verifiqué son 26 letras. Es por eso que este código se rompe.
ib11
5

Esta es una función basada en la respuesta de @ DamienFennelly anterior. Si me das un visto bueno, dale un pulgar también. :PAGS

Function outColLetterFromNumber(iCol as Integer) as String
    sAddr = Cells(1, iCol).Address
    aSplit = Split(sAddr, "$")
    outColLetterFromNumber = aSplit(1)
End Function
BrettFromLA
fuente
2
Buena, pero ¿en qué se diferencia de la respuesta aceptada?
Ioannis
@loannis, basé la mía en la respuesta de DamianFennelly, no en la respuesta aceptada. Pero sí, la mía se parece mucho a la respuesta aceptada, excepto que una línea se divide en dos para que sea más legible.
BrettFromLA
3

Hay una manera muy simple de usar Excel Power: use la Range.Cells.Addresspropiedad de esta manera:

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

Esto devolverá la dirección de la columna deseada en la fila 1. Tómela de 1:

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

Tenga en cuenta que es tan rápido y poderoso que puede devolver direcciones de columna que incluso existen.

¡Sustituya lngRowel número de columna deseado usando la Selection.Columnpropiedad!

flaviomorgado
fuente
2

Aquí hay un revestimiento simple que se puede usar.

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

Solo funcionará para una designación de columna de 1 letra, pero es bueno para casos simples. Si necesita que funcione exclusivamente para designaciones de 2 letras, puede usar lo siguiente:

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

Esto funcionará independientemente de qué columna dentro de su línea de código para la celda que se encuentra en la fila X, en la columna Y:

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

Si tiene una celda con un nombre único definido "Nombre de celda":

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

La solución de brettdj funciona fantásticamente, pero si se encuentra con esto como una solución potencial por la misma razón que yo, pensé que ofrecería mi solución alternativa.

El problema que tenía era desplazarme a una columna específica basada en la salida de una función MATCH (). En lugar de convertir el número de columna a su letra de columna paralela, elegí alternar temporalmente el estilo de referencia de A1 a R1C1. De esta manera, podría desplazarme al número de columna sin tener que manipular una función VBA. Para alternar fácilmente entre los dos estilos de referencia, puede 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
fuente
1

Continuando con la respuesta brettdj, aquí es hacer que la entrada del número de columna sea opcional. Si se omite la entrada del número de columna, la función devuelve la letra de la columna de la celda que llama a la función. Sé que esto también se puede lograr usando simplemente ColumnLetter(COLUMN()), pero pensé que sería bueno si pudiera entenderlo inteligentemente.

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

La compensación de esta función es que sería muy, muy ligeramente más lenta que la respuesta de brettdj debido a la IFprueba. Pero esto se podría sentir si la función se usa repetidamente durante una gran cantidad de veces.

Rosetta
fuente
1

Aquí hay una respuesta tardía, solo para un enfoque simplista usando Int()y Ifen el caso de columnas de 1-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
fuente
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
fuente
1

Aquí, una función 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
fuente
1

Esta fórmula le dará a la columna en función de un rango (es decir, A1 ), donde el rango es una sola celda. Si se proporciona un rango de celdas múltiples, devolverá la celda superior izquierda. Tenga en cuenta que ambas referencias de celda deben ser iguales:

MID (CELL ("dirección", A1 ), 2, SEARCH ("$", CELL ("dirección", A1 ), 2) -2)

Cómo funciona:

CELL ("propiedad", "rango") devuelve un valor específico del rango dependiendo de la propiedad utilizada. En este caso la dirección de la celda. La propiedad de dirección devuelve un valor $ [col] $ [fila], es decir, A1 -> $ A $ 1. La función MID analiza el valor de la columna entre los símbolos $.

Thom
fuente
0

Manera fácil de obtener el nombre de la columna

Sub column()

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

End Sub

Espero que ayude =)

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

Así que llego tarde a la fiesta aquí, pero quiero aportar otra respuesta que nadie más haya abordado aún y que no implique matrices. Puedes hacerlo con una simple manipulación de cadenas.

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

Después de tener la entrada en el formato $A$1, use la Midfunción, comience en la posición 2 para dar cuenta de la primera $, luego encuentre dónde $aparece la segunda en la cadena usando InStr, y luego reste 2 para dar cuenta de esa posición inicial.

Esto le brinda la ventaja de ser adaptable para toda la gama de columnas posibles. Por lo tanto, ColLetter(1)devuelve "A" y ColLetter(16384)devuelve "XFD", que es la última columna posible para mi versión de Excel.

Lavandera
fuente
-1

La letra de la columna del número de columna se puede extraer usando la fórmula siguiendo los pasos
1. Calcule la dirección de la columna usando la fórmula DIRECCIÓN
2. Extraiga la letra de la columna usando la función MID y FIND

Ejemplo:
1.
Resultados de DIRECCIÓN (1000,1000,1) $ TODOS $ 1000
2 . = MID (F15,2, FIND ("$", F15,2) -2)
resultados TODOS asumiendo que F15 contiene el resultado del paso 1.

De una vez, podemos escribir
MID (ADDRESS (1000,1000,1), 2, FIND ("$", DIRECCIÓN (1000,1000,1), 2) -2)

Bhanu Sinha
fuente
-1

esto es solo para REFEDIT ... generalmente usa la versión breve del código hasta aquí ... fácil de leer y entender / usa 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
fuente
-2

¿Qué hay de simplemente convertir al número ASCII y usar Chr () para convertir de nuevo a una letra?

col_letter = Chr (Selection.Column + 96)

carne de vaca
fuente
-6

Aquí hay otra forma:

{

      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
fuente
1
No es necesario crear una cadena que enumere las letras del alfabeto. ASCII esencialmente lo ha hecho por nosotros.
Caltor