【问题标题】:Function to convert column number to letter?将列号转换为字母的功能?
【发布时间】:2012-09-29 14:29:30
【问题描述】:

有没有 Excel VBA 函数可以从数字中返回列字母?

例如,输入 100 应该返回CV

【问题讨论】:

  • @FrancisDean 这是这个问题的反面,它正在从号码中寻找地址
  • @brettdj 链接的答案显示数字到字母和字母到数字。
  • @FrancisDean 公平点,我查看了链接中的问题标题,而不是接受的答案

标签: excel vba excel-udf


【解决方案1】:

此函数返回给定列号的列字母。

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

【讨论】:

  • 如果您想为自己保存变量声明和额外的代码行,可以将(0) 添加到拆分命令的末尾。例如Col_letter = Split(Cells(1, lngCol).Address(True, False), "$")(0)
  • 说的很对,不过我觉得用几行更易读。
  • 为什么要在这种情况下使用布尔参数。你可以这样做:............................................. ……v = Split(Cells(1, lngCol).Address, "$")(1)
  • 虽然这已经很老了,但我有一个小补充——首先检查数字是否为正,否则你会遇到错误。如果 lngcol
  • 使用VBS时,请记住.Cells是Excel的一个属性,也就是说你需要使用<excel_object>.Cells()。否则,您将收到类型不匹配错误。
【解决方案2】:

如果您不想使用范围对象:

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

【讨论】:

  • 不清楚为什么你基于 如果你不想使用范围对象:发​​布了一个更长的带有循环的方法
  • @brettdj 我可以想象几个原因:1)通过我的测试,这种方法大约快 6 倍 2)它不需要访问 Excel API 3)它可能具有更小的内存占用。编辑:另外,我不知道为什么我对一个超过一年的答案发表评论:S
  • 不过,提高速度有一个缺点。如果传入无效的列号,则使用范围对象会引发错误。即使有人仍在使用 Excel 2003,它也可以工作。如果您需要这种异常,请使用 range 方法。否则,向 robartsd 致敬。
  • IF ColumnNumber <= Columns.Count 最好避免对版本进行假设。
  • 使用此代码的另一个原因是,如果您不在 VBA 中,而是在 VB、.net 等中。
【解决方案3】:

对我有用的是:

Cells(Row,Column).Address 

这将为您返回 $AE$1 格式参考。

【讨论】:

  • 这不能回答问题。
【解决方案4】:

  • 例如: MsgBox Columns( 9347 ).Address 返回

要返回列字母Split((Columns(Column Index ).Address(,0)),":")(0)

  • 例如: MsgBox Split((Columns( 2734 ).Address(,0)),":")(0) 返回

  


【讨论】:

  • 这个适用于我在 Office 365 中:string col = Worksheet.Columns[column].Address;返回 col.Substring(col.IndexOf(":") + 2);由于某种原因,其他表达式,例如 Range = Worksheet.Cells[1,column],正在引发错误(在 Cells 调用中或当我尝试获取地址时,不记得 - 抱歉 - 哪些行在哪个具体情况。)
【解决方案5】:

还有一个使用递归的解决方案:

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 的数字。谢谢!
  • 余数永远不能超过 26 那么为什么不是整数而不是长整数呢?
  • @Caltor 除非您有使用整数的特殊目的,例如调用需要一个整数的 API,否则您永远不应该选择整数而不是长整数。 VBA 针对 Long 进行了优化。 VBA 处理 Long 的速度比 Integer 快。
  • @ExcelHero 我不知道。不过 Long 不会比 Integer 占用更多的内存吗?
  • @Caltor 实际上 Long 是 32 位,而 Integer 是 16 位。但这在现代计算中并不重要。 25 年前……这很重要。但今天(甚至 15 年前)这种差异完全无关紧要。
【解决方案6】:

还有一种方法可以做到这一点。 Brettdj's answer让我想到了这个,但是如果你使用这种方法你不必使用变体数组,你可以直接去一个字符串。

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

