我需要一种将Excel列字母转换为其正确数字的算法。
它将使用的语言是C#,但是任何人都可以使用,甚至可以使用伪代码。
请注意,我将把它放在C#中,并且我不想使用Office dll。
对于" A",预期结果将为1
对于'AH'= 34
对于'XFD'= 16384
有关相反的信息(从数字到列字母),请参阅:stackoverflow.com/questions/181596/
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);
很棒的作品太好了,非常感谢。
我很好奇,字符数组的用途是什么?它似乎可以通过以下方式直接索引到字符串中而起作用:sum + =(columnName [i]-A + 1)
@RyanW编辑包含您的建议,谢谢。
对于任何人都无法通过以上操作正确解决上述问题,或者碰巧需要在PHP中使用它:ideone.com/rE2xi4
我正在使用Open XML SDK 2.0,我认为UInt32作为返回类型比int更合适。
int result = colName.Select((c, i) =>
((c - 'A' + 1) * ((int)Math.Pow(26, colName.Length - i - 1)))).Sum();
int col = colName.ToCharArray().Select(c => c - 'A' + 1).
Reverse().Select((v, i) => v * (int)Math.Pow(26, i)).Sum();
完善。花了我一点时间来研究为什么要反转(这是因为BB高于AZ)。通过使用索引,可以避免其他人遇到的字符长度错误。
从最后到第一个循环浏览字符。将每个字母的值(A = 1,Z = 26)乘以26 ** N,加到一个总计中。我不具备C#的字符串操作技能,因此这里有一些非常混杂的伪代码:
sum=0;
len=length(letters);
for(i=0;i
sum += ((letters[len-i-1])-'A'+1) * pow(26,i);
如果有人感兴趣,这是我用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);
您能否将其视为26基数,然后用字母代替26基数?
因此,实际上,您最右边的数字将始终是1到26之间的原始数字,而"数字"的其余部分(左侧)是26个被收集的数字吗?因此,A代表26的很多,B代表2,依此类推。
举个例子:
B = 2 = Column 2
AB = 26 * 1(A) + 2 = Column 28
BB = 26 * 2(B) + 2 = Column 54
DA = 26 * 4(D) + 1 = Column 105
等等
"您能否将其视为26的基数"。这不起作用,因为您建议的数字系统缺少零。但是,看看您的示例,我将得到一个想法,我将把代码放入答案中。
@BH-在问题的上下文中这不是必需的-Excel中没有零列(问题是"将Excel列字母转换为其数字的算法是什么?")。话虽如此,上面还有更好的答案:)
我对任何答案都不满意,所以这里有一个简短的版本:
int col ="Ab".Aggregate(0, (a, c) => a * 26 + c & 31); // 28
或更好的是,忽略非A-Za-z字符:
int col =" !$Ab$3".Aggregate(0, (a, c) => (uint)((c | 32) - 97) > 25 ? a : a * 26 + c & 31); // 28
我想这基本上与其他一些答案大致相同,但是可能会使数字的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;
}
像其他人一样,我颠倒了字符数组,因此我不需要了解指数。
在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