我是否缺less一些东西,或者这是用于计算excel列字符的Microsoftalgorithm不正确?

我试图用Python编写一个函数,它input一个列号并输出相应的Excel列代码(例如:5 – >“E”,27 – >“AA”)。 我试着实现这里给出的algorithm: http : //support.microsoft.com/kb/833402 ,这是下面的视觉基本:

Function ConvertToLetter(iCol As Integer) As String Dim iAlpha As Integer Dim iRemainder As Integer iAlpha = Int(iCol / 27) iRemainder = iCol - (iAlpha * 26) If iAlpha > 0 Then ConvertToLetter = Chr(iAlpha + 64) End If If iRemainder > 0 Then ConvertToLetter = ConvertToLetter & Chr(iRemainder + 64) End If End Function 

我的Python版本:

 def excelcolumn(colnum): alpha = colnum // 27 remainder = colnum - (alpha*26) out = "" if alpha > 0: out = chr(alpha+64) if remainder > 0: out = out + chr(remainder+64) return out 

这工作正常,直到列号53导致“A [”,因为alpha = 53 // 27 == 1 ,因此remainder = 53 - 1*26 == 27这意味着第二个字符chr(64+27)将是“ [”。 我错过了什么吗? 我的VBA技能是相当平淡,所以这可能是问题。

编辑:我正在使用Python 3.3.1

Microsoft公式不正确。 我敢打赌,他们从来没有testing超过53.当我在Excel中testing自己,它给出了同样的错误答案,你的做法。

以下是我如何做到这一点:

 def excelcolumn(colnum): alpha, remainder = colnum // 26, colnum % 26 out = "" if alpha == 0 else chr(alpha - 1 + ord('A')) out += chr(remainder + ord('A')) return out 

并不是说这个假设是基于0的列号,而VBA代码假设是基于1的。

如果您需要延伸超过701列,则需要与注释中所述的内容略有不同:

 def excelcolumn(colnum): if colnum < 26: return chr(colnum + ord('A')) return excelcolumn(colnum // 26 - 1) + chr(colnum % 26 + ord('A')) 

这是一个办法:

 def xl_col_to_name(col_num): col_str = '' while col_num: remainder = col_num % 26 if remainder == 0: remainder = 26 # Convert the remainder to a character. col_letter = chr(ord('A') + remainder - 1) # Accumulate the column letters, right to left. col_str = col_letter + col_str # Get the next order of magnitude. col_num = int((col_num - 1) / 26) return col_str 

这使:

 >>> xl_col_to_name(5) 'E' >>> xl_col_to_name(27) 'AA' >>> xl_col_to_name(256) 'IV' >>> xl_col_to_name(1000) 'ALL' 

这取自XlsxWriter模块中的实用程序function 。

我要回答你的具体问题:

这是用于计算excel列字符的Microsoftalgorithm不正确吗?

是的 。 一般来说,当你想要有两个数的整数除法(通常称为DIV )和余数(通常称为MOD )时,应该使用与分母相同的值。 因此,你应该在两个地方使用26或27。

所以,algorithm是不正确的(很容易看出, iCol=27 ,其中iAlpha=1iRemainder=1 ,而它应该是iRemainder=0 )。

在这种情况下,数字应该是26.因为这给你从零开始的数字,你应该添加ascii("A") (= 65),一般来说,而不是64.双重错误使它适用于一些案例。

这个(难以接受的)混乱可能源于AZ有26列,从AZZ有26 * 27列,从AZZ有26 * 27 * 27列,等等。

适用于任何列的代码,并且是非recursion的

 def excelcolumn(colnum): if colnum < 1: raise ValueError("Index is too small") result = "" while True: if colnum > 26: colnum, r = divmod(colnum - 1, 26) result = chr(r + ord('A')) + result else: return chr(colnum + ord('A') - 1) + result 

(从这里取)。