はじめに
openpyxlを使用してPythonスクリプトからExcelを処理する際に,「最終行の取得」で躓いたので紹介します.備忘録です.
動作環境
- Python 3.12.0
- openpyxl 3.1.2
openpyxlはpipを使用してインストールできます.
pip install openpyxl
最終行取得コード
早速ですが最終行取得のソースコードを紹介します.
ソースコード
import openpyxl as px
# Excelファイルの指定
inputFile = r"C:\Qiita\test.xlsx"
# 指定したExcelを開く
wb = px.load_workbook(inputFile)
# 開いたExcelファイルの一番左のシートを選択
ws = wb.worksheets[0]
# 最大行番号を取得
max = ws.max_row
openpyxlのworksheet.max_row
属性は最大行番号を取得します.下図の例では "9" を返します.
うわめっちゃスッキリ書けるなぁ...と感心していると罠にハマってしまったわけです.
実はこのmax_row(最終行取得),セルに値が入っていなくても書式が設定されているとそのセルを最終行と認識してしまうのです.
試しにA10の書式を変更してみましょう.
今回は文字制御を「折り返して全体を表示」に変更してみます.
設定を更新して上記のコードを再実行するとmaxは10を返します.
新規でBookを作成する場合,このような事象は起きにくいとは思いますが,既存のファイルを処理する場合は注意が必要です.
個人的書式変更してるやんあるあるは,「フォント(サイズ,字体)の変更」「セルの白塗りつぶし(透明のつもり)」です.共有ファイルなんてのは何が起きてるかわかりません,いろんな方が触りますからね...
対応策
対応策としては,最終行を取得した後,「セルをディクリメントしていき,値が設定されているか確認する」というまあ力技です.以下ソースコードです.
import openpyxl as px
# Excelファイルの指定
inputFile = r"C:\Qiita\test.xlsx"
# 指定したExcelを開く
wb = px.load_workbook(inputFile)
# 開いたExcelファイルの一番左のシートを選択
ws = wb.worksheets[0]
# 最大行番号を取得
max = ws.max_row
# 最終行に値があるか確認する
while True:
if ws.cell(row=max, column=1).value == None:
max -= 1
else:
break
おわりに
max_row
に限らずmax_column
でも同様のため,最終行列を取得する際は注意が必要です.
(そういえばVBAでも同じような仕様だったような...?)