我是否缺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=1
和iRemainder=1
,而它应该是iRemainder=0
)。
在这种情况下,数字应该是26.因为这给你从零开始的数字,你应该添加ascii("A")
(= 65),一般来说,而不是64.双重错误使它适用于一些案例。
这个(难以接受的)混乱可能源于A
到Z
有26列,从A
到ZZ
有26 * 27列,从A
到ZZ
有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
(从这里取)。