在Excel/VSTO中使用C#将列号转换为列字母

5

如何查找列名或表头?

例如,如果我在Excel中选择第5列,则希望结果为“E”。如何获取对应于列编号的字母或字符。

请帮我编写代码。

6个回答

5
public static string GetColumnName(int columnNumber)
{
    const string letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    string columnName = "";

    while (columnNumber > 0)
    {
        columnName = letters[(columnNumber - 1) % 26] + columnName;
        columnNumber = (columnNumber - 1) / 26;
    }

    return columnName;
}

1
嗯... 如果超过 26 列怎么办?AA、AB、AC 等。 - Ahmad
抱歉,我意识到这个问题已经解决了。请参考此链接:https://dev59.com/QHVC5IYBdhLWcg3wykej。 - Ahmad

2

如果使用 Application.ActiveCell.get_Address(true, true, Excel.AlReferenceStyle.xlA1, missing, missing) 可以获得单元格的地址信息,然后解析返回的字符串或使用正则表达式获取列标题。

我只是简单地使用了以下代码:

string location = Application.ActiveCell.get_Address(true, true, Excel.AlReferenceStyle.xlA1, missing, missing);
string tokens = x.Split("$".ToCharArray());
MessageBox.Show(String.Format("Column {0}", result[0]));

2
这段代码是错误的。以下是已经更正的版本:var location = sheet.Range["A1"].Offset[0, columnNumber - 1].Address[true, true, XlReferenceStyle.xlA1, Missing, Missing]; var tokens = location.Split('$'); return tokens[1]; - Phred Menyhert

1
public static long GetColumnNumber(string columnName)
{
    int letterPos = 0;   
    long columnNumber = 0;
    for (int placeHolder = columnName.Length - 1; placeHolder >= 0; placeHolder--)
    {
        int currentSum = 1;
        for (int multiplier = 0; multiplier < placeHolder; multiplier++)
            currentSum *= 26;
        int letterValue = (int) columnName[letterPos];
        currentSum *= letterValue - 64;
        columnNumber += currentSum;
        if (letterPos != columnName.Length)
            letterPos++;
        //Console.WriteLine(((int)columnName[i]-64) + " = " + columnName[i]);
    }
        return columnNumber;
}

只有当columnName是大写字符串时,此方法才能正常工作,由于某种原因b不是B。因此需要使用column.Name.ToUpper()。 - Jim

0

这在VBA中使用双重替换很好,其中R是单个单元格Excel范围:

ColumnLetter = Replace(Replace(R.AddressLocal(ReferenceStyle:=1), "$", vbNullString), R.Row, vbNullString) 它基于在工作表上使用的等效思想。在单元格公式中使用此方法,甚至更短:

=SUBSTITUTE(ADDRESS(1,COLUMN(M1),4),1,"")

这将返回字母 M,并适用于列 XFD。单元格引用 M1 可以是任何范围的任何位置。对于范围或多个单元格,返回左上角列。

它获取列中第一个单元格的地址,然后通过用 NullString 替换尾随的 1 来删除它。(ADDRESS 中的 4 确保地址作为相对地址返回,即不带 $ 符号。)

感谢 barry houdini,他启发了我寻找一个好答案。


0
以下是一个完整的方法,它可以为传递的整数值提供相应的字母表。
private String Number2String(int number, bool isCaps)
    {
        int number1 = number / 27;
        int number2 = number - (number1 * 26);
        if (number2 > 26)
        {
            number1 = number1 + 1;
            number2 = number - (number1 * 26);
        }
        Char a = (Char)((isCaps ? 65 : 97) + (number1 - 1));
        Char b = (Char)((isCaps ? 65 : 97) + (number2 - 1));
        Char c = (Char)((isCaps ? 65 : 97) + (number - 1));
        string d = String.Concat(a, b);
        if (number <= 26)
            return c.ToString();
        else
            return d;
    }

0

我使用这两个:

public string GetExcelColumn(int index)
{
    int quotient = index / 26;

    if (quotient > 0)
        return GetExcelColumn(quotient - 1) + (char)((int)'A' + (index % 26));
    else
        return "" + (char)((int)'A' + index);
}

static IEnumerable<string> GetExcelColumns()
{
    var alphabet = new string[]{""}.Union(from c in Enumerable.Range((int)'A', 26) select Convert.ToString((char)c));

    return from c1 in alphabet
            from c2 in alphabet
            from c3 in alphabet.Skip(1)                    // c3 is never empty
            where c1 == string.Empty || c2 != string.Empty // only allow c2 to be empty if c1 is also empty
            select c1 + c2 + c3;
}

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