将列号转换为字母的函数是什么?

183

有人有一段Excel VBA函数可以根据给定的数字返回相应的列字母吗?

例如输入100,应该返回CV


4
请查看这个问题:https://dev59.com/w2kw5IYBdhLWcg3wJXIh。 - Francis Dean
@FrancisDean,这是与该问题相反的情况,该问题是从数字中查找地址。 - brettdj
2
@brettdj所提供的答案展示了数字转字母和字母转数字的方法。 - Francis Dean
2
@FrancisDean 说得好,我看了链接中的问题标题而不是被接受的答案。 - brettdj
28个回答

251

这个函数返回给定列号对应的列字母。

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

19
如果您想节省变量声明和多余的代码行,可以在Split命令的末尾添加(0)。例如:Col_letter = Split(Cells(1, lngCol).Address(True, False), "$")(0) - Caltor
6
没问题,但我认为将其拆成几行更易读。 - brettdj
8
在这种情况下为什么要费心处理布尔参数呢?你可以这样做:................................................... v = Split(Cells(1, lngCol).Address, "$")(1) - Excel Hero
2
虽然这个很老,但是我有一个小改动-首先检查数字是否为正数,因为否则你会遇到错误。如果lngcol<=0,则... - Selkie
1
在使用VBS时,请记住.Cells是Excel的属性,这意味着您需要使用<excel_object>.Cells()。否则,您将会得到类型不匹配的错误。 - Stevoisiak

104

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

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
36
我可以想象出几个原因:1)经过我的测试,这种方法大约快6倍;2)它不需要访问Excel API;3)它可能有更小的内存占用。编辑:此外,我不确定为什么要评论一年前的答案:S - Blackhawk
6
然而,提高速度也存在缺点。如果传入无效的列数,使用范围对象会引发错误。即使有人仍在使用Excel 2003,该方法仍然有效。如果您需要这种异常情况,请选择范围方法。否则,向robartsd致敬。 - Engineer Toast
6
如果使用IF ColumnNumber <= Columns.Count,会更好一些,可以避免对版本的假设。 - brettdj
1
使用此代码的另一个原因是,如果您不在VBA中,而是在VB、.net等环境中。 - Maury Markowitz
显示剩余2条评论

55

对我有用的方法是:

Cells(Row,Column).Address 

这将为您返回 $AE$1 格式的引用。


3
这并没有回答这个问题。 - Pochmurnik
这正是解决我的问题的答案。虽然我使用的是另一种语言,但它让我进入了正确的方向。我将其视为伪代码并加以理解。以下是我使用的代码: $ws.Columns[$lastCol].Rows[$lastRow].Address().Replace('$','') - Lord Helmet

47

I'm surprised nobody suggested:   Columns(Column Index).Address

例如:MsgBox Columns( 9347 ).Address 返回 $MUM:$MUM
将仅返回列字母的代码翻译如下:

只返回列字母(s):Split((Columns(列索引).Address(,0)),":")(0)

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

  More Examples



这个在Office 365中对我有效:string col = Worksheet.Columns[column].Address; return col.Substring(col.IndexOf(":") + 2);由于某些原因,其他表达式(例如Range = Worksheet.Cells [1,column])会抛出错误(无论是在Cells调用还是在尝试获取地址时,我记不清楚了 - 抱歉 - 哪些行在哪些特定情况下抛出)。 - Sam Azer
更短的方法只返回列字母:Split(Columns(idx).Address, "$")(2) - 而不是 *Split((Columns(idx).Address(,0)),":")(0)*,其中 idx 是表示列索引的长整型。 - T.M.

20

还有一种方法可以实现这个。 Brettdj的回答 让我想到了这个,但是如果您使用此方法,则不必使用变体数组,而可以直接转到字符串。

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

或者您可以使用这个方法使其更加紧凑

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

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


19

使用递归的解决方案:

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的数字转换。谢谢! - David Krider
1
余数永远不会超过26,所以为什么不使用整数而不是长整数呢? - Caltor
11
除非您有特殊用途需要使用整数(例如调用要求整数的 API),否则您永远不应该选择整数而不是长整型。VBA 优化了长整型。VBA 处理长整型比处理整数更快。 - Excel Hero
1
@ExcelHero 我不知道这点。但是,Long类型比Integer类型占用更多的内存吧? - Caltor
6
@Caltor 的确,Long类型在计算机中占据32位,而Integer类型则占据16位。但这对于现代计算机并不重要。25年前...这很重要。但是今天(甚至15年前),它们之间的差异已经变得完全可以忽略不计了。 - Excel Hero

12

这可以通过使用一个公式来实现:

=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

11

2
我刚刚注意到这与Nikolay Ivanov的解决方案基本相同,这使得我的解决方案稍微不太新颖。我会保留它,因为它展示了一些细节上稍微不同的方法。 - alexanderbird
1
好的解决方案有两个原因:不使用任何对象(如范围、单元格等);定义非常紧凑。 - loved.by.Jesus

10

robertsd的代码非常优雅,然而为了使其具有未来性,将n的声明更改为long类型。

如果您想要一个避免使用宏的公式,这里有一个可以在包括第702列在内的范围内工作的东西。

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

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


此外,以下是一种将列字母转换为列号的公式,以类似的方式呈现。 - optimiertes

7
最新更新:请忽略下面的函数,@SurasinTancharoen提醒我在n = 53时它会出现错误。
对于那些感兴趣的人,以下是n = 200以下其他出错的值:

Certain values of

请使用@brettdj的函数来满足您的所有需求。它甚至可以处理Microsoft Excel最新的列数限制:16384应该返回XFD

enter image description here

更新结束

以下函数由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 标准版
  • Microsoft Excel 2000 标准版
  • Microsoft Excel 97 标准版

2
作为参考,当Chr()无法很好地处理大数字时,这会出现更大列集的问题。 - Azuvector
2
这里有一个bug。尝试执行ConvertToLetter(53),它应该是'BA',但是会失败。 - Surasin Tancharoen
@SurasinTancharoen非常感谢您指出这个缺陷。我从未想过微软会提供一个有问题的函数,因为他们是创建Microsoft Excel的人。从现在开始,我将放弃这个函数,并使用@brettdj的函数,即使可以正确地处理最新的Microsoft Excel列数限制“Col_Letter(16384)=“XFD””。 - mtbink.com
4
这个“除以27”的概念从何而来?据我所知,英文只有26个字母。这就是为什么这段代码出错的原因。 - ib11

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接