Chức năng chuyển đổi số cột thành chữ?


143

Có ai có hàm VBA Excel có thể trả về (các) chữ cái cột từ một số không?

Ví dụ, nhập 100 sẽ trở lại CV.



@FrancisDean đó là mặt trái của câu hỏi này đang tìm địa chỉ từ số
brettdj

2
@brettdj Câu trả lời được liên kết hiển thị cả số thành chữ cái và chữ cái cho số.
Phanxicô

2
@FrancisDean điểm công bằng, tôi đã xem tiêu đề câu hỏi trong liên kết đến thay vì câu trả lời được chấp nhận
brettdj 30/03/2015

Câu trả lời:


211

Hàm này trả về ký tự cột cho một số cột đã cho.

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

mã kiểm tra cho cột 100

Sub Test()
    MsgBox Col_Letter(100)
End Sub

9
Bạn có thể thêm (0)vào cuối lệnh Split nếu bạn muốn lưu cho mình một khai báo biến và dòng mã bổ sung. ví dụCol_letter = Split(Cells(1, lngCol).Address(True, False), "$")(0)
Caltor

3
Điều đó khá chính xác, nhưng tôi nghĩ nó dễ đọc hơn khi sử dụng một vài dòng.
brettdj

6
Tại sao phải bận tâm với các thông số Boolean trong tình huống này. Bạn có thể làm được việc này:............................................. ......v = Split(Cells(1, lngCol).Address, "$")(1)
Anh hùng Excel

1
Mặc dù điều này rất cũ, tôi có một bổ sung nhỏ - trước tiên hãy kiểm tra xem số có dương không, vì nếu không bạn sẽ gặp lỗi. nếu lngcol <= 0 thì
Selkie

1
Khi sử dụng VBS, hãy nhớ rằng đó .Cellslà một thuộc tính của Excel, nghĩa là bạn cần sử dụng <excel_object>.Cells(). Nếu không, bạn sẽ nhận được một lỗi không khớp loại.
Stevoisiak

88

Nếu bạn không muốn sử dụng một đối tượng phạm vi:

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
Không rõ lý do tại sao bạn đăng một phương thức dài hơn với một vòng lặp trên cơ sở Nếu bạn không muốn sử dụng một đối tượng phạm vi:
brettdj

29
@brettdj Tôi có thể tưởng tượng một số lý do: 1) phương pháp này nhanh hơn khoảng 6 lần bởi thử nghiệm của tôi 2) nó không yêu cầu quyền truy cập vào API API 3) có lẽ nó có dung lượng bộ nhớ nhỏ hơn. EDIT: Ngoài ra, tôi không chắc tại sao tôi nhận xét về câu trả lời hơn một năm tuổi: S
Blackhawk

6
Tuy nhiên, có một nhược điểm đối với tốc độ tăng. Sử dụng đối tượng phạm vi sẽ gây ra lỗi nếu bạn chuyển vào số cột không hợp lệ. Nó hoạt động ngay cả khi ai đó vẫn đang sử dụng Excel 2003. Nếu bạn cần loại ngoại lệ đó, hãy sử dụng phương pháp phạm vi. Nếu không, kudos để robartsd.
Kỹ sư Toast

6
IF ColumnNumber <= Columns.Countsẽ tốt hơn để tránh các giả định xung quanh các phiên bản.
brettdj

1
Một lý do khác để sử dụng mã này là nếu bạn không ở VBA mà ở VB, .net, v.v.
Maury Markowitz

46

Một cái gì đó phù hợp với tôi là:

Cells(Row,Column).Address 

Điều này sẽ trả về tham chiếu định dạng $ AE $ 1 cho bạn.


1
Điều này không trả lời câu hỏi.
Pochmurnik

33

Tôi ngạc nhiên không ai đề xuất: ** <code> </ code> <code> Cột (</ code> *** <code> Chỉ mục cột </ code> *** <code>). Địa chỉ </ code> <mã> </ code> **

  • Ví dụ: MsgBox Columns( 9347 ).Address trả về ** <code> $ MUM: $ MUM </ code> ** .

Để trả về CHỈ (các) chữ cái cột :Split((Columns(Column Index).Address(,0)),":")(0)

  • Ví dụ: MsgBox Split((Columns( 2734 ).Address(,0)),":")(0) trả về ** <code> DAD </ code> ** .

  Thêm ví dụ



