diff --git a/tools/est-test/PLAN.md b/tools/est-test/PLAN.md index 466d20862..5a8fb0216 100644 --- a/tools/est-test/PLAN.md +++ b/tools/est-test/PLAN.md @@ -489,6 +489,7 @@ 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] 사용위치 검색 창(원본 TfrmUsesDataSerch btnSerch·btnAllDisplay) — 현재 표 항목을 품명·규격(빈칸·|·괄호 무시)으로 거르고 골라 사용위치 보기. 검증완료: 바인딩 통과, ORCA 브라우저에서 노임 9개 → 「보 통」 1개 → 보통인부 사용위치 11곳. - [x] 인쇄양식 불러오기·저장하기(원본 mnuPrintFormatLoad·Save 0x10ed318·0x10ed000 — spec_pc §3) — .pfot(인쇄정보표 MIDAS 이진) 읽기·쓰기 `print-format.cjs`(설명 BLOB·빈 칸 표지까지 보존, 원본 파일 그대로 다시 쓰면 바이트 같음). 불러오면 공사 인쇄표를 그 값으로, 저장은 지금 인쇄표를 원본 설치 main.pfot 필드 설명자 위에(`EST_PFOT_TEMPLATE`). .gfot(cxGrid 열 배치)는 웹 격자와 호환되지 않아 하지 않음. - 검증완료: `test_est_print_format.py`(설치 .pfot 두 개 바이트 같음·고친 값 반영) 및 바인딩 시험 통과, 서버 경로로 읽고 다시 쓴 파일 cmp 같음. ORCA 브라우저에서 샘플 인쇄양식 저장(32,755 바이트). - [x] 엑셀데이타를 EST로 변환 7개 탭(원본 TfrmExcelToEst 0x109c3bc — spec_pc §1) — 노임·자재·견적·표준시장·단가산출·일위대가·내역서 탭마다 시트명·시작/끝행·필드별 열 글자(.xlsx·.xls), 노임 → 자재 → 견적 → 표준 → 단산 → 일위 → 내역 차례로 새 공사(현재 원가 서식, 자동계산 끔 — Excel 값 그대로). 셀 규칙(Trim·줄바꿈·앞 「.」·㎡/㎥·「*」→「×」·쉼표·노무비율 ×100·「B:D」 이어붙임), 노임 단가 → Cost1·TC, 견적·표준 → O 칸 함께, 빈 코드 N+10자리, 내역 36행 채움. 단가산출·일위대가 머리 줄 꼴로 호표 만들기(코드·TitleCode·Index·LineData 품명/규격/단위 표지, [합계] 줄 지움), 못 읽은 시트 안내. 하지 않음: 글자 굵기 판정·고정폭 머리말·단가산출 목록 시트형(굵기·폭 정보 없음). diff --git a/tools/est-test/index.html b/tools/est-test/index.html index 13a7cf025..05c27ada2 100644 --- a/tools/est-test/index.html +++ b/tools/est-test/index.html @@ -316,6 +316,7 @@ > { EstApp.render(); } - function handle(name, state) { + // 사용위치 검색 창(TfrmUsesDataSerch btnSerch·btnAllDisplay): 현재 표 항목을 품명·규격(빈칸·|·괄호 무시)으로 거르고 골라 사용위치 보기 + function usesList(state, word) { + const rows = state.project.tables[state.view]; + if (!rows) throw Error("자료 화면에서 쓰세요."); + const norm = (x) => String(x ?? "").replace(/[\s|()]/g, ""), + w = norm(word), + { esc } = EstApp; + const list = rows + .map((r, i) => [r, i]) + .filter( + ([r]) => (r.Name || r.Code) && (!w || norm(r.Name).includes(w) || norm(r.Size).includes(w)), + ) + .slice(0, 300); + EstApp.showDialog( + "데이터 사용위치 검색", + `
${list.map(([r, i]) => ``).join("")}
${esc(r.Code ?? "")}${esc(r.Name ?? "")}${esc(r.Size ?? "")}
`, + ); + } + + function handle(name, state, node) { + if (name === "uses-list" || name === "uses-list-all") { + usesList(state, ""); + return true; + } + if (name === "uses-list-search") { + usesList(state, document.querySelector("[data-uses-word]")?.value || ""); + return true; + } + if (name === "uses-list-pick") { + EstExtra.showUsesSearchDialog(state.project.tables[state.view][Number(node.dataset.i)]); + return true; + } if (name === "pfot-load" || name === "pfot-save") { pfot(name, state).catch((error) => { state.notice = error.message;