- 공공기관2/3 작업본 + 오늘 제출 17곳 D~J 카테고리 셀병합 정상화 - 한국지역난방공사 옵션2(고아셀 F98 수정)+전행 높이17 - 제출_프리랜서2_2026-06-21.zip 생성(17개 xlsx, 2,468행) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
54 lines
2.3 KiB
Python
54 lines
2.3 KiB
Python
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)
|