代码之家  ›  专栏  ›  技术社区  ›  goric

如何找到与给定整数对应的Excel列名?[复制品]

  •  30
  • goric  · 技术社区  · 16 年前

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

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

    20 回复  |  直到 10 年前
        1
  •  38
  •   Joseph Sturtevant    16 年前

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

    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());
    }
    
        2
  •  26
  •   Samuel Audet    12 年前

    这是最干净的 对的 我可以想出解决办法(用Java,但可以随意使用你喜欢的语言):

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

    但是如果你发现这个代码有错误,请告诉我,谢谢。

        3
  •  11
  •   Jason Z    16 年前

    语言不可知算法如下:

    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的实例,以适应交替的字母。

        4
  •  7
  •   Craig0409    14 年前

    谢谢,约瑟夫·斯图尔特!您的代码工作得很好-我需要它在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
    
        5
  •  5
  •   chris neilsen    13 年前

    约瑟夫的代码很好,但是,如果您不想或不需要使用vba函数,可以试试这个。

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

    =MID(ADDRESS(1,A2),2,LEN(ADDRESS(1,A2))-3)
    
        6
  •  3
  •   chris neilsen    13 年前
    IF(COLUMN()>=26,CHAR(ROUND(COLUMN()/26,1)+64)&CHAR(MOD(COLUMN(),26)+64),CHAR(COLUMN()+64))
    

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

    上面的公式在列上失败 AY , AZ 以及以下每一项 nY nZ 柱。修正公式为:

    =IF(COLUMN()>26,CHAR(ROUNDDOWN((COLUMN()-1)/26,0)+64)&CHAR(MOD((COLUMN()-1),26)+65),CHAR(COLUMN()+64)
    
        7
  •  3
  •   neontapir    10 年前

    来自WCM:

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

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

    请注意,由于地址函数的使用,此公式不稳定。可变函数是每次更改后由Excel重新计算的函数。 通常Excel只在依赖引用更改时重新计算公式。

    使用这个公式可能是一个性能杀手。

        8
  •  2
  •   Be Brave Be Like Ukraine    12 年前

    下面是从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
    
        9
  •  2
  •   Jim Drannbauer    12 年前

    红宝石一号衬里:

    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转换。最后把他们都接回来了。没有除法、模或递归。

    乐趣。

        10
  •  2
  •   Kent Pawar user2460369    11 年前

    这在MS Excel 2003-2010中工作正常。应该适用于支持 细胞(…) Address 功能:

    1. 第28列——取 columnNumber=28 ; Cells(1, columnNumber).Address 收益率 "$AB$1" .
    2. $ sign返回数组: ["","AB","1"]
    3. 所以 Split(Cells(1, columnNumber).Address, "$")(1) 提供列名称 "AB" .

    更新:

    取自 How to convert Excel column numbers into alphabetical characters

    ' 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

        11
  •  1
  •   PabloG    16 年前

    我想您需要VBA代码:

    Public Function GetColumnAddress(nCol As Integer) As String
    
    Dim r As Range
    
    Set r = Range("A1").Columns(nCol)
    GetColumnAddress = r.Address
    
    End Function
    
        12
  •  1
  •   vzczc    16 年前

    这是您在VBA中想要的

    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
    
        13
  •  1
  •   Maslow    15 年前

    这似乎在vb.net中有效

    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
    

    我拿约瑟夫的给BH测试,然后喂它980-1000,看起来很不错。

        14
  •  1
  •   iDevlop    12 年前

    在VBA中,假设lcol是列号:

    function ColNum2Letter(lCol as long) as string
        ColNum2Letter = Split(Cells(1, lCol).Address, "$")(0)
    end function
    
        15
  •  0
  •   wcm    16 年前

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

    有一件事要注意。从Office2007开始,Excel实际上有16384列。也就是说XFD(原来最大256列是IV)。您必须对这些方法进行一些修改,以使它们适用于三个字符。

    不应该那么难…

        16
  •  0
  •   Dick Kusleika    16 年前

    这是Gary Waters的解决方案

    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/

        17
  •  0
  •   Ralph M. Rickenbach    16 年前

    考虑到wcm的注释(顶值=xfd),您可以这样计算它;

    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)。

        18
  •  0
  •   AndrewD    12 年前

    FYI T-SQL将Excel列名作为单个语句给定一个序数(从零开始)。

    任何低于0或高于16383的值(Excel2010中的最大列数)都返回空值。

    ; 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
    
        19
  •  -1
  •   goric    16 年前

    我现在用这个,但我觉得它可以优化。

    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;
    }
    
        20
  •  -2
  •   anon    15 年前

    =char(64+column())