Cái này hoạt động với tôi trong Office 365: string col = Worksheet.Columns [cột] .Address; return col.Sub chuỗi (col.IndexOf (":") + 2); Vì một số lý do, các biểu thức khác, chẳng hạn như Range = Worksheet.Cells [1, cột], đã bị lỗi (trong cuộc gọi của Ô hoặc khi tôi cố lấy địa chỉ, không thể nhớ - xin lỗi - dòng nào ném vào đó trường hợp cụ thể.)
Sam Azer

19

Chỉ còn một cách nữa để làm điều này. Câu trả lời của Brettdj khiến tôi nghĩ về điều này, nhưng nếu bạn sử dụng phương pháp này, bạn không phải sử dụng một mảng biến thể, bạn có thể chuyển trực tiếp đến một chuỗi.

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

hoặc có thể làm cho nó nhỏ gọn hơn một chút với điều này

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

Lưu ý điều này không phụ thuộc vào bạn tham chiếu hàng 1 trong đối tượng ô.


18

Và một giải pháp sử dụng đệ quy:

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

Cắt và dán hoàn hảo để chuyển đổi số lớn hơn 676. Cảm ơn!
David Krider

1
Phần còn lại không bao giờ có thể nhiều hơn 26, vậy tại sao không phải là một số nguyên chứ không phải là dài?
Caltor 18/2/2015

10
@Caltor Trừ khi bạn có mục đích đặc biệt để sử dụng Số nguyên, như gọi API yêu cầu một ví dụ, bạn không bao giờ nên chọn Số nguyên trong thời gian dài. VBA được tối ưu hóa cho Longs. VBA xử lý Longs nhanh hơn số nguyên.
Excel Hero

1
@ExcelHero Tôi không biết điều đó. Không phải một Long mất nhiều bộ nhớ hơn một Integer sao?
Caltor

6
@Caltor Thật vậy, Long là 32 bit, trong khi Số nguyên là 16. Nhưng điều đó không quan trọng trong điện toán hiện đại. 25 năm trước ... nó quan trọng rất nhiều. Nhưng ngày nay (thậm chí 15 năm trước), sự khác biệt là hoàn toàn không quan trọng.
Anh hùng Excel

9

Điều này có sẵn thông qua việc sử dụng một công thức:

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

và do đó cũng có thể được viết dưới dạng hàm VBA theo yêu cầu:

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

8

Đây là phiên bản câu trả lời của robartsd (với hương vị của giải pháp một dòng của Jan Wijninckx ), sử dụng đệ quy thay vì vòng lặp.

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

Tôi đã thử nghiệm điều này với các đầu vào sau:

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

2
Tôi chỉ nhận thấy rằng điều này về cơ bản giống như giải pháp của Nikolay Ivanov, điều này làm cho tôi ít tiểu thuyết hơn. Tôi sẽ bỏ nó đi vì nó cho thấy một cách tiếp cận hơi khác đối với một vài chi tiết vụn vặt
alexanderbird

Giải pháp tốt cho hai lý do: không sử dụng bất kỳ đối tượng nào (chẳng hạn như phạm vi, ô, v.v.); định nghĩa rất nhỏ gọn.
yêu.by.Jesus

8

Mã của robertsd là thanh lịch, nhưng để làm cho nó trở thành bằng chứng trong tương lai, hãy thay đổi khai báo của n để gõ dài

Trong trường hợp bạn muốn một công thức để tránh macro, đây là một cái gì đó hoạt động đến cột 702

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

Trong đó A1 là ô chứa số cột được chuyển đổi thành chữ cái.


7

CẬP NHẬT MỚI NHẤT : Vui lòng bỏ qua chức năng bên dưới, @SurasinTancharoen quản lý để thông báo cho tôi rằng nó bị hỏng tại n = 53.
Đối với những người quan tâm, đây là các giá trị bị hỏng khác ngay bên dướin = 200 :

Một số giá trị của

Vui lòng sử dụng chức năng @brettdj cho tất cả các nhu cầu của bạn. Nó thậm chí hoạt động cho giới hạn số cột tối đa mới nhất của Microsoft Excel: 16384nên cung cấpXFD

