공공기관2 작업 중. _temp 몽타주(재생성가능)는 제외. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
64 lines
2.8 KiB
Python
64 lines
2.8 KiB
Python
import sys, io
|
|
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
|
|
import openpyxl, importlib.util
|
|
from openpyxl.utils import get_column_letter
|
|
from collections import Counter
|
|
P = r'D:\01.프로젝트\DB수집\작업파일\광역_사이트맵\충청남도\8.서산시\충청남도_서산시.xlsx'
|
|
wb=openpyxl.load_workbook(P); ws=wb.active
|
|
M=list(ws.merged_cells.ranges)
|
|
def mof(r,c):
|
|
for m in M:
|
|
if m.min_row<=r<=m.max_row and m.min_col<=c<=m.max_col: return m
|
|
return None
|
|
def eff(r,c):
|
|
m=mof(r,c); return ws.cell(m.min_row,m.min_col).value if m else ws.cell(r,c).value
|
|
data=[r for r in range(3,ws.max_row+1) if ws.cell(r,2).value not in (None,'')]
|
|
print(f'시트:{ws.title} 데이터행:{len(data)} max_row:{ws.max_row} 총병합:{len(M)}')
|
|
print('헤더병합:', [h for h in ('B1:R1','S1:W1','Y1:AA1') if h in {str(m) for m in M}])
|
|
|
|
# 1) 구조검수 (검수체크 재사용)
|
|
spec=importlib.util.spec_from_file_location('chk', r'D:\01.프로젝트\DB수집\작업파일\광역_사이트맵\_검수체크.py')
|
|
chk=importlib.util.module_from_spec(spec); spec.loader.exec_module(chk)
|
|
n,issues=chk.inspect(P)
|
|
print(f'\n=== 구조검수: {"PASS" if not issues else "FAIL "+str(len(issues))+"건"} ===')
|
|
for x in issues: print(' ✗',x)
|
|
|
|
# 2) 정렬 분포 (가로/세로/wrap) per 주요 컬럼
|
|
print('\n=== 정렬 분포 (열: (horiz,vert,wrap) -> 행수) ===')
|
|
for c in (2,4,5,6,7,11,13,14,15):
|
|
cnt=Counter()
|
|
for r in data:
|
|
a=ws.cell(r,c).alignment
|
|
cnt[(a.horizontal, a.vertical, a.wrap_text)]+=1
|
|
print(f' {get_column_letter(c)}: {dict(cnt)}')
|
|
|
|
# 3) 행높이
|
|
hc=Counter(ws.row_dimensions[r].height for r in range(1,ws.max_row+1))
|
|
print('\n행높이 분포:', dict(hc))
|
|
|
|
# 4) 미병합 부모그룹 탐지 (E5,F6,G7)
|
|
def parent_groups(c):
|
|
groups=[]; i=0
|
|
while i<len(data):
|
|
r=data[i]; v=ws.cell(r,c).value
|
|
if v in (None,'') or (mof(r,c) and mof(r,c).min_row!=r): i+=1; continue
|
|
parent=tuple(eff(r,cc) for cc in range(4,c)); rows=[r]; j=i+1
|
|
while j<len(data):
|
|
r2=data[j]
|
|
if tuple(eff(r2,cc) for cc in range(4,c))!=parent: break
|
|
cv=ws.cell(r2,c).value; m2=mof(r2,c)
|
|
if (cv in (None,'')) or (m2 and m2.min_row<r2): rows.append(r2); j+=1
|
|
else: break
|
|
if len(rows)>1 and any(ws.cell(rr,c+1).value not in (None,'') for rr in rows):
|
|
m=mof(r,c); groups.append((rows[0],rows[-1],v,bool(m and m.max_row>m.min_row))); i=j
|
|
else: i+=1
|
|
return groups
|
|
print('\n=== 부모그룹 병합상태 (★비병합=이상후보) ===')
|
|
for c,nm in [(5,'E'),(6,'F'),(7,'G')]:
|
|
gs=parent_groups(c)
|
|
if not gs: continue
|
|
un=[g for g in gs if not g[3]]
|
|
print(f' {nm}: 총{len(gs)} 병합{len(gs)-len(un)} ★비병합{len(un)}')
|
|
for a,z,v,mg in un:
|
|
print(f' ★ {nm}{a}:{z} {v!r} (E={eff(a,5)!r} F={eff(a,6)!r})')
|