# -*- coding: utf-8 -*- import openpyxl, io wb=openpyxl.load_workbook("한국지역난방공사.xlsx"); ws=wb.active out=io.open("_mergeplan_out.txt","w",encoding="utf-8") def w(*a): out.write(" ".join(str(x) for x in a)+"\n") COLS={4:'D',5:'E',6:'F',7:'G',8:'H',9:'I',10:'J'} mx=ws.max_row # effective values eff={} for r in range(3,mx+1): for c in range(4,11): eff[(r,c)]=ws.cell(r,c).value for mr in ws.merged_cells.ranges: if mr.min_col>=4 and mr.max_col<=10: v=ws.cell(mr.min_row,mr.min_col).value for r in range(mr.min_row,mr.max_row+1): for c in range(mr.min_col,mr.max_col+1): eff[(r,c)]=v def ev(r,c): v=eff[(r,c)]; return str(v).strip() if v not in(None,"") else "" def ppath(r,c): return tuple(ev(r,cc) for cc in range(4,c)) # target merges: per col, runs of equal effective value (non-empty) with identical parent path target=set() # (col,r1,r2) only when r2>r1 for c in range(4,11): r=3 while r<=mx: v=ev(r,c) if not v: r+=1; continue r2=r while r2+1<=mx and ev(r2+1,c)==v and ppath(r2+1,c)==ppath(r,c): r2+=1 if r2>r: target.add((c,r,r2)) r=r2+1 # existing single-col merges existing=set() for mr in ws.merged_cells.ranges: if mr.min_col==mr.max_col and 4<=mr.min_col<=10: existing.add((mr.min_col,mr.min_row,mr.max_row)) new=sorted(target-existing) removed=sorted(existing-target) # existing merges not in target (will be replaced) w("=== TARGET vs EXISTING (full re-merge plan) ===") w("target merges:",len(target),"existing single-col merges:",len(existing)) w(f"\n--- merges to CHANGE/ADD ({len(new)}) ---") for c,r1,r2 in new: # find overlapping existing for context ovl=[e for e in existing if e[0]==c and not(e[2]r2)] w(f" {COLS[c]}{r1}:{COLS[c]}{r2} '{ev(r1,c)}' 기존:{['%s%d:%d'%(COLS[c],a,b) for (cc,a,b) in ovl] if ovl else '없음(신규)'}") w(f"\n--- existing merges NOT in target ({len(removed)}) [재병합시 사라짐, 확인용] ---") for c,r1,r2 in removed: w(f" {COLS[c]}{r1}:{COLS[c]}{r2} top='{ws.cell(r1,c).value}'") out.close(); print("new",len(new),"removed-not-in-target",len(removed))