"""후속 수정(2026-10-26: A 굽힘 R 마무리, C 운곡 B2 다리 끝 2100, D 갈고리 c·d 도면 값)을 엑셀에 반영한다. - 수정 내역: R-13(A), R-14(C), R-15(D) 추가, R-1·R-3·R-4 비고에 후속 완료 표시 - 수정 증거(마크별): 같은 철근 행 추가 - 미수정·보류: 완료된 행 갱신, 옥성 B9 a 범위 메모 추가 - 수정 파일·해시: 새 파일 5개 추가, 이전 최신본은 '중간본' - 공통 문제 상세(이미지) I열: C-1 행(4·7·9) 문구 갱신 같은 R-13 이 이미 있으면 중단(이중 적용 방지). """ import copy import datetime import hashlib import json import sys from pathlib import Path import openpyxl from openpyxl.styles import PatternFill ROOT = Path(r"D:\★Pier 자료\프로그램\Pier_T") REV = ROOT / "검토파일" RES = ROOT / "Code" / "검토수정" / "결과" XLSX = REV / "4개교_공통사항_종합.xlsx" fx1 = json.loads((RES / "c1_fix_remaining_ungok_okseong.json").read_text(encoding="utf-8")) fx2 = json.loads((RES / "c1_fix_remaining_rampa.json").read_text(encoding="utf-8")) hk = json.loads((RES / "c1_hook_cd.json").read_text(encoding="utf-8")) wb = openpyxl.load_workbook(XLSX) ws = wb["수정 내역"] if any(r[0].value == "R-13" for r in ws.iter_rows(min_row=4)): sys.exit("R-13 이 이미 있음 - 중단") GREEN = PatternFill("solid", fgColor="FFE2EFDA") GRAY = PatternFill("solid", fgColor="FFD9D9D9") def append_like(sheet, values, like_row): r = sheet.max_row + 1 for j, v in enumerate(values, 1): c = sheet.cell(row=r, column=j, value=v) s = sheet.cell(row=like_row, column=j) c.font = copy.copy(s.font) c.fill = copy.copy(s.fill) c.border = copy.copy(s.border) c.alignment = copy.copy(s.alignment) c.number_format = s.number_format sheet.auto_filter.ref = "A3:%s%d" % (openpyxl.utils.get_column_letter(sheet.max_column), r) return r u, o, ra = fx1["ungok"], fx1["okseong"], fx2["rampa"] p3, c9c13, c12, b2 = u["stat"]["P3_done"], o["stat"]["C9_done"] + o["stat"]["C13_done"], ra["stat"]["C12_done"], u["stat"]["B2_done"] hp5, hp3, hp31 = hk["okseong"]["sample"]["P5"], hk["rampa"]["sample"]["P3"], hk["rampa"]["sample"]["P3-1"] n_p5, n_p3, n_p31 = hk["okseong"]["stat"]["P5_done"], hk["rampa"]["stat"]["P3_done"], hk["rampa"]["stat"]["P3-1_done"] rows = [ ["R-13", "운곡·옥성·Ramp-A", "굽힘 반지름(C-1) 마무리 — 형상이 복잡해 보류했던 철근", "운곡 P3(H19 링), 옥성 C9·C13(H25), Ramp-A C12(H19)", "H19 R42.75 / H25 R56.25", "H19 R42.93 / H25 R56.95", p3 + c9c13 + c12, "사용자 승인 2026-10-26(창 선택 A). 운곡 P3: 호가 이어진 형상이라 '시작점·접선 고정, 호만 키우고 뒤를 평행 이동' 방식(철근 끝 이동 최대 %.2f mm). 옥성·Ramp-A: 기존 모서리 방식 + 파이프 생성 설정 변경(원래 곡선도 기본 설정으로는 실패)" % u["end_shift_mm"]["max"], "운곡교p1_수정7_20261026.3dm / 옥성교P1_G5_수정4_20261026.3dm / ramp-A G5_수정2_20261026.3dm", "저장 직전 문서 재스캔: 부족 호 운곡 P3 144 → 0, 옥성 C9·C13 90 → 0, Ramp-A C12 60 → 0. 객체 수 동일(3,236 / 3,862 / 2,255). 파이프 부피 ±0.5% 이내", "이로써 4교 모든 굽힘의 중심선 R 이 KDS 최소(모델 파이프 기준) 이상"], ["R-14", "운곡교", "기초 U자 철근 B2 다리 끝 해석 통일", "B2 (S25)", "다리 끝 z 2072.5 (B1 높이)", "다리 끝 z 2100 (바깥 상면 철근선, 산외·옥성과 동일 해석)", b2, "사용자 승인 2026-10-26(창 선택 C): 도면 U자 다리 길이 = 하면선~상면선 [추론]", "운곡교p1_수정7_20261026.3dm", "저장 직전 문서 확인: 38본 다리 끝 z 2100 (이동 전 2072.5 확인 후 적용)", "다리가 약 27.5mm 길어져 재료표 b 1,950 과의 차이는 약 27mm 로 줄어듦"], ["R-15", "옥성·Ramp-A", "갈고리 c·d 도면 값 적용 (도면에 r·c·d 가 있는 철근)", "옥성 P5(H16), Ramp-A P3(H16)·P3-1(H16)", "모델: 135° 호 R24 + 곧은 구간 약 150 (c·d 정의와 다름)", "P5: r60·호 134.65°(c 141)·d 80 / P3: r60·호 134.65°(c 141)·d 100 / P3-1: r135·호 70.03°(c 165)·d 150", n_p5 + n_p3 + n_p31, "사용자 지시 2026-10-26: 도면에 있으면 도면을 따르고 없으면 KDS. 도면 상세 행의 L = a+b+c+d (c = 호 길이, 호 각도 = c ÷ r, d = 곧은 구간) 로 확인", "옥성교P1_G5_수정5_20261026.3dm / ramp-A G5_수정3_20261026.3dm", "저장 직전 문서 확인: 호 반지름·각도·호 길이·곧은 구간이 도면과 일치 (P5 호 길이 141.0 · P3 141.0 · P3-1 165.0). 객체 수 동일", "KDS: r 이 H16 최소 23.9 이상, d 80(5db 79.5)·100·150 은 5db 이상. P3-1 갈고리는 약 70° 로 도면에 따름 [도면 c÷r]"], ] for row in rows: r = append_like(ws, row, 4) ws.cell(row=r, column=1).fill = GREEN for r in ws.iter_rows(min_row=4): if r[0].value in ("R-1", "R-3", "R-4"): r[10].value = str(r[10].value or "") + " → 2026-10-26 후속 수정 R-13 으로 보류분 완료" ev = wb["수정 증거(마크별)"] ev_rows = [ ["운곡교", "P3", "H19", "굽힘 반지름(C-1) 마무리", p3, "R 42.75", "R 42.93", None, "시작점·접선 고정 + 뒤쪽 평행 이동. 끝 이동 %.2f mm. 부족 호 144 → 0" % u["end_shift_mm"]["max"]], ["옥성교", "C9", "H25", "굽힘 반지름(C-1) 마무리", o["stat"]["C9_done"], "R 56.25", "R 56.95", None, "파이프 설정 fitRail=False. 부족 호 50 → 0"], ["옥성교", "C13", "H25", "굽힘 반지름(C-1) 마무리", o["stat"]["C13_done"], "R 56.25", "R 56.95", None, "파이프 설정 fitRail=False. 부족 호 40 → 0"], ["Ramp-A교", "C12", "H19", "굽힘 반지름(C-1) 마무리", c12, "R 42.75", "R 42.93", None, "파이프 설정 fitRail=False. 부족 호 60 → 0"], ["운곡교", "B2", "S25", "기초 철근 U자 다리 끝(기초 하단 기준 mm)", b2, "다리 끝 z 2072.5", "다리 끝 z 2100", 27.5, "다리 길이 +27.5 (본당)"], ["옥성교", "P5", "H16", "갈고리 c·d 도면 값", n_p5, "135° R24 + 곧은 구간 약 150 / 길이 %.1f" % hp5["old_len"], "R60 · %.2f° · 호 %.1f · d %.1f / 길이 %.1f" % (hp5["arc_deg"], hp5["arc_len"], hp5["tail"], hp5["new_len"]), round((hp5["new_len"] - hp5["old_len"]) * n_p5, 1), "도면 r60 c141 d80"], ["Ramp-A교", "P3", "H16", "갈고리 c·d 도면 값", n_p3, "135° R24 + 곧은 구간 / 길이 %.1f" % hp3["old_len"], "R60 · %.2f° · 호 %.1f · d %.1f / 길이 %.1f" % (hp3["arc_deg"], hp3["arc_len"], hp3["tail"], hp3["new_len"]), round((hp3["new_len"] - hp3["old_len"]) * n_p3, 1), "도면 r60 c141 d100"], ["Ramp-A교", "P3-1", "H16", "갈고리 c·d 도면 값", n_p31, "135° R24 + 곧은 구간 / 길이 %.1f" % hp31["old_len"], "R135 · %.2f° · 호 %.1f · d %.1f / 길이 %.1f" % (hp31["arc_deg"], hp31["arc_len"], hp31["tail"], hp31["new_len"]), round((hp31["new_len"] - hp31["old_len"]) * n_p31, 1), "도면 r135 c165 d150 (호 각도 c÷r = 70°)"], ] for row in ev_rows: append_like(ev, row, 4) hold = wb["미수정·보류"] for r in hold.iter_rows(min_row=4): k = (str(r[0].value), str(r[1].value)) if k == ("운곡교", "P3 (H19 링)") or k == ("옥성교", "C9·C13 (H25)") or k == ("Ramp-A교", "C12 (H19)"): r[3].value = "수정 완료(2026-10-26): 굽힘 R 을 KDS 최소 이상으로 다시 만듦" r[4].value = "'수정 내역' R-13. " + str(r[4].value) r[5].value = "-" if k == ("운곡교", "B2 (S25 U자)"): r[3].value = "수정 완료(2026-10-26): 다리 끝을 2100 으로 통일" r[4].value = "'수정 내역' R-14. 산외·옥성과 같은 해석" r[5].value = "-" append_like(hold, ["옥성교", "B9 (H19 C형 띠철근)", "171본", "도면 상세 a=586~548 은 범위값(모델은 평균 567 고정)", "사용자 설명: 재료표를 보고 방향 길이에 따라 J 값이 들어가야 함. 도면 B9 행에는 J 가 없고 a 범위(586~548)만 있어 어느 방향·어떤 규칙으로 a 가 변하는지 미확인 → 수정하지 않음", "a 범위가 변하는 방향·규칙 확인(도면 위치 지정)", "R-10 취소 이후 미결"], 4) fs = wb["수정 파일·해시"] def sha(p): h = hashlib.sha256() with open(p, "rb") as f: for blk in iter(lambda: f.read(1 << 20), b""): h.update(blk) return h.hexdigest() old_latest = {"운곡교p1_수정6_20261026.3dm", "옥성교P1_G5_수정2_20261026.3dm", "ramp-A G5_수정_20261023.3dm"} for r in fs.iter_rows(min_row=4): name = str(r[1].value).split("/")[-1] if name in old_latest and r[3].value == "최신": r[3].value = "중간본" r[3].fill = PatternFill(fill_type=None) new_files = [ ("운곡교", "철근 모델랑 운곡교P1_바이브코딩/운곡교p1_수정7_20261026.3dm", "P3 굽힘 R 마무리 + B2 다리 끝 2100 — 전체 수정 포함", "최신"), ("옥성교", "검토_옥성교P1/옥성교P1_G5_수정4_20261026.3dm", "C9·C13 굽힘 R 마무리", "중간본"), ("옥성교", "검토_옥성교P1/옥성교P1_G5_수정5_20261026.3dm", "P5 갈고리 도면 값 — 전체 수정 포함(전단철근 수정3 제외)", "최신"), ("Ramp-A교", "Ramp-A교P1/ramp-A G5_수정2_20261026.3dm", "C12 굽힘 R 마무리", "중간본"), ("Ramp-A교", "Ramp-A교P1/ramp-A G5_수정3_20261026.3dm", "P3·P3-1 갈고리 도면 값 — 전체 수정 포함", "최신"), ] for b, rel, what, st in new_files: p = REV / rel stt = p.stat() r = append_like(fs, [b, "검토파일/" + rel, what, st, round(stt.st_size / 1e6, 1), datetime.datetime.fromtimestamp(stt.st_mtime).strftime("%Y-%m-%d %H:%M"), sha(p)], 4) if st == "최신": fs.cell(row=r, column=4).fill = GREEN else: fs.cell(row=r, column=4).fill = PatternFill(fill_type=None) ws2 = wb["공통 문제 상세(이미지)"] ws2["I4"].value = ("[완료] 4개 교량 굽힘 반지름을 KDS 24 14 21 기준으로 교체 (2026-10-23~26). H19 R42.75→42.93, H22 R49.5→49.85, H25 R56.25→56.95 (철근 끝점 고정, 호만 커짐 → 철근 1본당 0.08~1.2mm 짧아짐).\n" "교체 본수(기초 제외): 운곡 390+P3 72 · 산외 207 · 옥성 561+18 · Ramp-A 260+12. 기초 철근은 별도 규칙과 함께 처리: 운곡 155 · 산외 62 · 옥성 214.\n" "검증: 수정본 전수 스캔 → 4교 모든 굽힘 호가 KDS 최소 중심선 R 이상 (기준 미달 호 0개).\n" "상세: '수정 내역' R-1~R-8, R-13, '수정 증거(마크별)', 'KDS 직경별 R' 시트") ws2["I4"].fill = copy.copy(GREEN) t7 = str(ws2["I7"].value).split("\n보류")[0] ws2["I7"].value = t7 + "\n(후속 수정 R-13 으로 옥성 C9·C13 18본도 완료)" t9 = str(ws2["I9"].value).split("\n보류")[0] ws2["I9"].value = t9.replace("[일부 완료]", "[수정 완료]") + "\n(후속 수정 R-13 으로 운곡 P3 72본·Ramp-A C12 12본도 완료)" ws2["I9"].fill = copy.copy(GREEN) wb.save(XLSX) print("saved")