最近、Excel を Python から操作するライブラリ Openpyxl をいじる必要があってその個人的メモです。Openpyxl の特徴としては、Excel 本体がなくても動くという点です。したがって、Linux などで Excel ファイルに対してバッチ処理を行うのにも使えます。
但し、ネットの情報などによると、互換性は今一つな点があり、場合によってはファイルを壊してしまう可能性もあると指摘しているものもありますが、基本的な処理を行う限りはさほど問題ないと思われます。
また、VBA ですと ファイルに VBA を使ったウィルスなどが含まれている場合がありますので、第 3 者に対して使ってもらうようなファイルに仕込むのはちょっと躊躇します。しかし、外部から Excel ファイルを操作する Openpyxl なら、スクリプトがファイルに仕込まれていないので、あらかじめ、安心できるルートで正しいスクリプトを配布できる体制がとれるならば、セキュリティ上の心配も少なくなります。
レファレンスドキュメントサイト
以下に、開発者によるレファレンスドキュメントがあります。
特に難しいところはないと思いますが、上位のオブジェクトは下位のオブジェクトのリスト変数になっている場合が多いです。
Workbook:
Workbook は、Worksheet を要素とする辞書型リスト変数です。仮に、wb を Workbook オブジェクトのインスタンスだとすると、ワークシートに対しては、wb["Sheet1"], wb["入力"] というようにワークシート名でアクセスできます。
なお、インデックス番号を使って、wb[0] というようなアクセスはできません。インデックス番号を使いたい場合は、worksheets プロパティを使い
wb.worksheets[0]
というようにアクセスします。この時インデックス番号は 0 から始まります。
Worksheet:
Worksheet は Cell, Row, Column を要素とする辞書型リスト変数で、やはり sh1 をインスタンスだとすると、行、列、セルに対して以下のようにアクセス可能です。
セルに対しては sh1["A1"], 行に対しては sh1["1"], 列に対しては、sh1["A"] という形でアクセス可能です。
行に対して:
sh1["1"] または、sh1[1]
※インデックス番号でアクセスする場合は、通常の Python のリスト変数とは異なり、インデックス番号が 1 から始まります。つまり Excel の行番号と一致します。
列に対して:
sh1["A"]
※ sh1[1] と入れてしまうと、行にアクセスしてしまいます。なお、wb.columns[1] というようにインデックス番号でアクセスできると解説しているサイトもありましたが、その筆者の勘違いなのか、バージョンアップで仕様が変更になったのかは分かりませんが、少なくとも現在のバージョン(3.1.2)では columns プロパティは subscriptable ではないと怒られて、エラーになります。
セルに対して:
sh1["A1"] または、sh1[1][0]
※インデックス番号でアクセスするときは、2次元リスト変数の形になります。但し、行番号は 1 から始まりますが、列番号は 0 から始まります。
更に、cell メソッドを使ってセルにアクセスすることもできます。
cell メソッドの書式は、cell(行番号, 列番号) ですので、
sh1.cell(1, 1)
となりますが、cellメソッドのインデックス番号は、行、列とも 1 から始まります。
Row:
セルを要素とするタプルになります。仮に、Row のインスタンス r1 とすると、セルに対して:
r1[0]
でアクセス可能ですが、このインデックス番号は、行の中の列番号を示すので、0 から始まります。なお、r1["A"] はダメです。またタプルですので値の入力は受け付けません。
Column:
やはりセルを要素とするタプルになります。仮に、Column のインスタンスを c1 とするとセルに対して:
c1[0]
でアクセス可能です。インデックス番号は、0 から始まります。c1["1"] というのは受け付けてくれません。またタプルですので値の入力は受け付けません。
セルに入る値です。この中身は、Python の通常の文字列ですのでシーケンシャル、つまり1文字ずつのリスト変数です。インデックス番号も Python の標準通り 0 から始まります。
OpenPyXl の鬼門として、インデックス番号が Excel に準じて 1 から始まるケースと Python の標準である 0 から始まるケースが混在していて非常に紛らわしいです。どういうロジックでそのような差が出ているのかもよく分かりません。
とりあえず、第三者が見ても分かりやすいプログラミングのためには、セルへのアクセスは極力 sh1["A1"] 形式か、sh1.cell(1, 1) 形式に限り、他の方法はなるべく使わないようにするのが良いように思います。