关于算法:如何找到与给定整数对应的Excel列名称?

关于算法:如何找到与给定整数对应的Excel列名称?

How do I find the Excel column name that corresponds to a given integer?

本问题已经有最佳答案,请猛点这里访问。

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

编辑:一种语言不可知的算法来确定这是这里的主要目标。


我曾经写过这个函数来执行确切的任务:

1
2
3
4
5
6
7
8
9
10
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());
}

这是我能想到的最干净正确的解决方案(使用Java,但可以使用自己喜欢的语言):

1
2
3
4
5
6
7
8
9
String getNthColumnName(int n) {
    String name ="";
    while (n > 0) {
        n--;
        name = (char)('A' + n%26) + name;
        n /= 26;
    }
    return name;
}

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


语言不可知算法将如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
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个实例,以适应其他字母


谢谢,约瑟夫·斯特尔万特(Joseph Sturtevant)!您的代码运行完美-我在vbscript中需要它,所以想和我分享我的版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
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


约瑟夫的代码不错,但是,如果您不需要或不需要使用VBA函数,请尝试一下。

假设n的值在单元格A2
使用此功能:

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

从wcm:

如果您不想使用VBA,可以使用此
用您想要的号码替换colnr

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

请注意,由于使用了ADDRESS函数,此公式易变。易失函数是每次更改后excel都会重新计算的函数。
通常,excel仅在其依赖引用发生更改时才重新计算公式。

使用此公式可能会导致性能下降。


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

这适用于2个字母列(直到列ZZ)。您必须为3个字母列嵌套另一个if语句。

上面的公式在列AYAZ以及以下每个nYnZ列上均无效。校正后的公式为:

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

Ruby一线:

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

它将整数转换为base26,然后将其拆分并进行一些数学运算以将每个字符转换为ascii。最后,将他们重新团结在一起。无除法,模数或递归。

乐趣。


这是从VBScript版本到SQL Server 2000+的转换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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


