Funzione per convertire il numero di colonna in lettera?


143

Qualcuno ha una funzione VBA di Excel che può restituire le lettere della colonna da un numero?

Ad esempio, inserendo 100 dovrebbe tornare CV.


4
Dai un'occhiata a questa domanda: stackoverflow.com/questions/10106465/…
Francis Dean,

@FrancisDean è il contrario di questa domanda che sta cercando l'indirizzo dal numero
brettdj

2
@brettdj La risposta collegata mostra sia il numero che la lettera.
Francis Dean,

2
@FrancisDean, punto giusto, ho guardato il titolo della domanda nel link piuttosto che la risposta accettata
brettdj

Risposte:


211

Questa funzione restituisce la lettera della colonna per un determinato numero di colonna.

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

codice di test per la colonna 100

Sub Test()
    MsgBox Col_Letter(100)
End Sub

9
È possibile aggiungere il (0)alla fine del comando Split se si desidera salvare una dichiarazione variabile e una riga di codice aggiuntiva. ad es.Col_letter = Split(Cells(1, lngCol).Address(True, False), "$")(0)
Caltor,

3
È abbastanza corretto, ma ho pensato che fosse più leggibile usare diverse righe.
Brettdj,

6
Perché preoccuparsi dei parametri booleani in questa situazione. Puoi farlo:............................................. ......v = Split(Cells(1, lngCol).Address, "$")(1)
Excel Hero,

1
Anche se questo è molto vecchio, ho un'aggiunta minore: controllo prima se il numero è positivo, poiché altrimenti si verificano errori. se lngcol <= 0 allora
Selkie

1
Quando si utilizza VBS, ricordare che .Cellsè una proprietà di Excel, il che significa che è necessario utilizzare <excel_object>.Cells(). In caso contrario, verrà visualizzato un errore di mancata corrispondenza del tipo.
Stevoisiak,

88

Se preferisci non utilizzare un oggetto intervallo:

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

1
Non è chiaro il motivo per cui hai pubblicato un metodo più lungo con un ciclo sulla base di Se preferisci non utilizzare un oggetto range:
brettdj

29
@brettdj Posso immaginare diversi motivi: 1) questo metodo è circa 6 volte più veloce dai miei test 2) non richiede l'accesso all'API di Excel 3) presumibilmente ha un footprint di memoria più piccolo. EDIT: Inoltre, non sono sicuro del motivo per cui ho commentato una risposta di un anno: S
Blackhawk,

6
Tuttavia, c'è un inconveniente per la maggiore velocità. L'uso dell'oggetto range genera un errore se si passa un numero di colonna non valido. Funziona anche se qualcuno sta ancora usando Excel 2003. Se hai bisogno di quel tipo di eccezione, scegli il metodo range. Altrimenti, complimenti a robartsd.
Ingegnere Toast,

6
IF ColumnNumber <= Columns.Countsarebbe meglio evitare ipotesi sulle versioni.
Brettdj,

1
Un altro motivo per usare questo codice è se non sei in VBA ma in VB, .net, ecc.
Maury Markowitz,

46

Qualcosa che funziona per me è:

Cells(Row,Column).Address 

Questo restituirà il riferimento in formato $ AE $ 1 per te.


1
Questo non risponde alla domanda.
Pochmurnik,

33

Sono sorpreso che nessuno abbia suggerito: ** <code> </code> <code> Colonne (</code> *** <code> Indice colonne </code> *** <code>) .Indirizzo </code> <code> </ code> **

  • Ad esempio: MsgBox Columns( 9347 ).Address ritorni ** <code> $ MUM: $ MUM </ code> ** .

Per restituire SOLO le lettere della colonna :Split((Columns(Column Index).Address(,0)),":")(0)

  • Ad esempio: MsgBox Split((Columns( 2734 ).Address(,0)),":")(0) ritorni ** <code> DAD </ code> ** .

  Altri esempi



