Function CL(ByVal x As Integer) As String
If x >= 1 And x <= 26 Then
CL = Chr(x + 64)
Else
CL = CL((x - x Mod 26) / 26) & Chr((x Mod 26) + 1 + 64)
End If
End Function
2
对不起,这是Python而不是C#,但至少结果是正确的:
def ColIdxToXlName(idx):
if idx < 1:
raise ValueError("Index is too small")
result = ""
while True:
if idx > 26:
idx, r = divmod(idx - 1, 26)
result = chr(r + ord('A')) + result
else:
return chr(idx + ord('A') - 1) + result
for i in xrange(1, 1024):
print "%4d : %s" % (i, ColIdxToXlName(i))
2
另一种VBA方式
Public Function GetColumnName(TargetCell As Range) As String
GetColumnName = Split(CStr(TargetCell.Address), "$")(1)
End Function
private static string Turn(uint col)
{
if (col < 1 || col > 16384) //Excel columns are one-based (one = 'A')
throw new ArgumentException("col must be >= 1 and <= 16384");
if (col <= 26) //one character
return ((char)(col + 'A' - 1)).ToString();
else if (col <= 702) //two characters
{
char firstChar = (char)((int)((col - 1) / 26) + 'A' - 1);
char secondChar = (char)(col % 26 + 'A' - 1);
if (secondChar == '@') //Excel is one-based, but modulo operations are zero-based
secondChar = 'Z'; //convert one-based to zero-based
return string.Format("{0}{1}", firstChar, secondChar);
}
else //three characters
{
char firstChar = (char)((int)((col - 1) / 702) + 'A' - 1);
char secondChar = (char)((col - 1) / 26 % 26 + 'A' - 1);
char thirdChar = (char)(col % 26 + 'A' - 1);
if (thirdChar == '@') //Excel is one-based, but modulo operations are zero-based
thirdChar = 'Z'; //convert one-based to zero-based
return string.Format("{0}{1}{2}", firstChar, secondChar, thirdChar);
}
}
20
int nCol = 127;
string sChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string sCol = "";
while (nCol >= 26)
{
int nChar = nCol % 26;
nCol = (nCol - nChar) / 26;
// You could do some trick with using nChar as offset from 'A', but I am lazy to do it right now.
sCol = sChars[nChar] + sCol;
}
sCol = sChars[nCol] + sCol;
Function GetColumnName(colNum As Integer) As String
Dim d As Integer
Dim m As Integer
Dim name As String
d = colNum
name = ""
Do While (d > 0)
m = (d - 1) Mod 26
name = Chr(65 + m) + name
d = Int((d - m) / 26)
Loop
GetColumnName = name
End Function
6
private String getColumn(int c) {
String s = "";
do {
s = (char)('A' + (c % 26)) + s;
c /= 26;
} while (c-- > 0);
return s;
}
它不完全是26,系统中没有0 . 如果有,'Z'后面跟'BA'而不是'AA' .
2
根据Graham的代码,这是一个javascript版本
function (columnNumber) {
var dividend = columnNumber;
var columnName = "";
var modulo;
while (dividend > 0) {
modulo = (dividend - 1) % 26;
columnName = String.fromCharCode(65 + modulo) + columnName;
dividend = parseInt((dividend - modulo) / 26);
}
return columnName;
};
2
在Delphi(Pascal):
function GetExcelColumnName(columnNumber: integer): string;
var
dividend, modulo: integer;
begin
Result := '';
dividend := columnNumber;
while dividend > 0 do begin
modulo := (dividend - 1) mod 26;
Result := Chr(65 + modulo) + Result;
dividend := (dividend - modulo) div 26;
end;
end;
public static string ColumnAdress(int col)
{
if (col <= 26) {
return Convert.ToChar(col + 64).ToString();
}
int div = col / 26;
int mod = col % 26;
if (mod == 0) {mod = 26;div--;}
return ColumnAdress(div) + ColumnAdress(mod);
}
public static int ColumnNumber(string colAdress)
{
int[] digits = new int[colAdress.Length];
for (int i = 0; i < colAdress.Length; ++i)
{
digits[i] = Convert.ToInt32(colAdress[i]) - 64;
}
int mul=1;int res=0;
for (int pos = digits.Length - 1; pos >= 0; --pos)
{
res += digits[pos] * mul;
mul *= 26;
}
return res;
}
1
游戏稍晚,但这是我使用的代码(在C#中):
private static readonly string _Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static int ColumnNameParse(string value)
{
// assumes value.Length is [1,3]
// assumes value is uppercase
var digits = value.PadLeft(3).Select(x => _Alphabet.IndexOf(x));
return digits.Aggregate(0, (current, index) => (current * 26) + (index + 1));
}
13
对不起,这是Python而不是C#,但至少结果是正确的:
def excel_column_number_to_name(column_number):
output = ""
index = column_number-1
while index >= 0:
character = chr((index%26)+ord('A'))
output = output + character
index = index/26 - 1
return output[::-1]
for i in xrange(1, 1024):
print "%4d : %s" % (i, excel_column_number_to_name(i))
/**
* Calculate the column letter abbreviation from a 1 based index
* @param {Number} value
* @returns {string}
*/
getColumnFromIndex = function (value) {
var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
var remainder, result = "";
do {
remainder = value % 26;
result = base[(remainder || 26) - 1] + result;
value = Math.floor(value / 26);
} while (value > 0);
return result;
};
public static char ColIndexToLetter(short index)
{
if (index < 0 || index > 25) throw new ArgumentException("Index must be between 0 and 25.");
return (char)('A' + index);
}
哎呀,如果你对你传入的内容有信心,你甚至可以删除验证并使用这个内联:
(char)('A' + index)
这在许多语言中都非常相似,因此您可以根据需要进行调整 .
再次, only use this if you're 100% sure you won't have more than 26 columns .
private string ExcelColumnIndexToName(int Index)
{
string range = string.Empty;
if (Index < 0 ) return range;
int a = 26;
int x = (int)Math.Floor(Math.Log((Index) * (a - 1) / a + 1, a));
Index -= (int)(Math.Pow(a, x) - 1) * a / (a - 1);
for (int i = x+1; Index + i > 0; i--)
{
range = ((char)(65 + Index % a)).ToString() + range;
Index /= a;
}
return range;
}
//老邮政
C#中基于零的解决方案 .
private string ExcelColumnIndexToName(int Index)
{
string range = "";
if (Index < 0 ) return range;
for(int i=1;Index + i > 0;i=0)
{
range = ((char)(65 + Index % 26)).ToString() + range;
Index /= 26;
}
if (range.Length > 1) range = ((char)((int)range[0] - 1)).ToString() + range.Substring(1);
return range;
}
54
只是使用递归抛出一个简单的两行C#实现,因为这里的所有答案似乎都比必要的复杂得多 .
/// <summary>
/// Gets the column letter(s) corresponding to the given column number.
/// </summary>
/// <param name="column">The one-based column index. Must be greater than zero.</param>
/// <returns>The desired column letter, or an empty string if the column number was invalid.</returns>
public static string GetColumnLetter(int column) {
if (column < 1) return String.Empty;
return GetColumnLetter((column - 1) / 26) + (char)('A' + (column - 1) % 26);
}
1
这是一个Actionscript版本:
private var columnNumbers:Array = ['A', 'B', 'C', 'D', 'E', 'F' , 'G', 'H', 'I', 'J', 'K' ,'L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
private function getExcelColumnName(columnNumber:int) : String{
var dividend:int = columnNumber;
var columnName:String = "";
var modulo:int;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = columnNumbers[modulo] + columnName;
dividend = int((dividend - modulo) / 26);
}
return columnName;
}
4
在perl中,输入1(A),27(AA)等 .
sub excel_colname {
my ($idx) = @_; # one-based column number
--$idx; # zero-based column index
my $name = "";
while ($idx >= 0) {
$name .= chr(ord("A") + ($idx % 26));
$idx = int($idx / 26) - 1;
}
return scalar reverse $name;
}
Private Function GetExcelColumnName(ByVal aiColNumber As Integer) As String
Dim BaseValue As Integer = Convert.ToInt32(("A").Chars(0)) - 1
Dim lsReturn As String = String.Empty
If (aiColNumber > 26) Then
lsReturn = GetExcelColumnName(Convert.ToInt32((Format(aiColNumber / 26, "0.0").Split("."))(0)))
End If
GetExcelColumnName = lsReturn + Convert.ToChar(BaseValue + (aiColNumber Mod 26))
End Function
30 回答
..并转换为PHP:
在这里查看所有提供的版本后,我决定使用递归自己做一个 .
这是我的vb.net版本:
对不起,这是Python而不是C#,但至少结果是正确的:
另一种VBA方式
这些我的代码将特定数字(索引从1开始)转换为Excel列 .
我的单元测试:
Easy with recursion.
我很惊讶到目前为止所有解决方案都包含迭代或递归 .
这是我在恒定时间内运行的解决方案(无循环) . 此解决方案适用于所有可能的Excel列,并检查输入是否可以转换为Excel列 . 可能的列在[A,XFD]或[1,16384]范围内 . (这取决于您的Excel版本)
Update :Peter 's comment is right. That'是我在浏览器中编写代码的结果 . :-)我的解决方案没有编译,它错过了最左边的字母,它正在以相反的顺序构建字符串 - 所有现在都已修复 .
除了错误之外,该算法基本上将数字从基数10转换为基数26 .
Update 2 :Joel Coehoorn是正确的 - 上面的代码将返回AB为27.如果它是真正的基数26,AA将等于A,Z之后的下一个数字将是BA .
优化原始解决方案(在C#中):
如果有人需要在没有VBA的Excel中执行此操作,这里有一种方法:
其中colNum是列号
在VBA中:
它不完全是26,系统中没有0 . 如果有,'Z'后面跟'BA'而不是'AA' .
根据Graham的代码,这是一个javascript版本
在Delphi(Pascal):
我正在尝试用Java做同样的事情......我写了下面的代码:
现在,一旦我用columnNumber = 29运行它,它给我结果=“CA”(而不是“AC”)任何评论我缺少的?我知道我可以通过StringBuilder来反转它....但是看看格雷厄姆的回答,我有点困惑......
Java中的相同实现
这个答案是在javaScript中:
您可能需要双向转换,例如从Excel列地址(如AAZ)到整数以及从任何整数到Excel . 下面的两种方法就是这样做的 . 假设基于1的索引,“数组”中的第一个元素是元素编号1.此处没有大小限制,因此您可以使用ERROR之类的地址,这将是列号2613824 ......
游戏稍晚,但这是我使用的代码(在C#中):
对不起,这是Python而不是C#,但至少结果是正确的:
通过这些测试用例:
列号:494286 => ABCDZ
列号:27 => AA
列号:52 => AZ
我是这样做的:
JavaScript Solution
如果你只想要一个没有代码的单元格公式,这里有一个公式:
这是所有其他人以及Google重定向的问题所以我在这里发布 .
其中许多答案都是正确的,但对于简单的情况来说太麻烦,例如当您没有超过26列时 . 如果您对是否可能进入双字符列有任何疑问,请忽略此答案,但如果您确定不会,那么您可以在C#中这样做这么简单:
哎呀,如果你对你传入的内容有信心,你甚至可以删除验证并使用这个内联:
这在许多语言中都非常相似,因此您可以根据需要进行调整 .
再次, only use this if you're 100% sure you won't have more than 26 columns .
我在第一篇文章中发现了一个错误,所以我决定坐下来做数学 . 我发现用于识别Excel列的数字系统不是另一个人发布的基本系统 . 请考虑基数10中的以下内容 . 您也可以使用字母表中的字母来执行此操作 .
空间:......................... S1,S2,S3:S1,S2,S3
.................................... 0,00,000:A,AA,AAA
.................................... 1,01,001:.. B,AB,AAB
.................................... ......,......,......:......,......,......
.................................... 9,99,999:.. Z,ZZ,ZZZ
太空总状态:10,100,1000:26,676,17576
总国家:............... 1110 ................ 18278
Excel使用基数26对单个字母空间中的列进行编号 . 您可以看到,通常情况下,状态空间进展为a,a ^ 2,a ^ 3,...对于某些基数a,以及状态总数是a ^ 2 a ^ 3 ....
假设您要查找前N个空格中的状态A的总数 . 这样做的公式是A =(a)(a ^ N-1)/(a-1) . 这很重要,因为我们需要找到与我们的索引K相对应的空间N.如果我想找出K在数字系统中的位置,我需要用K替换A并求解N.解是N = log {基础a}(A(a-1)/ a 1) . 如果我使用a = 10和K = 192的例子,我知道N = 2.23804 ....这告诉我K位于第三个空间的开头,因为它大于两个 .
下一步是准确找到我们当前空间的距离 . 为了找到这个,从K中减去使用N的层数生成的A.在这个例子中,N的层数是2 . 因此,A =(10)(10 ^ 2 - 1)/(10-1)= 110,正如您组合前两个空格的状态时所预期的那样 . 这需要从K中减去,因为在前两个空间中已经考虑了前110个状态 . 这使我们有82个州 . 因此,在该数字系统中,基数10中的192的表示是082 .
使用基本索引为零的C#代码是
//老邮政
C#中基于零的解决方案 .
只是使用递归抛出一个简单的两行C#实现,因为这里的所有答案似乎都比必要的复杂得多 .
这是一个Actionscript版本:
在perl中,输入1(A),27(AA)等 .
我想抛出我使用的静态类,用于col index和col Label之间的交互 . 我为ColumnLabel方法使用修改后的接受答案
像这样用......
这是我在PHP中的超级晚期实现 . 这个是递归的 . 我在发现这篇文章之前写的 . 我想看看其他人是否已经解决了这个问题......
我在VB.NET 2003中使用这个,它运行良好...