繁体   English   中英

获取 Excel 列 label (A, B, ..., Z, AA, ..., AZ, BA, ..., ZZ, AAA, AAB, ...)

[英]Get the Excel column label (A, B, ..., Z, AA, ..., AZ, BA, ..., ZZ, AAA, AAB, ...)

给定 Excel 列 header 的字母,我需要 output 列号。

它是AZ ,然后是AA-AZ然后是BA-BZ等等。

我想通过它 go 就像它是 26 进制一样,我只是不知道如何实现它。

它适用于像AA这样的简单算法,因为26^0 = 1 + 26^1 = 26 = 27

但是对于像ZA这样的东西,如果我做26 ^ 26 (z 是第 26 个字母),output 显然太大了。 我错过了什么?

如果我们将“A”解码为 0,“B”解码为 1,……那么“Z”为 25,“AA”为 26。

所以它不是纯 26 基编码,因为前缀“A”对值没有影响,“AAAB”必须与“B”相同,就像十进制系统中 0001 相等到 1. 但这里不是这样。

“AA”的值为 1*26 1 + 0,“ZA”的值为 26*26 1 + 0。

我们可以概括并说“A”的值应该是 1,“B”应该是 2,……等等(除了单个字母编码)。 所以在“AAA”中,最右边的“A”代表系数为0,而其他的“A”代表系数:1*26 2 + 1*26 1 + 0

这导致以下代码:

def decode(code):
    val = 0
    for ch in code: # base-26 decoding "plus 1"
        val = val * 26 + ord(ch) - ord("A") + 1 
    return val - 1

当然,如果我们希望列号以 1 而不是 0 开头,那么只需将最后的语句替换为:

return val

权力总和

您可以将 26 的幂的倍数相加:

def xl2int(s):
    s = s.strip().upper()
    return sum((ord(c)-ord('A')+1)*26**i
               for i,c in enumerate(reversed(s)))

xl2int('A')
# 1

xl2int('Z')
# 26

xl2int('AA')
# 27

xl2int('ZZ')
# 702

xl2int('AAA')
# 703

int内置

您可以使用字符串转换表和带有base参数的int内置函数。

由于您的基础已损坏,您需要为长度为 n 的输入添加 26**n+26**(n-1)+...+26**0,您可以使用int('11...1', base=26)其中 1 的数量与输入字符串的长度一样多。

from string import ascii_uppercase, digits
t = str.maketrans(dict(zip(ascii_uppercase, digits+ascii_uppercase)))

def xl2int(s):
    s = s.strip().upper().translate(t)
    return int(s, base=26)+int('1'*len(s), base=26)

xl2int('A')
# 1

xl2int('Z')
# 26

xl2int('AA')
# 27

xl2int('ZZ')
# 702

xl2int('AAA')
# 703

翻译的工作原理

它移动每个字符,以便 A -> 0, B -> 1...J -> 9, K -> A... Z -> P。然后它使用int将其转换为整数。 但是得到的数字是不正确的,因为我们在数字中的每个数字位置都缺少 26**x,所以我们添加了与输入中的数字一样多的 26 的幂。

另一种方法,写在 VBA 中:

Function nColumn(sColumn As String) As Integer

' Return column number for a given column letter.

' 676 = 26^2
' 64 = Asc("A") - 1

nColumn = _
    (IIf(Len(sColumn) < 3, 0, Asc(Left(      sColumn    , 1)) - 64) * 676) + _
    (IIf(Len(sColumn) = 1, 0, Asc(Left(Right(sColumn, 2), 1)) - 64) * 26) + _
                             (Asc(     Right(sColumn    , 1)) - 64)

End Function

或者您可以直接在工作表中进行:

=(if(len(<clm>) < 3, 0, code(left(      <clm>    , 1)) - 64) * 676) + 
 (if(len(<clm>) = 1, 0, code(left(right(<clm>, 2), 1)) - 64) * 26) + 
                       (code(     right(<clm>    , 1)) - 64)

我还发布了以类似方式完成的逆运算

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM