- spreadsheet_actions(키 · 메뉴 → 이름) + actions_run(몸통 · 늦게): Ctrl+Shift++ · Ctrl+- (행 · 열 통째면 바로) · F5 · Ctrl+G · Ctrl+9/0 · Ctrl+Shift+9/0 · Ctrl+B/I/U/5 · Ctrl+Shift+& · Ctrl+Shift+_ · Ctrl+; · Ctrl+PageDown/PageUp · Shift+F11 · Shift+Alt+→/← - [데이터 ▾] 에 이동 · 틀 고정 ▸ · 칸 넣기/지우기 · 텍스트 나누기 · 중복 제거 · 연속 채우기 · 윤곽 ▸ - 식 편집 중 F4 참조 $ 돌리기(cycleAbs) · 접힌 묶음 행 · 열은 방향키가 건너뜀 - 크기: 수식 분석 · 자동 필터 · 찾기 패널을 처음 쓸 때 불러옴 — 화면 27.0 KB · 합 60.9 KB - M02 [스프레드시트 시험] ORCA 수치 확인 · D 규칙 시험 9 통과 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L6KXAabDTenEU7hrDQmCKY
128 lines
4.6 KiB
JavaScript
128 lines
4.6 KiB
JavaScript
/* 스프레드시트 D 순수 규칙 시험 도우미 — 고름 · 입력 글 규칙 · 가리키기 자리 · 채우기 끌기 목표.
|
|
* pytest(test_spreadsheet_d_input.py)가 부르고 결과 JSON 을 판정. */
|
|
const path = require("path");
|
|
const { load, SS } = require("./helper_spreadsheet_d_bundle.cjs");
|
|
|
|
const sel = load(path.join(SS, "spreadsheet_selection.ts"));
|
|
const ed = load(path.join(SS, "spreadsheet_editor.ts"));
|
|
const mouse = load(path.join(SS, "spreadsheet_mouse.ts"));
|
|
const addr = load(path.join(SS, "spreadsheet_address.ts"));
|
|
const sample = require(path.join(SS, "spreadsheet_sample.json"));
|
|
|
|
const s1 = sample.시트[0];
|
|
const a1 = (s) => `${addr.toA1(s.활성.r, s.활성.c)}|${addr.rangeToA1(s.범위[0])}`;
|
|
const cell = (r, c) => sel.selectCell(s1, r, c);
|
|
const keys = (start, list) => {
|
|
let s = start;
|
|
return list.map(([dr, dc, o]) => a1((s = sel.move(s1, s, dr, dc, o || {}))));
|
|
};
|
|
|
|
const out = {
|
|
// 병합 C4:F4 안을 누르면 병합 전체 · 활성은 왼위
|
|
mergeClick: a1(cell(3, 4)),
|
|
// 병합에서 오른쪽 → G4 · 왼쪽 → B4
|
|
mergeMove: keys(cell(3, 2), [
|
|
[0, 1],
|
|
[0, -1],
|
|
[0, -1],
|
|
]),
|
|
// Shift+→ 두 번(병합 걸침) · Shift+← 줄임 · Shift+↓
|
|
shiftExtend: keys(cell(3, 0), [
|
|
[0, 1, { extend: true }],
|
|
[0, 1, { extend: true }],
|
|
[0, -1, { extend: true }],
|
|
[1, 0, { extend: true }],
|
|
]),
|
|
// Ctrl+↓ 값 뭉치 끝 → 시트 끝 · Ctrl+↑ 되돌아 값
|
|
ctrlJump: keys(cell(2, 0), [
|
|
[1, 0, { jump: true }],
|
|
[1, 0, { jump: true }],
|
|
[-1, 0, { jump: true }],
|
|
]),
|
|
// 숨긴 열 J 건너뜀(I → K)
|
|
hiddenSkip: keys(cell(0, 8), [[0, 1]]).map((x) => x.split("|")[0]),
|
|
// 열 머리 C — 병합 C3:F3 걸쳐 C:F
|
|
colHead: addr.rangeToA1(sel.selectCols(s1, 2, 2).범위[0]),
|
|
// 고름 안 Enter 돌기(열 먼저) · Tab(행 먼저)
|
|
cycleEnter: (() => {
|
|
let s = {
|
|
시트: "s1",
|
|
범위: [{ r0: 10, c0: 10, r1: 11, c1: 11 }],
|
|
활성: { r: 10, c: 10 },
|
|
기준: { r: 10, c: 10 },
|
|
};
|
|
return [1, 1, 1, 1].map(() => addr.toA1((s = sel.cycle(s1, s, 1, 0)).활성.r, s.활성.c));
|
|
})(),
|
|
cycleTab: (() => {
|
|
let s = {
|
|
시트: "s1",
|
|
범위: [{ r0: 10, c0: 10, r1: 11, c1: 11 }],
|
|
활성: { r: 10, c: 10 },
|
|
기준: { r: 10, c: 10 },
|
|
};
|
|
return [1, 1, 1].map(() => addr.toA1((s = sel.cycle(s1, s, 0, 1)).활성.r, s.활성.c));
|
|
})(),
|
|
cycleSingle: sel.cycle(s1, cell(3, 2), 1, 0),
|
|
usedEnd: addr.toA1(sel.usedEnd(s1).r, sel.usedEnd(s1).c),
|
|
// 입력 글 → 칸
|
|
textToCell: ["12", "1,234.5", "50%", "-1e3", "true", "'=12", "=", "=A1+1", "", "1,23", "abc"].map(
|
|
(t) => ed.textToCell(t, { 서식: 4 }),
|
|
),
|
|
textToCellNoStyle: ed.textToCell("", {}),
|
|
cellToText: [
|
|
{ 값: "=12" },
|
|
{ 값: "12" },
|
|
{ 값: "abc" },
|
|
{ 값: 1.5 },
|
|
{ 값: false },
|
|
{ 식: "A1*2" },
|
|
undefined,
|
|
].map((c) => ed.cellToText(c)),
|
|
// 참조 넣을 자리
|
|
insertable: [
|
|
["=", 1],
|
|
["=A1+", 4],
|
|
["=A1", 3],
|
|
["=SUM(", 5],
|
|
["=SUM(A1,", 8],
|
|
["=1 + ", 5],
|
|
["abc", 3],
|
|
["=A1+B", 4],
|
|
].map(([t, p]) => ed.insertableAt(t, p)),
|
|
// 참조 색 — 같은 글은 같은 색 · 다른 시트
|
|
highlights: ed
|
|
.refHighlights("=A1+B2:C3*A1+치수!B1", "s1", (n) => (n === "치수" ? "s2" : null))
|
|
.map((h) => `${h.시트}:${addr.rangeToA1(h.범위)}:${h.색번호}`),
|
|
// 함수 자동 완성 · 인자 도움말 자리
|
|
hint: ["=su", "=A1+ro", "=A1", "=ROUND(B5,", "=SUM(A1,MAX(1,2),", '=IF(A1=",",', "abc"].map((t) =>
|
|
ed.formulaHint(t),
|
|
),
|
|
// 채우기 끌기 목표
|
|
fill: [[{ r: 9, c: 1 }], [{ r: 2, c: 6 }], [{ r: 3, c: 1 }], [{ r: 2, c: 1 }]].map(([p]) => {
|
|
const t = mouse.fillTarget({ r0: 1, c0: 1, r1: 3, c1: 2 }, p);
|
|
return [addr.rangeToA1(t.target), t.clear && addr.rangeToA1(t.clear)];
|
|
}),
|
|
// F4 참조 $ 돌리기 — 네 번이면 제자리 · 범위 두 끝 · 시트 이름 · 참조 밖이면 null
|
|
abs: (() => {
|
|
const seq = [];
|
|
let t = { text: "=A1+B2", caret: 3 };
|
|
for (let i = 0; i < 4; i++) seq.push((t = ed.cycleAbs(t.text, t.caret)).text);
|
|
const range = ed.cycleAbs("=SUM(Sheet2!A1:B3)", 10);
|
|
return [
|
|
...seq,
|
|
`${range.text}|${range.caret}`,
|
|
ed.cycleAbs("=SUM(1)", 5),
|
|
ed.cycleAbs("A1", 1),
|
|
];
|
|
})(),
|
|
// 접힌 묶음 행 건너뜀(2 → 5)
|
|
foldSkip: (() => {
|
|
const s = {
|
|
...s1,
|
|
행: { ...s1.행, 3: { 묶음: { 층: 1, 접힘: true } }, 4: { 묶음: { 층: 1, 접힘: true } } },
|
|
};
|
|
return addr.toA1(sel.move(s, sel.selectCell(s, 1, 11), 1, 0).활성.r, 11);
|
|
})(),
|
|
};
|
|
console.log(JSON.stringify(out));
|