如何找到与给定整数对应的Excel列名?

33

如何确定Excel中第n列的列名(例如“AQ”或“BH”)?

编辑:确定此问题的语言无关算法是主要目标。


3
请勿删除此内容。A)它是必要的作为占位符,以增加搜索找到规范的机会。B)它有很好的答案。 - Lance Roberts
1
这里解决的一般问题是双射数码的转换,具体来说是双射基-26 - ecatmur
20个回答

45

我曾经编写了这个函数来执行这项任务:

public static string Column(int column)
{
    column--;
    if (column >= 0 && column < 26)
        return ((char)('A' + column)).ToString();
    else if (column > 25)
        return Column(column / 26) + Column(column % 26 + 1);
    else
        throw new Exception("Invalid Column #" + (column + 1).ToString());
}

我有什么遗漏吗?条件“(column >= 0 && column < 26)”和“(column > 25)”不是重叠了吗?“else if”测试是打字错误吗? - Onorio Catenacci
3
“column > 25”是说“column >= 26”的另一种方式。我认为后者更清晰,但两种方法都是正确的。 - technomalogical
惊人的解决方案。太棒了,我希望我能给+10。 - Elbek
Excel 2007 允许您有三字符列。因此,您需要另一个情况(或者用该模式替换)。 - Michael
3
@Michael - 这个算法是递归的,并且适用于任何大小的列。我已在Excel 2007的3字符列上进行了测试,它们可以正常工作(例如,Column(703) = "AAA"Column(704) = "AAB")。 - Joseph Sturtevant

28

这是我能想到的最简洁的正确解决方案(用Java编写,但可以使用您喜欢的语言):

String getNthColumnName(int n) {
    String name = "";
    while (n > 0) {
        n--;
        name = (char)('A' + n%26) + name;
        n /= 26;
    }
    return name;
}

但是如果您在这段代码中发现错误, 请务必让我知道,谢谢。


3
优秀的代码,非常简洁。但是您能解释一下 n-- 的原理吗? - seeker
6
让我看看能否简单地解释一下...每个数字都有26个符号,但这不是基于26的。这有点像基于27,但没有0。 n-- 是一种从基础27中移除0的方法,我们剩下的是[1, 26]范围映射到[A,Z]。明白了吗? - Samuel Audet
3
提醒一下所有尝试使用这个例子的人:如果你像我一样没有启动大脑,需要注意n是列号(从1开始),而不是索引号(从0开始)! - eventhorizon
@eventhorizon 没错! - Pavithran Ravichandiran
其他语言实现的注意事项:这里的 n /= 26 是整数除法,即舍弃余数(或小数部分)。 - Wolfie

11

语言无关的算法如下:

function getNthColumnName(int n) {
   let curPower = 1
   while curPower < n {
      set curPower = curPower * 26
   }
   let result = ""
   while n > 0 {
      let temp = n / curPower
      let result = result + char(temp)
      set n = n - (curPower * temp)
      set curPower = curPower / 26
   }
   return result

这个算法还考虑了Excel升级后能否处理超过16k列的情况。如果你想要更进一步,可以传入一个额外的值,并将26的实例替换为另一个数字以适应其他字母表。


好的。我假设temp是一个整数,那么 let temp = n / curPower 这个除法是如何取整的?还有 / 26 呢? - SantiBailors

7

谢谢你,Joseph Sturtevant!你的代码完美地运行了 - 我需要它在vbscript中,所以我想分享我的版本:

Function ColumnLetter(ByVal intColumnNumber)
    Dim sResult
    intColumnNumber = intColumnNumber - 1
    If (intColumnNumber >= 0 And intColumnNumber < 26) Then
        sResult = Chr(65 + intColumnNumber)
    ElseIf (intColumnNumber >= 26) Then
        sResult = ColumnLetter(CLng(intColumnNumber \ 26)) _
                & ColumnLetter(CLng(intColumnNumber Mod 26 + 1))
    Else
        err.Raise 8, "Column()", "Invalid Column #" & CStr(intColumnNumber + 1)
    End If
    ColumnLetter = sResult
End Function

6

Joseph的代码很好,但是如果你不想或者不需要使用VBA函数,可以尝试以下方法。

假设n的值在单元格A2中,请使用以下函数:

=MID(ADDRESS(1,A2),2,LEN(ADDRESS(1,A2))-3)

3
IF(COLUMN()>=26,CHAR(ROUND(COLUMN()/26,1)+64)&CHAR(MOD(COLUMN(),26)+64),CHAR(COLUMN()+64))

这个公式适用于两个字母的列(直到列ZZ)。如果要使用三个字母的列,您需要嵌套另一个if语句。

上述公式在列AYAZ和每个后续的nYnZ列上失败。更正后的公式为:

=IF(COLUMN()>26,CHAR(ROUNDDOWN((COLUMN()-1)/26,0)+64)&CHAR(MOD((COLUMN()-1),26)+65),CHAR(COLUMN()+64)

3

Ruby一行代码:

def column_name_for(some_int)
    some_int.to_s(26).split('').map {|c| (c.to_i(26) + 64).chr }.join # 703 => "AAA"
end

它将整数转换为26进制,然后将其拆分并进行一些数学计算,以将每个字符从ASCII转换。最后将它们全部连接在一起。没有除法、模运算或递归。

有趣。


1
错误的写法:column_name_for(26) => 'A@' - Ringding

3

来自wcm:

如果您不想使用VBA,您可以使用此方法,将colnr替换为您想要的数字

=MID(ADDRESS(1,colnr),2,LEN(ADDRESS(1,colnr))-3)

请注意,由于使用了ADDRESS函数,此公式是易变的。易变的函数是指在每次更改后都会被Excel重新计算的函数。 通常情况下,只有当它们的相关引用发生更改时,Excel才会重新计算公式。 使用此公式可能会对性能产生负面影响。

2
这在 MS Excel 2003-2010 中运行良好。应该适用于支持 Cells(...).Address 函数的早期版本:
  1. 对于第28列 - 取 columnNumber=28; Cells(1, columnNumber).Address 返回 "$AB$1"
  2. $ 符号进行拆分,返回数组:["","AB","1"]
  3. 因此,Split(Cells(1, columnNumber).Address, "$")(1) 给出列名 "AB"

更新:
摘自如何将Excel列编号转换为字母字符
' The following VBA function is just one way to convert column number 
' values into their equivalent alphabetical characters:

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

适用于:Microsoft Office Excel 2007 SE / 2002 SE / 2000 SE / 97 SE

2

以下是VBScript版本转换为SQL Server 2000+版本的内容。

CREATE FUNCTION [dbo].[GetExcelColRef] 
(
    @col_seq_no int
)
RETURNS varchar(5)
AS
BEGIN

declare @Result varchar(5)
set @Result = ''
set @col_seq_no = @col_seq_no - 1
If (@col_seq_no >= 0 And @col_seq_no < 26) 
BEGIN
    set @Result = char(65 + @col_seq_no)
END
ELSE
BEGIN
    set @Result = [dbo].[GetExcelColRef] (@col_seq_no / 26) + '' + [dbo].[GetExcelColRef]  ((@col_seq_no % 26) + 1)
END
Return @Result

END
GO

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