在MS Excel 2003-2010中可以正常工作。适用于支持Cells(...)。Address函数的早期版本:

  • 对于第28列-采用columnNumber=28; Cells(1, columnNumber).Address返回"$AB$1"
  • $符号上进行拆分将返回数组:["","AB","1"]
  • 因此,Split(Cells(1, columnNumber).Address,"$")(1)为您提供列名称"AB"
  • 更新:

    摘自如何将Excel列号转换为字母字符

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    ' 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 / 2002SE / 2000SE / 97SE


    这似乎在vb.net中起作用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Public Function Column(ByVal pColumn As Integer) As String
        pColumn -= 1
        If pColumn >= 0 AndAlso pColumn < 26 Then
            Return ChrW(Asc("A"c) + pColumn).ToString
        ElseIf (pColumn > 25) Then
            Return Column(CInt(math.Floor(pColumn / 26))) + Column((pColumn Mod 26) + 1)
        Else
        stop
            Throw New ArgumentException("Invalid column #" + (pColumn + 1).ToString)
        End If
    End Function

    我拿了约瑟夫(Joseph's)并将其测试到BH,然后以980-1000喂食,看起来不错。


    在VBA中,假设lCol是列号:

    1
    2
    3
    function ColNum2Letter(lCol as long) as string
        ColNum2Letter = Split(Cells(1, lCol).Address,"$")(0)
    end function

    我想您需要VBA代码:

    1
    2
    3
    4
    5
    6
    7
    8
    Public Function GetColumnAddress(nCol As Integer) As String

    Dim r As Range

    Set r = Range("A1").Columns(nCol)
    GetColumnAddress = r.Address

    End Function

    这就是您在VBA中想要的

    1
    2
    3
    4
    5
    Function GetNthExcelColName(n As Integer) As String
        Dim s As String
        s = Cells(1, n).Address
        GetNthExcelColName = Mid(s, 2, InStr(2, s,"$") - 2)
    End Function


    这些好人发布的所有这些代码示例看起来都不错。

    有一件事情要注意。从Office 2007开始,Excel实际上最多有16,384列。转换为XFD(原来的256列最大值为IV)。您将不得不对这些方法进行一些修改,以使它们适用于三个字符。

    不应该那么难...


    这是Gary Waters解决方案

    1
    2
    3
    4
    5
    6
    7
    8
    9
    Function ConvertNumberToColumnLetter2(ByVal colNum As Long) As String
        Dim i As Long, x As Long
        For i = 6 To 0 Step -1
            x = (1 - 26 ^ (i + 1)) / (-25) - 1 ‘ Geometric Series formula
            If colNum > x Then
                ConvertNumberToColumnLetter2 = ConvertNumberToColumnLetter2 & Chr(((colNum - x - 1)\ 26 ^ i) Mod 26 + 65)
            End If
        Next i
    End Function

    通过http://www.dailydoseofexcel.com/archives/2004/05/21/column-numbers-to-letters/


    考虑到wcm的注释(最高值= xfd),可以这样计算:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function IntToExcel(n: Integer); string;
    begin
       Result := '';
       for i := 2 down to 0 do
       begin
          if ((n div 26^i)) > 0) or (i = 0) then
             Result := Result + Char(Ord('A')+(n div (26^i)) - IIF(i>0;1;0));
          n := n mod (26^i);
       end;
    end;

    字母表中有26个字符,我们有一个数字系统,就像十六进制或二进制一样,只是带有一个不寻常的字符集(A..Z),在位置上代表26的幂:(26 ^ 2)(26 ^ 1)( 26 ^ 0)。


    FYI T-SQL以单个语句为Excel列名指定序数(从零开始)。

    小于0或大于16,383(Excel2010中的最大列)的任何值都将返回NULL。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    ; WITH TestData AS ( -- Major change points
        SELECT -1 AS FieldOrdinal
        UNION ALL
        SELECT 0
        UNION ALL
        SELECT 25
        UNION ALL
        SELECT 26
        UNION ALL
        SELECT 701
        UNION ALL
        SELECT 702
        UNION ALL
        SELECT 703
        UNION ALL
        SELECT 16383
        UNION ALL
        SELECT 16384
    )
    SELECT
          FieldOrdinal
        , CASE
           WHEN FieldOrdinal < 0     THEN NULL
           WHEN FieldOrdinal < 26    THEN ''
           WHEN FieldOrdinal < 702   THEN CHAR (65 + FieldOrdinal / 26 - 1)
           WHEN FieldOrdinal < 16384 THEN CHAR (65 + FieldOrdinal / 676 - 1)
                                        + CHAR (65 + (FieldOrdinal / 26) - (FieldOrdinal / 676) * 26 - 1)
           ELSE NULL
          END
          + CHAR (65 + FieldOrdinal % 26)
     FROM TestData
     ORDER BY FieldOrdinal

    我目前正在使用它,但是我感觉可以对其进行优化。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    private String GetNthExcelColName(int n)
    {
        String firstLetter ="";  
        //if number is under 26, it has a single letter name
        // otherwise, it is 'A' for 27-52, 'B' for 53-78, etc
        if(n > 26)
        {
            //the Converts to double and back to int are just so Floor() can be used
            Double value = Convert.ToDouble((n-1) / 26);
            int firstLetterVal = Convert.ToInt32(Math.Floor(value))-1;
            firstLetter = Convert.ToChar(firstLetterValue + 65).ToString();
        }    

        //second letter repeats
        int secondLetterValue = (n-1) % 26;
        String secondLetter = Convert.ToChar(secondLetterValue+65).ToString();

        return firstLetter + secondLetter;
    }


    = CHAR(64 + COLUMN())


    推荐阅读

      探探语言设置|探探怎么设置语言

      探探语言设置|探探怎么设置语言,,1. 探探怎么设置语言打开探探软件,然后就有消息提示的红点,点开就行了!其实这些软件都是挺简单的操作的,都是

      git设置编码|git语言设置

      git设置编码|git语言设置,,git设置编码点击cap4j搜索从git直接链接上拉代码。git语言设置Git是一个开源的分布式版本控制系统,可以有效、高

      目标焊机快捷键|目标焊接工具

      目标焊机快捷键|目标焊接工具,,1. 目标焊接工具焊工实训的目的?培养一个合格的焊工,国家是要花费很大的财力合物力的。比如说,造船厂的焊工,建

      区域语言设置|区域语言设置工具

      区域语言设置|区域语言设置工具,,区域语言设置工具你好,大致的方法如下,可以参考:1、按下键盘的windows 图标,再开始菜单中单击“设置”;出现的

      c4d语言设置|c4d汉语设置

      c4d语言设置|c4d汉语设置,,1. c4d汉语设置mac版的C4D是这样的,中文字体是有的,但是是以拼音的形式存在,比如黑体就是ht。中文字体以拼音方式

      电脑宣传语|电脑宣传语言

      电脑宣传语|电脑宣传语言,,1. 电脑宣传语言1.我做好了与你过一辈子的打算,也做好了你随时要走的准备,2.每段青春都会苍老,但我希望记忆里的你

      office语言设置|微软office语言设置

      office语言设置|微软office语言设置,,微软office语言设置一、首先点击桌面左下角“WIN键”。二、弹出选项内点击“所有程序”。三、接着点

      小米设置日语|小米设置日语语言

      小米设置日语|小米设置日语语言,,1. 小米设置日语语言MIUI系统文字目前只支持简体中文、繁体中文、英文、藏文和维吾尔文,不支持日文 2. 小