如何通过索引实现列的自我命名?
如何通过索引实现列的自我命名?
我希望能够实例化我的Cell
类,并将单元格实例命名为"A"、"B"、"C"等,就像在Excel电子表格中一样。
我有一个像这样的Cell
类:
public class Cell { public Cell(Range nativeCell) { NativeCell = nativeCell; } public Range NativeCell { get; private set; } }
还有我的Sheet
类:
public class Sheet { private IDictionary_cells; public Sheet(Worksheet nativeSheet) { NativeSheet = nativeSheet; _cells = new Dictionary (); for (int rowIndex = 1; rowIndex <= NativeSheet.Rows.Count; ++rowIndex) for (int colIndex = 1; colIndex <= NativeSheet.Columns.Count; ++colIndex) { ICell newCell = new Cell(NativeSheet.Cells(rowIndex, colIndex)); newCell.Name = ?? // 这个名称应该看起来像"A1"、"B1"、"AA3"、"CB20"等。 Cells.Add(newCell.Name, newCell); } } public IDictionary Cells { get { return _cells; } } public Worksheet NativeSheet { get; private set; } }
我需要根据字母和重复使用字母的规则来生成一个名称,一旦遇到最后一个字母'Z',就要将字母加倍和三倍。该算法必须生成我将与rowIndex
值连接起来的字母,以实现这种类似Excel的命名策略。
字母如下:
A, B, C, D...Z, AA, AB, AC...AZ, BA, BB, BC...BZ, CA...XAA, XAB, XAC...
虽然我们清楚地知道colIndex
值1肯定指代列"A",值2 = "B",值3 = "C"等。
我的问题特别在于当我们加倍字母时。
你有任何简单实现这个的想法吗?
谢谢!=)
如何从索引实现列自命名?
问题的出现原因:VB.NET代码中的问题导致了列名计算错误。
解决方法:修复VB.NET代码中的错误。
下面是修复后的VB.NET代码:
'''Returns the Excel-style name of the column from the column index. ''' The column index. Function GetColumnName(ByVal colIndex As Integer) As String If colIndex < 1 Then Throw New ArgumentException("Column number must be greater or equal to 1.") Dim result As New List(Of String) 'letter codes start at Chr(65)' Do While colIndex > 0 'reduce the column number by 1 else the 26th column (Z) will become 0 (@) ' 'add 65 to the result and find the Chr() value. ' 'insert the character at position 0 of the character list ' 'integer divide by 26 to remove the column from the stack and repeat till ' 'there are no columns in the stack. ' result.Insert(0, Chr(65 + CInt((colIndex - 1) Mod 26))) colIndex = (colIndex - 1) \ 26 Loop Return String.Join("", result.ToArray) End Function
C#版本的代码:
///Returns the Excel-style name of the column from the column index. /// The column index. static string GetColumnName(int colIndex) { if (colIndex < 1) throw new ArgumentException("Column number must be greater or equal to 1."); var result = new List(); //letter codes start at Chr(65)' while (colIndex > 0) { //reduce the column number by 1 else the 26th column (Z) will become 0 (@) //add 65 to the result and find the Chr() value. //insert the character at position 0 of the char list //integer divide the column index by 26 to remove the last calculated column //from the stack and repeat till there are no columns in the stack. result.Insert(0, Microsoft.VisualBasic.Strings.Chr(65 + Convert.ToInt32((colIndex - 1) % 26))); colIndex = (int)((colIndex-1)/ 26); } return new string(result.ToArray()); }
这个函数经过测试,可以正确计算列名,即使是到列索引1000也没有问题。
原问题与Joel Coehoorn在类似问题的答案之间的区别在于,我的解决方法可以计算从列索引1到整型的最大值,而Joel的解决方法只能计算到列索引26。
此外,我认为while循环在处理数学模运算时会带来一些额外的处理开销,因为只有26个字符需要关注。当获取一个大于1的数的模时,这意味着你必须将字符加倍,依此类推。至于Joel Coehoorn的答案,它是递归的,所以它会将返回的字符串加倍和三倍,因此它应该可以处理任何整数值,就我了解的算法而言。
修复错误后的代码经过测试,可以正确计算列名。
问题的出现原因:
在Excel表格中,每个列都有一个索引值,但是通常情况下我们更习惯使用列的字母编号来表示列的位置。因此,有时候我们需要将列的索引值转换为相应的字母编号。
解决方法:
可以通过递归的方式将列的索引值转换为相应的字母编号。以下是一个可能的实现方法:
def get_column_name(index): if index <= 0: return "" else: return get_column_name((index - 1) // 26) + chr((index - 1) % 26 + ord('A')) column_index = 28 column_name = get_column_name(column_index) print(column_name)
运行以上代码,将输出列索引值为28的列的字母编号,即"AB"。
希望这个方法能帮到你。