かなり苦労したのでメモ*1。このPythonコードの実行速度は下のVBAコードより圧倒的に速い。
#-*- coding: shift_jis -*- import openpyxl #元データのシート wb = openpyxl.load_workbook('testIn.xlsx',data_only=True) ws = wb['Sheet1'] #結合したセルの Range データを文字情報化して、バッファする listMerged=[] for rng in ws.merged_cells: listMerged.append(str(rng)) #セルの結合を解除し、左上の値を代入する for strRng in listMerged: leftTop = (strRng.split(':'))[0] ws.unmerge_cells(strRng) for row in ws[strRng]: for cell in row: cell.value = ws[leftTop].value #結果を保存する wb.save(filename='testOut.xlsx')
Sub cellUnmergeDataSpread(r As Range) ' ' 入力の r で決まる Range 内の結合セルデータを調べて、 ' セルの結合を全部解除して、結合してた全てのセルにデータをばらまく ' Dim o As Object, r0 As Range, v, i, j '[セル番号=>データの入ったセルのセル番号]の辞書の作成 Set o = CreateObject("Scripting.Dictionary") For i = 1 To r.Rows.Count For j = 1 To r.Columns.Count Set r0 = r.Cells(i, j) v = r0.MergeArea.item(1).Address(0, 0) o.Add r0.Address, v Next j Next i r.unmerge '結合解除はここ For Each v In o '結合解除したセルに左上セルのデータのコピー r.Parent.Range(v).Value = r.Parent.Range(o.item(v)).Value Next v End Sub
mergeする方は結合セルの探索にopenpyxl.worksheet.cell_range.CellRange*2を使うといいのかな?