Функция для преобразования номера столбца в букву?


143

У кого-нибудь есть функция Excel VBA, которая может возвращать букву (буквы) столбца из числа?

Например, ввод 100 должен вернуться CV.


4
Проверьте этот вопрос: stackoverflow.com/questions/10106465/…
Фрэнсис Дин

@FrancisDean, который является противоположностью этого вопроса, который ищет адрес из числа
brettdj

2
@brettdj В ответе указана цифра к букве и буква к номеру.
Фрэнсис Дин

2
@FrancisDean Справедливо, я посмотрел на название вопроса в ссылке, а не на принятый ответ
brettdj

Ответы:


211

Эта функция возвращает букву столбца для данного номера столбца.

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

тестовый код для столбца 100

Sub Test()
    MsgBox Col_Letter(100)
End Sub

9
Вы можете добавить в (0)конец команду Split, если хотите сохранить объявление переменной и дополнительную строку кода. напр.Col_letter = Split(Cells(1, lngCol).Address(True, False), "$")(0)
Caltor

3
Это совершенно правильно, но я подумал, что удобнее читать несколько строк.
brettdj

6
Зачем беспокоиться о булевых параметрах в этой ситуации. Ты можешь сделать это:............................................. ......v = Split(Cells(1, lngCol).Address, "$")(1)
Excel Hero

1
Хотя это очень старое, у меня есть небольшое дополнение - сначала проверить, является ли число положительным, так как в противном случае вы столкнетесь с ошибками. если lngcol <= 0 тогда
Selkie

1
При использовании VBS помните, что .Cellsэто свойство Excel, то есть его необходимо использовать <excel_object>.Cells(). В противном случае вы получите ошибку несоответствия типов.
Stevoisiak

88

Если вы не хотите использовать объект диапазона:

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
Непонятно, почему вы разместили более длинный метод с циклом на основе Если вы не хотите использовать объект диапазона:
brettdj

29
@brettdj Я могу представить себе несколько причин: 1) этот метод примерно в 6 раз быстрее при моем тестировании 2) он не требует доступа к API Excel 3) он предположительно имеет меньший объем памяти. РЕДАКТИРОВАТЬ: Кроме того, я не уверен, почему я прокомментировал ответ более года: S
Blackhawk

6
Есть недостаток в увеличенной скорости, хотя. Использование объекта диапазона вызывает ошибку, если вы передаете неверный номер столбца. Это работает, даже если кто-то все еще использует Excel 2003. Если вам нужно такое исключение, используйте метод range. В противном случае, слава Робарцд.
Инженер Тост

6
IF ColumnNumber <= Columns.Countбыло бы лучше избегать предположений относительно версий.
brettdj

1
Другая причина использовать этот код, если вы не в VBA, а в VB, .net и т. Д.
Мори Марковиц


33

Я удивлен, что никто не предложил: ** <code> </ code> <code> Столбцы (</ code> *** <code> Индекс столбцов </ code> *** <code>). Адрес </ code> <код> </ код> **

  • Например: MsgBox Columns( 9347 ).Address возвращает ** <код> $ МАМА: $ MUM </ код> ** .

Чтобы вернуть ТОЛЬКО буквы столбца :Split((Columns(Column Index).Address(,0)),":")(0)

  • Например: MsgBox Split((Columns( 2734 ).Address(,0)),":")(0) возвращает ** <код> DAD </ код> ** .

  Больше примеров



Это работает для меня в Office 365: строка col = Worksheet.Columns [column] .Address; return col.Substring (col.IndexOf (":") + 2); По какой-то причине другие выражения, такие как Range = Worksheet.Cells [1, column], выдавали ошибки (либо при вызове Cells, либо когда я пытался получить адрес, я не могу вспомнить - извините - какие строки где были выброшены, какие конкретные случаи.)
Сэм Азер

19

Еще один способ сделать это. Ответ Бреттджа заставил меня задуматься об этом, но если вы используете этот метод, вам не нужно использовать вариантный массив, вы можете перейти непосредственно к строке.

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

или может сделать это немного более компактным с этим

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

Обратите внимание, что это зависит от того, ссылаетесь ли вы на строку 1 в объекте клеток.


18

И решение с использованием рекурсии:

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

