0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ループ処理時の結合セルの注意点

Posted at

はじめに

PythonでExcelを操作できるopenpyxlを使用して,全行・全列のループ処理時の結合セルの扱いについての注意点,備忘録です.

動作環境

  • Python 3.12.0
  • openpyxl 3.1.2

openpyxlはpipを使用してインストールできます.

pip install openpyxl

問題点

サンプルとして,下図の表を扱う場合を考えます.

image.png

B列の「A/B」欄を全て(B2~B12)"A"に変更したい場合,結合セルを考慮せずに記述すると以下のようになります.
最大行の取り方は「openpyxlでExcelの最終行を取得する際に気を付けること」を参考.

import openpyxl as px

excelFile = r"C:\Book1.xlsx"
wb = px.load_workbook(excelFile)
ws = wb.worksheets[0]

max = ws.max_row
for i in range(2, max+1):
    ws.cell(row = i, column = 2).value = "A"

wb.save(excelFile)
wb.close()

上記のスクリプトを実行すると,次のAttributeErrorが発生します.

AttributeError: 'MergedCell' object attribute 'value' is read-only

エラーコードを読んでわかる通り,MergedCell(結合セル)型のvalue属性は読み出し専用であって書き込みはできません.

サンプルの表では,B5,6 と B10,11 が結合されており,そこに表示されている値を持っているのは B5 と B10 のセルであり,B6 と B11 ではありません.

セルを結合すると,結合した範囲の左上のセル以外のすべてのセルがワークシートから削除されます.結合されたセルの境界情報を保持するため,結合されたセルの境界セルはNoneの値を持つ結合セル(今回の例ではB6,B11)として作成されます.B列をループで出力すると次のようになります.

2 A
3 A
4 A
5 A
6 None
7 A
8 B
9 B
10 B
11 None
12 B

ここで,ループ処理によって "B6,B11のセルの値を書き換える" というコードが実行された場合,上述の設計上,read-onlyなのは自然な動きだと思います.

解決策

結合セルの判定を追加して,AttributeErrorを回避します.

import openpyxl as px

excelFile = r"C:\Book1.xlsx"
wb = px.load_workbook(excelFile)
ws = wb.worksheets[0]

max = ws.max_row
for i in range(2, max+1):
    typeCell = isinstance(ws.cell(row = i, column = 2), px.cell.cell.MergedCell)
    if not typeCell:
        ws.cell(row = i, column = 2).value = "A"

wb.save(excelFile)
wb.close()

isinstance関数でセルがMergedCell型か判定し,typeCellにはBool値(True / False)が格納されます.
not演算子を使用することで,条件分岐では書き換え可能なセル(typeCell == False)のみ,処理を行うことができます.

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?