From d7682c69c6a6dbe18b8413c4f0e5ff97d776ee60 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Thu, 12 Nov 2026 13:10:25 +0900 Subject: [PATCH] =?UTF-8?q?feat(est-test):=20=EC=88=98=EB=9F=89=EC=82=B0?= =?UTF-8?q?=EC=B6=9C=EC=84=9C=20=EC=97=91=EC=85=80=ED=98=95=EC=8B=9D=20?= =?UTF-8?q?=EC=A0=84=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- tools/est-test/PLAN.md | 3 +++ tools/est-test/native-excel-sheet.cjs | 5 ++-- tools/est-test/native-quantity-sheets.js | 30 ++++++++++++++++++++++-- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/tools/est-test/PLAN.md b/tools/est-test/PLAN.md index 4b08ac894..dae997c8d 100644 --- a/tools/est-test/PLAN.md +++ b/tools/est-test/PLAN.md @@ -487,6 +487,9 @@ ative-standard.js에 표준시장단가 원천(SilJukDat)과 내역 행(EstMainD - 남음: 구성비·요율 전환(CalcBase), 약어 표시(SName), 제비율 기준 문서 보기(원본 한글 파일). - [x] 수량산출서 검색·전체보기(원본 TFRMMULLANG btnSerch·btnAllDisplay — 빈칸·|·괄호 무시 포함 검색) — 고르기 줄을 `native-quantity-sheets.js` 로 옮겨 700줄 제한 유지. - 검증완료: `test_est_quantity_sheets.py` 검색 시험 포함 수량 시험 22개 통과. ORCA 브라우저에서 「집수」 검색 → 항목에 집수정이 있는 「배수」만·선택 이동, 전체보기 → 3개 복귀, 샘플 복구. + - [x] 수량산출서 엑셀형식 전환(원본 TFRMMULLANG popSetMode — DataKind 로 편집기 교체) — 산출서 화면 「엑셀형식으로」: 엑셀 시트가 없으면 빈 시트를 만들어 엑셀형으로, 「일반형식으로」는 엑셀 내용을 보관한 채 끄고 셀 연결 수량을 쓰지 않음. 바꾼 산출서는 ESTX 저장 거부(JSON). + - 검증완료: 엑셀·산출서·바인딩 시험 11개 통과. ORCA 브라우저에서 새 산출서 → 엑셀형식(격자 160칸) → A1 =2*3 → 6, 일반형식으로 → 격자 숨김·보관, 샘플 복구. + - 제외(원본에서도 쓰지 않거나 외부 프로그램): 제비율 적용기준 보기(설치 폴더 한글 문서를 한글 프로그램으로 열 뿐, 그림 3장), 엑셀물량 열기(Microsoft Excel 을 COM 으로 열 뿐 EST 로 읽지 않음), 플러스 일위대가로 변환(메뉴에 걸리지 않아 원본에서 실행 불가). - [x] 표시 설정(원본 연차공사 환경설정 TfrmEstMultiOption 0xf9c8f0 · 열 순서 0xf0f620) — 비목순서(합/노/재/경 · 합/재/노/경 · 노/재/경/합 · 재/노/경/합, 4·5 는 원본처럼 그대로) 금액·단가 열 재배치, 구분(선택출처) 열 보이기, 품명정렬. 계산 환경 `Display`, 계산 불변. 원본은 연차공사 문서에서만 열지만 웹은 모든 표에 적용. 품명 두 줄 표기·비고란 발췌근거는 하지 않음. - 검증완료: `test_est_display.py`(재/노/경/합 순·4번 그대로·구분 숨김·정렬) 통과. ORCA 브라우저에서 내역서 노/재/경/합 → NU·GU·JU·SU·TU / NC·GC·JC·SC·TC, 품명 가운데, 도급액 불변, 설정 지워 복구. - [x] 원가계산서 순공사비 입력(원본 가로양식 TfrmWongaH popTotalInput 0xe7fbf8) — 연결 54 줄이 있으면 「순공사비 항목이 있습니다」(그 줄 고름), 없으면 맨 위에 「순 공 사 비」(연결 54, 금액 = 직접공사비) 넣고 다시 계산. 원본이 이어서 하는 원가 전체 초기화(모든 줄 자리수·도급액 고정 지움)는 사용자 설정을 지우는 부작용이라 하지 않음. diff --git a/tools/est-test/native-excel-sheet.cjs b/tools/est-test/native-excel-sheet.cjs index d62ba5feb..dc5d44357 100644 --- a/tools/est-test/native-excel-sheet.cjs +++ b/tools/est-test/native-excel-sheet.cjs @@ -221,8 +221,9 @@ const EstExcelSheet = (() => { } // 연결된 셀 값 → 항목 수량 function itemValues(sheet) { - const out = new Map(), - digits = sheet.options?.digits ?? 2, + const out = new Map(); + if (sheet.excelOff) return out; // 일반형으로 돌린 산출서는 셀 연결을 쓰지 않음 + const digits = sheet.options?.digits ?? 2, mode = sheet.options?.roundMode ?? 2; for (const [code, l] of Object.entries(sheet.excelLinks || {})) { const v = sheet.excel?.[l.n]?.cells?.[key(l.row, l.col)]?.value; diff --git a/tools/est-test/native-quantity-sheets.js b/tools/est-test/native-quantity-sheets.js index 712be2f12..c2734d28a 100644 --- a/tools/est-test/native-quantity-sheets.js +++ b/tools/est-test/native-quantity-sheets.js @@ -187,13 +187,39 @@ const EstQuantitySheets = (() => { mark(sheet, index, start, end, EstQuantity.nextItemCode(sheet), editor.value); else free(sheet, index, start, editor.value); }, false); - } else return false; + } else if (name === "excel-mode") excelMode(state); + else return false; return true; } // 엑셀형 수량산출서(원본 TFRMMULEXCEL) — 편집 화면은 native-excel-view.js. + // 엑셀형식(popSetMode): 원본은 DataKind 를 바꿔 편집기를 갈아끼움 — 웹은 빈 엑셀 시트를 만들거나 끄고 켬(내용은 보관). function excelView(sheet) { - return typeof EstExcelView === "undefined" ? "" : EstExcelView.render(sheet, EstApp.state); + if (typeof EstExcelView === "undefined") return ""; + const on = sheet.excel?.length && !sheet.excelOff; + return `

${on ? EstExcelView.render(sheet, EstApp.state) : ""}`; + } + function excelMode(state) { + const sheet = state.project.quantitySheets?.find((s) => s.Code === state.quantitySheet); + if (!sheet) throw Error("수량산출서를 고르세요."); + const on = sheet.excel?.length && !sheet.excelOff; + if ( + !confirm( + on + ? "일반형식으로 바꾸시겠습니까? 엑셀 내용은 보관됩니다." + : "엑셀형식으로 바꾸시겠습니까?", + ) + ) + return; + EstApp.change(() => { + if (on) sheet.excelOff = true; + else { + sheet.excel ||= [{ name: "Sheet1", cells: {} }]; + sheet.excelLinks ||= {}; + delete sheet.excelOff; + } + sheet.excelEdited = true; + }, false); } return { copy, move, mark, free, excelView, matches, selector, handle };