nhập mô tả hình ảnh ở đây

KẾT THÚC CẬP NHẬT


Chức năng dưới đây được cung cấp bởi 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

Nguồn: Cách chuyển đổi số cột Excel thành các ký tự chữ cái

ÁP DỤNG CHO

  • Microsoft Office Excel 2007
  • Phiên bản tiêu chuẩn Microsoft Excel 2002
  • Phiên bản tiêu chuẩn Microsoft Excel 2000
  • Phiên bản tiêu chuẩn Microsoft Excel 97

2
Để tham khảo, pukes này với các bộ cột lớn hơn như Chr () không xử lý tốt số lượng lớn.
Azuvector

2
Điều này có một lỗi. Hãy thử ConvertToLetter (53) đáng lẽ là 'BA' nhưng sẽ thất bại.
Surasin Tancharoen

@SurasinTancharoen Cảm ơn bạn rất nhiều vì đã chú ý đến lỗ hổng này. Tôi chưa bao giờ nghĩ Microsoft sẽ cung cấp một chức năng bị hỏng vì họ là người đã tạo ra Microsoft Excel. Tôi sẽ từ bỏ chức năng này kể từ bây giờ và sẽ sử dụng chức năng @brettdj thậm chí sửa tối đa số lượng giới hạn cột tối đa mới nhất của Microsoft ExcelCol_Letter(16384) = "XFD"
mtbink.com

4
Và việc "chia cho 27" này đến từ đâu trên trái đất? Lần cuối tôi kiểm tra có 26 chữ cái. Đây là lý do tại sao mã này bị phá vỡ.
ib11

5

Đây là một chức năng dựa trên câu trả lời của @ DamienFennelly ở trên. Nếu bạn cho tôi một ngón tay cái lên, cho anh ấy một ngón tay cái quá! : P

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

2
Tốt, nhưng nó khác với câu trả lời được chấp nhận như thế nào?
Ioannis

@loannis Tôi dựa vào câu trả lời của DamianFennelly, không phải câu trả lời. Nhưng vâng, tôi trông rất giống câu trả lời được chấp nhận, ngoại trừ một dòng được chia thành hai để dễ đọc hơn.
BrettFromLA

3

Có một cách rất đơn giản bằng cách sử dụng nguồn Excel: Sử dụng thuộc Range.Cells.Addresstính, theo cách này:

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

Điều này sẽ trả về địa chỉ của cột mong muốn trên hàng 1. Lấy địa chỉ 1:

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

Lưu ý rằng nó nhanh và mạnh đến mức bạn có thể trả về các địa chỉ cột thậm chí còn tồn tại!

Thay thế lngRowcho số cột mong muốn bằng cách sử dụng Selection.Columntài sản!


2

Đây là một lót đơn giản có thể được sử dụng.

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

Nó sẽ chỉ hoạt động cho một chỉ định cột 1 chữ cái, nhưng nó là tốt đẹp cho các trường hợp đơn giản. Nếu bạn cần nó để làm việc chỉ với 2 ký tự, thì bạn có thể sử dụng như sau:

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

2

Điều này sẽ hoạt động bất kể cột nào bên trong một dòng mã của bạn cho ô nằm ở hàng X, trong cột Y:

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

Nếu bạn có một ô có tên được xác định duy nhất "Cellname":

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

1

Giải pháp từ brettdj hoạt động tuyệt vời, nhưng nếu bạn bắt gặp đây là một giải pháp tiềm năng cho cùng một lý do, tôi nghĩ rằng tôi sẽ cung cấp giải pháp thay thế của mình.

Vấn đề tôi gặp phải là cuộn đến một cột cụ thể dựa trên đầu ra của hàm MATCH (). Thay vì chuyển đổi song song số cột thành ký tự cột, tôi đã chọn tạm thời chuyển kiểu tham chiếu từ A1 sang R1C1. Bằng cách này, tôi có thể chỉ cần cuộn đến số cột mà không cần phải thực hiện chức năng VBA. Để dễ dàng chuyển đổi giữa hai kiểu tham chiếu, bạn có thể sử dụng mã VBA này:

Sub toggle_reference_style()

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

End Sub

1

