- 요율 화면 오른쪽 위 보기 단추 둘(기본 시트 · 세션 기억) — 한 번에 하나만 보임 - 우클릭: 리스트 줄 「시트에서 보기」 · 시트 칸 「리스트에서 보기」 · 대응 없으면 흐림 + 대응 요율 없음(메뉴 부품에 disabled 항목 · 시트 부품에 cellMenu 옵션) - 시트 칸 → RT 줄 찾기 순수 함수(UI_RateSheet_Map.ts) · 병합 칸 보정 · 겹치면 좁은 범위 - 책 대응 범위를 상자 표제 칸까지 넓힘(RT000004 값 칸 BR51 누락 바로잡음) — 값 · RT 정본 그대로 - 대조 스크립트 audit_요율대조.py(RT 잎 216 · 시트 칸 없음 8 · 시트에만 있는 칸 1 · B09 사용 표시) - 시험: test_805_1_rate_views 신설 · test_798_1 대응표 전수 추가 · 옛 「줄 누르면 이동」은 우클릭 메뉴로 대체 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
53 lines
1.7 KiB
TypeScript
53 lines
1.7 KiB
TypeScript
/* =============================================================================
|
|
* M01_MasterData_UI_RateSheet_Map.ts
|
|
* 요율 화면 시트 칸 → RT 줄 찾기 (805-1) — 순수 계산 · 화면 · fetch 없음.
|
|
* 책의 `대응`(RT 키 → 시트 · 첫 칸 · 칠할 범위)을 거꾸로 읽음. 겹치면 가장 좁은 범위(RT000007 ⊂ RT000006).
|
|
* 병합 칸 안쪽은 병합의 왼쪽 위 칸으로 바꿔 찾음(예 고용보험 7등급 AH79:AT82).
|
|
* ========================================================================== */
|
|
|
|
export interface RateSpot {
|
|
시트: string;
|
|
칸: string;
|
|
범위: string;
|
|
}
|
|
|
|
export interface RateArea {
|
|
r0: number;
|
|
c0: number;
|
|
r1: number;
|
|
c1: number;
|
|
}
|
|
|
|
export type ParseArea = (a1: string) => RateArea | null;
|
|
|
|
const inside = (a: RateArea, r: number, c: number): boolean =>
|
|
r >= a.r0 && r <= a.r1 && c >= a.c0 && c <= a.c1;
|
|
|
|
/** 시트 id · 행 · 열(0 부터) → RT 키 · 대응 없으면 null. `merges` = 그 시트의 병합 A1 목록. */
|
|
export function keyAt(
|
|
spots: Record<string, RateSpot>,
|
|
parse: ParseArea,
|
|
merges: readonly string[] | undefined,
|
|
sheetId: string,
|
|
row: number,
|
|
col: number,
|
|
): string | null {
|
|
let [r, c] = [row, col];
|
|
for (const text of merges ?? []) {
|
|
const m = parse(text);
|
|
if (m && inside(m, r, c)) {
|
|
[r, c] = [m.r0, m.c0];
|
|
break;
|
|
}
|
|
}
|
|
let best: string | null = null;
|
|
let bestSize = Infinity;
|
|
for (const [key, spot] of Object.entries(spots)) {
|
|
const a = spot.시트 === sheetId ? parse(spot.범위) : null;
|
|
if (!a || !inside(a, r, c)) continue;
|
|
const size = (a.r1 - a.r0 + 1) * (a.c1 - a.c0 + 1);
|
|
if (size < bestSize) [best, bestSize] = [key, size];
|
|
}
|
|
return best;
|
|
}
|