如何在不使用自动从Excel直接获取值的情况下,将数字转换为C#中的Excel列名。
Excel 2007的可能范围为1到16384,即它支持的列数。结果值应采用excel列名称的形式,例如A,AA,AAA等。
答案 0 :(得分:835)
我是这样做的:
private string GetExcelColumnName(int columnNumber)
{
int dividend = columnNumber;
string columnName = String.Empty;
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
dividend = (int)((dividend - modulo) / 26);
}
return columnName;
}
答案 1 :(得分:55)
如果有人需要在没有VBA的Excel中执行此操作,可以采用以下方法:
=SUBSTITUTE(ADDRESS(1;colNum;4);"1";"")
其中colNum是列号
在VBA中:
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
答案 2 :(得分:19)
抱歉,这是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))
答案 3 :(得分:17)
您可能需要双向转换,例如从Excel列地址(如AAZ)到整数以及从任何整数到Excel。下面的两种方法就是这样做的。假设基于1的索引,“数组”中的第一个元素是元素编号1。 这里没有大小限制,所以你可以使用像ERROR这样的地址,这就是第2613824号栏目......
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;
}
答案 4 :(得分:13)
我在第一篇文章中发现了一个错误,所以我决定坐下来做数学运算。我发现用于识别Excel列的数字系统不是另一个人发布的基础26系统。请考虑基数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 + 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#代码是
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;
}
// Old Post
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;
}
答案 5 :(得分:10)
简单递归。
public static string GetStandardExcelColumnName(int columnNumberOneBased)
{
int baseValue = Convert.ToInt32('A');
int columnNumberZeroBased = columnNumberOneBased - 1;
string ret = "";
if (columnNumberOneBased > 26)
{
ret = GetStandardExcelColumnName(columnNumberZeroBased / 26) ;
}
return ret + Convert.ToChar(baseValue + (columnNumberZeroBased % 26) );
}
答案 6 :(得分:10)
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;
更新:Peter的评论是对的。这就是我在浏览器中编写代码所得到的。 :-)我的解决方案没有编译,它错过了最左边的字母,它正在以相反的顺序构建字符串 - 现在都修复了。
除了错误之外,该算法基本上将数字从基数10转换为基数26。
更新2 :Joel Coehoorn是正确的 - 上面的代码将返回AB为27.如果它是真正的基数26,AA将等于A和Z之后的下一个数字将是BA。
int nCol = 127;
string sChars = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string sCol = "";
while (nCol > 26)
{
int nChar = nCol % 26;
if (nChar == 0)
nChar = 26;
nCol = (nCol - nChar) / 26;
sCol = sChars[nChar] + sCol;
}
if (nCol != 0)
sCol = sChars[nCol] + sCol;
答案 7 :(得分:8)
这个答案在javaScript中:
function getCharFromNumber(columnNumber){
var dividend = columnNumber;
var columnName = "";
var modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = String.fromCharCode(65 + modulo).toString() + columnName;
dividend = parseInt((dividend - modulo) / 26);
}
return columnName;
}
答案 8 :(得分:8)
我很惊讶到目前为止所有解决方案都包含迭代或递归。
这是我在恒定时间内运行的解决方案(无循环)。此解决方案适用于所有可能的Excel列,并检查输入是否可以转换为Excel列。可能的列在[A,XFD]或[1,16384]范围内。 (这取决于您的Excel版本)
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);
}
}
答案 9 :(得分:7)
..并转换为php:
function GetExcelColumnName($columnNumber) {
$columnName = '';
while ($columnNumber > 0) {
$modulo = ($columnNumber - 1) % 26;
$columnName = chr(65 + $modulo) . $columnName;
$columnNumber = (int)(($columnNumber - $modulo) / 26);
}
return $columnName;
}
答案 10 :(得分:7)
使用递归抛出一个简单的两行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);
}
答案 11 :(得分:6)
Java中的相同实现
public String getExcelColumnName (int columnNumber)
{
int dividend = columnNumber;
int i;
String columnName = "";
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
i = 65 + modulo;
columnName = new Character((char)i).toString() + columnName;
dividend = (int)((dividend - modulo) / 26);
}
return columnName;
}
答案 12 :(得分:5)
我想抛出我使用的静态类,用于col index和col Label之间的交互。我为ColumnLabel方法使用了修改后的接受答案
public static class Extensions
{
public static string ColumnLabel(this int col)
{
var dividend = col;
var columnLabel = string.Empty;
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnLabel = Convert.ToChar(65 + modulo).ToString() + columnLabel;
dividend = (int)((dividend - modulo) / 26);
}
return columnLabel;
}
public static int ColumnIndex(this string colLabel)
{
// "AD" (1 * 26^1) + (4 * 26^0) ...
var colIndex = 0;
for(int ind = 0, pow = colLabel.Count()-1; ind < colLabel.Count(); ++ind, --pow)
{
var cVal = Convert.ToInt32(colLabel[ind]) - 64; //col A is index 1
colIndex += cVal * ((int)Math.Pow(26, pow));
}
return colIndex;
}
}
使用此类似......
30.ColumnLabel(); // "AD"
"AD".ColumnIndex(); // 30
答案 13 :(得分:5)
游戏稍晚,但这是我使用的代码(在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));
}
答案 14 :(得分:5)
在这里查看了所有提供的版本之后,我决定使用递归来自己做一个。
这是我的vb.net版本:
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
答案 15 :(得分:4)
如果你只想要一个没有代码的单元格公式,这里有一个公式:
IF(COLUMN()>=26,CHAR(ROUND(COLUMN()/26,1)+64)&CHAR(MOD(COLUMN(),26)+64),CHAR(COLUMN()+64))
答案 16 :(得分:4)
在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;
答案 17 :(得分:3)
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'。
答案 18 :(得分:2)
另一种VBA方式
Public Function GetColumnName(TargetCell As Range) As String
GetColumnName = Split(CStr(TargetCell.Address), "$")(1)
End Function
答案 19 :(得分:2)
JavaScript解决方案
/**
* 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;
};
答案 20 :(得分:2)
在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;
}
答案 21 :(得分:2)
这是一个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;
}
答案 22 :(得分:2)
优化原始解决方案(在C#中):
public static class ExcelHelper
{
private static Dictionary<UInt16, String> l_DictionaryOfColumns;
public static ExcelHelper() {
l_DictionaryOfColumns = new Dictionary<ushort, string>(256);
}
public static String GetExcelColumnName(UInt16 l_Column)
{
UInt16 l_ColumnCopy = l_Column;
String l_Chars = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String l_rVal = "";
UInt16 l_Char;
if (l_DictionaryOfColumns.ContainsKey(l_Column) == true)
{
l_rVal = l_DictionaryOfColumns[l_Column];
}
else
{
while (l_ColumnCopy > 26)
{
l_Char = l_ColumnCopy % 26;
if (l_Char == 0)
l_Char = 26;
l_ColumnCopy = (l_ColumnCopy - l_Char) / 26;
l_rVal = l_Chars[l_Char] + l_rVal;
}
if (l_ColumnCopy != 0)
l_rVal = l_Chars[l_ColumnCopy] + l_rVal;
l_DictionaryOfColumns.ContainsKey(l_Column) = l_rVal;
}
return l_rVal;
}
}
答案 23 :(得分:1)
虽然我迟到了,Graham's answer远非最佳状态。特别是,您不必使用tableView:cellForRow:atIndexPath()
,请致电func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if(self.brandNamesCopyCounter > 0){
brandNamesCopyCounter -= 1
let cell = currentTableView.dequeueReusableCellWithIdentifier("brandCell") as! HomeSearchBrandCell
if(searchActive){
if(filteredBrands.count > indexPath.row){
cell.title.text = filteredBrands[indexPath.row]
if(cell.iconFacility != nil){
cell.iconFacility.image = UIImage.init(named: "brands.pdf")
}
}
} else {
print(indexPath.row)
if(brandsArray.count > indexPath.row){
cell.title.text = brandsArray[indexPath.row].name_en
}
if(cell.iconFacility != nil){
cell.iconFacility.image = UIImage.init(named: "brands.pdf")
}
}
return cell
}else{
let cell = currentTableView.dequeueReusableCellWithIdentifier("homeSearchCell") as! HomeSearchCell
if(searchActive){
if(filtered.count > indexPath.row){
print(indexPath.row)
cell.title.text = self.filtered[indexPath.row]
if(cell.iconFacility != nil){
cell.iconFacility.image = UIImage.init(named: "shops.pdf")
}
}
} else {
cell.title.text = shops[indexPath.row].name
if(cell.iconFacility != nil){
cell.iconFacility.image = UIImage.init(named: "shops.pdf")
}
}
return cell
}
}
并应用modulo
演员。考虑到在C#世界的大多数情况下,你将从0开始编号,这是我的修订版:
ToString()
答案 24 :(得分:1)
此代码段适用于 A 到 ZZ 列名称
string columnName = columnNumber > 26 ? Convert.ToChar(64 + (columnNumber / 26)).ToString() + Convert.ToChar(64 + (columnNumber % 26)) : Convert.ToChar(64 + columnNumber).ToString();
答案 25 :(得分:1)
似乎很多答案都比必要的复杂得多。这是基于上述递归的通用Ruby答案:
关于此答案的一件好事是,它不仅限于英语字母的26个字符。您可以在COLUMNS
常量中定义任意范围,它将做正确的事情。
# vim: ft=ruby
class Numeric
COLUMNS = ('A'..'Z').to_a
def to_excel_column(n = self)
n < 1 ? '' : begin
base = COLUMNS.size
to_excel_column((n - 1) / base) + COLUMNS[(n - 1) % base]
end
end
end
# verify:
(1..52).each { |i| printf "%4d => %4s\n", i, i.to_excel_column }
这将打印以下内容,例如:
1 => A
2 => B
3 => C
....
33 => AG
34 => AH
35 => AI
36 => AJ
37 => AK
38 => AL
39 => AM
40 => AN
41 => AO
42 => AP
43 => AQ
44 => AR
45 => AS
46 => AT
47 => AU
48 => AV
49 => AW
50 => AX
51 => AY
52 => AZ
答案 26 :(得分:1)
打字稿
function lengthToExcelColumn(len: number): string {
let dividend: number = len;
let columnName: string = '';
let modulo: number = 0;
while (dividend > 0) {
modulo = (dividend - 1) % 26;
columnName = String.fromCharCode(65 + modulo).toString() + columnName;
dividend = Math.floor((dividend - modulo) / 26);
}
return columnName;
}
答案 27 :(得分:1)
这是根据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;
};
答案 28 :(得分:1)
抱歉,这是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))
通过了这些测试用例:
答案 29 :(得分:1)
这是所有其他人以及Google重定向的问题,所以我在此处发布此内容。
这些答案中有许多是正确的,但对于简单的情况来说太麻烦,例如当你没有超过26列时。如果您对是否可能进入双字符列有任何疑问,请忽略此答案,但如果您确定没有,那么您可以在C#中执行此操作简单:
auto
哎呀,如果您对自己传入的内容充满信心,甚至可以删除验证并使用此内联:
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);
}
这在许多语言中非常相似,因此您可以根据需要进行调整。
同样,只有在您100%确定您不会超过26列时才使用此功能。
答案 30 :(得分:1)
这些我的代码将特定数字(索引从1开始)转换为Excel列。
public static string NumberToExcelColumn(uint number)
{
uint originalNumber = number;
uint numChars = 1;
while (Math.Pow(26, numChars) < number)
{
numChars++;
if (Math.Pow(26, numChars) + 26 >= number)
{
break;
}
}
string toRet = "";
uint lastValue = 0;
do
{
number -= lastValue;
double powerVal = Math.Pow(26, numChars - 1);
byte thisCharIdx = (byte)Math.Truncate((columnNumber - 1) / powerVal);
lastValue = (int)powerVal * thisCharIdx;
if (numChars - 2 >= 0)
{
double powerVal_next = Math.Pow(26, numChars - 2);
byte thisCharIdx_next = (byte)Math.Truncate((columnNumber - lastValue - 1) / powerVal_next);
int lastValue_next = (int)Math.Pow(26, numChars - 2) * thisCharIdx_next;
if (thisCharIdx_next == 0 && lastValue_next == 0 && powerVal_next == 26)
{
thisCharIdx--;
lastValue = (int)powerVal * thisCharIdx;
}
}
toRet += (char)((byte)'A' + thisCharIdx + ((numChars > 1) ? -1 : 0));
numChars--;
} while (numChars > 0);
return toRet;
}
我的单元测试:
[TestMethod]
public void Test()
{
Assert.AreEqual("A", NumberToExcelColumn(1));
Assert.AreEqual("Z", NumberToExcelColumn(26));
Assert.AreEqual("AA", NumberToExcelColumn(27));
Assert.AreEqual("AO", NumberToExcelColumn(41));
Assert.AreEqual("AZ", NumberToExcelColumn(52));
Assert.AreEqual("BA", NumberToExcelColumn(53));
Assert.AreEqual("ZZ", NumberToExcelColumn(702));
Assert.AreEqual("AAA", NumberToExcelColumn(703));
Assert.AreEqual("ABC", NumberToExcelColumn(731));
Assert.AreEqual("ACQ", NumberToExcelColumn(771));
Assert.AreEqual("AYZ", NumberToExcelColumn(1352));
Assert.AreEqual("AZA", NumberToExcelColumn(1353));
Assert.AreEqual("AZB", NumberToExcelColumn(1354));
Assert.AreEqual("BAA", NumberToExcelColumn(1379));
Assert.AreEqual("CNU", NumberToExcelColumn(2413));
Assert.AreEqual("GCM", NumberToExcelColumn(4823));
Assert.AreEqual("MSR", NumberToExcelColumn(9300));
Assert.AreEqual("OMB", NumberToExcelColumn(10480));
Assert.AreEqual("ULV", NumberToExcelColumn(14530));
Assert.AreEqual("XFD", NumberToExcelColumn(16384));
}
答案 31 :(得分:1)
我正在尝试用Java做同样的事情...... 我写了以下代码:
private String getExcelColumnName(int columnNumber) {
int dividend = columnNumber;
String columnName = "";
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
char val = Character.valueOf((char)(65 + modulo));
columnName += val;
dividend = (int)((dividend - modulo) / 26);
}
return columnName;
}
现在,当我使用columnNumber = 29运行它时,它会给我结果=“CA”(而不是“AC”) 我缺少什么评论? 我知道我可以通过StringBuilder来反转它....但是看看格雷厄姆的回答,我有点困惑....
答案 32 :(得分:1)
这是我在PHP中的超级晚期实现。这个是递归的。我在发现这篇文章之前写的。我想知道其他人是否已经解决了这个问题......
public function GetColumn($intNumber, $strCol = null) {
if ($intNumber > 0) {
$intRem = ($intNumber - 1) % 26;
$strCol = $this->GetColumn(intval(($intNumber - $intRem) / 26), sprintf('%s%s', chr(65 + $intRem), $strCol));
}
return $strCol;
}
答案 33 :(得分:0)
在VB.Net 2005中使用它:
Private Function ColumnName(ByVal ColumnIndex As Integer) As String
Dim Name As String = ""
Name = (New Microsoft.Office.Interop.Owc11.Spreadsheet).Columns.Item(ColumnIndex).Address(False, False, Microsoft.Office.Interop.Owc11.XlReferenceStyle.xlA1)
Name = Split(Name, ":")(0)
Return Name
End Function
答案 34 :(得分:0)
这是从零开始的列索引的更简单解决方案
public static string GetColumnIndexNumberToExcelColumn(int columnIndex)
{
int offset = columnIndex % 26;
int multiple = columnIndex / 26;
int initialSeed = 65;//Represents column "A"
if (multiple == 0)
{
return Convert.ToChar(initialSeed + offset).ToString();
}
return $"{Convert.ToChar(initialSeed + multiple - 1)}{Convert.ToChar(initialSeed + offset)}";
}
答案 35 :(得分:0)
T-SQL(SQL SERVER 18)
该解决方案的副本在第一页上
CREATE FUNCTION dbo.getExcelColumnNameByOrdinal(@RowNum int)
RETURNS varchar(5)
AS
BEGIN
DECLARE @dividend int = @RowNum;
DECLARE @columnName varchar(max) = '';
DECLARE @modulo int;
WHILE (@dividend > 0)
BEGIN
SELECT @modulo = ((@dividend - 1) % 26);
SELECT @columnName = CHAR((65 + @modulo)) + @columnName;
SELECT @dividend = CAST(((@dividend - @modulo) / 26) as int);
END
RETURN
@columnName;
END;
答案 36 :(得分:0)
这是编码测试中常见的问题。 它有一些限制: 每行最大列数= 702 输出应具有行号+列名,例如703的答案是2A。 (注意:我刚刚从另一个答案中修改了现有代码) 这是相同的代码:
static string GetExcelColumnName(long columnNumber)
{
//max number of column per row
const long maxColPerRow = 702;
//find row number
long rowNum = (columnNumber / maxColPerRow);
//find tierable columns in the row.
long dividend = columnNumber - (maxColPerRow * rowNum);
string columnName = String.Empty;
long modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
dividend = (int)((dividend - modulo) / 26);
}
return rowNum+1+ columnName;
}
}
答案 37 :(得分:0)
public static string ConvertToAlphaColumnReferenceFromInteger(int columnReference)
{
int baseValue = ((int)('A')) - 1 ;
string lsReturn = String.Empty;
if (columnReference > 26)
{
lsReturn = ConvertToAlphaColumnReferenceFromInteger(Convert.ToInt32(Convert.ToDouble(columnReference / 26).ToString().Split('.')[0]));
}
return lsReturn + Convert.ToChar(baseValue + (columnReference % 26));
}
答案 38 :(得分:0)
这是我在python中的解决方案
import math
num = 3500
row_number = str(math.ceil(num / 702))
letters = ''
num = num - 702 * math.floor(num / 702)
while num:
mod = (num - 1) % 26
letters += chr(mod + 65)
num = (num - 1) // 26
result = row_number + ("".join(reversed(letters)))
print(result)
答案 39 :(得分:0)
已经有30多个解决方案,但这是我的单行C#解决方案...
public string IntToExcelColumn(int i)
{
return ((i<16926? "" : ((char)((((i/26)-1)%26)+65)).ToString()) + (i<2730? "" : ((char)((((i/26)-1)%26)+65)).ToString()) + (i<26? "" : ((char)((((i/26)-1)%26)+65)).ToString()) + ((char)((i%26)+65)));
}
答案 40 :(得分:0)
以前的大多数答案都是正确的。这是将列号转换为excel列的另一种方法。 如果我们将其视为基本转换,则解决方案非常简单。只需将列号转换为26,因为只有26个字母。 这是您可以执行的操作:
步骤:
将列设置为商
从商变量中减去一个(来自上一步),因为我们需要以{为3}结束ascii table。
除以26,得到余数。
这是执行此操作的代码:)
def convert_num_to_column(column_num):
result = ""
quotient = column_num
remainder = 0
while (quotient >0):
quotient = quotient -1
remainder = quotient%26
result = chr(int(remainder)+97)+result
quotient = int(quotient/26)
return result
print("--",convert_num_to_column(1).upper())
答案 41 :(得分:0)
对于它的价值,这里是Powershell中Graham的代码:
function ConvertTo-ExcelColumnID {
param (
[parameter(Position = 0,
HelpMessage = "A 1-based index to convert to an excel column ID. e.g. 2 => 'B', 29 => 'AC'",
Mandatory = $true)]
[int]$index
);
[string]$result = '';
if ($index -le 0 ) {
return $result;
}
while ($index -gt 0) {
[int]$modulo = ($index - 1) % 26;
$character = [char]($modulo + [int][char]'A');
$result = $character + $result;
[int]$index = ($index - $modulo) / 26;
}
return $result;
}
答案 42 :(得分:0)
另一种解决方案:
private void Foo()
{
l_ExcelApp = new Excel.ApplicationClass();
l_ExcelApp.ReferenceStyle = Excel.XlReferenceStyle.xlR1C1;
// ... now reference by R[row]C[column], Ex. A1 <==> R1C1, C6 <==> R3C6, ...
}
在此处查看更多内容 - Cell referencing in Excel for everyone! by Dr Nitin Paranjape
答案 43 :(得分:0)
感谢这里的答案!!帮助我提出了这些辅助功能,以便与我在Elixir / Phoenix工作的Google表格API进行一些互动
这是我想出的(可能会使用一些额外的验证和错误处理)
在Elixir:
def number_to_column(number) do
cond do
(number > 0 && number <= 26) ->
to_string([(number + 64)])
(number > 26) ->
div_col = number_to_column(div(number - 1, 26))
remainder = rem(number, 26)
rem_col = cond do
(remainder == 0) ->
number_to_column(26)
true ->
number_to_column(remainder)
end
div_col <> rem_col
true ->
""
end
end
反函数:
def column_to_number(column) do
column
|> to_charlist
|> Enum.reverse
|> Enum.with_index
|> Enum.reduce(0, fn({char, idx}, acc) ->
((char - 64) * :math.pow(26,idx)) + acc
end)
|> round
end
还有一些测试:
describe "test excel functions" do
@excelTestData [{"A", 1}, {"Z",26}, {"AA", 27}, {"AB", 28}, {"AZ", 52},{"BA", 53}, {"AAA", 703}]
test "column to number" do
Enum.each(@excelTestData, fn({input, expected_result}) ->
actual_result = BulkOnboardingController.column_to_number(input)
assert actual_result == expected_result
end)
end
test "number to column" do
Enum.each(@excelTestData, fn({expected_result, input}) ->
actual_result = BulkOnboardingController.number_to_column(input)
assert actual_result == expected_result
end)
end
end
答案 44 :(得分:0)
(我意识到这个问题与C#有关,但如果有人阅读时需要用 Java 做同样的事情,那么以下内容可能会有用)
事实证明,使用Jakarta POI中的“CellReference”类可以轻松完成此操作。此外,转换可以双向完成。
// Convert row and column numbers (0-based) to an Excel cell reference
CellReference numbers = new CellReference(3, 28);
System.out.println(numbers.formatAsString());
// Convert an Excel cell reference back into digits
CellReference reference = new CellReference("AC4");
System.out.println(reference.getRow() + ", " + reference.getCol());
答案 45 :(得分:0)
我在VB.NET 2003中使用这个,它运行良好......
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
答案 46 :(得分:0)
每种方式的F#版
let rec getExcelColumnName x = if x<26 then int 'A'+x|>char|>string else (x/26-1|>c)+ c(x%26)
原谅最小化,正在开发更好的https://stackoverflow.com/a/4500043/57883
版本<小时/> 和相反的方向:
// return values start at 0
let getIndexFromExcelColumnName (x:string) =
let a = int 'A'
let fPow len i =
Math.Pow(26., len - 1 - i |> float)
|> int
let getValue len i c =
int c - a + 1 * fPow len i
let f i = getValue x.Length i x.[i]
[0 .. x.Length - 1]
|> Seq.map f
|> Seq.sum
|> fun x -> x - 1
答案 47 :(得分:0)
以下是我在Python中的表现。该算法解释如下:
alph = ('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')
def labelrec(n, res):
if n<26:
return alph[n]+res
else:
rem = n%26
res = alph[rem]+res
n = n/26-1
return labelrec(n, res)
函数labelrec可以使用数字和空字符串调用,如:
print labelrec(16383, '')
以下是它有效的原因: 如果十进制数字的写入方式与Excel工作表列相同,则数字0-9将正常写入,但10将变为“00”,然后20将变为“10”,依此类推。映射少数数字:
0 - 0
9 - 9
10 - 00
20 - 10
100 - 90
110 - 000
1110 - 0000
所以,模式很清楚。从单位的位置开始,如果数字小于10,则其表示与数字本身相同,否则您需要通过减去1来调整剩余数字并递归。当数字小于10时,您可以停止。
在上述解决方案中对基数26应用相同的逻辑。
P.S。如果您希望数字从1开始,请在将数字减1后调用输入数字上的相同函数。
答案 48 :(得分:0)
看到另一个VBA答案 - 这可以在base64中使用1行UDF完成:
Function GetColLetter(ByVal colID As Integer) As String
GetColLetter = Split(Cells(1, colID).Address, "$")(1)
End Function
答案 49 :(得分:0)
NodeJS实施:
/**
* getColumnFromIndex
* Helper that returns a column value (A-XFD) for an index value (integer).
* The column follows the Common Spreadsheet Format e.g., A, AA, AAA.
* See https://stackoverflow.com/questions/181596/how-to-convert-a-column-number-eg-127-into-an-excel-column-eg-aa/3444285#3444285
* @param numVal: Integer
* @return String
*/
getColumnFromIndex: function(numVal){
var dividend = parseInt(numVal);
var columnName = '';
var modulo;
while (dividend > 0) {
modulo = (dividend - 1) % 26;
columnName = String.fromCharCode(65 + modulo) + columnName;
dividend = parseInt((dividend - modulo) / 26);
}
return columnName;
},
感谢Convert excel column alphabet (e.g. AA) to number (e.g., 25)。反过来说:
/**
* getIndexFromColumn
* Helper that returns an index value (integer) for a column value (A-XFD).
* The column follows the Common Spreadsheet Format e.g., A, AA, AAA.
* See https://stackoverflow.com/questions/9905533/convert-excel-column-alphabet-e-g-aa-to-number-e-g-25
* @param strVal: String
* @return Integer
*/
getIndexFromColumn: function(val){
var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', i, j, result = 0;
for (i = 0, j = val.length - 1; i < val.length; i += 1, j -= 1) {
result += Math.pow(base.length, j) * (base.indexOf(val[i]) + 1);
}
return result;
}
答案 50 :(得分:0)
Objective-C实施:
-(NSString*)getColumnName:(int)n {
NSString *name = @"";
while (n>0) {
n--;
char c = (char)('A' + n%26);
name = [NSString stringWithFormat:@"%c%@",c,name];
n = n/26;
}
return name;
}
SWIFT实施:
func getColumnName(n:Int)->String{
var columnName = ""
var index = n
while index>0 {
index--
let char = Character(UnicodeScalar(65 + index%26))
columnName = "\(char)\(columnName)"
index = index / 26
}
return columnName
}
答案 51 :(得分:0)
我今天必须做这项工作,我的实现使用递归:
private static string GetColumnLetter(string colNumber)
{
if (string.IsNullOrEmpty(colNumber))
{
throw new ArgumentNullException(colNumber);
}
string colName = String.Empty;
try
{
var colNum = Convert.ToInt32(colNumber);
var mod = colNum % 26;
var div = Math.Floor((double)(colNum)/26);
colName = ((div > 0) ? GetColumnLetter((div - 1).ToString()) : String.Empty) + Convert.ToChar(mod + 65);
}
finally
{
colName = colName == String.Empty ? "A" : colName;
}
return colName;
}
这会考虑以方法字符串形式出现的数字以及从&#34; 0&#34;开始的数字。 (A = 0)
答案 52 :(得分:0)
巧合而优雅 Ruby 版本:
def col_name(col_idx)
name = ""
while col_idx>0
mod = (col_idx-1)%26
name = (65+mod).chr + name
col_idx = ((col_idx-mod)/26).to_i
end
name
end
答案 53 :(得分:0)
如果您想要以编程方式引用单元格,那么如果使用工作表的Cells方法,则会获得更易读的代码。它采用行和列索引而不是传统的单元格引用。它与Offset方法非常相似。
答案 54 :(得分:-1)
Microsoft Excel Miniature,Quick-and-Dirty公式。
您好,
这是从数字中获取Excel字符列标题的一种方法....
我为Excel单元格创建了一个公式。
(即我采用了不使用VBA编程的方法。)
该公式查看一个包含数字的单元格,并以字母形式告诉您该列是什么。
附图:
我这样做是为了证明公式有效,这样您就可以查看公式的输出并查看上面的列标题,并在视觉上验证公式是否有效。 : - )
= CONCATENATE(MID(&#34; _abcdefghijklmnopqrstuvwxyz&#34;,(IF(MOD(K1,26)大于0,INT(K1 / 26)+1,(INT(K1 / 26)))), 1),MID(&#34; ABCDEFGHIJKLMNOPQRSTUVWXYZ&#34;,IF(MOD(K1,26)= 0.26,MOD(K1,26)),1))
下划线是出于调试目的 - 让你知道有一个实际空间并且它正常工作。
使用上面的公式 - 无论你放入K1 - 公式都会告诉你列标题是什么。
当前形式的公式仅为2位数(ZZ),但可以修改为添加第3个字母(ZZZ)。
答案 55 :(得分:-4)
public string ToBase26(int number)
{
if (number < 0) return String.Empty;
int remainder = number % 26;
int value = number / 26;
return value == 0 ?
String.Format("{0}", Convert.ToChar(65 + remainder)) :
String.Format("{0}{1}", ToBase26(value - 1), Convert.ToChar(65 + remainder));
}