공공기관2 작업 중. _temp 몽타주(재생성가능)는 제외. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
80 lines
3.9 KiB
Python
80 lines
3.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
# GNB트리의 menu_id→(D,E,F,G)로 시트 전행 재라벨 (level-shift 교정). 사용: _relabel_menuid.py <no> [--apply]
|
|
import openpyxl, glob, os, re, sys, json, shutil
|
|
from copy import copy
|
|
from openpyxl.styles import PatternFill
|
|
NO=int(sys.argv[1]); APPLY='--apply' in sys.argv
|
|
BLUE=PatternFill(fill_type='solid',fgColor='FFBDD7EE'); MAXC=27
|
|
BASE=os.path.dirname(os.path.abspath(__file__))
|
|
t=json.load(open(os.path.join(BASE,'_gnb_trees.json'),encoding='utf-8'))[str(NO)]
|
|
path=[None]*8; mid2={}
|
|
for x in t['tree']:
|
|
lvl=x.get('lvl')
|
|
if lvl is None or lvl>=8: continue
|
|
path[lvl]=x.get('t')
|
|
for k in range(lvl+1,8): path[k]=None
|
|
m=re.search(r'menu_id=([0-9]+)',str(x.get('href') or ''))
|
|
if m: mid2.setdefault(m.group(1),(path[1],path[2],path[3],path[4]))
|
|
def mid(u):
|
|
m=re.search(r'menu_id=([0-9]+)',str(u or '')); return m.group(1) if m else None
|
|
d=[x for x in glob.glob(os.path.join(BASE,'%d.*'%NO)) if os.path.isdir(x)][0]
|
|
xp=[p for p in glob.glob(os.path.join(d,'*.xlsx')) if not os.path.basename(p).startswith(('_','~')) and 'conflict' not in os.path.basename(p) and 'backup' not in p][0]
|
|
mt=os.path.getmtime(xp); wb=openpyxl.load_workbook(xp); ws=wb.active
|
|
def eff(r,c):
|
|
v=ws.cell(r,c).value
|
|
if v is not None: return v
|
|
for mr in ws.merged_cells.ranges:
|
|
if mr.min_col==c and mr.min_row<=r<=mr.max_row: return ws.cell(mr.min_row,c).value
|
|
data=[r for r in range(3,ws.max_row+1) if any(ws.cell(r,c).value not in (None,'') for c in (2,4,5,6,7,11))]
|
|
chg=0
|
|
for r in data:
|
|
g=mid2.get(mid(ws.cell(r,11).value))
|
|
if g:
|
|
cur=(eff(r,4),eff(r,5),ws.cell(r,6).value,ws.cell(r,7).value)
|
|
if cur!=tuple(g): chg+=1
|
|
print('site %d: menu_id매칭 %d/%d행, 변경필요 %d'%(NO,sum(1 for r in data if mid2.get(mid(ws.cell(r,11).value))),len(data),chg))
|
|
if not APPLY: print('DRY'); sys.exit(0)
|
|
snap={(r,c):copy(ws.cell(r,c)._style) for r in data for c in range(1,MAXC+1)}
|
|
recs=[]
|
|
for r in data:
|
|
g=mid2.get(mid(ws.cell(r,11).value)); mark=set()
|
|
if g:
|
|
D,E,F,G=g
|
|
if (eff(r,4),eff(r,5),ws.cell(r,6).value,ws.cell(r,7).value)!=(D,E,F,G): mark={4,5,6,7}
|
|
else:
|
|
D,E,F,G=eff(r,4),eff(r,5),ws.cell(r,6).value,ws.cell(r,7).value
|
|
rec={'src':r,'D':D,'E':E,'F':F,7:G,'mark':mark,'url':ws.cell(r,11).value}
|
|
for c in range(8,MAXC+1): rec[c]=ws.cell(r,c).value
|
|
hl=ws.cell(r,11).hyperlink; rec['hl']=hl.target if hl else rec['url']; recs.append(rec)
|
|
for mr in list(ws.merged_cells.ranges):
|
|
if mr.min_row>=3: ws.unmerge_cells(str(mr))
|
|
n=len(recs)
|
|
for i,rc in enumerate(recs):
|
|
r=3+i; src=rc['src']
|
|
for c in range(1,MAXC+1): ws.cell(r,c)._style=copy(snap[(src,c)])
|
|
ws.cell(r,2).value=i+1; ws.cell(r,3).value=ws.cell(src,3).value
|
|
ws.cell(r,4).value=rc['D']; ws.cell(r,5).value=rc['E']; ws.cell(r,6).value=rc['F']
|
|
for c in range(7,MAXC+1): ws.cell(r,c).value=rc.get(c)
|
|
kc=ws.cell(r,11); kc.value=rc['url']; kc.hyperlink=rc['hl'] if rc['url'] else None
|
|
for c in rc['mark']: ws.cell(r,c).fill=BLUE
|
|
for r in range(3+n,ws.max_row+1):
|
|
for c in range(1,MAXC+1):
|
|
cell=ws.cell(r,c); cell.value=None; cell.hyperlink=None; cell.fill=PatternFill(fill_type=None)
|
|
def rem(col,sc):
|
|
r=3
|
|
while r<3+n:
|
|
v=ws.cell(r,col).value
|
|
if v is None or v=='': r+=1; continue
|
|
r2=r
|
|
while r2+1<3+n and ws.cell(r2+1,col).value==v and all(ws.cell(r2+1,s).value==ws.cell(r,s).value for s in sc): r2+=1
|
|
if r2>r:
|
|
for rr in range(r+1,r2+1): ws.cell(rr,col).value=None
|
|
ws.merge_cells(start_row=r,start_column=col,end_row=r2,end_column=col)
|
|
r=r2+1
|
|
rem(7,[4,5,6]); rem(6,[4,5]); rem(5,[4]); rem(4,[])
|
|
if os.path.getmtime(xp)!=mt: print('ABORT'); sys.exit(1)
|
|
shutil.copy(xp, os.path.join(d,'_backup',os.path.basename(xp).replace('.xlsx','_backup_menuid재라벨전.xlsx')))
|
|
wb.save(xp)
|
|
bs=[ws.cell(r,2).value for r in range(3,3+n)]
|
|
print('saved %d행 B연속%s'%(n,bs==list(range(1,n+1))))
|