Questo funziona per me in Office 365: string col = Worksheet.Columns [colonna] .Address; return col.Substring (col.IndexOf (":") + 2); Per qualche ragione altre espressioni, come Range = Worksheet.Cells [1, colonna], generavano errori (nella chiamata di Cells o quando ho provato a prendere l'indirizzo, non ricordo - scusa - quali linee dove casi specifici.)
Sam Azer

19

Solo un altro modo per farlo. La risposta di Brettdj mi ha fatto pensare a questo, ma se usi questo metodo non devi usare un array di varianti, puoi andare direttamente a una stringa.

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

o può renderlo un po 'più compatto con questo

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

Si noti che ciò dipende dal fatto che si fa riferimento alla riga 1 nell'oggetto celle.


18

E una soluzione che utilizza la ricorsione:

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

Taglia e incolla perfetto per convertire numeri superiori a 676. Grazie!
David Krider,

1
Il resto non può mai essere più di 26, quindi perché non un numero intero piuttosto che lungo?
Caltor,

10
@Caltor A meno che tu non abbia uno scopo speciale per l'utilizzo di un numero intero, come chiamare un'API che ne richiede uno, ad esempio, non dovresti mai scegliere un numero intero su un lungo. VBA è ottimizzato per Longs. Processi VBA Lunga più velocemente degli Integer.
Excel Hero,

1
@ExcelHero Non lo sapevo. Tuttavia, un Long non richiede più memoria di un intero?
Caltor,

6
@Caltor In effetti un Long è di 32 bit, mentre un numero intero è 16. Ma questo non ha importanza nel calcolo moderno. 25 anni fa ... contava molto. Ma oggi (anche 15 anni fa) la differenza è totalmente insignificante.
Excel Hero

9

Questo è disponibile tramite una formula:

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

e quindi può anche essere scritto come una funzione VBA come richiesto:

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

8

Questa è una versione della risposta di robartsd (con il sapore della soluzione a una riga di Jan Wijninckx ), usando la ricorsione invece di un ciclo.

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

Ho provato questo con i seguenti input:

1   => "A"
26  => "Z"
27  => "AA"
51  => "AY"
702 => "ZZ"
703 => "AAA" 
-1  => ""
-234=> ""

2
Ho appena notato che questa è sostanzialmente la stessa della soluzione di Nikolay Ivanov, che rende il mio un po 'meno romanzo. Lascio perdere perché mostra un approccio leggermente diverso per alcuni minutia
alexanderbird

Buona soluzione per due motivi: non usare alcun oggetto (come intervallo, cella e così via); definizione molto compatta.
loved.by.Jesus

8

Il codice di robertsd è elegante, ma per renderlo a prova di futuro, cambia la dichiarazione di n per digitare long

Nel caso in cui desideri una formula per evitare le macro, ecco qualcosa che funziona fino alla colonna 702 inclusa

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

dove A1 è la cella contenente il numero di colonna da convertire in lettere.


7

ULTIMO AGGIORNAMENTO : si prega di ignorare la funzione di seguito, @SurasinTancharoen è riuscito ad avvisarmi che si è rotto alle n = 53.
Per coloro che sono interessati, ecco altri valori non corretti appena sotto n = 200:

Alcuni valori di

Si prega di utilizzare la funzione @brettdj per tutte le esigenze. Funziona anche per l'ultimo limite massimo di colonne di Microsoft Excel: 16384dovrebbe dareXFD

inserisci qui la descrizione dell'immagine

FINE AGGIORNAMENTO


La funzione seguente è fornita da 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: come convertire i numeri di colonna di Excel in caratteri alfabetici

SI APPLICA A

  • Microsoft Office Excel 2007
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Excel 97 Standard Edition

2
Per riferimento, ciò si verifica con gruppi di colonne più grandi poiché Chr () non gestisce bene numeri grandi.
Azuvector,

2
Questo ha un bug. Prova ConvertToLetter (53) che avrebbe dovuto essere 'BA' ma non funzionerà.
Surasin Tancharoen,

@SurasinTancharoen Grazie mille per aver notato questo difetto. Non ho mai pensato che Microsoft avrebbe fornito una funzione non funzionante in quanto sono loro a creare Microsoft Excel. Abbandonerò questa funzione da ora in poi e userò la funzione @brettdj che correggerà fino all'ultimo limite massimo di colonne di Microsoft ExcelCol_Letter(16384) = "XFD"
mtbink.com

4
E da dove viene questa "divisione per 27"? L'ultima volta che ho controllato ci sono 26 lettere. Questo è il motivo per cui questo codice si rompe.
ib11,

5

Questa è una funzione basata sulla risposta di @DamienFennelly sopra. Se mi dai un pollice in su, anche un pollice in su! : P

Function outColLetterFromNumber(iCol as Integer) as String
    sAddr = Cells(1, iCol).Address
    aSplit = Split(sAddr, "$")
    outColLetterFromNumber = aSplit(1)
End Function

2
Buono, ma in cosa differisce dalla risposta accettata?
Ioannis,

@loannis Ho basato il mio sulla risposta di DamianFennelly, non su quella accettata. Ma sì, la mia assomiglia molto alla risposta accettata, tranne per il fatto che una riga è divisa in due per renderla più leggibile.
BrettFromLA,

3

Esiste un modo molto semplice usando Excel power: usa la Range.Cells.Addressproprietà, in questo modo:

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

Questo restituirà l'indirizzo della colonna desiderata sulla riga 1. Prendilo come segue 1:

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

Si noti che è così veloce e potente che è possibile restituire gli indirizzi di colonna che esiste persino!

Sostituisci lngRowil numero di colonna desiderato usando la Selection.Columnproprietà!


2

Ecco una semplice fodera che può essere utilizzata.

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

Funzionerà solo per una designazione di colonna di 1 lettera, ma è utile per casi semplici. Se ne hai bisogno per funzionare esclusivamente con designazioni di 2 lettere, puoi utilizzare quanto segue:

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

2

Funzionerà indipendentemente dalla colonna all'interno della tua riga di codice per la cella che si trova nella riga X, nella colonna Y:

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

Se hai una cella con un nome definito univoco "Nome cella":

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

1

La soluzione di Brettdj funziona in modo fantastico, ma se la trovi come una potenziale soluzione per lo stesso motivo, pensavo che avrei offerto la mia soluzione alternativa.

Il problema che stavo riscontrando era scorrere fino a una colonna specifica in base all'output di una funzione MATCH (). Invece di convertire il numero di colonna nella sua lettera in parallelo, ho scelto di alternare temporaneamente lo stile di riferimento da A1 a R1C1. In questo modo potrei semplicemente scorrere fino al numero della colonna senza dover passare da una funzione VBA. Per alternare facilmente tra i due stili di riferimento, puoi utilizzare questo codice VBA:

Sub toggle_reference_style()

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

End Sub

1

Proseguendo sulla risposta di Brettdj, ecco come rendere facoltativo l'inserimento del numero di colonna. Se l'immissione del numero di colonna viene omessa, la funzione restituisce la lettera della colonna della cella che chiama la funzione. So che questo può essere ottenuto anche semplicemente ColumnLetter(COLUMN()), ma ho pensato che sarebbe bello se riuscisse a capirlo in modo intelligente.

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

Il compromesso di questa funzione è che sarebbe molto più lento della risposta di Brettdj a causa del IFtest. Ma questo potrebbe essere avvertito se la funzione viene utilizzata ripetutamente per un numero molto elevato di volte.


1

Ecco una risposta tardiva, solo per un approccio semplicistico usando Int()e Ifnel caso di colonne di 1-3 caratteri:

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

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

1

Qui, una semplice funzione in 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;

1

Questa formula fornirà la colonna in base a un intervallo (ovvero A1 ), in cui l'intervallo è una singola cella. Se viene fornito un intervallo di più celle, verrà restituita la cella in alto a sinistra. Nota, entrambi i riferimenti di cella devono essere uguali:

MID (CELL ("address", A1 ), 2, SEARCH ("$", CELL ("address", A1 ), 2) -2)

Come funziona:

CELL ("proprietà", "intervallo") restituisce un valore specifico dell'intervallo in base alla proprietà utilizzata. In questo caso l'indirizzo della cella. La proprietà address restituisce un valore $ [col] $ [riga], ovvero A1 -> $ A $ 1. La funzione MID analizza il valore della colonna tra i simboli $.


0

Modo semplice per ottenere il nome della colonna

Sub column()

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

End Sub

Spero che aiuti =)


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

