以前の記事で、エクセルの列を表すアルファベットを数値に変換するプログラムを書いたのですが、今回は、その逆変換つまり、数値をエクセルの列を表すアルファベットに変換してみようと思います。
————————
※2018/11/15追記
数値をエクセルの列を表すアルファベットに変換する関数については こちらのに記載されているものより、処理速度、保守性においてはるかに優れたコードがあります。以下のURLに記載しましたので、数値をエクセルの列を表すアルファベットに変換する場合は以下のURLを参考にしてください。
keimina.hatenablog.jp
————————
いつも通り、プログラミング言語は Python で行います。
今回は、おもいっきり横着してメモリーを大量消費する辞書を生成して無理やりやってみます。
そして最後に、作成した関数があっているかテストします。
まず、以前のコードをおさらいです。
数値をアルファベットに変換するコードは以下のようなものでした。
def conv(alphabet): total = 0 for n, i in enumerate(alphabet[::-1]): chr_num = ord(i.lower()) chr_A_num = ord('a') total += (1 + chr_num - chr_A_num)* (26**n) return total
この関数を使用するとアルファベットと数値の対応関係が得られます。
今回はこれを利用し、4文字までのアルファベットAからZZZZをこの関数に入力し対応関係を辞書として保存します。
これにより、制限付きですが、逆関数となる辞書が求まります。
制限はアルファベット4文字までということです。
それでも約47万列を表現できるため、実用上問題となる可能性は低いと思われます。
これをクラスで以下のようにまとめてみました。
使い方は、クラスのdocstringの使用方法の欄を参照してください。
class ExcelTool(object): ''' 注意: メモリを大量に消費するので注意してください。 47万列までしか対応しません。 初回インスタンス生成時に47万回計算する。そのためインスタンス生成に時間がかかる。 インスタンスを生成した後に、変換用のメソッドを呼び出せる。 使用方法: >>> # 最初に必ずインスタンスを作成する >>> et = ExcelTool() >>> # エクセルの列を表すアルファベットを数値に変換する >>> et.excel_alphabets_to_num("AA") 27 >>> # 数値をエクセルの列を表すアルファベットに変換する >>> et.num_to_excel_alphabets(27) 27 ''' def __init__(self): from itertools import product self.alphabets = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' #"".join(chr(i) for i in range(65, 91)) # 1-4文字のアルファベット作成し、数値に変換し、逆変換用の辞書を作る self.map_dict = {} for i in range(1, 5): self.map_dict.update({ self.excel_alphabets_to_num("".join(alphabet_combination)): "".join(alphabet_combination) for alphabet_combination in product(self.alphabets, repeat=i)}) def excel_alphabets_to_num(self, alphabet_combination): ''' 説明: エクセルの列を表すアルファベットを数値に変換する関数 引数: str エクセルの列を表すアルファベットの文字列(大文字小文字は関係ない) 戻り値: int アルファベットに対応する数値 ''' total = 0 char_A = ord('A') for n, i in enumerate(alphabet_combination[::-1]): total += (1 + ord(i.upper()) - char_A)* (26**n) return total def num_to_excel_alphabets(self, num): ''' 説明: 数値をエクセルの列を表すアルファベットに変換する関数 引数: int エクセルの列を表すアルファベットに変換するための数値 戻り値: str 引数で与えた整数値に対応するエクセルの列を表すアルファベットの文字列 文字列は常に大文字で返す。 ''' return self.map_dict[num] ################################### # 以下はテストのためのコード ################################### # はじめにインスタンスを作成する et = ExcelTool() print("テスト") print("======== 数値からアルファベット========") print("1 =>", et.num_to_excel_alphabets(1)) print("26 =>", et.num_to_excel_alphabets(26)) print("26*26+1(677) =>", et.num_to_excel_alphabets(26*26+1)) print("26*26+26(702) =>", et.num_to_excel_alphabets(26*26+26)) print("26*26+26+1(703) =>", et.num_to_excel_alphabets(26*26+26+1)) print("======== アルファベットから数値========") print("A =>", et.excel_alphabets_to_num('A')) print("Z =>", et.excel_alphabets_to_num('Z')) print("ZA =>", et.excel_alphabets_to_num('ZA')) print("ZZ =>", et.excel_alphabets_to_num('ZZ')) print("AAA =>", et.excel_alphabets_to_num('AAA'))
以下にテストの結果を載せます。
テストの結果:
テスト ======== 数値からアルファベット======== 1 => A 26 => Z 26*26+1(677) => ZA 26*26+26(702) => ZZ 26*26+26+1(703) => AAA ======== アルファベットから数値======== A => 1 Z => 26 ZA => 677 ZZ => 702 AAA => 703
以上になります。