Hơn nữa về câu trả lời của brettdj, ở đây là làm cho đầu vào của số cột tùy chọn. Nếu đầu vào số cột bị bỏ qua, hàm sẽ trả về ký tự cột của ô gọi đến hàm. Tôi biết điều này cũng có thể đạt được chỉ bằng cách sử dụng ColumnLetter(COLUMN()), nhưng tôi nghĩ nó sẽ tốt nếu nó có thể hiểu một cách khéo léo như vậy.

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

Sự đánh đổi của chức năng này là nó sẽ rất chậm hơn một chút so với câu trả lời của brettdj vì IFbài kiểm tra. Nhưng điều này có thể được cảm nhận nếu chức năng được sử dụng nhiều lần trong một số lượng rất lớn.


1

Đây là một câu trả lời muộn, chỉ dành cho cách tiếp cận đơn giản bằng cách sử dụng Int()Iftrong trường hợp có 1-3 cột ký tự:

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

Ở đây, một hàm đơn giản trong 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

Công thức này sẽ đưa ra cột dựa trên một phạm vi (nghĩa là A1 ), trong đó phạm vi là một ô duy nhất. Nếu một phạm vi đa ô được đưa ra, nó sẽ trả về ô trên cùng bên trái. Lưu ý, cả hai tham chiếu ô phải giống nhau:

MID (CELL ("địa chỉ", A1 ), 2, TÌM KIẾM ("$", CELL ("địa chỉ", A1 ), 2) -2)

Làm thế nào nó hoạt động:

CELL ("thuộc tính", "phạm vi") trả về một giá trị cụ thể của phạm vi tùy thuộc vào thuộc tính được sử dụng. Trong trường hợp này là địa chỉ ô. Thuộc tính địa chỉ trả về giá trị $ [col] $ [hàng], tức là A1 -> $ A $ 1. Hàm MID phân tích giá trị cột giữa các ký hiệu $.


0

Cách dễ dàng để có được tên cột

Sub column()

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

End Sub

Tôi hy vọng nó sẽ giúp =)


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

Vì vậy, tôi đến bữa tiệc muộn ở đây, nhưng tôi muốn đóng góp một câu trả lời khác mà chưa có ai giải quyết mà không liên quan đến mảng. Bạn có thể làm điều đó với thao tác chuỗi đơn giản.

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

Sau khi bạn có đầu vào ở định dạng $A$1, hãy sử dụng Midhàm, bắt đầu ở vị trí 2 để tính toán đầu tiên $, sau đó bạn tìm vị trí thứ hai $xuất hiện trong chuỗi bằng cách sử dụng InStr, sau đó trừ đi 2 để tính đến vị trí bắt đầu đó.

Điều này mang lại cho bạn lợi ích của việc có thể thích ứng với toàn bộ phạm vi của các cột có thể. Do đó, ColLetter(1)trả lại "A" và ColLetter(16384)trả lại "XFD", đây là cột có thể cuối cùng cho phiên bản Excel của tôi.


-1

Có thể trích xuất chữ cái cột từ số cột bằng công thức bằng các bước sau
1. Tính toán địa chỉ cột bằng công thức ADDRESS
2. Trích xuất chữ cái cột bằng hàm MID và FIND

Ví dụ:
1. ADDRESS (1000,1000,1)
kết quả $ ALL $
2 2 . = MID (F15,2, FIND ("$", F15,2) -2)
kết quả TẤT CẢ F15 chứa kết quả của bước 1

Trong một lần, chúng ta có thể viết
MID (ĐỊA CHỈ (1000,1000,1), 2, TÌM ("$", ĐỊA CHỈ (1000,1000,1), 2) -2)


-1

cái này chỉ dành cho REFEDIT ... thông thường sử dụng mã uphere phiên bản ngắn ... dễ đọc và dễ hiểu / nó sử dụng poz của $

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

Còn việc chuyển đổi sang số ascii và sử dụng Chr () để chuyển đổi trở lại thành một chữ cái thì sao?

col_letter = Chr (Lựa chọn.Column + 96)


-6

Đây là một cách khác:

{

      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
Không cần phải tạo một chuỗi liệt kê các chữ cái của bảng chữ cái. ASCII về cơ bản đã làm điều đó cho chúng tôi.
Caltor 18/2/2015
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.