或者可以让它更紧凑一点

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

请注意,这确实取决于您引用单元格对象中的第 1 行。

【讨论】:

    【解决方案7】:

    这可以通过使用公式来获得:

    =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's answer 的一个版本(带有Jan Wijninckx's one line solution 的味道),使用递归而不是循环。

      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=> ""
      

      【讨论】:

      • 我刚刚注意到这与 Nikolay Ivanov 的解决方案基本相同,这使我的解决方案不那么新颖。我会保留它,因为它对一些细节显示了稍微不同的方法
      • 好的解决方案有两个原因:不使用任何对象(例如范围、单元格等);非常紧凑的定义。
      【解决方案9】:

      robertsd's code 很优雅,但要使其经得起未来考验,请将 n 的声明更改为 long 类型

      如果您想要一个公式来避免使用宏,这里有一个适用于第 702 列(包括第 702 列)的公式

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

      其中 A1 是包含要转换为字母的列号的单元格。

      【讨论】:

        【解决方案10】:

        最新更新:请忽略下面的功能,@SurasinTancharoen 设法提醒我它在n = 53 已损坏。
        对于那些感兴趣的人,下面是n = 200 下方的其他损坏值:

        Please use @brettdj function for all your needs. It even works for Microsoft Excel latest maximum number of columns limit: 16384 should gives XFD

        更新结束


        以下功能由微软提供:

        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
        

        来源:How to convert Excel column numbers into alphabetical characters

        适用于

        • Microsoft Office Excel 2007
        • Microsoft Excel 2002 标准版
        • Microsoft Excel 2000 标准版
        • Microsoft Excel 97 标准版

        【讨论】:

        • 作为参考,这具有较大的列集作为 Chr() 不能很好地处理大数字。
        • 这有一个错误。尝试 ConvertToLetter(53),它应该是 'BA',但它会失败。
        • @SurasinTancharoen 非常感谢您注意到这个缺陷。我从没想过微软会提供一个损坏的功能,因为他们是自己创建 Microsoft Excel 的人。从现在开始,我将放弃此功能,并将使用@brettdj 功能,该功能甚至可以纠正最新的Microsoft Excel 最大列数限制Col_Letter(16384) = "XFD"
        • 这个“除以 27”究竟是从哪里来的?最后我检查了有 26 个字母。这就是代码中断的原因。
        【解决方案11】:

        这是一个基于上面@DamienFennelly's answer的函数。如果你给我一个大拇指,也给他一个大拇指! :P

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

        【讨论】:

        • 不错,但它与接受的答案有何不同?
        • @loannis 我基于 DamianFennelly 的回答,而不是接受的回答。但是,是的,我的看起来很像公认的答案,除了一行被分成两行以使其更具可读性。
        【解决方案12】:

        有一个非常简单的使用Excel power的方法:使用Range.Cells.Address属性,这样:

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

        这将返回第 1 行所需列的地址。将其从 1 中取出:

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

        请注意,它是如此快速和强大,以至于您可以返回甚至存在的列地址!

        使用Selection.Column 属性将lngRow 替换为所需的列号!

        【讨论】:

          【解决方案13】:

          这是一个简单的可以使用的衬里。

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

          它仅适用于 1 个字母的列名称,但它适用于简单的情况。如果您需要它专门用于 2 个字母的名称,那么您可以使用以下内容:

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

          【讨论】:

            【解决方案14】:

            无论位于 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)
            

            【讨论】:

              【解决方案15】:

              所以我在这里聚会迟到了,但我想提供另一个没有人解决但不涉及数组的答案。您可以通过简单的字符串操作来做到这一点。

              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 开始计算第一个$,然后使用@ 找到第二个$ 在字符串中出现的位置987654326@,然后减去 2 以说明该起始位置。

              这使您可以适应所有可能的列。因此,ColLetter(1) 返回“A”,ColLetter(16384) 返回“XFD”,这是我的 Excel 版本的最后一个可能的列。

              【讨论】:

                【解决方案16】:

                获取列名的简单方法

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

                希望对你有帮助 =)

                【讨论】:

                  【解决方案17】:

                  brettdj 的解决方案非常有效,但如果您出于与我相同的原因将其视为潜在解决方案,我想我会提供我的替代解决方案。

                  我遇到的问题是根据 MA​​TCH() 函数的输出滚动到特定列。我没有将列号平行转换为列字母,而是选择暂时将参考样式从 A1 切换到 R1C1。这样我就可以滚动到列号,而不必使用 VBA 函数。要在两种参考样式之间轻松切换,您可以使用此 VBA 代码:

                  Sub toggle_reference_style()
                  
                  If Application.ReferenceStyle = xlR1C1 Then
                    Application.ReferenceStyle = xlA1
                  Else
                    Application.ReferenceStyle = xlR1C1
                  End If
                  
                  End Sub
                  

                  【讨论】:

                    【解决方案18】:

                    进一步了解 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
                    

                    这个函数的权衡是,由于IF 测试,它会比 brettdj 的答案慢得多。但是,如果该功能被重复使用很多次,就会感觉到这一点。

                    【讨论】:

                      【解决方案19】:

                      这是一个较晚的答案,仅用于在 1-3 个字符列的情况下使用 Int()If 的简单方法:

                      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
                      

                      【讨论】:

                        【解决方案20】:
                        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
                        

                        【讨论】:

                          【解决方案21】:

                          这里是 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;
                          

                          【讨论】:

                            【解决方案22】:

                            此公式将根据范围(即 A1)给出列,其中范围是单个单元格。如果给出了多单元格范围,它将返回左上角的单元格。注意,两个单元格引用必须相同:

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

                            它是如何工作的:

                            CELL("property","range") 根据使用的属性返回范围的特定值。在这种情况下,单元格地址。 address 属性返回一个值 $[col]$[row],即 A1 -> $A$1。 MID 函数解析出 $ 符号之间的列值。

                            【讨论】:

                              【解决方案23】:
                              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
                              

                              【讨论】:

                                【解决方案24】:

                                可以通过以下步骤使用公式从列号中提取列字母
                                1.使用ADDRESS公式计算列地址
                                2. 使用 MID 和 FIND 函数提取列字母

                                示例:
                                1. 地址(1000,1000,1)
                                结果 $ALL$1000
                                2. =MID(F15,2,FIND("$",F15,2)-2)
                                结果 ALL 假设 F15 包含第 1 步的结果

                                我们可以一口气写出
                                MID(ADDRESS(1000,1000,1),2,FIND("$",ADDRESS(1000,1000,1),2)-2)

                                【讨论】:

                                  【解决方案25】:

                                  这仅用于 REFEDIT ... 一般使用 uphere 代码 短期版本...易于阅读和理解 / 它使用 $ 的 poz

                                  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
                                  

                                  【讨论】:

                                    【解决方案26】:

                                    Cap A 是 65,所以:

                                    MsgBox Chr(ActiveCell.Column + 64)

                                    发现于:http://www.vbaexpress.com/forum/showthread.php?6103-Solved-get-column-letter

                                    【讨论】:

                                      【解决方案27】:

                                      只转换为 ascii 数字并使用 Chr() 转换回字母怎么样?

                                      col_letter = Chr(Selection.Column + 96)

                                      【讨论】:

                                        【解决方案28】:

                                        这是另一种方式:

                                        {
                                        
                                              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
                                        
                                        }
                                        

                                        【讨论】:

                                        • 无需创建列出字母表的字符串。 ASCII 基本上已经为我们做到了。
                                        猜你喜欢
                                        • 2018-12-13
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 2019-03-25
                                        • 1970-01-01
                                        相关资源
                                        最近更新 更多