0

Quindi sono in ritardo alla festa qui, ma voglio contribuire con un'altra risposta che nessun altro ha ancora indirizzato che non coinvolge array. Puoi farlo con una semplice manipolazione delle stringhe.

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

Dopo aver inserito l'input nel formato $A$1, utilizzare la Midfunzione, iniziare dalla posizione 2 per tenere conto del primo$ , quindi trovare dove $appare il secondo nella stringa InStre quindi sottrarre 2 per tenere conto di quella posizione iniziale.

Questo ti dà il vantaggio di essere adattabile per l'intera gamma di possibili colonne. Pertanto, ColLetter(1)restituisce "A" e ColLetter(16384)restituisce "XFD", che è l'ultima colonna possibile per la mia versione di Excel.


-1

La lettera della colonna dal numero della colonna può essere estratta usando la formula seguendo i passaggi
1. Calcola l'indirizzo della colonna usando la formula ADDRESS
2. Estrai la lettera della colonna usando la funzione MID e FIND

Esempio:
1.
Risultati ADDRESS (1000,1000,1) $ ALL $ 1000
2 . = Risultati MID (F15,2, TROVA ("$", F15,2) -2)
TUTTI i F15 assunti contengono il risultato del passaggio 1

In una volta possiamo scrivere
MID (INDIRIZZO (1000,1000,1), 2, TROVA ( "$", INDIRIZZO (1000,1000,1), 2) -2)


-1

questo è solo per REFEDIT ... generalmente usa il codice qui sopra versione a breve ... facile da leggere e capire / usa poz di $

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


-2

che ne dite di convertire il numero ASCII e di usare Chr () per riconvertire in una lettera?

col_letter = Chr (Selection.Column + 96)


-6

Ecco un altro modo:

{

      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

}

1
Non è necessario creare una stringa che elenchi le lettere dell'alfabeto. ASCII lo ha fatto essenzialmente per noi.
Caltor,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.