Вырезание и вставка идеально подходит для преобразования чисел больше 676. Спасибо!
Дэвид Крайдер

1
Остаток не может быть больше 26, так почему бы не целое число, а не длинное?
Caltor

10
@Caltor Если у вас нет особой цели для использования Integer, например, для вызова API, который требует его, например, вы никогда не должны выбирать Integer вместо Long. VBA оптимизирован для Longs. VBA обрабатывает Longs быстрее, чем Integer.
Excel Hero

1
@ExcelHero Я не знал этого. Разве Long не занимает больше памяти, чем Integer?
Caltor

6
@Caltor Действительно, Long - 32 бита, а Integer - 16. Но в современных вычислениях это не имеет значения. 25 лет назад ... это имело большое значение. Но сегодня (даже 15 лет назад) разница совершенно несущественна.
Excel Hero

9

Это доступно через формулу:

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

и так также может быть записан как функция VBA по запросу:

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

8

Это версия ответа robartsd (со вкусом однострочного решения Яна Вийнинка ), использующего рекурсию вместо цикла.

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

Я проверил это со следующими входами:

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

2
Я только что заметил, что это по сути то же самое, что решение Николая Иванова, которое делает мое немного менее оригинальным. Я оставлю это, потому что это показывает немного другой подход для некоторых мелочей
alexanderbird

Хорошее решение по двум причинам: не использовать какой-либо объект (например, диапазон, ячейку и т. Д.); очень компактное определение.
love.by.Иисус

8

Код Робертса элегантен, но чтобы сделать его перспективным, измените объявление n на long

Если вы хотите, чтобы формула избегала макрокоманд, вот что работает до столбца 702 включительно

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

где A1 - это ячейка, содержащая номер столбца, который нужно преобразовать в буквы.


7

ПОСЛЕДНИЕ ОБНОВЛЕНИЯ : Пожалуйста, игнорируйте функцию ниже, @SurasinTancharoen удалось предупредить меня, что она сломана в n = 53.
Для тех, кто заинтересован, ниже приведены другие значения n = 200:

Определенные значения

Пожалуйста, используйте функцию @brettdj для всех ваших потребностей. Это работает даже для Microsoft Excel с последним максимальным количеством столбцов: 16384следуетXFD

введите описание изображения здесь

КОНЕЦ ОБНОВЛЕНИЯ


Функция ниже предоставлена ​​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

Источник: Как преобразовать номера столбцов Excel в алфавитные символы

ОТНОСИТСЯ К

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

2
Для справки, это приводит к большим наборам столбцов, так как Chr () плохо обрабатывает большие числа.
Azuvector

2
В этом есть ошибка. Попробуйте ConvertToLetter (53), который должен был быть «BA», но он потерпит неудачу.
Суразин Танчароен

@SurasinTancharoen Большое спасибо за то, что отметили этот недостаток. Я никогда не думал, что Microsoft предоставит сломанную функцию, поскольку именно они сами создали Microsoft Excel. Я откажусь от этой функции с этого момента и буду использовать функцию @brettdj, которая даже корректирует до максимального числа столбцов в Microsoft Excel максимальное числоCol_Letter(16384) = "XFD"
mtbink.com

4
И откуда на Земле это «деление на 27»? Последнее, что я проверил, есть 26 букв. Вот почему этот код ломается.
ib11

5

Эта функция основана на ответе @ DamienFennelly выше. Если ты дашь мне большой палец, тоже подними его! :П

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

2
Хороший, но чем он отличается от принятого ответа?
Иоаннис

@loannis Я основал мой ответ Дамиана Феннелли, а не принятый. Но да, мой выглядит очень похоже на принятый ответ, за исключением того, что одна строка разбита на две, чтобы сделать его более читабельным.
BrettFromLA

3

Существует очень простой способ использования Excel: используйте Range.Cells.Addressсвойство следующим образом:

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

Это вернет адрес нужного столбца в строке 1. Возьмите его из 1:

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

Обратите внимание, что он настолько быстрый и мощный, что вы можете возвращать адреса столбцов, которые даже существуют!

Замените lngRowжелаемый номер столбца, используя Selection.Columnсвойство!


2

Вот простой вкладыш, который можно использовать.

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

