22

これは、行と列の ID が指定されたときに COLUMN 名を指定するためのコードですが、 のような値を指定すると、 が返さrow = 1 and col = 104れるはずですが、CZD@

row = 1
col = 104
div = col
column_label = str()
while div:
    (div, mod) = divmod(div, 26)
    column_label = chr(mod + 64) + column_label

print column_label

私がしていることの何が問題になっていますか?

(このコードは、行、列の ID 値を提供し、同じ値の ALPHABETIC 値を期待する EXCEL 列の参照です。)

4

8 に答える 8

31

注:702この回答に示されているコードは、受け入れたときのコードではありません。これは、 (Excel の column に対応する) より大きい列番号を適切に処理できないというバグを見つけて修正したためです'ZZ'

問題が発生するのに十分な数の列番号を持つ以前のバージョンを使用したことがない可能性が非常に高いです。FWIW、Microsoft Excel の仕様と制限によると、最大 1,048,576 行 x 16,384 列 (つまり column 'XFD') のワークシートがサポートされています。

LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

def excel_style(row, col):
    """ Convert given row and column number to an Excel-style cell name. """
    result = []
    while col:
        col, rem = divmod(col-1, 26)
        result[:0] = LETTERS[rem]
    return ''.join(result) + str(row)

if __name__ == '__main__':
    addresses = [(1,  1), (1, 26),
                 (1, 27), (1, 52),
                 (1, 53), (1, 78),
                 (1, 79), (1, 104),
                 (1, 18253), (1, 18278),
                 (1, 702),  # -> 'ZZ1'
                 (1, 703),  # -> 'AAA1'
                 (1, 16384), # -> 'XFD1'
                 (1, 35277039)]

    print('({:3}, {:>10}) --> {}'.format('row', 'col', 'Excel'))
    print('==========================')
    for row, col in addresses:
        print('({:3}, {:10,}) --> {!r}'.format(row, col, excel_style(row, col)))

出力:

(row,       col) --> Excel
========================
(  1,         1) --> 'A1'
(  1,        26) --> 'Z1'
(  1,        27) --> 'AA1'
(  1,        52) --> 'AZ1'
(  1,        53) --> 'BA1'
(  1,        78) --> 'BZ1'
(  1,        79) --> 'CA1'
(  1,       104) --> 'CZ1'
(  1,     18253) --> 'ZZA1'
(  1,     18278) --> 'ZZZ1'
(  1,       702) --> 'ZZ1'
(  1,       703) --> 'AAA1'
(  1,     16384) --> 'XFD1'
(  1,  35277039) --> 'BYEBYE1'
于 2013-10-03T21:02:39.893 に答える
17

インデックスの問題がいくつかあります。

したがって、問題を解決するには、すべてのインデックスを一致させる必要があります。

def colToExcel(col): # col is 1 based
    excelCol = str()
    div = col 
    while div:
        (div, mod) = divmod(div-1, 26) # will return (x, 0 .. 25)
        excelCol = chr(mod + 65) + excelCol

    return excelCol

print colToExcel(1) # => A
print colToExcel(26) # => Z
print colToExcel(27) # => AA
print colToExcel(104) # => CZ
print colToExcel(26**3+26**2+26) # => ZZZ
于 2013-10-03T08:43:32.147 に答える
2

私はそれが次のようなものだと思います:

def get_col(col):
    """Get excel-style column names"""
    (div, mod) = divmod(col, 26)
    if div == 0:
        return str(unichr(mod+64))
    elif mod == 0:
        return str(unichr(div+64-1)+'Z')
    else:
        return str(unichr(div+64)+unichr(mod+64))

いくつかのテスト:

>>> def get_col(col):
...     (div, mod) = divmod(col, 26)
...     if div == 0:
...         return str(unichr(mod+64))
...     elif mod == 0:
...         return str(unichr(div+64-1)+'Z')
...     else:
...         return str(unichr(div+64)+unichr(mod+64))
... 
>>> get_col(105)
'DA'
>>> get_col(104)
'CZ'
>>> get_col(1)
'A'
>>> get_col(55)
'BC'
于 2013-10-03T08:37:52.590 に答える
1

私はそれを理解したと思います。 divmod(104,26) は mod=0 となり、chr(0+64) = 64、つまり '@' になります。

この行を column_label の前に追加する"mod=26 if mod==0 else mod" と、うまくいくと思います

column_label=''
div=104
while div:
    (div, mod) = divmod(div, 26)
    mod=26 if mod==0 else mod
    column_label = chr(mod + 64) + column_label

print column_label
于 2013-10-03T08:31:05.230 に答える
0

このコードを使用してください:

def xlscol(colnum):
    a = []
    while colnum:
        colnum, remainder = divmod(colnum - 1, 26)
        a.append(remainder)
    a.reverse()
    return ''.join([chr(n + ord('A')) for n in a])
于 2016-03-11T17:09:22.870 に答える