DB_JOB/작업파일/_스크립트/_find_unmerged.py
hehihoho3 df16c98366 백업: DB수집 전체 스냅샷 (공공기관2 정리 전)
공공기관2 작업 중. _temp 몽타주(재생성가능)는 제외.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 18:15:40 +09:00

57 lines
2.4 KiB
Python

import sys, io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
import openpyxl
from openpyxl.utils import get_column_letter
ws = openpyxl.load_workbook(r'D:\01.프로젝트\DB수집\작업파일\_제출패키지_2026-06-03\프리\충청남도_부여군.xlsx'.replace('프리','프리랜서1')).active
merges=list(ws.merged_cells.ranges)
def merge_of(r,c):
for m in merges:
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=merge_of(r,c)
if m: return ws.cell(m.min_row,m.min_col).value
return ws.cell(r,c).value
def raw(r,c): return 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,'')]
dset=set(data)
# For each category column, find a standalone value cell followed by >=1 None-unmerged cell
# under the SAME parent (cols < c effective equal) -> an UNMERGED group (merge removed).
print('=== 병합이 풀린(또는 누락된) 카테고리 그룹 후보 ===')
found=[]
for c in (4,5,6,7): # D,E,F,G
for r in data:
if merge_of(r,c): continue # this cell is in a merge -> ok
v=raw(r,c)
if v in (None,''): continue # need a value to be the group head
# scan down for trailing None-unmerged under same parent (cols < c effective same)
parent=tuple(eff(r,cc) for cc in range(4,c))
run=[]
r2=r+1
while r2 in dset:
# parent must match
if tuple(eff(r2,cc) for cc in range(4,c))!=parent: break
cell_in_merge=merge_of(r2,c)
cv=raw(r2,c)
if cv in (None,'') and not cell_in_merge:
run.append(r2); r2+=1; continue
break
if run:
found.append((c,r,run[-1],v,len(run)+1))
for c,a,z,v,n in found:
col=get_column_letter(c)
print(f' {col}{a}:{col}{z} 값={v!r} (행 {a}~{z}, {n}행이 병합 안 됨) D={eff(a,4)!r} E={eff(a,5)!r} F={eff(a,6)!r}')
if not found:
print(' 없음')
# Also: list every None+unmerged cell in D/E/F/G that sits under a value (orphan blanks)
print('\n=== D/E/F/G 빈칸+비병합 셀(고아 빈칸) 전수 ===')
for c in (4,5,6,7):
col=get_column_letter(c)
orph=[r for r in data if raw(r,c) in (None,'') and not merge_of(r,c)]
# filter: those that have a value somewhere above in same column within 50 rows (likely should inherit)
print(f' {col}: {len(orph)}', orph[:30])