import openpyxl from openpyxl.utils import get_column_letter wb=openpyxl.load_workbook('한국지역난방공사.xlsx'); ws=wb.active ms=list(ws.merged_cells.ranges) N=ws.max_row errs=[] # 1 header merges intact hdr={'B1:R1','S1:W1','Y1:AA1'} have=set(str(m) for m in ms) for h in hdr: if h not in have: errs.append('header merge missing '+h) # 2 merge overlaps cells={} for m in ms: for r in range(m.min_row,m.max_row+1): for c in range(m.min_col,m.max_col+1): if (r,c) in cells: errs.append(f'overlap at {get_column_letter(c)}{r}') cells[(r,c)]=1 # 3 child merge must not cross parent boundary: for each col c in E..J, a merge cannot span rows whose parent(c-1 effective) differ def eff(r,c): v=ws.cell(r,c).value if v is not None: return v for m in ms: if m.min_row<=r<=m.max_row and m.min_col<=c<=m.max_col: return ws.cell(m.min_row,m.min_col).value return None for m in ms: if m.min_row>=3 and 5<=m.min_col<=10: pc=m.min_col-1 pv=set(eff(r,pc) for r in range(m.min_row,m.max_row+1)) if len(pv)>1: errs.append(f'merge {m} crosses parent {get_column_letter(pc)} values {pv}') # 4 every data row has D and at least leaf; D must be non-empty(eff) holes=0 for r in range(3,N+1): if eff(r,4) in (None,''): holes+=1 if holes: errs.append(f'{holes} rows with empty D') # 5 K hyperlink consistency for r in range(3,N+1): k=ws.cell(r,11) if k.value and (not k.hyperlink or k.hyperlink.target!=k.value): errs.append(f'K{r} link mismatch') # 6 blue N cells preserved (>=12) and Y/Z/AA fill region bluecnt=sum(1 for r in range(3,N+1) for c in [14] if ws.cell(r,c).fill.patternType=='solid' and getattr(ws.cell(r,c).fill.fgColor,'rgb','')=='FFBDD7EE') # 7 B sequential bs=[ws.cell(r,2).value for r in range(3,N+1)] if bs!=list(range(1,len(bs)+1)): errs.append('B not sequential') # 8 page M=1, site MNOPQ empty, board M numeric for r in range(3,N+1): L=ws.cell(r,12).value;M=ws.cell(r,13).value if L=='페이지' and M!=1: errs.append(f'page M!=1 r{r}') if L=='사이트' and any(ws.cell(r,c).value not in (None,'') for c in (13,14,15,16,17)): errs.append(f'site filled r{r}') print('rows',N-2,'merges',len(ms),'blueN cells(any)',bluecnt) print('ERRORS:',len(errs)) for e in errs[:30]: print(' ',e)