knowledge(경쟁사): 변경설계 계산모드 실증 · 진행률 장부 신설

T9 확정 — 계류보전 2025(변경) 의 공사원가계산서가 당초·변경·증감을 나란히
내는 것을 찾아 가름. 직접노무비가 +8,802,162 늘었는데도 건강보험료·
노인장기요양보험료·연금보험료는 증감 0 임.

- 재계산 모드: 간접노무비·산재·고용. 요율은 당초와 같고 변경 밑수로 다시
  계산하면 원 단위로 일치
- 당초액 유지 모드: 건강·장기요양·연금. 사후정산 대상이라 설계 단계에서
  당초액을 그대로 가져감. 재계산했다면 85만 원이 더 붙었을 것
- 전부 재계산으로 구현하면 그만큼 틀림

곁들여 출력 시트가 21종이 아니라 30종이었음. 설계변경 시트 3종이 있어
「변경 출력이 표본에 없다」던 앞선 서술이 틀렸음.

문서 19(진행률 장부) 신설 — 원천별로 파일·표·시트를 실제로 세어 진행률과
남은 것을 적음. 계수 스크립트 추가.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Prk9BCHG1EMAywk9k8wegA
This commit is contained in:
2026-09-13 13:38:06 +09:00
co-authored by Claude Opus 5
parent 94a9412ac8
commit 46dc94af70
5 changed files with 203 additions and 1 deletions
@@ -25,6 +25,7 @@
| 16 골든셋 회귀 결과 | **원가계산을 다시 세워 원 단위로 맞춘 실증** — 프로젝트 6건 전 항목 일치 | (저장소 파일) |
| 17 단가조립 검증 | **일위대가·중기 시간당 사용료 구조와 손료율 실측** | (저장소 파일) |
| 18 누락 계산로직 점검 | **사슬에 빠진 칸 찾기** — 노임 환산식·단가산출 Q식·설정 스냅샷·집계표 반올림 | (저장소 파일) |
| 19 진행률 장부 | **어디까지 봤고 무엇이 남았나** — 원천별 실측 진행률, 차단점 현황 | (저장소 파일) |
> **정본은 저장소 파일이다** — `resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/`.
> 위 Orca 링크는 보기용이며, 문서를 지식DB 자리로 옮기면서 주소가 한 번 바뀌었다.
@@ -68,6 +69,7 @@
| 단가산출 `D`코드 | **문서에 없었음** | **A**`Q=3600qKfE/Cm`, 성분 = 절사(시간단가/Q, 소수1) | 18번 §2.2 |
| 계산 설정 스냅샷 | 「화면 없이 재현 불가」 | **출력 XLSX `〓 INITIAL 〓` 에 있음** | 18번 §2.3 |
| 집계표 행 금액 | 서술만 | **A** — 사사오입 100%. 호표 성분 소계(절사)와 다른 자리 | 18번 §2.4 |
| 변경설계 간접비 모드 | 「모드가 여럿」까지만 | **A 실증** — 건강·장기요양·연금은 **당초액 유지**, 나머지는 재계산 | 19번 §6, 08번 §2 |
분석일: 2026-09-13
대상: `C:\경영정보(주)`
@@ -82,7 +82,24 @@ STC에는 두 형태가 동시에 확인된다.
- 비교표는 `original`, `previous`, `current`, `delta`를 모두 계산한다.
- 삭제 항목은 물리 삭제하지 않고 현재 차수에 0/제외 상태로 남겨 코드 대응을 보존한다.
- 신규 항목은 안정적인 내부 ID와 차수별 표시 순서를 가진다.
- 간접비 항목마다 `recalculated`, `proportional_from_original`(방법 A), `delta_times_rate`(방법 B), `carry_original`, `manual`을 **계산모드 값으로 저장**한다. 절사 비선형성 때문에 모드가 다르면 원 단위 결과가 갈리므로, 모드를 하나로 고정하면 STmate 결과를 재현할 수 없다.
- 간접비 항목마다 `recalculated`, `proportional_from_original`(방법 A), `delta_times_rate`(방법 B), `carry_original`, `manual`을 **계산모드 값으로 저장**한다.
### 실데이터로 확인된 모드 — A등급 (2026-09-13)
계류보전 2025(변경)의 `공사원가계산서`는 당초·변경·증감을 나란히 낸다. **직접노무비가 `32,976,276 → 41,778,438`(+8,802,162)로 늘었는데 세 항목은 증감이 0이다.**
| 항목 | 당초 | 변경 | 증감 | 재계산했다면 | 모드 |
|---|---:|---:|---:|---:|---|
| 간접노무비 | 4,715,607 | 5,974,316 | +1,258,709 | 5,974,316 ✅ | `recalculated` |
| 산재보험료 | 1,341,831 | 1,699,998 | +358,167 | 1,699,998 ✅ | `recalculated` |
| 고용보험료 | 380,688 | 482,302 | +101,614 | 482,302 ✅ | `recalculated` |
| **건강보험료** | 1,328,500 | 1,328,500 | **0** | 1,683,108 | **`carry_original`** |
| **노인장기요양보험료** | 172,040 | 172,040 | **0** | 217,961 | **`carry_original`** |
| **연금보험료** | 1,686,389 | 1,686,389 | **0** | 2,136,526 | **`carry_original`** |
요율은 당초·변경이 같다(간접노무비 14.300%, 산재 3.560%, 고용 1.010%). 요율을 바꾼 것이 아니라 **항목마다 모드가 다르다.** 건강·장기요양·연금은 **사후정산 대상**이라 설계 단계에서 당초액을 그대로 가져간다 — §10의 「직접입력」 옵션이 이것이다.
**전부 재계산으로 두면 이 세 항목에서 85만 원이 어긋난다.** 모드를 하나로 고정하면 STmate 결과를 재현할 수 없다.
- Aislo 자체 기본값으로는 전 차수 독립 재계산(`recalculated`)을 권장하되, **STmate 호환 모드와 구분해서** 둔다.
## 3. 일괄 단가변경·물가변동
@@ -0,0 +1,121 @@
# 진행률 장부 — 어디까지 봤고 무엇이 남았나
갱신일: 2026-09-13
세는 법: 눈대중이 아니라 **파일·표·시트를 실제로 세어** 적음. 재현 스크립트 `40_스크립트/coverage_ledger.py`
## 1. 한눈에
| 원천 | 전체 | 본 것 | 남은 것 | 진행 |
|---|---:|---:|---:|---|
| 설치 폴더 `System` 파일 | 186 | 186 등록·형식·내부구조 | 암호화 13개는 **영구 불가** | ▓▓▓▓▓▓▓▓▓▓ 100% |
| 기준 요율표 `JB_*` | 43 | 43 전수 파싱·블록·확장차이 | 셀 좌표 일부 | ▓▓▓▓▓▓▓▓░░ 85% |
| 실무 프로젝트 `STC` | 7 | 7 전부 | — | ▓▓▓▓▓▓▓▓▓▓ 100% |
| STC 안의 표 | 16종 | **10종 읽고 씀** · 4종 빈 표 | **2종 암호화** (`BDQTY`·`SYSINFO`) | ▓▓▓▓▓▓▓▓▓░ 88% |
| STmate 출력 `XLSX` | 6 | 6 전부 | — | ▓▓▓▓▓▓▓▓▓▓ 100% |
| 출력 시트 | **30종** | **14종 계산 검증** · 1종 부분 | 15종 (목록·표지·변형 내역서) | ▓▓▓▓▓░░░░░ 48% |
| 계산 사슬 단계 | 8 | **8 전부** | — | ▓▓▓▓▓▓▓▓▓▓ 100% |
| 09번이 꼽은 호환성 차단점 | 6 | **3 해결 · 1 부분** | 2 (실행 필요) | ▓▓▓▓▓▓░░░░ 58% |
## 2. 설치 폴더 186개
| 갈래 | 개수 | 상태 |
|---|---:|---|
| PE 실행모듈 (`*.CPM`·`*.BPL`·`*.EXE`) | 82 | 헤더·섹션·임포트·문자열 전수. 핵심 12개는 호출자리까지 |
| ZIP 계열 (`*.STBSC` 등) | 28 | 컨테이너 확인, 내부는 암호 |
| JB 요율표 | 43 | **전수 파싱** — 형태·블록·2020-05-27 확장 차이 |
| 암호화 기준단가 (`*.BSC`·`*.CSTA`) | 13 | ⛔ **본문 암호화 — 영구 불가** |
| 기타 | 20 | 형식 판정 완료 |
⛔ 13개 안에 **자재 57,580건·노임 460건·중기 833건·표준시장단가 4,921건**이 들어 있다. 이것이 「완제품 복제 불가」의 유일한 근거다.
## 3. 출력 시트 30종 — 가장 많이 남은 곳
### ✅ 계산 검증 완료 14종
```
공사원가계산서 · 설계내역서 · 일위대가표 · 중기사용료 · 자재단가대비표
단가산출근거 · 환율및기초자료 · 〓 INITIAL 〓
재료비수량금액집계표 · 노무비수량금액집계표 · 경비수량금액집계표
설계변경내역서 · 설계변경금액대비표 · 설계변경증감대비표
```
### ◐ 부분 1종
`중기시간금액집계표` — 수량·단가·금액 열 위치를 못 맞춰 반올림 판정이 비어 있음.
### · 남은 15종 — 전부 **목록·표지·내역서 변형**
| 갈래 | 시트 |
|---|---|
| 색인·목록 (계산 없음) | 일위대가목록표 · 단가산출근거목록표 · 중기목록표 · 재료비목록표 · 노무비목록표 · 경비목록표 · 일식견적목록표 |
| 집계표 변형 | 일위대가수량금액집계표 · 단가산출근거수량금액집계표 · 일식견적수량금액집계표 |
| 내역서 변형 | 총괄설계내역서 · 총괄내역서 · 착공내역서 |
| 표지 | 〓 목 차 〓 · ※※안내※※ |
**새 계산 규칙이 나올 가능성은 낮다.** 집계표 변형 3종은 이미 확인한 집계표와 같은 반올림(사사오입)일 것으로 보이고, 내역서 변형 3종은 같은 값을 다른 묶음으로 낸 것이다. 다만 **확인은 안 했으므로 「확인 안 함」으로 센다.**
## 4. 계산 사슬 8단계 — 전부 확인
| # | 단계 | 근거 문서 |
|---:|---|---|
| ① | 일 노임 → 시간당 (설정식, 좌→우 순차) | 18번 §2.1 |
| ② | 중기 시간당 사용료 (손료·운전원·연료·잡품, 성분별 절사) | 17번 §3 |
| ③ | 단가산출 `D`코드 (`Q=3600qKfE/Cm`, 성분/Q 소수1 절사) | 18번 §2.2 |
| ④ | 일위대가 `B`코드 (구성 조립, 성분별 절사, 호표 간 참조) | 17번 §2·§5 |
| ⑤ | 내역 행 (`ROUNDDOWN(수량×단가)`) | 16번 |
| ⑥ | 계층 합산·제외금액 구역 | 16번 §4.1·§4.2 |
| ⑦ | 간접비 (밑수×요율, 행마다 절사, 앞 행 참조) | 16번 §3, 06번 §3 |
| ⑧ | 일반관리비 → 이윤 → 끝전조정 → 부가세 → 관급 → 총공사비 | 16번 §4.4 |
## 5. 호환성 차단점 여섯 — 현황
| # | 차단점 | 상태 | 근거 |
|---:|---|---|---|
| 1 | RATE 좌표 라벨·경계 | ◐ **부분** — 고정 칸(보험·산안비·이윤) 확정, 규모·기간 의존 칸은 남음 | 15번 §4 |
| 2 | `BDQTY` 세부 플래그 | ⛔ **암호화 — 불가** | 15번 §2 |
| 3 | 자재 자동채택 우선순위 | ✅ **최저가** | 17번 §5.5 |
| 4 | 중기 내부 절사 시점 | ✅ **성분별 절사** | 17번 §2 |
| 5 | UI 명령별 재계산 범위 | ⛔ 실행 필요 | 13번 T8 |
| 6 | 일괄변경 수동값 우선순위 | ⛔ 실행 필요 | 13번 T10 |
**추가로 09번 목록 밖에서 푼 것** — 변경설계 계산모드(아래 6장), 노임 환산식, 단가산출 Q식, 계산 설정 스냅샷, 집계표 반올림.
## 6. 변경설계 계산모드 — 이번에 확정 (T9)
계류보전 2025(변경) 프로젝트의 `공사원가계산서`**당초·변경·증감을 나란히** 낸다. 직접노무비가 `32,976,276 → 41,778,438`(+8,802,162)로 크게 늘었는데도 **세 항목은 증감이 0이다.**
| 항목 | 당초 | 변경 | 증감 | 재계산했다면 | 판정 |
|---|---:|---:|---:|---:|---|
| 간접노무비 | 4,715,607 | 5,974,316 | +1,258,709 | 5,974,316 ✅ | **재계산** |
| 산재보험료 | 1,341,831 | 1,699,998 | +358,167 | 1,699,998 ✅ | **재계산** |
| 고용보험료 | 380,688 | 482,302 | +101,614 | 482,302 ✅ | **재계산** |
| **건강보험료** | 1,328,500 | 1,328,500 | **0** | 1,683,108 (+354,608) | **당초액 유지** |
| **노인장기요양보험료** | 172,040 | 172,040 | **0** | 217,961 (+45,921) | **당초액 유지** |
| **연금보험료** | 1,686,389 | 1,686,389 | **0** | 2,136,526 (+450,137) | **당초액 유지** |
요율은 당초·변경이 같다(간접노무비 14.300%, 산재 3.560%, 고용 1.010%). 즉 요율을 바꾼 것이 아니라 **항목마다 모드가 다르다.**
**건강보험료·노인장기요양보험료·연금보험료는 사후정산 대상이라 설계 단계에서 당초액을 그대로 가져간다.** 11번 §10의 「보험료 사후정산 항목은 당초금액과 동일하게 직접 입력하는 옵션」이 실데이터로 확인됐다.
**재구현 필수** — 간접비 항목마다 `calc_mode ∈ {recalculated, carry_original, proportional_from_original, delta_times_rate, manual}` 을 저장할 것. 전부 재계산으로 두면 이 세 항목에서 **85만 원**이 어긋난다.
## 7. 남은 일 — 할 수 있는 것과 없는 것
### 지금 자료로 할 수 있는 것
| 순위 | 할 일 | 왜 |
|---:|---|---|
| 1 | 남은 시트 15종 훑기 | 새 규칙은 낮지만 **확인 안 한 칸을 0으로 만드는 값어치** |
| 2 | `중기시간금액집계표` 열 맞춰 반올림 판정 | 유일한 「부분」 |
| 3 | 일위대가 호표 **참조 그래프** 복원 → 위상순서 계산 재현 | ④단계를 실증으로 |
| 4 | 설계변경 **직접비 증감**까지 원 단위 재현 | 6장을 전 항목으로 넓힘 |
### 끝내 못 하는 것
| 무엇 | 왜 |
|---|---|
| 기초단가 원천 (자재 5.7만 건 등) | 본문 암호화 |
| `BDQTY` 수량 할증 | 본문 암호화 |
| UI 재계산 범위·일괄변경 우선순위 | **STmate 실행 필요 — 라이선스 없음** |
| 규모·기간 의존 요율 좌표 | 같음. 표본을 늘리면 좁혀지기는 함 |
| 수공 `S`·실적 `TA`/`SA` 형식 | **표본이 하나도 없음.** 그 형식 설계서가 한 건 생기면 바로 가능 |
@@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
"""진행률 장부 — 원천별로 무엇을 어디까지 봤나 실제로 센다."""
import sys, io, pathlib, zipfile, struct, re, warnings, collections
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
warnings.filterwarnings("ignore"); import openpyxl
SYS = pathlib.Path(r"C:\경영정보(주)\System")
PRAC = pathlib.Path(r"D:\aislo-wt\sub\resources\knowledge\original\실무문서")
# ── ① 설치 폴더 186개 ──
files = [p for p in SYS.rglob("*") if p.is_file()]
kinds = collections.Counter()
for p in files:
try: head = p.open("rb").read(2)
except Exception: head = b""
ext = p.suffix.upper()
if head == b"MZ": kinds["PE 실행모듈"] += 1
elif head == b"PK": kinds["ZIP 계열"] += 1
elif ext in (".JB_1",".JB_M",".JB_R",".JB_RA"): kinds["JB 요율표"] += 1
elif ext in (".BSC",".CSTA"): kinds["암호화 기준단가"] += 1
else: kinds["기타"] += 1
print("### ① 설치 폴더 `C:\경영정보(주)\System` 전체 %d" % len(files))
for k,v in kinds.most_common(): print(" %-16s %3d" % (k,v))
# ── ② 실무 STC ──
stcs = sorted(PRAC.rglob("*.STC"))
tabset = collections.Counter()
for s in stcs:
try: z = zipfile.ZipFile(s)
except Exception: continue
for n in z.namelist():
if n.upper().endswith(".DBF"): tabset[n.upper()] += 1
print("\n### ② 실무 프로젝트 STC %d건, 담긴 표 %d" % (len(stcs), len(tabset)))
# ── ③ STmate 생성 XLSX 시트 ──
sheets = collections.Counter(); nx = 0
for p in PRAC.rglob("*.xlsx"):
if p.name.startswith("~$"): continue
try: wb = openpyxl.load_workbook(p, data_only=True, read_only=True)
except Exception: continue
if "공사원가계산서" not in wb.sheetnames: continue
nx += 1
for s in wb.sheetnames: sheets[s] += 1
print("\n### ③ STmate 생성 XLSX %d건, 시트 %d" % (nx, len(sheets)))
DONE_SHEET = {"공사원가계산서","설계내역서","일위대가표","중기사용료","자재단가대비표",
"환율및기초자료","단가산출근거","〓 INITIAL 〓",
"재료비수량금액집계표","노무비수량금액집계표","경비수량금액집계표"}
PART_SHEET = {"중기시간금액집계표"}
print(" %-24s %s" % ("시트","상태"))
for s,_ in sheets.most_common():
st = "✅ 계산 검증" if s in DONE_SHEET else ("◐ 부분" if s in PART_SHEET else "· 미확인(목록·표지)")
print(" %-24s %s" % (s[:24], st))
d=len(DONE_SHEET & set(sheets)); pt=len(PART_SHEET & set(sheets))
print(" → 계산 검증 %d / %d 시트 (부분 %d)" % (d, len(sheets), pt))
DONE_TAB = {"BOQ11.DBF","BOQ12.DBF","COSTN.DBF","PRJLST.DBF","RATE.DBF","RATE_M.DBF",
"RATE_R.DBF","RATE_RA.DBF","RATE_A.DBF","RATE_B.DBF","SET_REP.DBF","KONGJONG.DBF"}
print("\n STC 표별 상태")
for t,c in sorted(tabset.items()):
st = "✅ 읽고 씀" if t in DONE_TAB else ("⛔ 암호화" if t in ("BDQTY.DBF","SYSINFO.DBF") else "· 빈 표/미사용")
print(" %-16s %d%s" % (t, c, st))
@@ -44,6 +44,7 @@
| 16 | **골든셋 회귀 결과** — 원가계산을 다시 세워 원 단위로 맞춘 실증 |
| 17 | **단가조립 검증** — 일위대가·중기 시간당 사용료 구조, 손료율 실측 |
| 18 | **누락 계산로직 점검** — 노임 환산식·단가산출 Q식·설정 스냅샷 |
| 19 | **진행률 장부** — 어디까지 봤고 무엇이 남았나 |
## 확정된 굵직한 것