エクセルのデータをプログラムで処理する時に、データが入力されているセルの範囲が必要になることがよくあります。そんな時にExcel VBAならば、シートの最終行からEnd(xlUp)
を用いて表の下端を調べるのが常套手段です。
一方、Pythonでエクセルファイルの処理によく用いるライブラリ「openpyxl」では、データの範囲をシートのmin_column
, min_row
, max_column
, max_row
で取得することができます。
それぞれ以下のようにデータが入力されているセル範囲の「列(column)と行(row)の位置」を1から始まる番号で取得できます。
以下のようなPythonのコード(xlrange_print.py)で確認できます。
# xlrange_print.py
import openpyxl
wb = openpyxl.load_workbook("company_members_range_test.xlsx")
ws = wb.worksheets[0]
fmt = "{:7d} {:7d} {:7d} {:7d}"
print("min_col min_row max_col max_row")
print(fmt.format(ws.min_column, ws.min_row, ws.max_column, ws.max_row))
# 出力結果
min_col min_row max_col max_row
1 1 6 11
今回は、実際に様々なパターンの表で、どのようにデータ入力範囲が取得されるかを確認します。
特に、max_column
とmax_row
は、表を1行ずつ処理する時に用いるiter_rows()
のデフォルトの走査範囲を決めるので、正しく把握しておく必要があります。iter_rows()
は、デフォルトでは「1列目からmax_column」の範囲を、「1行目からmax_rowまで」ループ処理します。
本記事の目次
パターン1:A1セル以外から始まる表の場合
A1セルからでなく、例えばC2セルからデータが始まっている場合でも、以下のように正しく取得できます。
# xlrange_print.py 出力結果
min_col min_row max_col max_row
3 2 8 12
パターン2:途中に空白をはさむ場合
表の途中に空白がある場合も、以下のように有効な表の範囲を取得してくれます。
# xlrange_print.py 出力結果
min_col min_row max_col max_row
2 2 8 14
パターン3:データ以外の部分に書式設定やスペースがある場合
データが入力されていない範囲でも中央揃えのような単純な書式設定があるだけでデータ範囲として認識されてしまいます。また、スペースの入力だけでもデータ範囲と見なされます。
# xlrange_print.py 出力結果
min_col min_row max_col max_row
2 2 8 16
罫線があるパターン
エクセルでは罫線も書式設定なので、セルにデータが入力されていなくても、以下のようにopenpyxlではデータ範囲として認識されます。
エクセルで書式設定をクリアする方法
エクセルファイルの書式設定をクリアすれば、上記のような問題は解消されます。書式が必要ないデータ専用のファイルでは、書式設定はクリアした方がプログラムから扱いやすくなります。
エクセルの操作は、以下のようにセルを選択して、[ホーム]の[編集]にある消しゴムのアイコンにある[書式のクリア]をクリックすればクリアできます。
注意すべきパターンは?
データ専用として書式設定していないエクセルファイルならば問題ありませんが、帳票のように書式設定で体裁を整えているファイルでは、余分は部分までデータ範囲として処理してしまうことがあるので、コードで何らかの工夫が必要です。
例えば、iter_rows()
で範囲を指定したり、コードで空行を検出する(セルの値がNoneになるかで判定)方法が考えられます。いくつかのパターンを以下のページにまとめましたので、ぜひ参考にしてください。