Он будет работать только для обозначения в 1 букву, но это хорошо для простых случаев. Если вам нужно, чтобы он работал исключительно для двухбуквенных обозначений, вы можете использовать следующее:

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

2

Это будет работать независимо от того, какой столбец внутри вашей строки кода для ячейки, расположенной в строке X, в столбце Y:

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

Если у вас есть ячейка с уникальным определенным именем «Cellname»:

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

1

Решение от brettdj работает фантастически, но если вы столкнетесь с этим как с потенциальным решением по той же причине, что и я, я подумал, что предложу свое альтернативное решение.

У меня возникла проблема с прокруткой до определенного столбца на основе выходных данных функции MATCH (). Вместо того, чтобы преобразовывать номер столбца в его параллельную букву, я решил временно переключить стиль ссылки с A1 на R1C1. Таким образом, я мог бы просто прокрутить номер столбца без необходимости использовать функцию VBA. Чтобы легко переключаться между двумя ссылочными стилями, вы можете использовать этот код VBA:

Sub toggle_reference_style()

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

End Sub

1

В продолжение ответа brettdj, здесь можно сделать необязательным ввод номера столбца. Если ввод номера столбца опущен, функция возвращает букву столбца ячейки, которая вызывает функцию. Я знаю, что это также может быть достигнуто с помощью просто ColumnLetter(COLUMN()), но я подумал, что было бы хорошо, если бы он умело это понимал.

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

Компромисс этой функции заключается в том, что она будет очень-чуть медленнее, чем ответ brettdj из-за IFтеста. Но это можно почувствовать, если функцию многократно использовать очень много раз.


1

Вот поздний ответ, только для упрощенного подхода Int()и Ifв случае столбцов из 1-3 символов:

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

Здесь простая функция на Паскале (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

Эта формула даст столбец на основе диапазона (т. Е. A1 ), где диапазон - это одна ячейка. Если указан диапазон из нескольких ячеек, он вернет верхнюю левую ячейку. Обратите внимание, что обе ссылки на ячейки должны быть одинаковыми:

MID (CELL («адрес», A1 ), 2, ПОИСК («$», CELL («адрес», A1 ), 2) -2)

Как это устроено:

CELL ("свойство", "диапазон") возвращает конкретное значение диапазона в зависимости от используемого свойства. В этом случае адрес ячейки. Свойство address возвращает значение $ [col] $ [row], то есть A1 -> $ A $ 1. Функция MID анализирует значение столбца между символами $.


0

Простой способ получить имя столбца

Sub column()

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

End Sub

Надеюсь это поможет =)


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

Так что я опаздываю на вечеринку здесь, но я хочу дать еще один ответ, который еще никто не адресовал, который не связан с массивами. Вы можете сделать это с помощью простых манипуляций со строками.

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

После того, как у вас есть ввод в формате $A$1, используйте Midфункцию, начните с позиции 2, чтобы учесть первое $, затем найдите, где второе $появляется в строке, используя InStr, а затем вычтите 2 из, чтобы учесть эту начальную позицию.

Это дает вам возможность адаптироваться ко всему диапазону возможных столбцов. Поэтому ColLetter(1)возвращает «A» и ColLetter(16384)возвращает «XFD», что является последним возможным столбцом для моей версии Excel.


-1

Букву столбца из номера столбца можно извлечь, используя формулу, выполнив следующие действия:
1. Рассчитайте адрес столбца, используя формулу ADDRESS.
2. Извлеките букву столбца, используя функции MID и FIND.

Пример:
1.
Результаты ADDRESS (1000,1000,1) $ ALL $ 1000
2 . = MID (F15,2, FIND ("$", F15,2) -2)
результаты ВСЕ при условии, что F15 содержит результат шага 1

За один раз мы можем написать
MID (ADDRESS (1000,1000,1), 2, FIND ( "$", АДРЕС (1000,1000,1), 2) -2)


-1

это только для REFEDIT ... в общем, используйте короткую версию кода ... легко читаемую и понятную / она использует поз $

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

как насчет простого преобразования в число ascii и использования Chr () для преобразования обратно в букву?

col_letter = Chr (Selection.Column + 96)


-6

Вот еще один способ:

{

      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
Не нужно создавать строку со списком букв алфавита. ASCII по сути сделали это для нас.
Caltor
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.