将 Excel 列字母转换为其数字的算法是啥?
Posted
技术标签:
【中文标题】将 Excel 列字母转换为其数字的算法是啥?【英文标题】:What is the algorithm to convert an Excel Column Letter into its Number?将 Excel 列字母转换为其数字的算法是什么? 【发布时间】:2009-03-20 20:14:42 【问题描述】:我需要一种算法来将 Excel 列字母转换为正确的数字。
将使用 C# 编写此语言,但任何语言都可以使用,甚至可以使用伪代码。
请注意,我将把它放在 C# 中,我不想使用 office dll。
对于“A”,预期结果为 1
对于'AH' = 34
对于'XFD' = 16384
【问题讨论】:
反之(从数字到列字母)参见:***.com/questions/181596/… 【参考方案1】:public static int ExcelColumnNameToNumber(string columnName)
if (string.IsNullOrEmpty(columnName)) throw new ArgumentNullException("columnName");
columnName = columnName.ToUpperInvariant();
int sum = 0;
for (int i = 0; i < columnName.Length; i++)
sum *= 26;
sum += (columnName[i] - 'A' + 1);
return sum;
【讨论】:
使用 Math.Pow 实际上不是最好的主意(浮点问题,性能...)使用 'sum*=26;sum+=(characters[i] -'A'+1) ;' 我很好奇,characters数组的用途是什么?它似乎可以通过直接索引到字符串中来工作: sum += (columnName[i] - 'A' + 1) 致任何在使上述内容正常工作时遇到问题的人,或者碰巧在 php 中需要此功能的人:ideone.com/rE2xi4 我正在使用 Open XML SDK 2.0,我认为 UInt32 作为返回类型可能比 int 更合适。【参考方案2】:int result = colName.Select((c, i) =>
((c - 'A' + 1) * ((int)Math.Pow(26, colName.Length - i - 1)))).Sum();
【讨论】:
【参考方案3】:int col = colName.ToCharArray().Select(c => c - 'A' + 1).
Reverse().Select((v, i) => v * (int)Math.Pow(26, i)).Sum();
【讨论】:
完美。我花了一点时间来研究你为什么要倒车(这是因为 BB 高于 AZ)。并且您通过使用索引避免了其他人遇到的一个字符长度错误。【参考方案4】:从最后一个到第一个循环遍历字符。将每个字母的值 (A=1, Z=26) 乘以 26**N,加到总和。我在 C# 中的字符串操作技能是不存在的,所以这里有一些非常混合的伪代码:
sum=0;
len=length(letters);
for(i=0;i<len;i++)
sum += ((letters[len-i-1])-'A'+1) * pow(26,i);
【讨论】:
【参考方案5】:如果有人感兴趣,这是我用 javascript 编写的解决方案。
var letters = "abc".toUpperCase();
var sum = 0;
for(var i = 0; i < letters.length;i++)
sum *= 26;
sum += (letters.charCodeAt(i) - ("A".charCodeAt(0)-1));
alert(sum);
【讨论】:
【参考方案6】:您能否将其视为以 26 为基数的数字,然后用字母代替以 26 为基数的数字?
所以实际上,您最右边的数字将始终是 1 到 26 之间的原始数字,而“数字”的其余部分(左侧部分)是收集的 26 的数量?所以 A 代表 26 的一个,B 代表 2,以此类推。
举个例子:
B = 2 = 第 2 列 AB = 26 * 1(A) + 2 = 第 28 列 BB = 26 * 2(B) + 2 = 第 54 列 DA = 26 * 4(D) + 1 = 第 105 列等
【讨论】:
“你能不能把它当作一个以 26 为基数的数字”。这应该不起作用,因为您建议的数字系统缺少零。但是看你的例子给了我一个想法,我将在我的答案中放入代码。 @BH - 在问题的上下文中,这不是必需的 - Excel 中没有零列(问题是“将 Excel 列字母转换为其数字的算法是什么?”)。话虽如此,上面还有更好的答案:)【参考方案7】:短版:
int col = "Ab".Aggregate(0, (a, c) => a * 26 + c & 31); // 28
忽略非A-Za-z
字符:
int col = " !$Af$3 ".Aggregate(0, (a, c) => (uint)((c | 32) - 'a') > 25 ? a : a * 26 + (c & 31)); // 32
【讨论】:
第二个忽略非 A-Za-z 字符的示例,为“AF”列及以上列返回错误的列索引...例如,单元格 AF1 应返回 32,但结果为 0 .【参考方案8】:在 Excel VBA 中,您可以使用 .Range
方法获取数字,如下所示:
Dim rng as Range
Dim vSearchCol as variant 'your input column
Set rng.Thisworkbook.worksheets("mySheet").Range(vSearchCol & "1:" & vSearchCol & "1")
然后使用.column
属性:
debug.print rng.column
如果您需要完整代码,请参见下文:
Function ColumnbyName(vInput As Variant, Optional bByName As Boolean = True) As Variant
Dim Rng As Range
If bByName Then
If Not VBA.IsNumeric(vInput) Then
Set Rng = ThisWorkbook.Worksheets("mytab").Range(vInput & "1:" & vInput & "1")
ColumnbyName = Rng.Column
Else
MsgBox "Please enter valid non Numeric column or change paramter bByName to False!"
End If
Else
If VBA.IsNumeric(vInput) Then
ColumnbyName = VBA.Chr(64 + CInt(vInput))
Else
MsgBox "Please enter valid Numeric column or change paramter bByName to True!"
End If
End If
End Function
【讨论】:
【参考方案9】:我想这基本上与其他一些答案几乎相同,但它可能会更清楚地说明数字数字的 alpha 等价物发生了什么。它不是一个基本的 26 系统,因为没有 0 占位符。也就是说,第 26 列将是 'A0' 或其他东西,而不是 26 进制中的 Z。它不是 27 进制,因为 'alpha-gits' 不代表 27 的幂。伙计,它真的让你明白这是多么混乱算术一定是在巴比伦人发明零之前!
UInt32 sum = 0, gitVal = 1;
foreach (char alphagit in ColumnName.ToUpperInvariant().ToCharArray().Reverse())
sum += gitVal * (UInt32)(alphagit - 'A' + 1)
gitVal *= 26;
像其他人一样,我反转了字符数组,所以我不需要知道任何关于指数的事情。
【讨论】:
【参考方案10】:为此,我只使用了一行:
int ColumnNumber = Application.Range[MyColumnName + "1"].Column;
【讨论】:
以上是关于将 Excel 列字母转换为其数字的算法是啥?的主要内容,如果未能解决你的问题,请参考以下文章