32

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

编辑:一个与语言无关的算法来确定这是这里的主要目标。

4

20 回答 20

42

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

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());
}
于 2008-08-22T15:53:47.503 回答
26

这是我能想到的最干净正确的解决方案(在 Java 中,但请随意使用您最喜欢的语言):

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

但是,如果您在此代码中发现错误,请告诉我,谢谢。

于 2010-12-26T02:55:37.097 回答
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 的实例替换为另一个数字以适应备用字母

于 2008-08-23T00:15:11.900 回答
7

谢谢,约瑟夫·斯图尔特万特!您的代码完美运行 - 我需要它在 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
于 2011-01-14T20:57:53.367 回答
6

Joseph 的代码很好,但是,如果您不想或不需要使用 VBA 函数,试试这个。

假设 n 的值在单元格中A2 使用这个函数:

=MID(ADDRESS(1,A2),2,LEN(ADDRESS(1,A2))-3)
于 2008-08-22T16:03:49.773 回答
3
IF(COLUMN()>=26,CHAR(ROUND(COLUMN()/26,1)+64)&CHAR(MOD(COLUMN(),26)+64),CHAR(COLUMN()+64))

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

上面的公式在 columns以及以下和列AY中的每一个上都失败了。修正后的公式为:AZnYnZ

=IF(COLUMN()>26,CHAR(ROUNDDOWN((COLUMN()-1)/26,0)+64)&CHAR(MOD((COLUMN()-1),26)+65),CHAR(COLUMN()+64)
于 2010-08-23T17:27:21.737 回答
3

从 wcm:

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

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

请注意,由于使用了 ADDRESS 函数,这个公式是不稳定的。易失函数是在每次更改后由 excel 重新计算的函数。通常,只有当它们的依赖引用发生变化时,excel 才会重新计算公式。

使用这个公式可能会成为性能杀手。

于 2012-11-16T08:56:47.850 回答
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 转换。终于把他们都重新聚在一起。没有除法、模数或递归。

乐趣。

于 2012-12-14T16:09:37.820 回答
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
于 2012-04-04T19:16:31.990 回答
2

这在 MS Excel 2003-2010 中运行良好。应该适用于支持Cells(...)的早期版本。地址功能:

  1. 对于第 28 列 - 服用columnNumber=28Cells(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

于 2013-06-06T10:24:47.987 回答
1

我想你需要 VBA 代码:

Public Function GetColumnAddress(nCol As Integer) As String

Dim r As Range

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

End Function
于 2008-08-22T16:11:02.907 回答
1

这可以满足您在 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
于 2008-08-31T18:12:13.213 回答
1

这似乎适用于 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,看起来不错。

于 2009-02-05T12:57:50.710 回答
1

在 VBA 中,假设 lCol 是列号:

function ColNum2Letter(lCol as long) as string
    ColNum2Letter = Split(Cells(1, lCol).Address, "$")(0)
end function
于 2010-02-18T23:25:14.727 回答
0

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

有一件事需要注意。从 Office 2007 开始,Excel 实际上有多达 16,384 列。这转化为 XFD(256 列的旧最大值是 IV)。您将不得不稍微修改这些方法以使它们适用于三个字符。

应该不会那么难...

于 2008-08-22T17:30:09.253 回答
0

这是 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/

于 2008-09-02T16:26:56.603 回答
0

考虑到 wcm (top value = 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)。

于 2008-09-08T19:23:14.817 回答
0

仅供参考,T-SQL 将给定序号(从零开始)的 Excel 列名称作为单个语句。

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

; 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
于 2012-09-27T05:48:02.550 回答
-1

我目前正在使用这个,但我感觉它可以优化。

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;
}
于 2008-08-22T15:58:03.157 回答
-3

=CHAR(64+列())

于 2009-08-11T04:45:03.290 回答