📝 한글 매크로 30종 사용설명서2026-09-29 · 엑셀과 한글 매크로 · 엑셀 매크로 →

한글 매크로 30종 — 단축키 하나로 끝나는 한글 업무

요일 자동 입력, 산출기초 계산, 표 계산·정렬·정리, 금액 한글 표기, 개인정보 마스킹, 좌석표까지. 매크로등록기로 두 단계면 어떤 한글 버전(2018~2024)에도 설치됩니다.

소개 영상설치(2단계)인터넷에서 받은 파일 실행매크로 30종 목록추천 단축키내려받기소스 복사·분석매크로별 사용법 영상자주 묻는 질문

1.소개 영상 (2분)

추천 매크로 22종을 단축키 순서로 시연합니다(화면은 한글 2024). 엑셀 매크로 소개 영상은 엑셀 매크로 페이지에 있습니다.

2.설치 — 매크로등록기 두 단계

매크로등록기
  1. 한글을 완전히 닫습니다. (한글이 켜져 있으면 저장소가 덮어써지지 않습니다)
  2. 한글매크로등록기.exe 실행 → [① 폴더에서 자동 등록 (불러오기)] → 내려받은 한글매크로_추천순서_msr 폴더(01_~30_ 파일)를 고르면 순서대로 슬롯(=단축키)에 등록됩니다.
  3. [② 한글에 설치 + 리본 메뉴 등록 (모든 버전)] 한 번 → 매크로 저장소를 한글 2018·2020·2022·2024 파일로 함께 만들고, 리본에 「한글매크로」 탭까지 넣습니다(기존 파일은 backup 폴더에 자동 백업).
  4. 한글을 켜서 Alt+Shift+L(매크로 실행) 목록에 30개가 보이면 성공. 리본 맨 오른쪽 「한글매크로」 탭에서 마우스로도 실행할 수 있습니다.

슬롯 0~10 = Alt+1~9,0,- / 11~21 = Alt+Shift+1~9,0,- / 22~29 = 실행 창(Alt+Shift+L)에서 이름 선택. 줄을 끌거나 ▲▼로 순서를 바꾸면 단축키가 바뀝니다.

한글 리본 한글매크로 탭

한글 폴더를 못 찾을 때 — [한글 폴더 설정...]

등록기 창 맨 아래 줄이 '한글 매크로 저장소: … (확인됨)' 이면 그대로 진행합니다. '(파일 없음)' 이면 [한글 폴더 설정...] 을 눌러 %AppData%\Hnc\User\Hwp 안의 HWPWMko-KR130.HMI(2024) / KR120(2022) / KR110(2020) 파일을 고릅니다(선택은 기억됨). 파일이 하나도 없으면 한글에서 Alt+Shift+H로 아무 매크로나 하나 저장하면 생깁니다.

한글 2024가 아니어도

[②]가 버전별 저장소 파일을 전부 만들어 두므로 2022·2020도 같은 방법입니다. 2018 이하는 매크로만 설치되고 리본 탭은 수동(도구 → 사용자 설정)입니다.

설치 영상 — 등록기 사용 · 한글에서 hmi 불러오기 · 리본 「한글매크로」 탭

설치 ① 매크로등록기 — 매크로 고르고 순서 정하기
드래그·▲▼ 로 순서(=단축키)를 정하고 버튼 하나로 저장

  • 매크로등록기.exe 를 열면 지금 한글에 설치된 매크로가 슬롯 0~29 순서대로 보입니다(글자·버튼을 크게 했습니다).
  • [① 폴더에서 자동 등록] → 매크로\추천매크로순서 폴더를 고르면 01_~30_ 파일 순서대로 슬롯(=단축키)에 자동 등록됩니다.
  • 줄을 끌어서(또는 ▲ 위로 / ▼ 아래로) 순서를 바꾸면 단축키가 바뀝니다.
  • [② 한글에 설치 + 리본 메뉴 등록 (모든 버전)] → 한글을 완전히 닫고 한 번 누르면 매크로 저장소(2018·2020·2022·2024 파일 함께)와 리본 「한글매크로」 탭이 같이 만들어집니다(백업은 backup\).
  • 저장소 위치는 %AppData% 환경변수로 자동 인식(사용자 이름·드라이브가 달라도 됨). 창 아래 '(확인됨)' 표시를 확인하고, 아니면 [한글 폴더 설정...] 으로 HWPWMko-KR***.HMI 를 고르세요(아래 [한글 폴더 설정...] 안내).

설치 ② 한글에서 통합 매크로 파일(.hmi) 불러오기
Alt+Shift+L → 폴더 아이콘 → 파일 형식 hmi → 파일 선택

  • 한글에서 Alt+Shift+L (도구 → 매크로 → 매크로 실행) 을 누릅니다.
  • 창 아래쪽 폴더 아이콘(불러오기)을 누르면 [매크로 불러오기] 창이 열립니다.
  • 파일 이름 칸에 %AppData%\Hnc\User\Hwp 를 넣고 Enter 하면 한글 매크로 폴더로 갑니다.
  • 파일 형식을 '통합 매크로 꾸러미 파일 (*.hmi)' 로 바꾸면 통합매크로.hmi 가 보입니다.
  • 선택 → [열기] 하면 매크로 목록이 통째로 바뀝니다. 기존 매크로를 남기려면 먼저 꾸러미 저장(디스켓 옆 아이콘)으로 백업.
  • 영상에서는 저장소를 바꾸지 않기 위해 마지막에 취소했습니다.

설치 ③ 한글 리본 「한글매크로」 탭
등록기 [② 한글에 설치 + 리본 메뉴 등록] 한 번이면 리본 탭까지 — 그룹별로 매크로 이름 그대로 버튼, 마우스만으로 실행

  • 한글을 닫고 등록기에서 [② 한글에 설치 + 리본 메뉴 등록] → 한글 리본 맨 오른쪽에 「한글매크로」 탭이 생깁니다.
  • 탭 안: A-서식 · B-계산 · C-표계산 · D-표정리 순서로 슬롯 0~21 의 매크로 22개가 이름 그대로 버튼(그룹 사이 구분선).
  • 버튼 = 단축키와 같은 실행. 영상: 날짜 줄에서 [요일입력], 표에서 [오름내림차순정렬].
  • 저장 위치 %AppData%\HNC\User\UxXml\130\Hancom2016\Hwp\Hwp_frame.xml (2022는 120), 원본은 backup\ 에 보관. 슬롯 22~29 는 리본 명령이 없어 올라가지 않음.
  • 파일이 없는 PC(리본을 바꾼 적 없음)는 한글 → 도구 → 사용자 설정 → [새 탭] → [설정] 한 번 뒤 다시 누르세요.

매크로등록기 버튼별 기능 (11개)

버튼 이름을 누르면 이 PC에서 버튼을 실제로 눌러 녹화한 영상과 설명이 열립니다(영상 위 띠: 버튼 이름과 하는 일).

1. [현재 설치 상태 다시 불러오기] — 한글에 지금 설치된 매크로 목록을 다시 읽습니다

이 버튼은 화면에서 바꾼 순서·추가는 버리고, 실제 설치된 상태로 되돌립니다.

누르면

  1. [현재 설치 상태 다시 불러오기] 클릭
  2. 확인 창 [예]

결과 목록 '(기존 설치)'.

2. [① 폴더에서 자동 등록] — 매크로 폴더를 고르면 01_~30_ 파일 순서대로 슬롯에 등록합니다

이 버튼은 파일 이름 앞 번호 순서 = 슬롯 = 단축키(Alt+1…).

누르면

  1. [① 📂 폴더에서 자동 등록] 클릭
  2. 폴더 선택(추천매크로순서)
  3. [예] 목록을 비우고 다시 채움

결과 슬롯 0~29에 30종이 등록됩니다.

3. [▲ 위로] — 고른 줄을 한 칸 위로 — 단축키가 바뀝니다

이 버튼은 목록에서 줄을 고르고 누릅니다(줄을 마우스로 끌어도 됨).

누르면

  1. 슬롯 줄 선택
  2. [▲ 위로] 클릭

결과 슬롯 번호(=단축키)가 하나 앞으로.

4. [▼ 아래로] — 고른 줄을 한 칸 아래로 옮깁니다

이 버튼은 자주 쓰는 매크로는 위(Alt+1~)로, 가끔 쓰는 것은 아래로.

누르면

  1. 슬롯 줄 선택
  2. [▼ 아래로] 클릭

결과 슬롯 번호가 하나 뒤로.

5. [선택 슬롯 비우기] — 고른 슬롯의 매크로를 목록에서 뺍니다

이 버튼은 필요 없는 매크로 자리를 비웁니다.

누르면

  1. 슬롯 줄 선택
  2. [선택 슬롯 비우기] 클릭

결과 그 슬롯이 빈칸이 됩니다(설치는 ②를 눌러야 반영).

6. [MSR 파일 추가...] — msr 파일을 골라 빈 슬롯에 넣습니다

이 버튼은 한 개씩 골라 넣을 때. 탐색기에서 목록으로 끌어 놓아도 됩니다.

누르면

  1. [MSR 파일 추가...] 클릭
  2. msr 파일 선택

결과 첫 빈 슬롯에 추가.

7. [통합 파일(.hmi) 저장...] — 지금 목록을 통합매크로.hmi 파일 하나로 저장합니다

이 버튼은 다른 PC에서는 한글 Alt+Shift+L → 폴더 아이콘으로 이 파일을 불러오면 됩니다.

누르면

  1. [통합 파일(.hmi) 저장...] 클릭
  2. 저장 위치 선택

결과 통합매크로.hmi.

8. [② 한글에 설치 + 리본 메뉴 등록] — 한글을 닫고 누르면 매크로 저장소와 리본 「한글매크로」 탭을 만듭니다

이 버튼은 한글 2018~2024 모든 버전 저장소 파일을 함께 쓰고, 기존 파일은 backup 폴더에 보관합니다.

누르면

  1. 한글 완전히 종료
  2. [② ⚡ 한글에 설치 + 리본 메뉴 등록] 클릭
  3. 확인 창 [예]

결과 설치 완료 안내 — 한글을 켜면 Alt+1… 과 리본 탭.

9. [한글 폴더 설정...] — 한글 매크로 저장소 파일(HWPWMko-KR***.HMI)을 직접 고릅니다

이 버튼은 다른 PC에서 '(파일 없음)'으로 나올 때. 보통 %AppData%\Hnc\User\Hwp 안에 있습니다.

누르면

  1. [한글 폴더 설정...] 클릭
  2. HWPWMko-KR***.HMI 선택

결과 고른 위치를 기억합니다.

10. [매크로 폴더 열기] — 한글 매크로 저장소 폴더를 탐색기로 엽니다

이 버튼은 backup 폴더의 예전 파일을 찾거나 직접 확인할 때.

누르면

  1. [매크로 폴더 열기] 클릭

결과 탐색기 창(저장소 폴더).

11. [전체 슬롯 비우기] — 목록의 모든 슬롯을 비웁니다

이 버튼은 처음부터 다시 고를 때.

누르면

  1. [전체 슬롯 비우기] 클릭
  2. 확인 창 [예]

결과 빈 목록(설치는 ②를 눌러야 반영).

%AppData%\Hnc\User\Hwp 폴더

▲ 탐색기 주소창에 %AppData%\Hnc\User\Hwp 를 붙여 넣으면 열리는 폴더 — HWPWMko-KR130.HMI 가 보이면 맞는 곳

다른 PC에 설치할 때 — 한글 매크로 폴더 찾기

경로는 PC마다 다르므로 %AppData%\Hnc\User\Hwp 로 찾습니다

  • 탐색기 주소창에 %AppData%\Hnc\User\Hwp 입력 → Enter. 이 PC는 C:\Users\user\AppData\Roaming\HNC\User\Hwp 이지만 다른 PC는 사용자 이름 부분이 다릅니다(한글 이름도 가능).
  • 찾을 파일: HWPWMko-KR130.HMI (한글 2024). 2022는 KR120, 2020은 KR110 — 숫자가 한글 버전입니다. Config130.json 이 같이 있으면 맞는 폴더입니다.
  • 매크로등록기는 이 폴더를 자동으로 찾고 숫자가 가장 큰 HMI 파일을 고릅니다. 창 아래 '(파일 없음)'이면 [한글 폴더 설정...] 으로 그 파일을 직접 선택(선택은 기억됨).
  • 폴더를 모르겠으면 한글에서 Alt+Shift+L → 폴더 아이콘(불러오기) → 대화상자 주소가 그 폴더입니다.

한글 2024 이하 버전일 때 — 매크로등록기 예시

파일 이름의 숫자가 한글 버전 — 등록기는 번호가 가장 큰 파일을 고릅니다

한글 버전내부 번호매크로 저장 파일 (%AppData%\Hnc\User\Hwp)리본 설정 파일 (%AppData%\HNC\User\UxXml)확인 상태
한글 202413.0HWPWMko-KR130.HMIUxXml\130\Hancom2016\Hwp\Hwp_frame.xml이 PC 실측 — ①② 모두 동작(영상은 이 버전)
한글 202212.0HWPWMko-KR120.HMI (같은 폴더)UxXml\120\Hancom2016\Hwp\Hwp_frame.xml이 PC 에 KR120 파일·UxXml\120 폴더 실재(2022·2024 공존) — ② 가 KR120 도 함께 만듦
한글 202011.0HWPWMko-KR110.HMI (같은 폴더)UxXml\110\… (파일 이름 확인)한컴 도움말: 개인 데이터 폴더\User\Hwp 에 저장 — ② 가 KR110 도 함께 만듦
한글 201810.0HWPWMko-KR100.HMI리본 자동 등록 미지원(수동)이름 규칙상 추정 — ② 가 KR100 도 만들지만 리본은 수동
NEO·2014 이하9.x 이하폴더·이름이 다름미지원등록기 [한글 폴더 설정...] 으로 직접 파일 지정 시도

한글 2022·2020 PC에 설치하기 — 차례대로 따라 하기

한글 2024가 아니어도 방법은 같습니다. 파일 이름의 숫자만 내 버전에 맞으면 됩니다

3.인터넷에서 받은 한글매크로등록기.exe 실행하기

Windows의 PC 보호

① 인터넷(140-245-77-55.sslip.io)에서 받은 한글매크로등록기.exe 를 처음 실행하면 Windows 가 'Windows의 PC 보호' 창을 띄웁니다(서명 없는 새 프로그램이라 나오는 안내). 창 안의 [추가 정보] 글자를 누릅니다.

실행 버튼

② [추가 정보] 를 누르면 아래에 [실행] 버튼이 나타납니다. [실행] 을 누르면 등록기가 열립니다. 한 번 실행하면 다음부터는 묻지 않습니다.

한글매크로등록기.exe 속성 — 차단 해제 체크

③ 실행이 계속 막히면 파일에서 마우스 오른쪽 → [속성] → 아래쪽 '차단 해제' 에 체크 → [확인]. 인터넷에서 받은 파일에 붙는 '차단' 표시를 푸는 것으로, 한글매크로등록기.exe 와 통합매크로.hmi 둘 다 해 두면 됩니다.

4.매크로 30종 목록 — 추천 순서(번호 = 파일 이름 앞 번호 = 단축키 순서)

번호매크로단축키그룹 코드무엇을 해 주나
01노란색Alt+1A-서식-10블록 잡은 글자에 노란 음영 + 빨간 글자(형광펜 대신) — 한 번 더 누르면 원래대로
02한셀입력Alt+2A-서식-09긴 글을 한 줄에 — 글자 크기는 그대로, 장평(최소 80%)·자간(최소 -10%)으로 맞추고, 그래도 넘치면 어절 단위 줄바꿈
03계산및합계Alt+3B-계산-01커서 줄만 계산, 여러 줄을 긁으면 각 줄 계산 + 윗줄에 합계 — 곱하기·나누기·더하기·빼기·괄호
04표머리두줄HY그래픽Alt+4A-서식-08표 양식 한 번에 — 제목 행 HY그래픽 굵게·회색 바탕·아래 이중선, 바깥 테두리 굵게
05표간격정리Alt+5A-서식-07표 열 너비를 내용에 맞게 — 순번·비고·숫자 열은 좁게, 글 열은 넓게, 표 너비는 그대로
06음수를세모로적용합계Alt+6C-표계산-08열의 음수를 모두 △로 바꾸고 합계까지
07번호재정렬Alt+7A-서식-04본문 전체의 1. 가. 1) 가) ① 계층 번호를 확인해 고치고(빨강), 표에서는 열을 자동 채우기로
08중복값색처리Alt+8D-표정리-02중복값을 묶음마다 다른 진한 색으로 표시합니다(한 번 더 누르면 검정으로)
09오름내림차순정렬Alt+9D-표정리-01한 번 누르면 오름차순, 한 번 더 누르면 내림차순 (14·15 통합)
10요일입력Alt+0A-서식-01날짜 뒤에 (요일)이 자동으로 붙습니다 — 2026. 10. 12. 도, 2026-10-12 · 2026/10/12 도
11개인정보마스킹Alt+-D-표정리-07명단의 이름·휴대전화·주민번호를 한 번에 가립니다 (신규)
12표위치확인및제거Alt+Shift+1C-표계산-09표 칸마다 주소([A1] [B2]…)를 빨간 안내문으로 — 계산식 값은 그대로, 칸을 골라 실행하면 고른 칸만
13표계산식적용및제거Alt+Shift+2C-표계산-10타이핑한 =C2/B2 같은 글자를 진짜 표 계산식으로 (적용) — 다시 실행하면 값만 남기고 계산식 제거
14선택셀표계산천원Alt+Shift+3C-표계산-01산출기초 칸에 커서만 두면 오른쪽 예산 칸이 채워집니다
15증감포함표계산천원Alt+Shift+4C-표계산-03예산(A)·예산(B)·증감·합계 행까지 한 번에
16합계행자동서식Alt+Shift+5D-표정리-05표의 합계 행을 굵게 + 위쪽 이중 실선(0.5mm)으로
17금액한글표기Alt+Shift+6A-서식-051,234,000원·1,234천원·12백만원 뒤에 (금일백이십삼만사천원) 처럼 한글 금액을 자동으로
18엑셀에서표데이터값복사Alt+Shift+7D-표정리-06엑셀에서 복사한 표를 붙여넣고 공백까지 정리
19글자수카운터Alt+Shift+8A-서식-06생기부 문장의 글자 수·바이트 수를 바로 확인합니다
20기간일수계산Alt+Shift+9A-서식-03'3. 2. ~ 3. 6.' 뒤에 (5일간) 을 자동으로 (신규)
21숫자자동콤마삽입Alt+Shift+0D-표정리-031400000 → 1,400,000, 천 단위 콤마를 한 번에
22표빈칸하이픈채우기Alt+Shift+-D-표정리-04표의 빈 칸을 한 번에 '-'로 채우고 가운데 정렬
23날짜표기통일실행 창(Alt+Shift+L)A-서식-022026-7-6, 2026/7/10, 2026.7.3 → 2026. 7. 6. 공문 표기로
24좌석표실행 창(Alt+Shift+L)E-좌석표-01명렬표(학년반·번호·이름) → 새 쪽에 교실 좌석표. 배치(5열25명/4열20명)와 출입문 좌/우를 예/아니요로
25전체열표계산천원실행 창(Alt+Shift+L)C-표계산-022027년·2026년처럼 산출기초가 여러 벌이면 한 번에 계산합니다
26중간합계증감포함표계산천원실행 창(Alt+Shift+L)C-표계산-04가./나. 그룹 중간합계와 전체 합계까지 한 번에
27구성비열채우기실행 창(Alt+Shift+L)C-표계산-05예산 열 옆에 구성비(%)를 자동으로 (신규)
28가로세로평균실행 창(Alt+Shift+L)C-표계산-06표 평균 한 매크로로 — [아니요] 가로: 행마다 평균을 마지막 열에 / [예] 세로: 커서 열의 평균을 마지막 행에
29등수정리실행 창(Alt+Shift+L)C-표계산-07점수 열 오른쪽에 등수를 채웁니다(동점은 공동 순위)
30전화번호서식통일실행 창(Alt+Shift+L)D-표정리-08전화번호를 010-1234-5678 로 통일하고, 같은 번호는 빨간색으로 (신규)

⚠ 페이지가 많은 문서(수십 쪽 이상)나 큰 표에서는 매크로 실행이 오래 걸릴 수 있습니다. 멈춘 것처럼 보여도 기다려 주세요 — 몇 분이 지나도 끝나지 않으면 자주 묻는 질문의 '매크로가 끝나지 않아요'를 보세요.
※ 표 매크로는 입력 커서가 있는 표 하나에만 적용됩니다. 문서의 다른 표는 그대로입니다.
※ 단축키가 없는 매크로(23~30번)는 Alt+Shift+L 로 [매크로 실행] 창을 열어 이름을 고르고 Enter 합니다.

5.추천 단축키 순서 (자주 쓰는 22종 = Alt·Alt+Shift)

순서는 등록기에서 마음대로 바꿀 수 있습니다. 실행이 안 되면 Alt+Shift+L 목록에 이름이 있는지, 커서가 표 안/밖 조건에 맞는지 먼저 확인하세요. 매크로 결과는 Ctrl+Z로 되돌릴 수 있습니다.

필요한 것만 골라 쓰세요 — 매크로등록기나 매크로선택.txt 에서 원하는 것만 담아 저장하면 됩니다.

2026-09-24 슬롯 30개 한도로 세 쌍을 하나로 합쳤습니다: 좌석표4열20명+5열25명 → 좌석표, 가로평균+세로평균 → 가로세로평균(방향을 예/아니요), 표계산식적용+다지우기 → 표계산식적용및제거(다시 실행하면 제거).

6.내려받기

한글매크로등록기.exe10.2 MB 추천순서 매크로 30개(.msr) zip722 KB 통합매크로.hmi(꾸러미)1.7 MB

소개 영상(mp4)9.0 MB 사용법(md)18 KB

한글매크로등록기.exe 11 MB(파이썬 Tk 프로그램, 설치 불필요) · 통합매크로.hmi 는 등록기 없이 한글 Alt+Shift+L → 불러오기(파일 형식 hmi)로도 넣을 수 있습니다.

7.매크로 소스 — 복사·다운로드·소스 분석(심화)

30종 매크로의 실제 소스(한글 스크립트 매크로, JScript)입니다. 배포 파일(.msr)에 든 코드와 똑같습니다. 단추 하나로 복사해 한글에 바로 붙여 넣거나, 매크로 하나만 .msr 파일로 받을 수 있습니다.

방법 1 · 복사해서 붙여넣기

  1. 원하는 매크로의 [전체 소스 복사]를 누릅니다(공통 라이브러리까지 한 번에 복사됩니다).
  2. 한글에서 [도구] → [매크로] → [매크로 정의](Alt+Shift+H)를 열고, 빈 번호(또는 바꿀 매크로)를 골라 이름을 매크로 이름(예: 계산및합계)으로 정합니다.
  3. [코드 편집]을 눌러 열린 편집 창의 내용을 모두 지우고(Ctrl+A) 붙여 넣은(Ctrl+V) 뒤 저장하고 닫습니다. 코드 속 함수 이름 OnScriptMacro_계산및합계의 뒷부분이 매크로 이름과 같아야 합니다.

방법 2 · .msr 파일로 넣기

  1. [.msr 다운로드]로 파일을 받습니다(한글 매크로 파일 그대로, 바이트 단위로 배포본과 같음).
  2. 한글 [도구] → [매크로] → [매크로 정의] → [불러오기]에서 받은 .msr 을 고릅니다. 30개를 한꺼번에 넣을 때는 위 내려받기의 매크로등록기가 편합니다.

한글 전역 스크립트 매크로는 30개(번호 0~29)까지만 문서를 실제로 바꿉니다. 이미 30개가 차 있으면 안 쓰는 매크로 하나를 지우고 넣으세요. 고치기 전에는 원래 코드를 메모장에 따로 저장해 두면 언제든 되돌릴 수 있습니다.

심화과정 — 매크로마다 [심화과정: 소스 분석]을 펼치면 블록별 동작, 핵심 한글 API(HAction · HParameterSet 등), 색·단위·범위를 바꾸는 방법이 나옵니다. 줄 번호를 누르면 소스의 그 줄로 바로 이동합니다. 대부분의 매크로 앞 1~660줄은 공통 라이브러리입니다.

01노란색 A-서식-10 Alt+1

블록 잡은 글자에 노란 음영 + 빨간 글자(형광펜 대신) — 한 번 더 누르면 원래대로

매크로 이름 노란색 · 전체 50줄(공통 라이브러리 없이 이 매크로만) · .msr 4 KB

.msr 다운로드 4 KB
소스 보기 (50줄)
심화과정: 소스 분석

블록으로 고른 글자에 노란 음영과 빨간 글자색을 한 번에 입히는 형광펜 대용 매크로입니다. 실행 전에 선택의 첫 글자 모양(음영색·글자색)을 읽어, 이미 칠해져 있으면 음영 없음·검정 글자로 되돌리는 토글 방식으로 동작합니다. 공통 라이브러리 없이 CharShape 액션 하나로 끝나는 50줄짜리 독립 매크로입니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 1~11줄① 색 상수 정의10줄 RGBColor(255, 255, 0) 이 노랑, RGBColor(255, 0, 0) 이 빨강입니다. RGBColor 는 R, G, B 순서로 받아 한글 내부 색 값(COLORREF, 0x00BBGGRR 의 BGR 순서)으로 바꿔 줍니다. 그래서 노랑은 내부적으로 0x0000FFFF, 빨강은 0x000000FF(=255)가 됩니다. 11줄의 4294967295(0xFFFFFFFF)는 '음영 없음'을 뜻하는 특수값이고, BLACK = 0 은 검정입니다.
  2. 13~19줄② 선택 범위를 기억하고 첫 글자만 다시 고르기CreateSet("ListParaPos") 로 위치 보관용 세트 두 개를 만들고, GetSelectedPosBySet(sset, eset) 로 블록의 시작·끝 위치를 저장합니다. 블록이 있으면 Cancel 로 선택을 풀고 SetPosBySet(sset) 로 시작점에 캐럿을 둔 뒤 MoveSelNextChar 로 첫 글자 한 개만 선택합니다. 서로 다른 모양이 섞인 선택에서는 한글이 글자 모양 값을 돌려주지 않을 때가 있어 첫 글자만 따로 읽는 것입니다.
  3. 20~25줄③ 첫 글자 모양 읽기와 원래 선택 복원HAction.GetDefault("CharShape", …) 를 부르면 선택한 글자의 현재 모양이 HCharShape 에 채워집니다. 21줄에서 ShadeColor == YELLOW 이고 TextColor == RED 이면 이미 칠한 곳(marked = true)으로 봅니다. 그다음 Cancel → 시작점 이동 → Select(블록 시작) → SetPosBySet(eset) 순서로 처음 선택을 그대로 다시 잡습니다.
  4. 26~30줄④ 블록이 없을 때와 파라미터 초기화블록 없이 실행하면(26-29줄) 캐럿 위치의 글자 모양으로 같은 판정을 합니다. 30줄에서 GetDefault 를 한 번 더 불러, 지금 선택(또는 캐럿) 기준의 글자 모양 값으로 HCharShape 를 새로 채운 뒤 필요한 항목만 고칩니다.
  5. 32~40줄⑤ 글꼴 종류 지정with (HParameterSet.HCharShape) 블록 안에서 한글·영문·한자·일어·기호·사용자·기타 7개 언어 계열의 FontType 을 모두 FontType("TTF") 로 지정합니다. 글꼴 이름(FaceName)은 건드리지 않으므로 기존 글꼴은 그대로 유지됩니다.
  6. 41~49줄⑥ 토글 적용marked 이면 ShadeColor = NO_SHADE, TextColor = BLACK 으로 되돌리고, 아니면 노란 음영과 빨간 글자를 넣습니다. 마지막 49줄 HAction.Execute("CharShape", …) 가 블록 전체에 한 번에 적용합니다. 판단은 첫 글자 기준이므로 선택 전체가 같은 방향으로 바뀝니다.

핵심 한글 API (HAction · HParameterSet …)

  • RGBColor(r, g, b) — R·G·B 값을 한글 내부 색 값(BGR 순서의 COLORREF)으로 바꿉니다. 숫자 상수로 직접 쓰려면 0x00BBGGRR 순서로 적어야 합니다.
  • CreateSet("ListParaPos") / GetSelectedPosBySet(sset, eset) — 위치(List·Para·Pos)를 담는 세트를 만들고, 현재 블록의 시작·끝 위치를 그 세트에 받아 옵니다. 블록이 없으면 false 를 돌려줍니다.
  • SetPosBySet(set) — 세트에 담긴 위치로 캐럿을 옮깁니다. 선택 범위를 복원할 때 Select 와 함께 씁니다.
  • HAction.Run("MoveSelNextChar") / HAction.Run("Select") / HAction.Run("Cancel") — 한 글자 늘려 선택, 블록 시작, 선택 해제입니다. 키보드 조작을 그대로 흉내 냅니다.
  • HAction.GetDefault("CharShape", HParameterSet.HCharShape.HSet) — 선택한 글자(또는 캐럿 위치)의 현재 글자 모양을 파라미터셋에 읽어 옵니다. ShadeColor·TextColor 로 상태를 판정하는 데 씁니다.
  • HAction.Execute("CharShape", HParameterSet.HCharShape.HSet) — 고친 글자 모양 값을 선택 범위에 적용합니다.
  • FontType("TTF") — 글꼴 종류 상수(트루타입)를 돌려줍니다. FontTypeHangul 등 언어 계열별 항목에 넣습니다.

부르는 공통 라이브러리 함수

  • 공통 라이브러리(L_*)를 쓰지 않습니다 — 한글 기본 객체만으로 동작하는 독립 매크로입니다.

이렇게 고쳐 쓰세요

  • 노란 음영을 연두색으로 — 10줄 RGBColor(255, 255, 0) 을 RGBColor(204, 255, 153) 처럼 바꿉니다. 인자는 R, G, B 순서이고 한글 내부에서는 BGR(0x0099FFCC)로 저장되니, 숫자로 직접 쓸 때는 순서를 뒤집어야 합니다. 21·28줄 판정도 같은 변수 YELLOW 를 쓰므로 함께 바뀝니다.
  • 글자색은 그대로 두고 음영만 넣기 — 46줄 TextColor = RED; 와 43줄 TextColor = BLACK; 을 지우고, 21·28줄 조건의 && HParameterSet.HCharShape.TextColor == RED 부분도 지웁니다. 조건을 남겨 두면 글자색이 빨강이 아니어서 되돌리기가 동작하지 않습니다.
  • 되돌릴 때 검정 대신 파랑 글자로 — 11줄 BLACK = 0 을 BLACK = 0x00FF0000 으로 바꿉니다. BGR 순서라 맨 앞 FF 가 파랑입니다(RGBColor(0, 0, 255) 로 써도 같습니다).

고칠 때 주의

  • 되돌릴지 여부는 선택의 첫 글자만 보고 정합니다. 첫 글자가 칠해져 있지 않으면 일부가 칠해진 선택도 전체를 다시 칠합니다.
  • 색 값을 바꾸면 예전 색으로 칠해 둔 곳은 '이미 칠한 곳'으로 인식되지 않습니다(21·28줄 비교값이 함께 바뀌기 때문).
  • 되돌리기는 원래 글자색을 기억하지 않고 항상 BLACK 값으로 바꿉니다.

02한셀입력 A-서식-09 Alt+2

긴 글을 한 줄에 — 글자 크기는 그대로, 장평(최소 80%)·자간(최소 -10%)으로 맞추고, 그래도 넘치면 어절 단위 줄바꿈

매크로 이름 한셀입력 · 전체 765줄(공통 라이브러리 1~660줄 + 이 매크로 661~765줄) · .msr 64 KB

.msr 다운로드 64 KB
소스 보기 (765줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

표 칸의 글자를 칸 너비에 맞춰 한 줄로 넣기 위해, 글자 크기는 그대로 두고 장평(최소 80%)과 자간(최소 -10%)을 계산해 줄이는 매크로입니다. 공통 라이브러리 L_cellMeasure 로 글자 폭을 어림해 칸 안쪽 너비와 비교하고, 들어가면 셀 속성 '한 줄로 입력'(LineWrap=1)을 켜며, 한계로도 넘치면 어절 단위 줄바꿈으로 바꿉니다. 셀 블록으로 여러 칸을 고르면 칸마다 따로 계산합니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 675~689줄① 표 확인과 대상 칸 모으기L_inTable() 로 표 안인지 확인합니다. 셀 블록이 있을 때 HAction.GetDefault("TableFormula", …) 의 Command 기본값이 =(B2,C2,…) 처럼 고른 칸 주소를 준다는 점을 이용해, 정규식으로 주소 목록을 꺼냅니다. 그다음 L_tableCells() 가 돌려준 칸 목록에서 주소(addr)가 일치하는 칸의 List 번호를 targets 에 넣고, 블록이 없으면 현재 칸 하나만 대상으로 합니다.
  2. 691~709줄② 한계값과 setWrap(한 줄로 입력·줄간격)691줄 MIN_RATIO = 80, MIN_SPACING = -10 이 줄일 수 있는 한계입니다. setWrap 은 TablePropertyDialog 를 ShapeType 3(셀)으로 열어 ShapeTableCell.LineWrap 을 1(한 줄로 입력) 또는 0(보통)으로 바꾸고, 이어서 그 칸을 TableCellBlock 으로 잡아 ParagraphShape 의 LineSpacingType = 0, LineSpacing = 100(글자에 따라 100%)을 적용합니다.
  3. 710~736줄③ setChar·setWordBreak·cellWidth 도우미setChar 는 칸 전체를 셀 블록으로 잡고 CharShape 의 RatioHangul~RatioUser(장평), SpacingHangul~SpacingUser(자간) 7개 언어 계열을 한꺼번에 같은 값으로 넣습니다. setWordBreak 는 문단 모양의 BreakNonLatinWord 를 0(어절 단위 줄 나눔)으로 바꾸고, cellWidth 는 셀 속성에서 ShapeTableCell.Width(HWPUNIT)를 읽어 옵니다.
  4. 738~748줄④ 측정과 1단계: 그대로 들어가는지칸마다 먼저 setChar(list, 100, 0) 으로 이전 실행 흔적을 지워 원래 폭으로 되돌립니다. L_cellMeasure 가 돌려준 need(가장 긴 줄의 어림 폭)와 칸 안쪽 너비 inner = cellWidth - margin 을 비교해 들어가면 '한 줄로 입력'만 켜고 다음 칸으로 넘어갑니다. 빈 칸이나 안쪽 너비가 0 이하인 칸은 건너뜁니다.
  5. 749~758줄⑤ 2·3단계: 장평, 그다음 자간 계산749줄 Math.ceil(inner / m.need * 100) 이 장평만으로 맞추는 값이며 80 이상이면 그 값을 씁니다. 부족하면 장평 80% 로 줄인 폭(need×0.8)에서 남는 너비를 '글자 수×글자 크기'로 나눠 자간 백분율을 구하고(755줄), -10 이상이면 장평 80%·그 자간으로 한 줄에 넣습니다.
  6. 759~764줄⑥ 4단계와 결과 안내한계로도 넘치면 장평 80%·자간 -10% 를 적용한 채 setWrap(list, 0) 으로 '한 줄로 입력'을 끄고 setWordBreak 로 어절 단위 줄바꿈을 켭니다. 끝으로 캐럿을 처음 칸으로 돌려놓고 단계별 칸 수를 L_msg 로 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.GetDefault("TableFormula", HParameterSet.HFieldCtrl.HSet) — 표 계산식 대화상자의 기본값을 읽습니다. 여기서는 Command 에 담긴 고른 칸 주소 목록(=(B2,C2,…))을 얻는 용도로만 씁니다.
  • HAction.GetDefault/Execute("TablePropertyDialog", HParameterSet.HShapeObject.HSet) — 셀 속성을 읽고 씁니다. SetItem("ShapeType", 3) 으로 셀 탭을 지정하고 ShapeTableCell.Width·LineWrap 을 다룹니다.
  • HParameterSet.HCharShape.RatioHangul / SpacingHangul … — 장평(%)과 자간(%)입니다. 한글·영문·한자·일어·기타·기호·사용자 7개 계열을 각각 지정해야 칸 안 모든 글자에 적용됩니다.
  • HAction.Execute("ParagraphShape", HParameterSet.HParaShape.HSet) — 문단 모양 적용입니다. LineSpacingType·LineSpacing(줄간격)과 BreakNonLatinWord(한글 줄 나눔 기준)를 바꿉니다.
  • HAction.Run("TableCellBlock") — 현재 칸을 셀 블록으로 잡습니다. 칸 안 모든 문단에 글자·문단 모양을 한 번에 적용하기 위해 씁니다.

부르는 공통 라이브러리 함수

  • L_inTable — 캐럿이 표 안(List != 0)인지 확인
  • L_tableCells — 병합 칸까지 고려해 모든 칸의 List 번호와 주소(A1, B2 …)를 구함
  • L_cellMeasure — 칸 글자 크기·안여백·가장 긴 줄의 어림 폭(need)과 글자 수(chars) 측정
  • L_charW / L_textW — 글자 종류별 어림 폭(한글 1em, 숫자 0.6em 등)으로 줄 폭 계산(L_cellMeasure 내부)
  • L_gotoPara — 지정한 칸(List)의 문단 처음으로 캐럿 이동
  • L_trim · L_here · L_msg — 공백 정리, 캐럿 위치 읽기, 안내창

이렇게 고쳐 쓰세요

  • 장평을 70% 까지 허용 — 691줄 MIN_RATIO = 80 을 MIN_RATIO = 70 으로 바꿉니다. 750·754줄 계산은 MIN_RATIO 변수를 쓰므로 자동으로 따라가지만, 안내 문구(757·763·764줄의 '80%')도 함께 고치면 안내가 맞습니다.
  • 자간 한계를 -15% 로 — 691줄 MIN_SPACING = -10 을 MIN_SPACING = -15 로 바꿉니다. 너무 줄이면 글자가 겹쳐 보이니 인쇄해 확인합니다.
  • 줄간격을 100% 가 아닌 130% 로 — 705줄 ps.LineSpacing = 100; 의 100 을 130 으로 바꿉니다(704줄 LineSpacingType 0 = 글자에 따라).

고칠 때 주의

  • 글자 폭은 실제 측정값이 아니라 글자 종류별 어림값이라 칸마다 약간의 오차가 있습니다. 1단계에서 '한 줄로 입력'을 켜는 것이 이 오차를 흡수합니다.
  • 여러 칸 인식은 TableFormula 기본값이 고른 칸 주소를 준다는 실측 동작에 기대고 있어, 셀 블록이 아닌 일반 글자 블록에서는 현재 칸만 처리됩니다.
  • 실행할 때마다 장평 100·자간 0 으로 먼저 되돌리므로, 손으로 따로 맞춰 둔 장평·자간도 다시 계산됩니다.

03계산및합계 B-계산-01 Alt+3

커서 줄만 계산, 여러 줄을 긁으면 각 줄 계산 + 윗줄에 합계 — 곱하기·나누기·더하기·빼기·괄호

매크로 이름 계산및합계 · 전체 875줄(공통 라이브러리 1~660줄 + 이 매크로 661~875줄) · .msr 75 KB

.msr 다운로드 75 KB
소스 보기 (875줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

본문 줄이나 표 칸에 적힌 산출식(예: 20,000원×28명×4회=)을 읽어 '=' 뒤에 결과를 채우거나, 이미 적힌 값을 검산해 틀리면 고쳐 쓰고 빨간색으로 표시합니다. 여러 줄(칸)을 블록으로 잡으면 각 줄을 계산한 뒤 금액 합계를 범위 윗줄의 ':' 뒤(표에서는 위 칸)에 적습니다. 계산은 공통 라이브러리의 사칙연산 계산기 L_evalExpr 를 쓰고, 실패하면 곱셈 전용 L_calcExpr 로 대신합니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 677~716줄① 계산 범위 정하기GetTextFile("TEXT", "saveblock") 으로 블록 글자를 읽어 줄 수(selLines)를 셉니다. 두 줄 이상이면 합계 모드(sumMode)입니다. 표 안이면 L_tableGeom 으로 표 구조를 구하고, 고른 칸 글자 집합(set)과 같은 글자가 이어지는 위·아래 칸까지 넓혀 세로 범위(r0~r1)를 정합니다. 본문이면 현재 문단 글자가 블록의 마지막 줄과 같은지로 블록이 위쪽인지 아래쪽인지 판단해 문단 번호 범위를 만듭니다.
  2. 718~739줄② 합산 기준 글머리와 결과 단위범위에서 처음 나오는 글머리 기호(L_level(st).mark)를 targetMark 로 잡아, 나중에 같은 기호 줄만 합산합니다(상위 '-' 항목과 하위 '·' 세부의 이중 합산 방지). 이어서 범위 앞뒤 12문단씩을 훑어 '=…천원' 과 '=…원' 표기 수를 세고, 천원 표기가 없고 원 표기만 있으면 결과 단위를 원, 그 밖에는 천원으로 정합니다.
  3. 742~760줄③ 줄별 계산: '=' 뒤가 비었으면 채우기줄마다 L_mulEdits 로 숫자 사이의 *, X, x 를 ×로 바꿀 편집 목록을 만들고, L_normMul 로 글자 수를 유지한 채 정규화한 문자열을 얻습니다. 마지막 '=' 앞부분을 L_evalExpr 로 계산하고, '=' 뒤에 숫자가 없으면 결과 문자열을 '=' 바로 뒤에 넣는 편집을 추가합니다. 결과가 금액이면 L_fmtAmount, 비율이면 L_fmt 로 표기합니다.
  4. 760~788줄④ 검산과 '=' 없는 줄'=' 뒤에 값이 있고 연산자가 하나 이상이면 검산합니다. 금액은 L_sumAmounts 로 적힌 값을 원 단위로 바꿔 천원 단위면 500원, 원 단위면 0.5원 이상 차이 날 때, 비율은 소수 둘째 자리 기준으로 다를 때 '=' 뒤 전체를 새 값으로 바꾸는 redEdit 를 만듭니다. '=' 가 없고 × 나 ÷ 가 있으면 줄 끝에 '=결과' 를 붙이고, 둘 다 없으면 줄 안 금액만 읽어 합계에 씁니다.
  5. 790~806줄⑤ 합산 집계와 편집 적용표 안이거나 기준 기호가 없거나 기호가 같은 줄의 금액만 total 에 더하고, 다른 기호 줄은 skipped 로 셉니다. 편집 목록은 L_applyEdits 가 오른쪽부터 적용해 앞쪽 위치가 밀리지 않게 합니다. 고쳐 쓴 값은 L_setCaret 로 위치를 잡고 MoveSelNextChar 로 글자 수만큼 선택한 뒤 CharShape 의 TextColor = 255(빨강)로 칠합니다.
  6. 808~826줄⑥ 결과가 없거나 한 줄만 계산한 경우합산할 금액이 없으면 비율 계산 결과만 알려 주거나 '계산할 금액을 찾지 못했습니다' 안내를 띄우고 끝냅니다. 블록이 아니었으면(sumMode=false) 계산 결과와 채움·고침 줄 수만 보여 주고 합계는 적지 않습니다.
  7. 828~874줄⑦ 블록 윗줄(윗칸)에 합계 쓰기합계 글은 "총 " + 금액 입니다. 표에서는 첫 선택 칸 위 칸이 비어 있으면 L_cellSet 으로 쓰고, 아니면 TableInsertUpperRow 로 행을 하나 넣어 같은 열에 씁니다. 본문에서는 윗줄에 ':' 가 있으면 그 뒤에 넣되 예전에 넣은 '총 …' 이 있으면 그 부분만 바꾸고, ':' 가 없으면 BreakPara 로 새 줄을 만들어 적은 뒤 결과를 안내합니다.

핵심 한글 API (HAction · HParameterSet …)

  • GetTextFile("TEXT", "saveblock") — 현재 블록의 글자를 문자열로 돌려줍니다. 줄은 \r\n 으로 구분되며, 블록이 없으면 null 이 올 수 있어 try 로 감쌌습니다.
  • HAction.GetDefault/Execute("CharShape", HParameterSet.HCharShape.HSet) — 고쳐 쓴 결과 글자에 TextColor = 255(BGR 0x0000FF, 빨강)를 적용합니다.
  • HAction.Run("MoveSelNextChar") — 글자 하나씩 선택을 넓힙니다. 고친 값의 길이만큼 반복해 그 부분만 선택합니다.
  • HAction.Run("TableInsertUpperRow") — 현재 칸 위에 빈 행을 넣습니다. 위 칸에 이미 글이 있을 때 합계를 적을 자리를 만듭니다.
  • HAction.Run("BreakPara") / ("MoveUp") / ("MoveParaBegin") — 문단 처음에서 Enter 를 눌러 위에 빈 문단을 만들고, 그 빈 줄로 올라가 처음으로 이동합니다.
  • HAction.Run("Cancel") — 블록 선택을 풉니다. 블록 글자를 읽은 직후와 색칠 직후에 부릅니다.

부르는 공통 라이브러리 함수

  • L_evalExpr — × ÷ + - 와 괄호, 원·천원 단위를 이해하는 산출식 계산기(금액/비율 구분, 연산자 수 반환)
  • L_calcExpr — 곱셈 전용 옛 계산기(L_evalExpr 실패 시 대체)
  • L_mulEdits / L_normMul — 숫자 사이 *, X, x 를 ×로 바꾸는 편집 목록과 정규화 문자열
  • L_applyEdits — 편집 목록을 오른쪽부터 적용(L_setCaret·Delete·L_insertText)
  • L_sumAmounts / L_fmtAmount / L_fmt — 줄 안 금액 합산과 천원·원 표기
  • L_tableGeom / L_cellList / L_cellText / L_cellSet — 표 행·열 구조와 칸 읽기·쓰기
  • L_level — 줄 앞 글머리 기호(○, -, 가. 등) 판별
  • L_paraText / L_lastPara — 문단 글자 읽기와 마지막 문단 번호

이렇게 고쳐 쓰세요

  • 결과 단위를 기본 원으로 — 726줄 var outUnit = "천원"; 을 "원" 으로, 738줄 outUnit = (nThou === 0 && nWon > 0) ? "원" : "천원"; 을 outUnit = (nThou > 0) ? "천원" : "원"; 으로 바꿉니다. 주변에 '=…천원' 표기가 있을 때만 천원을 씁니다.
  • 고쳐 쓴 값을 빨강 대신 파랑으로 — 801줄 TextColor = 255; 를 TextColor = 0xFF0000; 으로 바꿉니다. 한글 색 값은 BGR 순서라 0xFF0000 이 파랑입니다.
  • 합계 앞말 '총' 을 '합계' 로 — 834줄 "총 " + amount 를 "합계 " + amount 로 바꾸고, 다시 실행할 때 예전 값을 찾는 856줄 정규식 /^\s*총\s*[\d,]+…/ 의 '총' 도 '합계' 로 바꿉니다.
  • 단위 판단 범위를 넓히기 — 729줄 u0.para - 12, + 12 의 12 를 20 등으로 늘리면 더 넓은 범위의 표기 관례를 따릅니다.

고칠 때 주의

  • 본문 블록의 문단 범위는 현재 문단 글자가 블록 마지막 줄과 같은지로 추정합니다(708줄). 같은 글자의 줄이 반복되면 범위가 어긋날 수 있습니다.
  • 834줄과 856줄은 짝입니다. 합계 앞말만 바꾸면 재실행 때 예전 합계를 찾지 못해 ':' 뒤에 합계가 두 번 붙습니다.
  • 표 세로 범위는 고른 칸의 글자 집합으로 위·아래를 넓혀 찾으므로, 범위 바로 바깥 칸에 같은 글자가 있으면 함께 포함됩니다.

04표머리두줄HY그래픽 A-서식-08 Alt+4

표 양식 한 번에 — 제목 행 HY그래픽 굵게·회색 바탕·아래 이중선, 바깥 테두리 굵게

매크로 이름 표머리두줄HY그래픽 · 전체 177줄(공통 라이브러리 없이 이 매크로만) · .msr 12 KB

.msr 다운로드 12 KB
소스 보기 (177줄)
심화과정: 소스 분석

커서가 있는 표에 표마당(table_basic01.tbl)을 적용한 뒤, 셀 블록을 여러 번 바꿔 잡으며 테두리·선 굵기·첫 행 배경·첫 행 아래 이중선·글꼴(HY그래픽 12pt)을 차례로 입히는 매크로입니다. 키 조작과 대화상자 설정을 기록한 형태라 변수·조건문 없이 HAction.Run 과 GetDefault/Execute 짝이 위에서 아래로 이어집니다. 셀 블록 범위는 TableCellBlock(현재 칸), TableCellBlockExtend 두 번(표 전체), TableColEnd(행 끝까지 확장)로 정합니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 1~27줄① 표마당 적용HAction.GetDefault("TableTemplate", …) 로 표마당 파라미터를 받고 FileName 에 표마당 파일 이름을 넣어 Execute 합니다. table_basic01 → 01 → 02 → 01 순서로 네 번 적용하며, 마지막에 적용한 table_basic01.tbl(25줄)이 이후 작업의 바탕이 됩니다.
  2. 28~35줄② 표 전체 선택과 테두리 단추 동작TableCellBlock 한 번은 현재 칸, TableCellBlockExtend 를 두 번 더 부르면 표 전체 칸이 선택됩니다(F5 를 세 번 누른 것과 같음). 이어서 TableCellBorderInside, TableCellBorderAll, TableCellBorderNo 등 테두리 단추 동작을 차례로 실행합니다.
  3. 36~53줄③ 모든 칸 0.1mm 실선CellZoneBorder(고른 칸을 하나의 영역으로 보는 테두리)의 SelCellsBorderFill 에 위·아래·왼쪽·오른쪽 선 종류 HwpLineType("Solid"), 굵기 HwpLineWidth("0.1mm") 를 넣어 적용합니다. 그다음 Cancel 후 TableColBegin(행 처음)·TableColPageUp(열 맨 위)으로 캐럿을 표 왼쪽 위 칸에 둡니다.
  4. 56~71줄④ 첫 행 아래 이중선왼쪽 위 칸에서 TableCellBlock → TableCellBlockExtend → TableColEnd 로 첫 행 전체를 고릅니다. CellBorder(칸마다 적용)로 BorderTypeBottom = HwpLineType("DoubleSlim"), BorderWidthBottom = HwpLineWidth("0.5mm") 를 넣어 머리행 아래에 두 줄 선을 긋고, 다시 행 처음으로 돌아옵니다.
  5. 73~107줄⑤ 표 전체 선 굵기 0.4mm 와 채우기 속성다시 표 전체를 고르고 CellBorder 로 네 방향 선 굵기를 모두 HwpLineWidth("0.4mm") 로 지정합니다. 같은 파라미터에 FillAttr.Type = BrushType("NullBrush|KeepWinBrush|KeepGradBrush") 와 그러데이션 색 배열(0번 흰색, 1~9번 검정)도 함께 넘깁니다. 끝에서 TableColPageUp·TableColBegin 으로 왼쪽 위 칸으로 돌아갑니다.
  6. 108~127줄⑥ 첫 행 배경 연회색첫 행을 다시 고르고 FillAttr.Type = BrushType("NullBrush|WinBrush"), WinBrushFaceColor = RGBColor(242, 242, 242)(연회색 면), WinBrushFaceStyle = HatchStyle("None")(무늬 없음), WindowsBrush = 1 로 면 채우기를 켭니다.
  7. 130~143줄⑦ 첫 행 아래 이중선 다시 지정④와 같은 설정(DoubleSlim, 0.5mm)을 첫 행에 한 번 더 적용합니다. ⑤에서 표 전체 선 굵기를 0.4mm 로 바꿨기 때문에, 머리행 아래 이중선을 다시 확정하는 단계입니다.
  8. 145~173줄⑧ 글꼴 HY그래픽 12pt 와 진하게표 전체를 고른 상태에서 CharShape 의 FaceNameHangul~FaceNameUser 7개 계열을 모두 "HY그래픽" 으로, Height = PointToHwpUnit(12.0) 으로 지정합니다. 이어서 TableColPageUp 으로 열 맨 위로 이동해 CharShapeBold(진하게)를 실행하고, 행 처음으로 돌아가 선택을 풉니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.GetDefault/Execute("TableTemplate", HParameterSet.HTableTemplate.HSet) — 표마당을 적용합니다. FileName 에 한글에 들어 있는 표마당 파일 이름(.tbl)을 넣습니다.
  • HAction.Run("TableCellBlock") / ("TableCellBlockExtend") — 셀 블록 시작과 확장입니다. Block 1회 + Extend 2회 = 표 전체 선택, Block + Extend + TableColEnd = 현재 칸부터 행 끝까지입니다.
  • HAction.GetDefault/Execute("CellZoneBorder", HParameterSet.HCellBorderFill.HSet) — 고른 칸들을 하나의 영역으로 보고 테두리를 넣습니다. 값은 SelCellsBorderFill 하위 항목에 넣습니다.
  • HAction.GetDefault/Execute("CellBorder", HParameterSet.HCellBorderFill.HSet) — 고른 칸마다 테두리·배경을 적용합니다. BorderTypeBottom·BorderWidthBottom·FillAttr 등을 바로 씁니다.
  • HwpLineType("Solid" / "DoubleSlim") · HwpLineWidth("0.1mm") — 선 종류와 굵기 상수를 돌려줍니다. DoubleSlim 은 가는 이중선입니다.
  • FillAttr.WinBrushFaceColor = RGBColor(242, 242, 242) — 칸 면 채우기 색입니다. RGBColor 는 R, G, B 순서로 받아 BGR 순서의 내부 색 값으로 바꿉니다.
  • HParameterSet.HCharShape.FaceNameHangul … / PointToHwpUnit(12.0) — 언어 계열별 글꼴 이름과 글자 크기입니다. 크기는 포인트를 HWPUNIT(1pt = 100)으로 바꿔 넣습니다.
  • HAction.Run("TableColBegin") / ("TableColEnd") / ("TableColPageUp") — 행의 처음 칸, 행의 끝 칸, 열의 맨 위 칸으로 이동(블록 중이면 확장)합니다.

부르는 공통 라이브러리 함수

  • 공통 라이브러리(L_*)를 쓰지 않습니다 — 기록 매크로 형태로 한글 액션만 차례로 실행합니다.

이렇게 고쳐 쓰세요

  • 머리행 배경을 연회색에서 연파랑으로 — 116줄 RGBColor(242, 242, 242) 를 RGBColor(221, 235, 247) 로 바꿉니다. 숫자 상수로 직접 쓰려면 BGR 순서라 0x00F7EBDD 가 됩니다.
  • 글꼴과 크기 바꾸기 — 152~164줄의 "HY그래픽" 7곳을 PC에 설치된 다른 글꼴 이름으로 모두 바꾸고, 166줄 PointToHwpUnit(12.0) 의 12.0 을 11.0 등으로 바꿉니다.
  • 머리행 아래 이중선을 굵은 실선으로 — 64줄과 138줄 두 곳의 HwpLineType("DoubleSlim") 을 HwpLineType("Solid") 로 바꿉니다. 한 곳만 바꾸면 ⑦ 단계가 다시 이중선으로 덮어씁니다.
  • 표마당 없이 기존 표 모양 위에 꾸미기 — 4~27줄(TableTemplate 네 번)을 지우면 표마당을 적용하지 않고 테두리·배경·글꼴만 바뀝니다.

고칠 때 주의

  • 표 안에 있는지 확인하는 코드가 없습니다. 커서가 표 밖에 있으면 표 관련 액션이 실패하므로 반드시 표 안에서 실행해야 합니다.
  • HY그래픽 글꼴이 없는 PC에서는 한글이 다른 글꼴로 대체해 보여 줍니다.
  • 셀 블록 범위는 이전 단계가 남긴 캐럿 위치(왼쪽 위 칸)에 기대므로, 단계 끝의 TableColBegin·TableColPageUp·Cancel 줄을 지우면 다음 단계의 선택 범위가 달라집니다.

05표간격정리 A-서식-07 Alt+5

표 열 너비를 내용에 맞게 — 순번·비고·숫자 열은 좁게, 글 열은 넓게, 표 너비는 그대로

매크로 이름 표간격정리 · 전체 765줄(공통 라이브러리 1~660줄 + 이 매크로 661~765줄) · .msr 66 KB

.msr 다운로드 66 KB
소스 보기 (765줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

커서가 있는 표의 열 너비를 칸 내용에 맞춰 다시 나누는 매크로입니다. 표 전체 너비는 그대로 두고, 첫·끝 열과 숫자·짧은 항목 열은 가장 긴 내용이 한 줄에 들어갈 만큼만 주며, 남는 너비는 긴 글이 있는 '글 열'이 글자 수 비율대로 나눠 가집니다. 계산한 너비는 셀 속성(TablePropertyDialog)으로 칸마다 넣고, 행 높이는 최소값으로 돌려 내용에 맞게 자동 조정되게 합니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 673~681줄① 표 확인과 구조 읽기L_inTable() 로 표 안인지 확인한 뒤 L_tableCells() 로 모든 칸의 List 번호·열·행·병합 폭(colSpan)·현재 너비를 얻습니다. 열 수 N 이 2 미만이면 끝냅니다. 680줄 MINW = 2200 은 열 최소 너비(HWPUNIT, 약 7.8mm), 681줄 SAFE = 1.08 은 글자 폭 어림 오차를 위한 8% 여유입니다.
  2. 683~700줄② 열마다 필요한 너비와 '글 열' 판정병합되지 않은 칸만 L_cellMeasure 로 재어, 필요한 너비 need×1.08 + 좌우 안여백 + 120 의 열별 최댓값을 구합니다. 696줄 정규식으로 숫자·쉼표·%·△·날짜 글자만 있는 칸은 numLike 로 보고 제외하며, 제목행(0행)을 뺀 나머지 칸의 가장 긴 글자 수가 8자를 넘는 열을 '글 열'(isText)로 정합니다. 글 열의 너비 배분 비율에 쓸 글자 수 합(sumChars)도 함께 모읍니다.
  3. 702~714줄③ 고정 열과 글 열 나누기열이 3개 이상이면 첫 열과 마지막 열, 2개면 첫 열을 가장자리 열로 보고, 가장자리이거나 글 열이 아니면 고정 열(fixed)로 분류합니다. 글 열이 하나도 없으면 가운데 열들(2열 표는 둘째 열)을 글 열로 돌려 남는 너비를 나눠 갖게 합니다.
  4. 715~730줄④ 너비 배분고정 열 너비 합이 표 너비의 60%(716줄 W * 0.6)를 넘으면 비율대로 줄입니다. 표 너비에서 고정 열을 뺀 나머지 R 을 글 열들이 글자 수 합(sumChars, 없으면 need)에 비례해 나눠 갖고, 어느 열도 MINW 보다 좁아지지 않게 합니다. 반올림 오차는 가장 넓은 열에 더해 표 전체 너비가 정확히 유지되게 합니다.
  5. 732~745줄⑤ 칸마다 너비 적용병합 칸은 걸친 열들의 너비를 더한 값을 씁니다. 지금 너비와 15 HWPUNIT 이상 차이 나는 칸만 TablePropertyDialog 를 열어 ShapeType 3(셀), ShapeCellSize 1 로 두고 ShapeTableCell.Width 에 새 너비, Height = 282(최소 높이)를 넣어 Execute 합니다. 높이를 최소로 두면 한글이 내용에 맞게 행 높이를 다시 늘립니다.
  6. 746~757줄⑥ 표 전체 줄간격 100%표 첫 칸에서 TableCellBlock + TableCellBlockExtend 두 번으로 표 전체를 고르고, ParagraphShape 의 LineSpacingType = 0, LineSpacing = 100 을 적용합니다. 실패해도 try/catch 로 선택만 풀고 넘어갑니다.
  7. 759~764줄⑦ 결과 안내mm() 함수가 HWPUNIT 을 283.5 로 나눠 mm 로 바꿉니다. 열 이름(L_colName: A, B, C…)별로 '이전 너비→새 너비' 와 글 열 표시를 모아 L_msg 로 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.GetDefault/Execute("TablePropertyDialog", HParameterSet.HShapeObject.HSet) — 셀 속성을 읽고 바꿉니다. SetItem("ShapeType", 3) 으로 셀 대상, SetItem("ShapeCellSize", 1) 로 크기 변경을 지정합니다.
  • HParameterSet.HShapeObject.ShapeTableCell.Width / Height — 칸 너비·높이(HWPUNIT, 1mm ≈ 283.5)입니다. 높이 282 는 최소값으로, 내용에 맞게 자동으로 늘어나게 하는 용도입니다.
  • HAction.Run("TableCellBlock") / ("TableCellBlockExtend") — 셀 블록 시작과 확장입니다. 시작 1회 + 확장 2회로 표 전체 칸을 고릅니다.
  • HAction.GetDefault/Execute("ParagraphShape", HParameterSet.HParaShape.HSet) — 문단 모양을 적용합니다. LineSpacingType 0(글자에 따라)과 LineSpacing 100 으로 줄간격을 맞춥니다.
  • HAction.Run("Cancel") — 셀 블록 선택을 풉니다.

부르는 공통 라이브러리 함수

  • L_tableCells — 병합 칸까지 포함해 모든 칸의 열·행·colSpan·너비와 표 너비 W, 열 경계 xs 를 구함
  • L_cellMeasure — 칸 글자 크기·안여백·가장 긴 줄의 어림 폭·글자 수·전체 글 측정
  • L_charW / L_textW — 글자 종류별 폭 어림값(L_cellMeasure 내부)
  • L_colName — 열 번호를 A, B, …, AA 이름으로
  • L_gotoPara — 지정한 칸의 첫 문단으로 이동
  • L_inTable · L_msg — 표 안 확인, 안내창

이렇게 고쳐 쓰세요

  • 열 최소 너비를 약 10mm 로 — 680줄 MINW = 2200 을 MINW = 2835 로 바꿉니다(1mm ≈ 283.5 HWPUNIT).
  • 숫자 열에 여유를 더 주기 — 681줄 SAFE = 1.08 을 1.15 로 올리면 모든 열의 필요 너비가 15% 여유를 갖습니다.
  • 글 열로 보는 기준을 12자로 — 700줄 isText[j] = (bodyMax[j] > 8); 의 8 을 12 로 바꿉니다. 짧은 항목 열이 더 많이 '고정 열'로 남습니다.
  • 고정 열이 차지할 수 있는 비율 조정 — 716줄 Math.floor(W * 0.6) 의 0.6 을 0.5 로 낮추면 글 열에 더 많은 너비가 돌아갑니다.

고칠 때 주의

  • 글자 폭은 실제 측정이 아니라 어림값이라 몇 %의 오차가 있습니다. 결과가 아쉬우면 한 번 더 실행해도 됩니다.
  • 병합된 칸(colSpan이 1이 아닌 칸)은 너비 측정에서 빠지므로, 병합 칸에만 긴 글이 있는 열은 좁게 잡힐 수 있습니다.
  • 표 전체 너비 W 는 바꾸지 않습니다. 표가 이미 쪽보다 넓다면 그 너비 안에서만 다시 나눕니다.

06음수를세모로적용합계 C-표계산-08 Alt+6

열의 음수를 모두 △로 바꾸고 합계까지

매크로 이름 음수를세모로적용합계 · 전체 713줄(공통 라이브러리 1~660줄 + 이 매크로 661~713줄) · .msr 58 KB

.msr 다운로드 58 KB
소스 보기 (713줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

커서가 있는 열에서 첫 행(제목행)과 마지막 행(합계 행)을 뺀 데이터 칸의 숫자를 모두 더해 마지막 행 같은 열에 적는 매크로입니다. 더하는 동안 '-800' 처럼 적힌 음수 칸은 공문 표기 '△800' 으로 바꾸고, 합계가 음수면 결과도 △ 로 적습니다. 합계 칸에 이미 값이 있으면 공통 함수 L_fillOrMarkSigned 가 검산해 다를 때만 고쳐 쓰고 빨간색으로 표시합니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 671~682줄① 표 확인과 표 구조 읽기L_inTable() 로 표 안인지 확인하고, L_tableGeom() 으로 표 왼쪽 위 칸 번호(rowBase0)·열 수 N·행 수 R·현재 열(curCol)을 얻습니다. 제목·데이터·합계를 갖추려면 최소 3행이 필요하므로 geom.R < 3 이면 안내 후 끝냅니다.
  2. 684~689줄② 데이터 칸 숫자 읽기685줄 for (r = 1; r < geom.R - 1; r++) 가 1행부터 마지막 바로 앞 행까지 돕니다(0부터 세므로 1 = 둘째 행). L_cellList(geom, r, col) 로 칸 번호를 계산하고 L_cellText 로 글자를 읽어, L_cellNum 으로 쉼표를 빼고 앞의 △ 나 - 를 음수로 해석한 숫자를 얻습니다.
  3. 690~697줄③ 합산과 '-' 음수의 △ 변환숫자로 읽힌 칸만 sum 에 더하고 개수를 셉니다. 음수인데 글자가 '-' 로 시작하면 L_fmtSigned(num) 으로 '△1,200' 꼴 문자열을 만들어 L_cellSetNum 으로 칸을 다시 쓰고 오른쪽 정렬까지 합니다. 이미 △ 로 적힌 칸은 그대로 둡니다.
  4. 699~708줄④ 합계 칸 채우기·검산숫자 칸이 하나도 없으면 안내 후 끝냅니다. 마지막 행 같은 열 칸에 L_fillOrMarkSigned(resultList, sum) 을 부르면, 빈 칸이면 채우고(filled), 값이 같으면 정렬만 맞추고(kept), 다르면 올바른 값으로 고쳐 쓴 뒤 빨간 글자로 표시합니다. 돌려받은 상태를 '새로 채움·정상 확인·값 수정' 문구로 바꿉니다.
  5. 710~712줄⑤ 결과 안내몇 번째 열인지, 데이터 몇 행의 합계가 얼마인지(△ 표기), 바꾼 음수 칸 수와 합계 칸 처리 결과를 L_msg 안내창으로 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.Run("TableColBegin") / ("TableUpperCell") / ("TableLowerCell") — L_tableGeom 안에서 행 처음 칸·위 칸·아래 칸으로 움직이며 표의 행·열 수와 현재 위치를 셉니다.
  • GetTextFile("TEXT", "saveblock") — L_cellText → L_paraText 안에서 칸 문단을 블록으로 잡아 글자를 읽습니다.
  • HAction.Execute("InsertText", HParameterSet.HInsertText.HSet) — L_cellSet 안에서 칸 글자를 지운 뒤 새 문자열(△ 표기나 합계)을 넣습니다.
  • HAction.Execute("ParagraphShape", HParameterSet.HParaShape.HSet) — L_alignRight 안에서 AlignType = 2(오른쪽 정렬)를 적용합니다.
  • HAction.Execute("CharShape", HParameterSet.HCharShape.HSet) — L_cellRed 안에서 TextColor = 255(BGR 0x0000FF, 빨강)로 고친 칸을 표시합니다.

부르는 공통 라이브러리 함수

  • L_tableGeom — 표 왼쪽 위 칸 번호·열 수·행 수·현재 행/열(모든 행의 칸 수가 같다고 가정)
  • L_cellList — (행, 열)을 칸 List 번호로 계산
  • L_cellText / L_cellNum — 칸 글자 읽기, △·- 를 음수로 해석한 숫자 추출
  • L_fmtSigned — 음수를 '△1,200' 처럼 표기
  • L_cellSetNum — 칸 글자를 바꾸고 오른쪽 정렬(L_cellSet + L_alignRight)
  • L_fillOrMarkSigned — 결과 칸을 채우거나 검산해 다르면 고쳐 쓰고 빨간색(L_cellRed)
  • L_inTable · L_msg — 표 안 확인, 안내창

이렇게 고쳐 쓰세요

  • 제목행이 두 줄인 표에서 쓰기 — 685줄 for (r = 1; 를 for (r = 2; 로 바꾸면 위 두 행을 빼고 더합니다. 679줄 geom.R < 3 도 geom.R < 4 로 맞춥니다.
  • 데이터 칸의 '-' 음수는 그대로 두기 — 692~695줄(if (num < 0 && …) { … conv++; })을 지우면 합계만 △ 로 적고 데이터 칸은 바꾸지 않습니다.
  • △ 대신 ▲ 로 표기 — 공통 라이브러리 306줄 "△" 를 "▲" 로 바꾸고, 다시 읽을 수 있도록 221줄 t.charAt(0) === "△" 에도 ▲ 를 추가합니다. 라이브러리는 다른 매크로와 같은 코드이므로 이 매크로 파일 안의 사본만 고칩니다.

고칠 때 주의

  • 마지막 행을 무조건 합계 행으로 봅니다. 합계 행이 없는 표에서 실행하면 마지막 데이터 칸이 합계로 덮어써집니다.
  • L_tableGeom 은 모든 행의 칸 수가 같다고 가정하므로, 병합 칸이 있는 표에서는 다른 칸을 읽을 수 있습니다.
  • L_fillOrMarkSigned 의 설명 주석은 "marked" 를 돌려준다고 적혀 있지만 실제 반환값은 "corrected" 입니다. 706~708줄은 filled·kept 가 아니면 모두 '값 수정' 으로 처리하므로 동작에는 문제가 없습니다.

07번호재정렬 A-서식-04 Alt+7

본문 전체의 1. 가. 1) 가) ① 계층 번호를 확인해 고치고(빨강), 표에서는 열을 자동 채우기로

매크로 이름 번호재정렬 · 전체 786줄(공통 라이브러리 1~660줄 + 이 매크로 661~786줄) · .msr 67 KB

.msr 다운로드 67 KB
소스 보기 (786줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

표 안에서 실행하면 커서가 있는 열의 번호를 둘째 칸(첫 데이터 칸)부터 다시 매기고, 본문에서 실행하면 문서 전체 문단을 훑어 1. > 가. > 1) > 가) > ① 계층 번호를 확인·정정합니다. 표에서는 한글의 표 자동 채우기(TableAutoFill)를 먼저 쓰고 결과를 검사해 직접 고치며, 본문에서는 단계별 카운터로 기대 번호를 계산해 다른 번호만 바꿉니다. 바뀐 곳은 모두 빨간 글자로 표시합니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 672~703줄① 번호 종류 도우미 함수672줄 KOR 은 '가나다…하' 순서, 673줄 CIRC0 = 0x2460 은 ① 의 문자 코드입니다. coreKind 는 번호 글자를 digit(숫자)·kor(가나다)·circ(원문자)·alpha(영문)로 가르고, coreAt 은 종류와 순번 n 으로 번호 글자를, coreIndex 는 반대로 번호 글자의 순번을 돌려줍니다. setColor 는 문단의 지정 위치부터 len 글자를 선택해 CharShape 의 TextColor 를 바꿉니다.
  2. 705~722줄② 모드 분기와 표 씨앗 읽기705줄에서 L_inTable() 결과로 tableMode 또는 docMode 를 부릅니다. 표 모드는 L_tableGeom 으로 현재 열과 행 수를 얻고, 열의 모든 칸 글자를 before 배열에 저장합니다. 둘째 칸(before[1])을 정규식으로 '번호 + 구분자(. 또는 )) + 나머지 글' 로 나눠 시작 번호를 정하고, 셋째 칸이 비어 있으면 다음 번호로 먼저 채웁니다(자동 채우기에는 씨앗 두 개가 필요).
  3. 723~729줄③ 한글 표 자동 채우기둘째 칸에서 TableCellBlock → TableCellBlockExtend 후 TableLowerCell 을 행 수만큼 반복해 마지막 칸까지 셀 블록을 넓히고, HAction.Run("TableAutoFill") 로 한글 본래의 자동 채우기를 실행합니다. 성공 여부(auto)는 안내 문구에만 씁니다.
  4. 730~741줄④ 결과 검사와 직접 고치기각 칸의 기대값 coreAt(kind, start + (r - 1)) + sep + rest 와 실제 글자를 비교해 다르면 L_cellSet 으로 직접 고쳐 씁니다. 그 결과가 실행 전 글자(before)와 다르면 L_cellRed 로 빨간 글자를 입힙니다. 자동 채우기가 처리하지 못하는 가), ① 같은 종류도 이 단계에서 채워집니다.
  5. 745~756줄⑤ 본문 모드: 계층 정규식LV 배열의 순서가 곧 계층입니다: 1단계 1., 2단계 가., 3단계 1), 4단계 가), 5단계 ①. 1단계 정규식은 숫자를 두 자리까지만 받고, 뒤에 또 '숫자.' 가 이어지면 제외하는 (?!\s*\d{1,2}\.\s) 조건으로 '2026. 10. 12.' 같은 날짜를 번호로 보지 않습니다. cnt 는 단계별 현재 번호입니다.
  6. 757~777줄⑥ 문단 순회와 정정0번 문단부터 L_lastPara 로 구한 마지막 문단까지 L_paraText 로 읽어 처음 맞는 단계를 찾습니다. 그 단계 카운터를 1 올리고 하위 단계 카운터를 모두 0 으로 되돌린 뒤(768줄), 기대 번호와 다르면 L_applyEdits 로 번호 글자만 바꾸고 setColor 로 255(빨강)를 칠합니다. 첫 수정 사례는 안내용 sample 로 남깁니다.
  7. 778~784줄⑦ 결과 안내원래 문단으로 캐럿을 돌려놓고, 번호 줄을 하나도 못 찾았으면 지원 형식을 안내합니다. 찾았으면 확인한 줄 수, 고친 줄 수, 수정 예시와 계층 규칙을 L_msg 로 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.Run("TableAutoFill") — 셀 블록으로 고른 칸을 한글의 표 자동 채우기로 채웁니다. 앞 칸 두 개의 규칙을 이어 갑니다.
  • HAction.Run("TableCellBlock") / ("TableCellBlockExtend") / ("TableLowerCell") — 셀 블록을 시작·확장 모드로 바꾼 뒤 아래 칸으로 이동해 세로 범위를 넓힙니다.
  • HAction.GetDefault/Execute("CharShape", HParameterSet.HCharShape.HSet) — setColor 에서 선택한 번호 글자에 TextColor(255 = BGR 0x0000FF, 빨강)를 적용합니다.
  • HAction.Run("MoveSelNextChar") — 번호 글자 길이만큼 선택을 넓혀 그 부분만 색칠합니다.
  • GetTextFile("TEXT", "saveblock") — L_paraText·L_cellText 안에서 문단이나 칸 글자를 읽습니다.
  • HAction.Run("Delete") / HAction.Execute("InsertText", …) — L_applyEdits·L_cellSet 안에서 기존 번호를 지우고 새 번호를 넣습니다.

부르는 공통 라이브러리 함수

  • L_tableGeom / L_cellList — 표 행·열 수와 (행, 열) 칸 번호
  • L_cellText / L_cellSet / L_cellRed — 칸 글자 읽기·다시 쓰기·빨간 표시
  • L_paraText / L_lastPara — 문단 글자 읽기와 마지막 문단 번호
  • L_applyEdits / L_setCaret — 문단 안 지정 위치의 글자 바꾸기와 캐럿 이동
  • L_inTable · L_trim · L_here · L_gotoPara · L_msg — 표 안 확인, 공백 정리, 위치 읽기·이동, 안내창

이렇게 고쳐 쓰세요

  • 본문에서 고친 번호를 파랑으로 — 773줄 setColor(list, p, pos, want.length, 255); 의 255 를 0xFF0000 으로 바꿉니다(BGR 순서라 파랑). 표 모드는 라이브러리 L_cellRed(213줄 TextColor = 255)를 쓰므로 따로 고쳐야 합니다.
  • 세 자리 번호(100.)까지 인식 — 750줄 1단계 정규식의 두 곳 \d{1,2} 를 \d{1,3} 으로 바꿉니다. 날짜 오인 방지 조건(뒤에 '숫자.' 가 오면 제외)은 그대로 둡니다.
  • 계층 순서 바꾸기(예: 1) 과 가) 의 순서) — 749~755줄 LV 배열에서 3단계 줄(752줄)과 4단계 줄(753줄)의 위치를 맞바꿉니다. 배열 순서가 곧 계층이고, cnt 배열(756줄)은 5칸이므로 단계 수를 늘리면 cnt 초기값도 늘립니다.

고칠 때 주의

  • 본문 모드는 문서 전체 문단을 검사합니다. 번호 형식을 일부러 다르게 쓴 부분(예: 별첨의 독립 번호)도 계층 규칙에 맞춰 바뀔 수 있습니다.
  • 한 문단에서 처음 맞는 단계만 봅니다. '가.' 와 '가)' 처럼 비슷한 형식은 LV 순서(가. 가 먼저)에 따라 판정됩니다.
  • 표 모드는 L_tableGeom 을 써서 모든 행의 칸 수가 같다고 가정합니다. 병합 칸이 있는 열에서는 다른 칸을 고칠 수 있습니다.

08중복값색처리 D-표정리-02 Alt+8

중복값을 빨간 글자로, 한 번 더 누르면 묶음마다 다른 색으로

매크로 이름 중복값색처리 · 전체 752줄(공통 라이브러리 1~660줄 + 이 매크로 661~752줄) · .msr 62 KB

.msr 다운로드 62 KB
소스 보기 (752줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

커서가 있는 표 열에서 제목행을 뺀 칸들의 글자를 세어 두 번 이상 나오는 값을 찾고, 같은 값끼리 묶어 묶음마다 다른 글자색을 칠하는 매크로입니다. 실행 전에 중복 칸들의 현재 글자색을 읽어, 모두 검정이면 색을 칠하고 이미 색이 있으면 검정으로 되돌리는 토글로 동작합니다. 색은 10가지 진한 색 팔레트(BGR 숫자)에서 차례로 고릅니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 670~677줄① 표 확인과 색 팔레트L_inTable() 로 표 안인지 확인합니다. 675줄 PALETTE 는 한글 색 값(COLORREF, 0x00BBGGRR) 10개로, 255(빨강)·16711680(0xFF0000, 파랑)·32768(0x008000, 녹색)·8421376(0x808000, 청록)·8388608(0x800000, 감색)·1263499(갈색)·8388736(0x800080, 자주)·21964(0x0055CC, 진주황)·32896(0x008080, 올리브)·4210752(0x404040, 진회색) 순입니다. L_tableGeom 으로 현재 열과 행 수를 얻습니다.
  2. 679~694줄② 색 읽기·칠하기 도우미colorOf 는 칸 첫 문단을 MoveSelParaEnd 로 선택하고 GetDefault("CharShape") 로 TextColor 를 읽어 옵니다. paint 는 같은 방식으로 선택한 뒤 TextColor 에 색을 넣고 Execute("CharShape") 로 적용합니다. 두 함수 모두 끝에 Cancel 로 선택을 풉니다.
  3. 696~710줄③ 값별 횟수와 중복 묶음1행(둘째 행)부터 끝까지 L_trim(L_cellText(…)) 로 칸 글자를 읽어 texts 에 보관하고, 빈 칸은 건너뜁니다. freq 객체에 "k:" + 값 키로 횟수를 세고(키 앞에 k: 를 붙여 객체 기본 속성 이름과 겹치지 않게 함), 처음 나온 순서를 order 에 남깁니다. 횟수가 2 이상인 값만 groups 로 모으며, 없으면 안내 후 끝냅니다.
  4. 712~721줄④ 현재 상태 판단중복 칸마다 colorOf 로 글자색을 읽어, 하나라도 0(검정)이 아니면 allBlack 을 false 로 바꿉니다. 721줄 var mode = allBlack ? "multi" : "reset"; 에 따라 모두 검정이면 묶음별 색칠, 아니면 검정으로 되돌리기를 합니다.
  5. 723~738줄⑤ 칠하기중복 칸마다 색을 정합니다. multi 이면 그 값이 groups 에서 몇 번째 묶음인지(gi)를 찾아 PALETTE[gi % PALETTE.length] 를 쓰고, reset 이면 0(검정)을 씁니다. paint 로 칠하고 칸 수를 센 뒤, 캐럿을 열의 둘째 칸으로 돌려놓습니다.
  6. 740~751줄⑥ 결과 안내names 배열(빨강·파랑·녹색 …)을 팔레트와 같은 순서로 두어 '값 = 색 이름' 목록을 만들고, 모드에 맞는 문구를 L_msg 로 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.Run("MoveSelParaEnd") — 문단 처음부터 끝까지 선택합니다. 칸 글자 전체의 색을 읽고 바꾸는 범위를 정합니다.
  • HAction.GetDefault("CharShape", HParameterSet.HCharShape.HSet) — 선택한 글자의 현재 글자 모양을 읽어 옵니다. TextColor 로 지금 색을 판정합니다.
  • HAction.Execute("CharShape", HParameterSet.HCharShape.HSet) — HCharShape.TextColor 에 넣은 색(BGR 숫자)을 선택 범위에 적용합니다.
  • HAction.Run("Cancel") — 선택을 풉니다.
  • GetTextFile("TEXT", "saveblock") — L_cellText → L_paraText 안에서 칸 글자를 읽습니다.

부르는 공통 라이브러리 함수

  • L_tableGeom — 표 왼쪽 위 칸 번호·열 수·행 수·현재 열
  • L_cellList — (행, 열)을 칸 List 번호로
  • L_cellText / L_trim — 칸 글자 읽기와 앞뒤 공백 정리
  • L_gotoPara — 칸 첫 문단으로 이동
  • L_inTable · L_msg — 표 안 확인, 안내창

이렇게 고쳐 쓰세요

  • 첫 묶음 색을 빨강 대신 진분홍으로 — 675줄 PALETTE 의 첫 값 255 를 0x9314FF 로 바꾸고(RGB(255, 20, 147)을 BGR 순서로 쓴 값), 740줄 names 의 "빨강" 도 "분홍" 으로 바꿉니다. 색 값은 반드시 파랑·초록·빨강 순서로 적어야 합니다.
  • 공백 차이를 무시하고 같은 값으로 보기 — 699줄 var t = L_trim(L_cellText(…)); 끝에 .replace(/\s+/g, "") 를 붙입니다. '1 반' 과 '1반' 처럼 띄어쓰기만 다른 값도 같은 묶음이 됩니다.
  • 모든 중복을 한 가지 빨강으로만 표시 — 721줄을 var mode = allBlack ? "red" : "reset"; 으로 바꿉니다. 729줄에 이미 red 모드 처리(color = 255)와 742줄 안내 문구가 들어 있습니다.

고칠 때 주의

  • 머리 주석은 '검정 → 빨강 → 묶음별 색 → 검정' 3단계 순환을 설명하지만, 실제 721줄은 '검정 → 묶음별 색 → 검정' 2단계입니다. red 모드 코드와 allRed 변수는 남아 있지만 쓰이지 않습니다.
  • 색 판정은 칸 첫 문단 전체 선택의 TextColor 로 합니다. 칸 안에 색이 섞여 있으면 검정이 아닌 것으로 읽혀 되돌리기 쪽으로 동작할 수 있습니다.
  • 묶음이 10개를 넘으면 팔레트 색이 처음부터 다시 쓰여 서로 다른 묶음이 같은 색이 됩니다.

09오름내림차순정렬 D-표정리-01 Alt+9

한 번 누르면 오름차순, 한 번 더 누르면 내림차순 (14·15 통합)

매크로 이름 오름내림차순정렬 · 전체 729줄(공통 라이브러리 1~660줄 + 이 매크로 661~729줄) · .msr 60 KB

.msr 다운로드 60 KB
소스 보기 (729줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

커서가 있는 열을 기준으로 표의 데이터 행(제목행 제외)을 정렬하는 매크로입니다. 모든 데이터 행의 칸 글자를 배열로 읽어 JavaScript 의 sort 로 순서를 정한 뒤 칸에 다시 써 넣으며, 기준 열이 이미 오름차순이면 내림차순으로 바꾸는 토글로 동작합니다. 기준 열 값이 모두 숫자로 읽히면 숫자 비교, 하나라도 아니면 문자열 비교를 합니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 671~681줄① 표 확인과 데이터 행 수L_inTable() 로 표 안인지 확인하고 L_tableGeom() 으로 열 수 N·행 수 R·현재 열 curCol 을 얻습니다. 데이터 행 수 geom.R - 1(제목행 제외)이 2 미만이면 정렬하지 않고 끝냅니다.
  2. 683~695줄② 모든 데이터 행 읽기1행(둘째 행)부터 마지막 행까지, 각 행의 모든 열 칸 글자를 L_cellText 로 읽어 cells 배열에 담습니다. 기준 열 글자는 L_cellNum 으로 숫자 변환을 시도해, 하나라도 숫자가 아니면 allNumeric 을 false 로 바꿉니다. 행마다 {num, text, cells} 객체를 rows 에 쌓습니다.
  3. 697~705줄③ 비교 함수cmpAsc 는 오름차순 비교 함수입니다. 모두 숫자면 a.num - b.num 으로, 아니면 <, > 로 문자열(문자 코드 순)을 비교해 -1·0·1 을 돌려줍니다.
  4. 707~716줄④ 정렬 방향 정하기와 정렬이웃한 행을 차례로 비교해 한 번이라도 앞이 크면 오름차순이 아니라고 봅니다(isAsc=false). 오름차순이면서 실제로 증가한 쌍이 하나 이상 있으면(strictly) 이번에는 내림차순으로 정합니다. 716줄 rows.sort(…) 가 방향에 맞게 cmpAsc(a, b) 또는 cmpAsc(b, a) 로 정렬합니다.
  5. 718~724줄⑤ 정렬된 순서로 다시 쓰기정렬된 rows 를 1행부터 차례로, 모든 열 칸에 L_cellSet(L_cellList(geom, 1 + r, c), …) 로 써 넣습니다. 행을 옮기는 것이 아니라 칸 글자를 바꿔 쓰는 방식입니다. 끝나면 기준 열 둘째 칸으로 캐럿을 둡니다.
  6. 726~728줄⑥ 결과 안내정렬 방향, 데이터 행 수, 기준 열 번호, 숫자/문자 비교 여부와 다음 실행 때의 방향을 L_msg 로 알려 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.Run("TableColBegin") / ("TableUpperCell") / ("TableLowerCell") — L_tableGeom 안에서 표의 행 처음·위·아래 칸으로 이동하며 행·열 수와 현재 열을 셉니다.
  • SetPos(list, para, 0) / GetPosBySet() — L_gotoPara·L_here 안에서 칸(List 번호)으로 캐럿을 옮기고 현재 위치를 읽습니다.
  • GetTextFile("TEXT", "saveblock") — L_cellText → L_paraText 안에서 칸 첫 문단을 선택해 글자를 읽습니다.
  • HAction.Run("MoveSelParaEnd") / ("Delete") — L_cellSet 안에서 칸 첫 문단 글자를 선택해 지웁니다.
  • HAction.Execute("InsertText", HParameterSet.HInsertText.HSet) — L_insertText 안에서 정렬된 글자를 칸에 넣습니다.

부르는 공통 라이브러리 함수

  • L_tableGeom — 표 왼쪽 위 칸 번호·열 수·행 수·현재 열(모든 행의 칸 수가 같다고 가정)
  • L_cellList — (행, 열)을 칸 List 번호로
  • L_cellText — 칸 첫 문단 글자 읽기
  • L_cellNum — 쉼표·△·- 를 처리해 숫자로 읽기(숫자가 없으면 null)
  • L_cellSet — 칸 첫 문단 글자를 지우고 새로 넣기
  • L_gotoPara · L_here · L_trim · L_inTable · L_msg — 이동, 위치 읽기, 공백 정리, 표 확인, 안내창

이렇게 고쳐 쓰세요

  • 마지막 합계 행은 정렬에서 빼기 — 685줄 for (r = 1; r < geom.R; r++) 를 r < geom.R - 1 로, 677줄 var dataCount = geom.R - 1; 을 geom.R - 2 로 바꿉니다. 다시 쓰는 719줄 반복은 rows.length 기준이라 그대로 두면 됩니다.
  • 항상 오름차순으로만 정렬 — 714줄 var descending = (isAsc && strictly); 를 var descending = false; 로 바꿉니다(내림차순만 원하면 true).
  • 제목행이 두 줄인 표 — 685줄 r = 1 을 r = 2 로, 721줄 1 + r 을 2 + r 로, 724줄 L_cellList(geom, 1, col) 의 1 을 2 로, 677줄 geom.R - 1 을 geom.R - 2 로 바꿉니다.

고칠 때 주의

  • 칸의 첫 문단 글자만 읽고 다시 씁니다. 한 칸에 여러 문단이 있으면 둘째 문단부터는 제자리에 남아 행 내용이 어긋납니다. 글자 모양(색·굵기)도 함께 옮겨지지 않습니다.
  • 합계 행이 있으면 데이터와 함께 정렬됩니다(머리 주석에도 안내되어 있음). 위 수정 방법으로 마지막 행을 빼고 쓰는 것이 안전합니다.
  • 문자열 비교는 문자 코드 순서라 '10' 과 '9' 가 섞인 문자 열에서는 '10' 이 앞에 옵니다.

10요일입력 A-서식-01 Alt+0

날짜 뒤에 (요일)이 자동으로 붙습니다 — 2026. 10. 12. 도, 2026-10-12 · 2026/10/12 도

매크로 이름 요일입력 · 전체 121줄(공통 라이브러리 없이 이 매크로만) · .msr 10 KB

.msr 다운로드 10 KB
소스 보기 (121줄)
심화과정: 소스 분석

커서가 있는 문단 전체를 읽어 '2026. 7. 6.', '7. 10.', '2026-07-06' 같은 날짜를 정규식으로 모두 찾고, 각 날짜 바로 뒤에 '(월)' 처럼 요일을 넣는 매크로입니다. JavaScript Date 객체로 실제 존재하는 날짜인지 검증하고 요일을 구하며, 이미 요일이 붙은 날짜는 건너뜁니다. 글자 위치가 밀리지 않도록 문단 뒤쪽 날짜부터 InsertText 로 넣습니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 11~18줄① 요일표와 문단 글자 읽기11줄 WEEK 배열은 Date.getDay() 결과(0=일요일)에 맞춘 요일 글자입니다. MoveParaBegin → MoveSelParaEnd 로 커서 문단 전체를 선택하고 GetTextFile("TEXT", "saveblock") 으로 글자를 읽은 뒤, Cancel 로 선택을 풀고 다시 문단 처음으로 갑니다.
  2. 20~22줄② 문단 시작 위치(Pos) 기준값한글의 Pos 는 문단 처음이 0 이 아닐 수 있어서, 문단 처음에서 GetPosBySet().Item("Pos") 를 읽어 basePos 로 보관합니다. 나중에 'n번째 글자' 로 이동할 때 basePos + n 을 씁니다. 읽기에 실패하면 -1 로 두고 다른 이동 방식을 씁니다.
  3. 24~34줄③ 특수문자 복원과 빈 줄 확인GetTextFile 은 ❍, – 같은 문자를 &#10061; 처럼 숫자 엔티티로 돌려주므로, 16진·10진 엔티티와 &amp; 를 원래 글자로 되돌리고 끝의 줄바꿈을 지웁니다. 그래야 글자 위치가 실제 문서와 맞습니다. 글자가 없으면 안내 후 끝냅니다.
  4. 36~45줄④ 날짜 정규식39줄 정규식의 묶음은 (1) 4자리 연도, (2) 연도 뒤 구분기호, (3) 월, (4) 월 뒤 구분기호, (5) 일, (6) 끝 마침표입니다. 구분기호로 . - / _ , 를 받고 사이 공백을 허용합니다. 45줄은 빈 일치가 나와 무한 반복되는 것을 막는 안전장치입니다.
  5. 47~58줄⑤ 형식 걸러내기연도 뒤 기호와 월 뒤 기호가 다르면(2026-10.12) 버립니다. 마침표형은 끝 마침표가 있어야 하고(7.5 같은 소수 제외), 기호형은 연도가 있어야 합니다(10-12 같은 범위 제외). 기호형 날짜 뒤의 문장 마침표는 날짜 끝에서 빼고, 일치 바로 앞 글자가 숫자·점·쉼표·기호면 더 긴 숫자의 일부로 보고 건너뜁니다.
  6. 60~76줄⑥ 연도 상속·실존 날짜 검증·중복 방지연도가 있으면 lastYear 로 기억하고, 없으면 같은 줄 앞쪽 연도를, 그것도 없으면 올해(new Date().getFullYear())를 씁니다. new Date(y, mo - 1, d) 를 만든 뒤 연·월·일이 그대로인지 확인해 2월 30일처럼 넘어간 날짜를 버립니다. 날짜 뒤 4글자가 '(일)'~'(토)' 로 시작하면 건너뛰고, 아니면 삽입 위치와 요일을 hits 에 넣습니다.
  7. 78~92줄⑦ 뒤에서부터 (요일) 넣기찾은 날짜가 없으면 예시 형식을 안내합니다. 있으면 hits 를 뒤에서부터 돌며 gotoParaPos 로 날짜 끝 위치로 이동하고, HAction.Execute("InsertText", …) 로 "(" + 요일 + ")" 를 넣습니다. 뒤쪽부터 넣어야 앞쪽 날짜의 위치값이 바뀌지 않습니다.
  8. 94~120줄⑧ 보조 함수gotoParaPos(n) 은 GetPosBySet() 으로 받은 위치 세트의 Pos 를 basePos + n 으로 바꿔 SetPosBySet 하고, 실제로 그 위치에 갔는지 다시 읽어 확인합니다. 실패하면 문단 처음에서 MoveNextChar 를 n번 반복합니다. alertMsg 는 XHwpMessageBox 로 안내창을 띄웁니다.

핵심 한글 API (HAction · HParameterSet …)

  • GetTextFile("TEXT", "saveblock") — 선택한 범위의 글자를 문자열로 돌려줍니다. CP949 밖 문자는 &#숫자; 엔티티로 오므로 복원이 필요합니다.
  • HAction.Run("MoveParaBegin") / ("MoveSelParaEnd") / ("Cancel") — 문단 처음으로 이동, 문단 끝까지 선택, 선택 해제입니다.
  • GetPosBySet() / ps.SetItem("Pos", want) / SetPosBySet(ps) — 현재 위치(List·Para·Pos)를 세트로 읽고, Pos 만 바꿔 그 위치로 캐럿을 옮깁니다.
  • HAction.Run("MoveNextChar") — 한 글자 오른쪽으로 이동합니다. Pos 직접 이동이 실패했을 때 대신 씁니다.
  • HAction.GetDefault/Execute("InsertText", HParameterSet.HInsertText.HSet) — HInsertText.Text 에 넣은 문자열을 캐럿 위치에 입력합니다.
  • XHwpMessageBox.String / Flag / DoModal() — 안내 문구를 넣고 확인 단추 하나짜리(Flag 0) 메시지 창을 띄웁니다.
  • new Date(y, m, d).getDay() — JavaScript 기본 날짜 객체입니다. 날짜 검증과 요일 번호(0=일~6=토) 계산에 씁니다.

부르는 공통 라이브러리 함수

  • 공통 라이브러리(L_*)를 쓰지 않습니다 — gotoParaPos(97줄)와 alertMsg(116줄)가 라이브러리의 L_setCaret·L_msg 와 같은 역할을 함수 안에서 직접 합니다.

이렇게 고쳐 쓰세요

  • '(월)' 대신 '(월요일)' 로 넣기 — 90줄 "(" + hits[i].w + ")" 를 "(" + hits[i].w + "요일)" 로 바꿉니다. 73줄 중복 검사는 '(월' 로 시작하는지만 보므로 그대로 두어도 다시 실행할 때 건너뜁니다.
  • 연도가 없을 때 기본 연도 고정 — 63줄 (new Date()).getFullYear() 를 2027 처럼 숫자로 바꾸면, 줄에 연도가 하나도 없을 때 그 해로 요일을 계산합니다.
  • 괄호 대신 대괄호 '[월]' 로 — 90줄의 "(", ")" 를 "[", "]" 로 바꾸고, 73줄 정규식 /^\s*\(\s*[일월화수목금토]/ 의 \( 를 \[ 로 바꿔야 재실행 때 중복으로 붙지 않습니다.

고칠 때 주의

  • 커서가 있는 문단 하나만 처리합니다. 여러 줄을 블록으로 잡아도 커서 문단만 바뀝니다.
  • 삽입은 반드시 뒤에서부터 해야 합니다. 84줄 반복 방향을 앞에서부터로 바꾸면 두 번째 날짜부터 위치가 밀립니다.
  • 엔티티 복원(26~30줄)을 지우면 ❍ 같은 기호가 있는 줄에서 글자 수가 달라져 요일이 엉뚱한 자리에 들어갑니다.

11개인정보마스킹 D-표정리-07 Alt+-

명단의 이름·휴대전화·주민번호를 한 번에 가립니다 (신규)

매크로 이름 개인정보마스킹 · 전체 738줄(공통 라이브러리 1~660줄 + 이 매크로 661~738줄) · .msr 61 KB

.msr 다운로드 61 KB
소스 보기 (738줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

표 밖에서는 커서 문단 하나를, 표 안에서는 L_tableGeom 으로 구한 표 전체 칸을 읽어 정규식으로 주민등록번호·휴대전화 번호를 찾고, 찾은 위치를 edits 목록(위치·지울 글자 수·넣을 글자)으로 만들어 L_applyEdits 로 오른쪽부터 바꿔 씁니다. 표 0행(제목 행)에 '이름·성명' 같은 낱말이 있는 열은 이름 열로 보고, 그 아래 칸의 2~4글자 한글 이름 가운데를 * 로 바꿉니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 666~672줄① 이름 가리기 함수 PM_maskName칸 글자를 L_trim 으로 다듬은 뒤 /^[가-힣]{2,4}$/ 에 맞을 때만 처리합니다. 2글자는 둘째 글자를, 3글자는 가운데 글자를, 4글자는 셋째 글자를 * 로 바꾸고, 형식이 맞지 않으면 원래 문자열을 그대로 돌려줍니다.
  2. 675~681줄② 주민등록번호 찾기정규식 /(\d{6})-\d{7}/g 를 exec 로 반복해 찾을 때마다 앞 6자리만 남긴 m[1] + "-*******" 를 edits 에 넣습니다. 찾은 구간은 spans 배열에 따로 저장해 두어 다음 단계의 휴대전화 검사에서 겹침 여부를 판단합니다.
  3. 684~697줄③ 휴대전화 번호 찾기/(01[016789])[-.\s]?(\d{3,4})[-.\s]?(\d{4})/g 로 하이픈·점·공백 구분이나 붙여 쓴 번호를 모두 찾습니다. 주민번호 구간과 겹치거나 앞뒤에 숫자가 더 붙어 있으면(더 긴 숫자의 일부) 건너뛰고, 나머지는 010-****-5678 꼴로 가운데를 가리는 edit 를 만듭니다.
  4. 705~714줄④ 표 밖: 커서 문단만 처리L_inTable() 이 거짓이면 L_paraText 로 커서 문단 글자를 읽어 PM_edits 를 적용합니다. 이름은 열 제목으로 판단할 수 없으므로 번호만 가리고, 처리 건수를 L_msg 로 알린 뒤 끝냅니다.
  5. 715~721줄⑤ 표 구조와 이름 열 판정L_tableGeom() 으로 행 수(R)·열 수(N)·첫 칸 List 번호를 얻고, 0행의 각 칸을 L_cellList 로 찾아 읽습니다. 제목에 '이름·성명·학생명·담당자·교사명·성 명' 이 들어 있으면 nameCols[c] = true 로 표시합니다.
  6. 722~737줄⑥ 표 전체 칸 순회와 결과 안내모든 행·열을 돌며 빈칸은 건너뛰고, 1행 이후의 이름 열 칸은 PM_maskName 결과가 달라졌을 때만 L_cellSet 으로 통째로 바꿉니다. 그 밖의 칸은 PM_edits 결과를 L_applyEdits 로 반영하고, 마지막에 커서를 원래 칸으로 돌린 뒤 번호·이름 처리 건수를 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • GetPosBySet() (L_here 내부) — 현재 캐럿의 List·Para·Pos 를 읽습니다. List 가 0 이 아니면 표 칸 안이라는 판정(L_inTable)에 쓰입니다.
  • GetTextFile("TEXT", "saveblock") (L_paraText 내부) — 선택한 블록(문단 처음~끝)의 글자를 텍스트로 받아 옵니다. CP949 밖 글자는 숫자 엔티티로 오므로 L_unesc 로 되돌려 씁니다.
  • HAction.Execute("InsertText", HParameterSet.HInsertText.HSet) (L_insertText 내부) — 캐럿 위치에 가린 문자열을 넣습니다. 그 전에 HAction.Run("Delete") 로 원래 번호 글자 수만큼 지웁니다.
  • HAction.Run("TableColBegin" / "TableLowerCell" / "TableUpperCell") (L_tableGeom 내부) — 표의 행 시작 칸과 위·아래 칸으로 이동해 열 수·행 수를 계산합니다. 실패해도 안전한 이동만 골라 씁니다.
  • XHwpMessageBox.DoModal() (L_msg 내부) — 처리 건수와 안내문을 대화상자로 보여 줍니다.

부르는 공통 라이브러리 함수

  • L_here / L_inTable — 캐럿 위치 읽기와 표 안 여부 판정
  • L_paraText / L_cellText — 문단·칸 글자 읽기
  • L_applyEdits — edits 목록을 오른쪽부터 적용(앞쪽 위치가 밀리지 않게)
  • L_tableGeom / L_cellList — 표 행·열 수와 (행,열) 칸의 List 번호 계산
  • L_cellSet — 칸 글자를 통째로 바꾸기
  • L_trim / L_msg — 공백 다듬기와 안내 대화상자

이렇게 고쳐 쓰세요

  • 이름 열로 인식할 제목 낱말 추가(예: 보호자) — 720줄 정규식 /이름|성명|학생명|담당자|교사명|성 명/ 끝에 |보호자 를 덧붙입니다. 0행 제목 칸에 그 낱말이 들어 있는 열이 이름 열로 처리됩니다.
  • 주민등록번호 뒷자리 첫 글자(성별 자리)는 남기기 — 677줄 정규식을 /(\d{6})-(\d)\d{6}/g 로 바꾸고, 679줄 넣을 글자를 m[1] + "-" + m[2] + "******" 로 바꿉니다. 지울 글자 수 m[0].length 는 그대로 두면 됩니다.
  • 휴대전화는 뒷자리 4개를 가리기 — 694줄 m[1] + "-****-" + m[3] 을 m[1] + "-" + m[2] + "-****" 로 바꿉니다.
  • 이름을 첫 글자만 남기고 모두 가리기 — 669~671줄을 var s = t.charAt(0); for (var i = 1; i < t.length; i++) { s += "*"; } return s; 로 바꾸면 세 글자 이름은 첫 글자 + **, 두 글자 이름은 첫 글자 + * 가 됩니다(671줄의 4글자 처리도 이 반복문이 대신합니다).

고칠 때 주의

  • 이름 가리기는 칸 글자 전체가 2~4글자 한글일 때만 동작합니다. '이름(담임)' 처럼 다른 글자가 섞이면 건드리지 않으며, 이름 열 칸에서는 번호 가리기도 건너뜁니다(730줄 continue).
  • L_tableGeom 은 모든 행의 칸 수가 같다고 가정하므로 병합 칸이 있는 표에서는 일부 칸을 놓치거나 다른 칸을 이름 열로 볼 수 있습니다. L_cellText 는 칸의 첫 문단만 읽는다는 점도 주의합니다.
  • edits 는 원래 글자 위치 기준이므로 반드시 L_applyEdits(오른쪽부터 적용)로 넣어야 합니다. 앞에서부터 직접 바꾸면 뒤쪽 위치가 밀립니다.

12표위치확인및제거 C-표계산-09 Alt+Shift+1

표 칸마다 주소([A1] [B2]…)를 빨간 안내문으로 — 계산식 값은 그대로, 칸을 골라 실행하면 고른 칸만

매크로 이름 표위치확인및제거 · 전체 768줄(공통 라이브러리 1~660줄 + 이 매크로 661~768줄) · .msr 65 KB

.msr 다운로드 65 KB
소스 보기 (768줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

표의 모든 칸(또는 셀 블록으로 고른 칸)을 L_tableCells 로 훑어 한글 표 계산식 주소(A1, B2 …)를 구하고, 칸 맨 앞에 안내문이 '[B2]' 인 누름틀(InsertFieldTemplate)을 넣어 위치를 보여 줍니다. 대상 칸에 이미 이 매크로의 누름틀(또는 예전 방식의 빨간 '[B2]' 글자)이 있으면 반대로 지우며, 표시·제거 때 쉼표 없는 서식의 계산식 필드는 L_formulaComma 로 쉼표 서식으로 바꿉니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 675~680줄① 표 안 확인과 상수 준비표 밖이면 안내 후 끝냅니다. 누름틀 도움말로 쓸 표식 문자열 HELP 와, 예전 방식 표시('[A1]' 글자)를 알아보는 정규식 /^\[[A-Z]{1,3}[0-9]{1,4}\]/ 를 준비합니다.
  2. 682~692줄② 셀 블록으로 고른 칸 알아내기TableFormula 의 기본값을 HFieldCtrl 에 읽어 Command 를 봅니다. 셀 블록 상태에서는 =(B2,C2,B3,C3) 꼴로 나오므로 괄호 안을 쉼표로 나눠 sel 객체에 주소를 담고, 끝나면 Cancel 로 대화상자 준비 상태를 취소합니다.
  3. 694~699줄③ 표 전체 칸과 대상 칸 목록L_tableCells() 로 병합 칸까지 포함한 모든 칸의 List 번호와 주소(addr)를 얻습니다. 고른 칸이 있으면 그 주소에 해당하는 칸만, 없으면 표 전체를 targets 에 담습니다.
  4. 701~726줄④ 지금 표시 상태 판정L_ctrlMap() 으로 문서의 누름틀(%clk)·계산식 필드(%fmu)를 칸별로 모읍니다. ours() 는 명령 문자열에 HELP 가 든 누름틀을, oldMark() 는 첫 글자가 빨간색(TextColor 255 = BGR 0x0000FF)인 '[B2]' 글자를 찾으며, 대상 칸 중 하나라도 표시가 있으면 removing 을 참으로 둡니다.
  5. 728~742줄⑤ 제거 모드우리 누름틀은 DeleteCtrl 로 지우고, 예전 빨간 글자 표시는 칸 맨 앞에서 그 길이만큼 Delete 를 실행해 지웁니다. 지운 뒤 L_ctrlMap 을 다시 만들어 계산식 필드에 L_formulaComma 를 적용합니다.
  6. 743~755줄⑥ 표시 모드: 누름틀 넣기먼저 계산식 필드의 쉼표 서식을 맞춘 뒤, 각 칸 맨 앞으로 가서 InsertFieldTemplate 을 실행합니다. TemplateDirection(안내문)은 '[B2]', TemplateHelp 는 HELP, TemplateName 은 '표위치_B2' 로 넣고 성공한 칸 수를 셉니다.
  7. 757~767줄⑦ 커서 정리와 결과 안내원래 칸으로 돌아가 MoveParaEnd 로 칸 글자 끝에 커서를 둡니다(누름틀 안에 타이핑되지 않게). 범위(고른 칸 수 또는 행×열)와 쉼표 서식 수정 수를 담아 표시·제거 결과를 알립니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.GetDefault("TableFormula", HParameterSet.HFieldCtrl.HSet) — 표 계산식 대화상자의 기본값을 읽습니다. 여기서는 Command 값에서 셀 블록으로 고른 칸 주소 목록을 얻는 데 씁니다.
  • HAction.Execute("InsertFieldTemplate", HParameterSet.HInsertFieldTemplate.HSet) — 캐럿 위치에 누름틀을 넣습니다. TemplateDirection(안내문)·TemplateHelp·TemplateName 을 채워 칸 주소를 표시합니다.
  • DeleteCtrl(ctrl) — L_ctrlMap 이 찾아 둔 누름틀 컨트롤 객체를 문서에서 지웁니다. 칸의 글자는 건드리지 않습니다.
  • HeadCtrl / CtrlID / Properties.Item("Command") / GetAnchorPos(0) (L_ctrlMap 내부) — 문서의 컨트롤을 처음부터 따라가며 종류(%clk, %fmu)·명령 문자열·들어 있는 칸(List)을 모읍니다.
  • HAction.GetDefault("CharShape", HParameterSet.HCharShape.HSet) — 선택한 첫 글자의 글자 모양을 읽어 TextColor 가 255(빨강)인지로 예전 표시인지 판단합니다.
  • HAction.GetDefault("TablePropertyDialog", HParameterSet.HShapeObject.HSet) (L_tableCells 내부) — 칸마다 너비·높이를 읽어 병합 칸이 있는 표에서도 열·행 번호와 주소를 계산합니다.

부르는 공통 라이브러리 함수

  • L_tableCells — 병합 칸을 포함한 모든 칸의 List 번호와 계산식 주소(A1 …)
  • L_ctrlMap — 칸별 누름틀(%clk)·계산식 필드(%fmu) 지도
  • L_formulaComma — 쉼표 없는 서식(%g)의 계산식 필드를 쉼표 서식(%g,)으로 다시 넣기
  • L_cellText / L_gotoPara — 칸 글자 읽기와 칸 첫 문단으로 이동
  • L_inTable / L_here / L_trim / L_msg — 표 안 판정·위치·문자열·안내

이렇게 고쳐 쓰세요

  • 표시를 대괄호 없이 'B2' 로만 보이기 — 750줄 "[" + targets[i].addr + "]" 를 targets[i].addr 로 바꿉니다. 제거는 705줄에서 TemplateHelp(HELP) 로 찾으므로 그대로 동작합니다.
  • 계산식 필드의 쉼표 서식은 건드리지 않기 — 742줄과 744줄의 for (…) { if (L_formulaComma(…)) { fixedComma++; } } 문장을 지웁니다. 그러면 commaMsg 도 빈 문자열이 됩니다.
  • 누름틀 이름 앞머리 바꾸기 — 752줄 "표위치_" 를 원하는 접두어로 바꿉니다. 이름은 표시 판정에 쓰이지 않으므로 이 줄만 바꾸면 됩니다.

고칠 때 주의

  • 679줄 HELP 문자열을 바꾸면 이미 문서에 넣어 둔 누름틀을 '우리 표시'로 알아보지 못해 지울 수 없게 됩니다. 바꾸기 전에 기존 표시를 먼저 지우십시오.
  • 고른 칸 인식은 셀 블록일 때 TableFormula 기본 Command 가 =(B2,C2,…) 로 나온다는 실측 동작에 기대고 있습니다. 블록이 아니면 sel 이 null 이 되어 표 전체가 대상입니다.
  • removing 은 대상 칸 중 하나라도 표시가 있으면 참이 되므로, 일부 칸만 표시된 상태에서 표 전체로 실행하면 나머지 칸에 새로 표시하지 않고 지우기만 합니다.

13표계산식적용및제거 C-표계산-10 Alt+Shift+2

타이핑한 =C2/B2 같은 글자를 진짜 표 계산식으로 (적용) — 다시 실행하면 값만 남기고 계산식 제거

매크로 이름 표계산식적용및제거 · 전체 749줄(공통 라이브러리 1~660줄 + 이 매크로 661~749줄) · .msr 64 KB

.msr 다운로드 64 KB
소스 보기 (749줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

L_tableCells 로 표의 모든 칸을 훑으면서 캐럿을 둔 칸의 CurFieldState 로 계산식 필드가 있는지 보고, 없으면 '=' 로 시작하는 글자를 모읍니다. '=' 글자 칸이 있으면 그 글자를 지우고 TableFormula 액션으로 진짜 표 계산식 필드를 넣고(적용), 없고 필드만 있으면 예/아니요 대화상자로 확인한 뒤 보이는 값만 일반 글자로 다시 써서 필드를 없앱니다(제거).

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 673~676줄① 표 안 확인L_inTable() 이 거짓이면 계산식을 타이핑한 표나 계산식 필드가 든 표 안에서 실행하라고 안내하고 끝냅니다.
  2. 677~689줄② 표 전체 칸 분류L_tableCells() 의 칸마다 첫 문단으로 가서 CurFieldState 가 2 인지(필드 칸) 보고, 아니면 한 글자 옮겨 한 번 더 확인합니다. 필드가 아니면 맨 앞의 '[D2]' 같은 주소 표시를 떼고 읽어, 두 글자 이상이면서 '=' 로 시작하는 칸을 typed 에 담습니다.
  3. 691~696줄③ 적용·제거 갈림길typed 가 있으면 apply(), 없고 fields 가 있으면 remove() 를 부르고, 둘 다 없으면 예시 계산식을 담아 안내합니다. apply·remove 는 아래에 선언된 내부 함수지만 JScript 함수 선언은 미리 올라가므로 여기서 부를 수 있습니다.
  4. 698~705줄④ 글자색을 검정으로 (blackPara)칸 첫 문단 전체를 선택하고 CharShape 의 TextColor 를 0(검정, BGR 0x000000)으로 실행합니다. 예전에 빨갛게 표시된 흔적이 계산 결과에 남지 않게 합니다.
  5. 707~714줄⑤ 계산식 문자열 다듬기와 검사공백(전각 포함)을 없애고 × ÷ - + 를 * / - + 로 바꾼 뒤 대문자로 만듭니다. /^=[A-Z0-9()+\-*\/:.,]+$/ 에 맞지 않으면 적용하지 않고 bad 목록에 칸 주소와 원문을 넣습니다.
  6. 715~731줄⑥ 표 계산식 필드 넣기L_cellSet 으로 타이핑한 글자를 지우고 글자색을 검정으로 맞춘 다음, HFieldCtrl 의 Command 를 수식 + "??%g,;;" 로 넣어 TableFormula 를 실행합니다. 성공하면 오른쪽 정렬과 검정색을 적용하고, 실패하면 원래 글자를 되살린 뒤 결과를 안내합니다.
  7. 734~738줄⑦ 제거 확인 대화상자XHwpMessageBox 의 Flag 를 4 + 32(예/아니요 + 물음표)로 띄우고, Result 가 6([예])이 아니면 커서만 원래 칸으로 돌리고 끝냅니다.
  8. 739~747줄⑧ 값만 남기고 필드 제거각 필드 칸에서 지금 보이는 계산 결과를 L_cellText 로 읽고, 숫자면 L_cellSetNum(오른쪽 정렬 포함), 아니면 L_cellSet 으로 같은 글자를 다시 씁니다. 칸을 지우고 다시 쓰는 과정에서 필드가 사라지며, 처리 수를 알립니다.

핵심 한글 API (HAction · HParameterSet …)

  • CurFieldState — 캐럿이 있는 자리의 필드 상태 값입니다. 이 매크로는 계산식 필드 칸이면 2 가 나온다는 실측을 이용해 필드 칸을 가려냅니다.
  • HAction.GetDefault / Execute("TableFormula", HParameterSet.HFieldCtrl.HSet) — 표 계산식 필드를 넣습니다. Command 에 =SUM(B2:B4)??%g,;; 처럼 수식과 숫자 서식(%g, = 천 단위 쉼표)을 함께 넣어야 결과가 보입니다.
  • HParameterSet.HFieldCtrl.HSet.SetItem("Command", …) — 파라미터 셋의 항목 값을 이름으로 직접 지정합니다.
  • HAction.Execute("CharShape", HParameterSet.HCharShape.HSet) — 선택 범위의 글자 모양을 바꿉니다. 여기서는 TextColor = 0 으로 검정색을 지정합니다.
  • XHwpMessageBox.Flag / DoModal / Result — 예/아니요 대화상자를 띄우고 누른 단추를 Result 로 받습니다(6 = 예).
  • HAction.Run("MoveSelParaEnd") / HAction.Run("Cancel") — 문단 끝까지 선택하고, 서식 적용 뒤 선택을 풉니다.

부르는 공통 라이브러리 함수

  • L_tableCells — 병합 칸 포함 모든 칸의 List 번호와 주소
  • L_cellText / L_cellSet / L_cellSetNum — 칸 글자 읽기·다시 쓰기·숫자 오른쪽 정렬
  • L_alignRight — 칸 문단을 오른쪽 정렬(ParagraphShape AlignType 2)
  • L_cellNum — 칸 글자에서 숫자 값 얻기(△·- 부호 포함)
  • L_gotoPara / L_here / L_inTable / L_trim / L_msg — 이동·위치·판정·안내

이렇게 고쳐 쓰세요

  • 계산 결과에 천 단위 쉼표를 넣지 않기 — 721줄 f + "??%g,;;" 를 f + "??%g;;" 로 바꿉니다(쉼표 서식 기호 , 를 뺌).
  • 계산 결과를 파란색으로 보이기 — 702줄 TextColor = 0 을 TextColor = 0xFF0000 으로 바꿉니다. 한글 색상값은 0x00BBGGRR(BGR) 순서라 0xFF0000 이 파랑입니다.
  • 제거할 때 확인 대화상자 없이 바로 진행 — 735~738줄(XHwpMessageBox 설정·DoModal·Result 검사)을 지웁니다. 실수로 실행해도 Ctrl+Z 로 되돌릴 수 있지만 확인 단계는 사라집니다.

고칠 때 주의

  • 714줄 검사식은 영문 대문자·숫자·괄호·사칙연산·콜론·점·쉼표만 허용합니다. 한글 낱말이나 % 같은 기호가 섞인 계산식은 적용되지 않고 '적용 못 한 칸' 으로 보고됩니다.
  • 적용과 제거는 691~692줄에서 자동으로 갈립니다. 표에 '=' 글자 칸이 하나라도 남아 있으면 계산식 필드가 있어도 제거 단계로 가지 않으므로, 제거하려면 먼저 '=' 글자 칸을 모두 적용하거나 지워야 합니다.
  • 제거는 DeleteCtrl 대신 값을 읽어 칸을 다시 쓰는 방식이라 칸의 첫 문단만 남습니다. 여러 문단이 든 필드 칸은 확인 후 실행하십시오.

14선택셀표계산천원 C-표계산-01 Alt+Shift+3

산출기초 칸에 커서만 두면 오른쪽 예산 칸이 채워집니다

매크로 이름 선택셀표계산천원 · 전체 769줄(공통 라이브러리 1~660줄 + 이 매크로 661~769줄) · .msr 63 KB

.msr 다운로드 63 KB
소스 보기 (769줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

커서 칸의 산출기초(예: 1,400,000원×2교=)에서 곱셈 기호를 ×로 통일하고 L_calcExpr 로 곱한 값을 원 단위로 구한 뒤 1000으로 나눠 반올림한 천원 값을 만듭니다. 오른쪽 칸이 있으면 L_fillOrMark 로 채우거나 검증·수정하고, 행의 마지막 열이면 같은 칸의 '=' 뒤에 써 넣으며, TableLowerCell 로 한 행씩 내려가 표 끝까지 반복합니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 683~690줄① 표 안 확인과 집계 변수표 밖이면 산출기초 예시를 안내하고 끝냅니다. 채움·유지·수정·건너뜀·행 수를 셀 변수와 한 행의 칸 수 N(처음 한 번만 계산)을 준비합니다.
  2. 692~704줄② 행 시작 칸과 오른쪽 칸 유무TableColBegin 으로 행 첫 칸의 List 번호(rowBase)를 읽고 L_gotoPara 로 원래 칸에 돌아옵니다. L_rowColCount 로 구한 칸 수 N 과 비교해 (list - rowBase) < (N - 1) 이면 오른쪽 칸이 있다고 판단합니다. TableRightCell 을 시험 삼아 실패시키지 않으려는 장치입니다.
  3. 706~718줄③ 곱셈 기호 통일과 계산칸 글자가 비어 있지 않으면 L_mulEdits 로 숫자 사이의 *, X, x 위치를 찾아 L_applyEdits 로 칸 안에서 ×로 고친 뒤 다시 읽습니다. 마지막 '=' 앞부분을 식으로 잘라 L_calcExpr 에 넘깁니다.
  4. 720~730줄④ 오른쪽 칸에 천원 값 채우기Math.round(calc.won / 1000) 로 천원 값을 만들고, 오른쪽 칸이 있으면 TableRightCell 로 옮겨 L_fillOrMark 를 부릅니다. 빈칸이면 채우고, 같으면 두고, 다르면 고쳐 쓴 뒤 빨간색으로 표시하며, TableLeftCell 로 돌아옵니다.
  5. 731~749줄⑤ 마지막 열이면 '=' 뒤에 쓰기오른쪽 칸이 없고 '=' 가 있으면 '=' 뒤가 비었을 때 L_cellSet 으로 식과 금액을 이어 씁니다. 이미 값이 있으면 L_cellNum 으로 비교해 0.5 미만 차이면 그대로 두고, 아니면 '=' 뒤만 L_applyEdits 로 바꾼 뒤 L_cellRed 로 칸 글자를 빨갛게 합니다.
  6. 750~764줄⑥ 건너뛰기와 다음 행 이동식이 없거나 계산되지 않는 칸은 skipped 로 셉니다. TableLowerCell 이 실패하거나 List 번호가 그대로면 표 끝으로 보고 반복을 멈추며, guard 가 2000 을 넘어도 멈춥니다.
  7. 766~768줄⑦ 결과 안내확인한 행 수와 새로 채움·정상 확인·값 수정(적색 표시)·건너뜀 건수를 L_msg 로 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.Run("TableColBegin") — 현재 행의 첫 칸으로 이동합니다. 실패하지 않는 이동이라 행 시작 List 번호를 읽는 데 씁니다.
  • HAction.Run("TableRightCell") / HAction.Run("TableLeftCell") — 오른쪽·왼쪽 칸으로 이동합니다. 실패하면 뒤이은 Delete/InsertText 가 무시되는 동작이 있어, 오른쪽 칸이 있다고 확인된 경우에만 부릅니다.
  • HAction.Run("TableLowerCell") — 아래 칸으로 이동해 다음 행을 처리합니다. 실패 여부와 List 번호 변화로 표 끝을 판단합니다.
  • HAction.Execute("CharShape", HParameterSet.HCharShape.HSet) (L_cellRed 내부) — TextColor = 255(BGR 0x0000FF, 빨강)로 고친 값을 표시합니다.
  • HAction.Execute("ParagraphShape", HParameterSet.HParaShape.HSet) (L_alignRight 내부) — 결과 칸을 AlignType = 2(오른쪽 정렬)로 맞춥니다.

부르는 공통 라이브러리 함수

  • L_rowColCount — TableRightCell 없이 한 행의 칸 수 계산
  • L_mulEdits / L_applyEdits — 숫자 사이 *, X, x 를 ×로 고치기
  • L_calcExpr — ×로 나눈 각 인수의 마지막 숫자를 곱하고 천원·원 단위를 원으로 환산
  • L_fillOrMark — 빈칸 채우기 / 같으면 유지 / 다르면 고쳐 쓰고 빨간색 표시
  • L_cellText / L_cellSet / L_cellNum / L_cellRed — 칸 읽기·쓰기·숫자 해석·적색 표시
  • L_fmtNum — 반올림한 정수에 천 단위 쉼표

이렇게 고쳐 쓰세요

  • 천원 대신 원 단위로 채우기 — 721줄 Math.round(calc.won / 1000) 을 Math.round(calc.won) 으로 바꿉니다. L_fillOrMark 와 L_fmtNum 은 받은 숫자를 그대로 쉼표 표기하므로 다른 곳은 고치지 않아도 됩니다.
  • 나누기·더하기가 섞인 산출기초도 계산 — 718줄 var calc = L_calcExpr(formula); 를 var ev = L_evalExpr(formula); var calc = { ok: ev.ok, won: ev.val }; 로 바꿉니다. L_evalExpr 는 공통 라이브러리에 있는 사칙연산 계산기로, 금액이면 원 단위 값을 val 로 돌려줍니다.
  • 마지막 열에서 틀린 값을 고칠 때 빨간색 표시는 하지 않기 — 746줄 L_cellRed(list); 를 지웁니다. 오른쪽 칸 쪽의 빨간 표시는 공통 함수 L_fillOrMark(라이브러리 334줄)에서 하므로 그쪽은 따로 고쳐야 합니다.

고칠 때 주의

  • L_calcExpr 는 × 로만 식을 나누고 각 인수의 마지막 숫자를 곱합니다. +, ÷ 가 든 식은 기대와 다른 값이 나오므로 그런 표에는 L_evalExpr 로 바꿔 쓰는 편이 안전합니다.
  • 오른쪽 칸 유무는 '모든 행의 칸 수가 같다'는 가정으로 계산합니다. 병합 칸이 있는 행에서는 hasRight 가 틀려 TableRightCell 이 실패할 수 있고, 그 뒤 글자 쓰기가 무시될 수 있습니다.
  • 라이브러리 함수(L_fillOrMark, L_calcExpr 등)를 고치면 이 함수를 쓰는 다른 표 계산 매크로도 함께 바뀝니다.

15증감포함표계산천원 C-표계산-03 실행 창(Alt+Shift+L)

예산(A)·예산(B)·증감·합계 행까지 한 번에

매크로 이름 증감포함표계산천원 · 전체 767줄(공통 라이브러리 1~660줄 + 이 매크로 661~767줄) · .msr 63 KB

.msr 다운로드 63 KB
소스 보기 (767줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

커서 칸을 A 산출기초로 보고 오른쪽으로 [예산A][B 산출기초][예산B][증감] 다섯 칸이 이어진다고 가정해, 각 산출기초를 L_readFormula 로 천원 값으로 계산해 예산 칸을 채우거나 검증하고 증감(A-B)을 음수면 △ 로 씁니다. 다음 행이 있는 동안 한 행씩 내려가며 합계를 모으고, 다음 행이 없는 마지막 행에는 누적 합계를 예산A·예산B·증감 칸에 넣습니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 675~683줄① 표 안 확인과 누적 변수표 밖이면 칸 순서를 안내하고 끝냅니다. 처리 건수와 함께 예산A·예산B 의 누적 합계 sumA, sumB 를 0 으로 준비합니다.
  2. 685~696줄② 다음 행이 있는지 미리 보기TableLowerCell 이 성공하고 List 번호가 바뀌면 hasNext 를 참으로 두고 TableUpperCell 로 곧바로 되돌아옵니다. 다음 행이 없는 행을 합계 행으로 보기 위한 판정입니다.
  3. 699~707줄③ A 산출기초 → 예산AL_readFormula 가 칸의 곱셈 기호를 ×로 고치고 '=' 앞 식을 계산해 천원 값(want)을 돌려줍니다. 계산되면 TableRightCell 로 옮겨 L_fillOrMark 로 채우거나 검증하고 TableLeftCell 로 돌아옵니다.
  4. 709~720줄④ B 산출기초 → 예산BL_tableRight(2) 로 두 칸 오른쪽(B 산출기초)으로 가서 같은 방식으로 계산하고, 그 오른쪽 예산B 칸을 L_fillOrMark 로 처리합니다.
  5. 721~731줄⑤ 증감 칸과 제자리 복귀A·B 중 하나라도 계산되면 다시 두 칸 오른쪽 증감 칸에 aInfo.want - bInfo.want 를 L_fillOrMarkSigned 로 씁니다(음수는 △). 끝나면 L_tableLeft(4) 또는 L_tableLeft(2) 로 A 산출기초 칸으로 돌아옵니다.
  6. 734~740줄⑥ 누적과 다음 행둘 다 없으면 건너뜀으로 세고, 계산된 값만 sumA·sumB 에 더합니다. L_gotoPara 로 A 칸을 확실히 다시 잡은 뒤 TableLowerCell 로 내려갑니다.
  7. 741~761줄⑦ 마지막 행 = 합계 행다음 행이 없으면 오른쪽 예산A 칸에 sumA, 세 칸 오른쪽 예산B 칸에 sumB, 그 두 칸 오른쪽 증감 칸에 sumA - sumB(△ 표기)를 L_fillOrMark 계열로 넣고 반복을 끝냅니다.
  8. 764~766줄⑧ 결과 안내합계 행을 포함한 행 수와 채움·유지·수정·건너뜀 건수를 L_msg 로 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.Run("TableLowerCell") / HAction.Run("TableUpperCell") — 아래 칸으로 갔다가 위로 되돌아와 다음 행 존재 여부를 확인하고, 행 단위로 내려가는 데 씁니다.
  • HAction.Run("TableRightCell") / HAction.Run("TableLeftCell") — 산출기초 칸과 결과 칸 사이를 한 칸씩 오갑니다. L_tableRight/L_tableLeft 는 이것을 n 번 반복합니다.
  • HAction.Execute("CharShape", HParameterSet.HCharShape.HSet) (L_cellRed 내부) — 틀린 값을 고친 칸의 글자를 TextColor = 255(BGR 0x0000FF, 빨강)로 표시합니다.
  • HAction.Execute("InsertText", HParameterSet.HInsertText.HSet) (L_cellSet 내부) — 칸 글자를 지운 뒤 계산 결과 문자열을 넣습니다.
  • HAction.Execute("ParagraphShape", HParameterSet.HParaShape.HSet) (L_alignRight 내부) — 결과 칸을 오른쪽 정렬(AlignType = 2)로 맞춥니다.

부르는 공통 라이브러리 함수

  • L_readFormula — 곱셈 기호 정정 후 '=' 앞 식을 계산해 {ok, want(천원)} 반환
  • L_fillOrMark — 빈칸 채우기 / 같으면 유지 / 다르면 고쳐 쓰고 빨간색 표시
  • L_fillOrMarkSigned — 위와 같되 음수를 △ 로 표기(증감 칸)
  • L_tableRight / L_tableLeft — 표 안에서 n칸 좌우 이동
  • L_gotoPara / L_here / L_inTable / L_msg — 칸 이동·위치·판정·안내

이렇게 고쳐 쓰세요

  • 증감 칸의 음수를 △ 대신 - 로 표기 — 723줄과 755줄의 L_fillOrMarkSigned 를 L_fillOrMark 로 바꿉니다. L_fillOrMark 는 L_fmtNum 을 써서 음수를 '-1,234' 처럼 씁니다.
  • 증감을 B-A(전년 대비가 아니라 반대 방향)로 계산 — 723줄 aInfo.want - bInfo.want 를 bInfo.want - aInfo.want 로, 755줄 sumA - sumB 를 sumB - sumA 로 함께 바꿉니다.
  • 마지막 행에 합계를 쓰지 않기(합계 행이 없는 표) — 741~761줄의 else 블록 안에서 L_fillOrMark 를 부르는 부분을 지우고 rows++; break; 만 남깁니다. 마지막 행도 데이터로 계산하려면 hasNext 판정(692~696줄)을 다시 설계해야 합니다.

고칠 때 주의

  • 669줄 주석은 '틀리면 값 보존 + 적색표시' 라고 하지만, 실제로 쓰는 L_fillOrMark 는 올바른 값으로 고쳐 쓴 뒤 빨간색으로 표시합니다. 동작은 라이브러리 코드를 기준으로 판단하십시오.
  • 이 매크로는 TableRightCell 을 미리 검사하지 않고 부릅니다. 칸이 다섯 개보다 적거나 병합 칸이 있는 표에서는 이동이 실패할 수 있고, 그 뒤 글자 쓰기가 무시되는 한글 엔진 동작이 생길 수 있으므로 열 구성을 맞춘 표에서만 실행하십시오.
  • 표의 마지막 행을 무조건 합계 행으로 봅니다. 합계 아래에 비고 행 등이 더 있으면 그 행에 합계가 들어갑니다.

16합계행자동서식 D-표정리-05 Alt+Shift+5

표의 합계 행을 굵게 + 위쪽 이중 실선(0.5mm)으로

매크로 이름 합계행자동서식 · 전체 716줄(공통 라이브러리 1~660줄 + 이 매크로 661~716줄) · .msr 59 KB

.msr 다운로드 59 KB
소스 보기 (716줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

커서 칸에서 TableLowerCell 을 더 이상 내려갈 수 없을 때까지 반복해 표의 마지막 행(합계 행)으로 간 뒤, TableColBegin 으로 행 첫 칸에서 시작해 TableRightCell 이 실패할 때까지 칸마다 처리합니다. 각 칸은 글자 전체를 선택해 CharShape 로 굵게 하고, CellBorder 액션으로 위쪽 테두리를 이중 실선 0.5mm 검정으로 바꿉니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 668~671줄① 표 안 확인L_inTable() 이 거짓이면 표 안 칸에 커서를 두라고 안내하고 끝냅니다.
  2. 673~682줄② 마지막 행까지 내려가기TableLowerCell 이 실패하거나 이동 뒤에도 List 번호가 그대로이면 마지막 행에 도착한 것으로 봅니다. guard 가 2000 을 넘으면 무한 반복을 막기 위해 멈춥니다.
  3. 684~692줄③ 행 첫 칸에서 순회 시작TableColBegin 으로 마지막 행의 첫 칸으로 이동하고, 칸마다 현재 List 번호를 읽어 처리합니다. scanGuard 300 은 칸 순회 안전장치입니다.
  4. 694~700줄④ 칸 글자 굵게L_gotoPara 로 칸 첫 문단 처음에 가서 MoveSelParaEnd 로 문단 끝까지 선택하고, CharShape 의 Bold = 1 을 실행한 뒤 Cancel 로 선택을 풉니다.
  5. 702~709줄⑤ 위쪽 테두리 = 이중 실선 0.5mmCellBorder 기본값을 HCellBorderFill 에 읽고 BorderTypeTop = 8(이중 실선), BorderWidthTop = 7(0.5mm), BorderColorTop = 0(검정)을 넣어 실행합니다. 주석에 따르면 8·7 은 한글에서 실측한 값입니다.
  6. 711~715줄⑥ 다음 칸과 결과 안내처리한 칸 수를 세고 TableRightCell 이 실패하면 행 끝으로 보고 멈춥니다. 마지막으로 처리 칸 수를 L_msg 로 알립니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.Run("TableLowerCell") — 아래 칸으로 이동합니다. 실패하거나 List 번호가 바뀌지 않으면 표의 마지막 행입니다.
  • HAction.Run("TableColBegin") / HAction.Run("TableRightCell") — 행 첫 칸으로 간 뒤 오른쪽으로 한 칸씩 이동합니다. TableRightCell 실패를 행 끝 신호로 씁니다.
  • HAction.GetDefault / Execute("CharShape", HParameterSet.HCharShape.HSet) — 선택한 칸 글자의 글자 모양을 읽고 Bold = 1(굵게)로 바꿉니다.
  • HAction.GetDefault / Execute("CellBorder", HParameterSet.HCellBorderFill.HSet) — 캐럿이 있는 칸의 테두리를 바꿉니다. BorderTypeTop·BorderWidthTop·BorderColorTop 으로 위쪽 선만 지정합니다.
  • HAction.Run("MoveSelParaEnd") / HAction.Run("Cancel") — 칸 문단 끝까지 선택하고 서식 적용 뒤 선택을 풉니다.

부르는 공통 라이브러리 함수

  • L_inTable — 커서가 표 칸 안인지(List != 0) 판정
  • L_here — 현재 List 번호 읽기(행 끝·표 끝 판정)
  • L_gotoPara — 칸 첫 문단 처음으로 이동
  • L_msg — 결과 안내 대화상자

이렇게 고쳐 쓰세요

  • 합계 행 글자를 빨간색으로도 표시 — 698줄 HParameterSet.HCharShape.Bold = 1; 다음 줄에 HParameterSet.HCharShape.TextColor = 0x0000FF; 를 넣습니다. 한글 색상값은 0x00BBGGRR(BGR) 순서라 0x0000FF 가 빨강입니다.
  • 위쪽 테두리를 파란색으로 — 708줄 BorderColorTop = 0 을 BorderColorTop = 0xFF0000 으로 바꿉니다(BGR 순서에서 파랑).
  • 굵게는 빼고 테두리만 적용 — 694~700줄(굵게 처리 블록)을 지웁니다. 704줄 L_gotoPara 가 다시 칸으로 이동하므로 테두리 처리는 그대로 동작합니다.

고칠 때 주의

  • 선 종류 8, 굵기 7 은 코드 주석의 실측값입니다. 다른 선 종류·굵기로 바꾸려면 한글에서 값을 직접 확인한 뒤 넣으십시오.
  • 표의 맨 마지막 행을 합계 행으로 봅니다. 합계 아래 비고 행이 있거나 커서 열에 세로 병합 칸이 있으면 다른 행이 처리될 수 있습니다.
  • 행 끝 판정에 TableRightCell 실패를 씁니다. 라이브러리 주석에 따르면 이 실패 뒤에는 Delete/InsertText 가 무시될 수 있으므로, 이 반복 뒤에 글자를 고치는 코드를 덧붙이지 마십시오.

17금액한글표기 A-서식-05 Alt+Shift+6

1,234,000원·1,234천원·12백만원 뒤에 (금일백이십삼만사천원) 처럼 한글 금액을 자동으로

매크로 이름 금액한글표기 · 전체 712줄(공통 라이브러리 1~660줄 + 이 매크로 661~712줄) · .msr 59 KB

.msr 다운로드 59 KB
소스 보기 (712줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

커서 문단(표 안이면 칸의 첫 문단) 글자를 읽어 정규식으로 '숫자 + 원·천원·만원·백만원·천만원·억원' 금액을 모두 찾고, 단위를 곱해 원 단위 값으로 환산합니다. KW_num2kor 가 네 자리씩 끊어 '일백이십삼만사천' 같은 한글 금액을 만들면, 금액 바로 뒤에 '(금…원)' 을 끼워 넣는 edits 를 모아 L_applyEdits 로 한 번에 반영합니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 662~668줄① 숫자 → 한글 변환 준비자릿수 글자(D: 일~구), 네 자리 안의 단위(U: 십·백·천), 네 자리 묶음 단위(B: 만·억·조·경) 배열을 둡니다. 음수·소수는 Math.floor(Math.abs(n)) 로 정리하고 0 이면 '영' 을 돌려줍니다.
  2. 669~680줄② 네 자리씩 끊어 읽기n % 10000 으로 네 자리 묶음을 꺼내 일의 자리부터 숫자 + 단위를 앞에 붙입니다. 숫자가 0 인 자리는 건너뛰고, '일' 도 생략하지 않아 '일백', '일천' 처럼 적습니다(위변조 방지). 묶음이 비어 있지 않을 때만 만·억 등 묶음 단위를 붙입니다.
  3. 689~694줄③ 대상 문단과 금액 정규식표 안이면 문단 0, 아니면 커서 문단을 L_paraText 로 읽습니다. UNIT 표에 단위별 배수를 두고, 쉼표 숫자·일반 숫자(소수 포함) 뒤에 공백이 있어도 되는 단위 글자를 찾는 정규식을 만듭니다.
  4. 695~704줄④ 금액마다 삽입 위치 계산바로 뒤가 '(금' 이면 이미 처리된 것으로 건너뛰고, 앞 글자가 '.' 이나 ',' 이면 숫자 중간에서 잡힌 것으로 보고 건너뜁니다. Math.round(L_num(m[1]) * UNIT[m[2]]) 로 원 단위 값을 만들어 금액 끝 위치에 '(금' + 한글 + '원)' 을 넣는 edit(del 0)를 추가합니다.
  5. 705~711줄⑤ 적용과 안내찾은 금액이 없으면 예시를 보여 주고 끝냅니다. 있으면 L_applyEdits 로 오른쪽부터 끼워 넣고 커서를 문단으로 돌린 뒤, 처리 건수와 첫 번째 결과를 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • GetTextFile("TEXT", "saveblock") (L_paraText 내부) — 문단 처음부터 끝까지 선택한 블록의 글자를 텍스트로 읽습니다.
  • GetPosBySet() / SetPosBySet() (L_here·L_setCaret 내부) — 캐럿 위치를 읽고, 문단 기준 Pos 에 글자 위치를 더해 삽입할 자리로 캐럿을 옮깁니다.
  • HAction.Execute("InsertText", HParameterSet.HInsertText.HSet) (L_insertText 내부) — 캐럿 위치에 '(금…원)' 문자열을 넣습니다.
  • XHwpMessageBox.DoModal() (L_msg 내부) — 처리 건수나 실패 안내를 대화상자로 보여 줍니다.

부르는 공통 라이브러리 함수

  • L_here / L_inTable — 캐럿 위치와 표 안 여부
  • L_paraText — 문단 글자 읽기(엔티티 복원 포함)
  • L_num — 쉼표를 뺀 숫자 변환
  • L_applyEdits / L_setCaret / L_insertText — 오른쪽부터 정확한 글자 위치에 끼워 넣기
  • L_gotoPara / L_msg — 문단 이동과 안내

이렇게 고쳐 쓰세요

  • '(금…원)' 대신 '(일금…원정)' 으로 표기 — 702줄 "(금" + KW_num2kor(val) + "원)" 을 "(일금" + KW_num2kor(val) + "원정)" 으로 바꾸고, 중복 방지 검사인 697줄 text.substr(end, 2) === "(금" 도 text.substr(end, 3) === "(일금" 으로 함께 바꿉니다.
  • '일십·일백·일천' 에서 '일' 을 생략 — 673줄 s = D[d] + U[i] + s; 를 s = ((d === 1 && i > 0) ? "" : D[d]) + U[i] + s; 로 바꿉니다. 다만 주석대로 '일' 을 모두 적는 쪽이 위변조 방지에는 유리합니다.
  • '원' 단위 금액만 처리 — 694줄 정규식 끝의 (백만원|천만원|천원|만원|억원|원) 을 (원) 으로 줄입니다. 700줄은 UNIT["원"] = 1 을 쓰므로 그대로 둡니다.

고칠 때 주의

  • 697줄 '(금' 검사와 702줄 삽입 문자열은 짝입니다. 한쪽만 바꾸면 다시 실행할 때 같은 금액에 표기가 두 번 붙습니다.
  • '3.5백만원' 처럼 소수 금액은 700줄에서 원 단위로 반올림한 뒤 변환합니다. 원 미만 금액은 표기되지 않습니다.
  • 표 안에서는 칸의 첫 문단(para 0)만 처리합니다. 두 번째 문단 이후의 금액은 바뀌지 않습니다.

18엑셀에서표데이터값복사 D-표정리-06 Alt+Shift+7

엑셀에서 복사한 표를 붙여넣고 공백까지 정리

매크로 이름 엑셀에서표데이터값복사 · 전체 713줄(공통 라이브러리 1~660줄 + 이 매크로 661~713줄) · .msr 58 KB

.msr 다운로드 58 KB
소스 보기 (713줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

표 밖에서 실행하면 HAction.Run("Paste") 로 클립보드 내용을 붙여넣고, 캐럿을 왼쪽·위로 옮겨 새로 생긴 표 안으로 들어갔는지 확인합니다. 그 뒤(또는 처음부터 표 안이면 바로) L_tableGeom 과 L_cellList 의 List 번호 계산으로 표의 모든 칸을 돌며 L_cleanCellText 로 앞뒤 공백을 지우고 연속 공백을 하나로 줄여, 달라진 칸만 다시 씁니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 676~684줄① 표 밖이면 붙여넣기L_inTable() 이 거짓이면 try 안에서 Paste 액션을 실행합니다. 실패하거나 예외가 나면 Excel 에서 범위를 복사한 뒤 다시 실행하라고 안내하고 끝냅니다.
  2. 685~694줄② 새 표 안으로 들어가기붙여넣은 직후 캐럿은 표 다음 자리에 있으므로 MoveLeft, MoveUp 으로 표 안으로 옮깁니다. 그래도 표 밖이면 일반 텍스트만 붙은 것으로 보고 안내하며, 성공하면 pastedNew 를 참으로 둡니다.
  3. 696~708줄③ 표 전체 칸 정리L_tableGeom() 으로 행 수 R·열 수 N·첫 칸 List 번호를 얻고, 두 겹 반복으로 L_cellList(geom, r, c) 칸을 읽습니다. L_cleanCellText 결과가 원래 글자와 다를 때만 L_cellSet 으로 바꿔 쓰고 정리한 칸 수를 셉니다.
  4. 710~712줄④ 결과 안내새로 붙여넣었는지 기존 표를 썼는지, 행×열 크기, 정리한 칸 수를 L_msg 로 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.Run("Paste") — 클립보드 내용을 붙여넣습니다. 주석의 실측에 따르면 Excel 에서 복사하면 함께 들어가는 HTML 형식을 한글이 표로 붙여넣습니다.
  • HAction.Run("MoveLeft") / HAction.Run("MoveUp") — 붙여넣기 뒤 표 다음에 놓인 캐럿을 표 안 칸으로 옮깁니다.
  • GetPosBySet() (L_here·L_inTable 내부) — List 번호를 읽어 표 칸 안인지 확인하고, 칸 순회의 기준으로 씁니다.
  • HAction.Run("TableColBegin" / "TableLowerCell" / "TableUpperCell") (L_tableGeom 내부) — TableRightCell 을 쓰지 않고 표의 열 수·행 수를 계산합니다.
  • HAction.Execute("InsertText", HParameterSet.HInsertText.HSet) (L_cellSet 내부) — 칸 글자를 지운 뒤 정리된 글자를 다시 넣습니다.

부르는 공통 라이브러리 함수

  • L_inTable — 표 안 여부(List != 0)
  • L_tableGeom — 표의 첫 칸 List 번호·행 수·열 수
  • L_cellList — (행, 열) 칸의 List 번호를 산술로 계산
  • L_cellText / L_cellSet — 칸 글자 읽기·바꿔 쓰기
  • L_cleanCellText — 앞뒤 공백 제거 + 연속 공백·탭을 하나로
  • L_msg — 결과 안내

이렇게 고쳐 쓰세요

  • 숫자 칸은 오른쪽 정렬까지 — 703~706줄 if 블록이 끝나는 706줄 } 다음(707줄 앞)에if (/^-?[\d,]+(\.\d+)?$/.test(cleaned)) { L_alignRight(list); } 를 넣습니다. L_alignRight 는 공통 라이브러리 함수입니다.
  • 칸 안의 공백을 모두 없애기 — 702줄 L_cleanCellText(text) 를 L_cleanCellText(text).replace(/ /g, "") 로 바꿉니다. 라이브러리 함수를 직접 고치면 다른 매크로에도 영향이 가므로 이 줄에서 처리합니다.
  • 붙여넣기 없이 기존 표만 정리 — 678~694줄 if 블록을 표 밖이면 안내 후 return; 하도록 바꿉니다(예: if (!L_inTable()) { L_msg("표 안에서 실행하세요."); return; }).

고칠 때 주의

  • L_tableGeom 은 모든 행의 칸 수가 같다고 가정합니다. Excel 에서 병합 셀이 있는 범위를 붙여넣으면 일부 칸을 건너뛰거나 엉뚱한 칸을 읽을 수 있습니다.
  • L_cellText·L_cellSet 은 칸의 첫 문단만 다룹니다. 줄바꿈이 든 칸은 첫 줄만 정리됩니다.
  • 686~687줄의 MoveLeft·MoveUp 으로 표에 들어간다는 것은 실측 동작입니다. 붙여넣는 위치(문서 끝·표 바로 뒤 등)에 따라 다른 칸이나 다른 표로 들어갈 수 있으니 결과를 확인하십시오.

19글자수카운터 A-서식-06 Alt+Shift+8

글자 수·바이트 수를 바로 알려 줍니다

매크로 이름 글자수카운터 · 전체 703줄(공통 라이브러리 1~660줄 + 이 매크로 661~703줄) · .msr 58 KB

.msr 다운로드 58 KB
소스 보기 (703줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

먼저 GetTextFile("TEXT", "saveblock") 으로 선택 영역 글자를 읽고, 선택이 없어 null 이 오면 표 칸 안에서는 TableCellBlock 으로 현재 칸을, 그 밖에서는 SelectAll 로 문서 전체를 선택해 다시 읽습니다. 끝의 줄바꿈을 떼고 문단 구분을 \n 하나로 맞춘 뒤 공백 포함·제외 글자 수와, ASCII 1바이트·그 밖 2바이트로 셈한 추정 바이트 수를 보여 줍니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 670~684줄① 대상 범위 정하기선택 영역 글자가 있으면 '선택 영역', 없고 표 안이면 TableCellBlock 으로 칸을 선택해 읽은 뒤 Cancel 로 풀고 '현재 칸', 그 밖에는 SelectAll 로 문서 전체를 읽고 '문서 전체' 로 둡니다.
  2. 685~688줄② 글자 정규화null 이면 빈 문자열로 바꿉니다. L_unesc 로 숫자 엔티티를 원래 글자로 되돌리고, 끝에 붙는 \r\n 하나를 뗀 뒤 남은 \r\n 은 \n 으로 바꿔 문단 구분이 한 글자로 세어지게 합니다.
  3. 690~691줄③ 공백 포함·제외 글자 수공백 포함은 문자열 길이 그대로, 공백 제외는 /[\s ]/g(줄바꿈·탭·전각 공백 포함)를 지운 길이입니다.
  4. 693~697줄④ 추정 바이트 수줄바꿈은 빼고, 문자 코드가 127 이하이면 1, 그보다 크면 2 를 더합니다. 업무시스템 입력란처럼 한글을 2바이트로 세는 방식에 맞춘 추정치입니다.
  5. 699~702줄⑤ 결과 안내범위 이름과 세 가지 수치를 한 대화상자로 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • GetTextFile("TEXT", "saveblock") — 현재 선택 블록의 글자를 텍스트로 돌려줍니다. 선택이 없으면 null 을 돌려주는 점을 이용해 선택 여부를 판정합니다.
  • HAction.Run("TableCellBlock") — 캐럿이 있는 표 칸을 블록으로 선택합니다.
  • HAction.Run("SelectAll") — 문서 전체를 선택합니다.
  • HAction.Run("Cancel") — 글자를 읽은 뒤 선택을 풀어 원래 상태로 돌립니다.
  • XHwpMessageBox.DoModal() (L_msg 내부) — 글자 수 결과를 대화상자로 보여 줍니다.

부르는 공통 라이브러리 함수

  • L_inTable — 표 칸 안인지 판정
  • L_unesc — GetTextFile 이 돌려준 &#…; 숫자 엔티티를 원래 글자로 복원
  • L_msg — 결과 안내 대화상자

이렇게 고쳐 쓰세요

  • 바이트 수를 UTF-8 기준(한글 3바이트)으로 — 696줄 (text.charCodeAt(i) <= 127) ? 1 : 2 의 2 를 3 으로 바꿉니다. 다만 UTF-8 에서 일부 기호는 2바이트이므로 정확히 하려면 charCodeAt(i) <= 0x7FF ? 2 : 3 처럼 구간을 나눠야 합니다.
  • 줄바꿈도 바이트 수에 포함 — 695줄 if (text.charAt(i) === "\n") { continue; } 를 지웁니다. 그러면 줄바꿈 하나가 1바이트로 더해집니다.
  • 공백 포함 글자 수에서 줄바꿈 빼기 — 690줄 text.length 를 text.replace(/\n/g, "").length 로 바꿉니다.

고칠 때 주의

  • 688줄의 끝 \r\n 제거는 GetTextFile 이 덧붙이는 꼬리표를 떼는 것입니다. 이 줄을 지우면 모든 결과가 2글자씩 늘어납니다.
  • 바이트 수는 어림값입니다. 이모지처럼 서로게이트 쌍으로 표현되는 글자는 글자 수 2, 바이트 4 로 셉니다.
  • 표 칸 안에 커서를 두고 선택 없이 실행하면 문서 전체가 아니라 현재 칸만 셉니다(674~678줄). 문서 전체를 세려면 표 밖 본문에서 실행하십시오.

20기간일수계산 A-서식-03 Alt+Shift+9

'3. 2. ~ 3. 6.' 뒤에 (5일간) 을 자동으로 (신규)

매크로 이름 기간일수계산 · 전체 696줄(공통 라이브러리 1~660줄 + 이 매크로 661~696줄) · .msr 58 KB

.msr 다운로드 58 KB
소스 보기 (696줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

커서 문단(표 안이면 칸의 첫 문단) 글자에서 '연. 월. 일.(요일) ~ 연. 월. 일.' 꼴의 기간을 RegExp 로 모두 찾고, 연도가 없으면 앞 날짜는 올해, 뒤 날짜는 앞 날짜의 연도를 씁니다. 두 날짜로 Date 객체를 만들어 밀리초 차이를 86400000 으로 나눈 뒤 1 을 더한 달력 일수(시작·끝 포함)를 '(N일간)' 으로 기간 바로 뒤에 끼워 넣습니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 668~670줄① 대상 문단 읽기L_here 로 캐럿 위치를 읽고, 표 안이면 문단 0, 아니면 커서 문단을 L_paraText 로 읽습니다.
  2. 671~672줄② 날짜·기간 정규식 만들기날짜 패턴 D 는 '(연도. )월. 일.' 에 선택적인 '(월)' 같은 요일 괄호를 붙인 문자열입니다. 이를 두 번 이어 가운데에 ~, ∼, ~, -, – 구분자를 둔 RegExp 를 g 옵션으로 만듭니다. 문자열로 쓰므로 역슬래시를 두 번(\\d) 적습니다.
  3. 674~676줄③ 이미 처리된 기간 건너뛰기찾은 기간 끝 다음 8글자가 /^\s*\(\d+일/ 에 맞으면 이미 '(N일…' 이 붙은 것으로 보고 넘어갑니다.
  4. 677~683줄④ 일수 계산m[1]·m[4] 는 연도, m[2]·m[5] 는 월, m[3]·m[6] 은 일입니다. new Date(연, 월-1, 일) 로 두 날짜를 만들고 Math.round((d2 - d1) / 86400000) + 1 로 시작·끝을 포함한 일수를 구하며, 잘못된 날짜이거나 1 미만이면 건너뜁니다.
  5. 684~688줄⑤ 삽입 목록 만들기기간 끝 위치에 '(N일간)' 을 넣는 edit(del 0)를 추가하고, 첫 결과는 안내용 예시(sample)로 저장합니다.
  6. 689~695줄⑥ 적용과 안내찾은 기간이 없으면 예시를 보여 주고 끝냅니다. 있으면 L_applyEdits 로 오른쪽부터 끼워 넣고 커서를 문단으로 돌린 뒤 처리 건수와 예시를 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • new RegExp(D + "\\s*[~∼~\\-–]\\s*" + D, "g") — 같은 날짜 패턴을 두 번 이어 붙인 정규식을 문자열로 조립합니다. 캡처 그룹 6개(연·월·일 ×2)가 생깁니다.
  • new Date(y, m - 1, d) / getTime() — JScript 날짜 객체로 두 날짜의 밀리초 값을 얻어 차이를 계산합니다. 월은 0부터 시작하므로 1을 뺍니다.
  • GetTextFile("TEXT", "saveblock") (L_paraText 내부) — 문단 전체를 선택해 글자를 읽습니다.
  • HAction.Execute("InsertText", HParameterSet.HInsertText.HSet) (L_insertText 내부) — 기간 끝 위치에 '(N일간)' 문자열을 넣습니다.

부르는 공통 라이브러리 함수

  • L_here / L_inTable — 캐럿 위치와 표 안 여부
  • L_paraText — 문단 글자 읽기
  • L_applyEdits / L_setCaret — 오른쪽부터 정확한 위치에 끼워 넣기
  • L_gotoPara / L_msg — 문단 이동과 안내

이렇게 고쳐 쓰세요

  • '(5일간)' 대신 '(총 5일)' 로 표기 — 684줄 "(" + days + "일간)" 을 "(총 " + days + "일)" 로 바꾸고, 중복 검사인 676줄 정규식 /^\s*\(\d+일/ 도 /^\s*\(총 \d+일/ 로 함께 바꿉니다.
  • 끝날을 빼고 박(夜) 수로 계산 — 682줄 끝의 + 1 을 지우고, 683줄 days < 1 은 같은 날짜(0박)를 허용하려면 days < 0 으로 바꿉니다. 684줄 문구도 '박' 으로 고칩니다.
  • 물결표 대신 '부터'·'까지' 등 다른 구분자 허용 — 672줄 구분자 묶음 [~∼~\\-–] 안에 원하는 한 글자를 추가합니다(예: 전각 대시 '-'). 여러 글자 낱말은 묶음 대신 (?:[~∼~\\-–]|부터) 처럼 바꿉니다.

고칠 때 주의

  • '12. 28. ~ 1. 3.' 처럼 해를 넘기는 기간에 연도를 생략하면 뒤 날짜가 앞 날짜와 같은 해로 계산되어 일수가 1 미만이 되므로 건너뜁니다. 뒤 날짜에 연도를 적어 주십시오.
  • 앞 날짜에 연도가 없으면 실행하는 컴퓨터의 올해 연도를 씁니다(677줄). 지난해 문서를 처리할 때는 윤년 여부 등이 달라질 수 있습니다.
  • 676줄 중복 검사와 684줄 삽입 문구는 짝입니다. 한쪽만 바꾸면 다시 실행할 때 일수가 두 번 붙습니다.

21숫자자동콤마삽입 D-표정리-03 Alt+Shift+0

1400000 → 1,400,000, 천 단위 콤마를 한 번에

매크로 이름 숫자자동콤마삽입 · 전체 729줄(공통 라이브러리 1~660줄 + 이 매크로 661~729줄) · .msr 59 KB

.msr 다운로드 59 KB
소스 보기 (729줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

커서가 있는 행의 왼쪽 끝 칸부터 오른쪽 끝 칸까지 훑으면서, 칸 글자가 콤마 없는 순수 숫자일 때만 천 단위 콤마를 넣고 오른쪽 정렬합니다. 한 행이 끝나면 TableLowerCell 로 다음 행으로 내려가 표의 마지막 행까지 반복하며, 계산식 필드가 든 칸은 글자를 덮어쓰지 않고 필드의 숫자 서식만 쉼표 서식으로 바꿉니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 670~673줄① 표 안인지 확인L_inTable() 은 캐럿의 List 번호가 0(본문)이 아니면 표 안으로 봅니다. 표 밖이면 안내 메시지만 띄우고 끝냅니다.
  2. 675~683줄② 계산식 필드 지도 만들기L_ctrlMap() 으로 문서의 컨트롤을 한 번 훑어 칸(List)별 계산식 필드(%fmu)·누름틀 목록을 만들어 둡니다. 안쪽 함수 fmuOf(list) 는 그 칸에 계산식 필드가 있으면 그 정보를 돌려줍니다.
  3. 685~695줄③ 행 반복 시작바깥 while 은 행 단위, 안쪽 while 은 칸 단위 반복입니다. 매 행마다 HAction.Run("TableColBegin") 으로 행의 첫 칸으로 가며, guard(2000행)·scanGuard(300칸) 상한으로 무한 반복을 막습니다.
  4. 697~704줄④ 계산식 칸은 서식만 교체칸에 계산식 필드가 있으면 L_formulaComma() 가 필드를 지우고 같은 식을 쉼표 서식(%g,)으로 다시 넣습니다. 그런 다음 TableRightCell 로 다음 칸으로 가고, 실패하면(행 끝) 안쪽 반복을 빠져나옵니다.
  5. 705~716줄⑤ 순수 숫자 칸에 콤마 넣기칸 글자를 정규식 /^-?\d+(\.\d+)?$/ 로 검사해 콤마·단위·다른 글자가 없는 정수/소수(음수 포함)만 고릅니다. L_fmt(L_num(t)) 로 콤마를 넣은 문자열이 원래와 다를 때만 L_cellSetNum() 으로 다시 쓰고 오른쪽 정렬합니다.
  6. 719~726줄⑥ 다음 행으로 이동행 첫 칸으로 돌아가 List 번호를 기억한 뒤 TableLowerCell 을 실행합니다. 이동이 실패하거나 List 번호가 그대로면 마지막 행으로 보고 끝냅니다.
  7. 728줄⑦ 결과 안내확인한 행 수, 콤마를 넣은 칸 수, 쉼표 서식으로 바꾼 계산식 칸 수를 L_msg() 로 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.Run("TableColBegin") — 캐럿을 현재 행의 첫(왼쪽 끝) 칸으로 옮깁니다. 행을 훑기 전과 다음 행으로 내려가기 전에 씁니다.
  • HAction.Run("TableRightCell") — 오른쪽 칸으로 이동하며, 더 갈 칸이 없으면 false 를 돌려줍니다. 이 매크로는 그 실패를 행 끝 신호로 씁니다.
  • HAction.Run("TableLowerCell") — 아래 칸으로 이동합니다. 실패하거나 위치가 그대로면 표의 마지막 행으로 판단합니다.
  • HeadCtrl / CtrlID (L_ctrlMap 안) — 문서의 첫 컨트롤부터 Next 로 따라가며 CtrlID 가 %fmu(계산식)인 컨트롤과 그 명령 문자열을 모읍니다.
  • HAction.Execute("TableFormula", HParameterSet.HFieldCtrl.HSet) (L_formulaComma 안) — 계산식 필드를 지운 자리에 같은 식을 쉼표 있는 숫자 서식으로 다시 넣습니다.

부르는 공통 라이브러리 함수

  • L_inTable — 캐럿이 표 칸 안인지(List≠0) 확인
  • L_ctrlMap — 칸별 계산식 필드·누름틀 지도
  • L_formulaComma — 계산식 필드를 쉼표 서식으로 다시 넣기
  • L_cellText — 칸 첫 문단 글자 읽기
  • L_fmt / L_num — 콤마 넣기 / 콤마 떼고 숫자로
  • L_cellSetNum — 칸 글자 교체 + 오른쪽 정렬
  • L_msg — 결과 메시지 상자

이렇게 고쳐 쓰세요

  • 연도처럼 네 자리 숫자(2026 등)는 콤마를 넣지 않기 — 708줄 조건 /^-?\d+(\.\d+)?$/.test(t) 앞에 !/^\d{4}$/.test(t) && 를 덧붙이면 정확히 네 자리 정수는 건너뜁니다.
  • 오른쪽 정렬은 하지 않고 콤마만 넣기 — 711줄 L_cellSetNum(list, withComma) 를 L_cellSet(list, withComma) 로 바꿉니다(L_cellSet 은 글자만 바꾸고 정렬은 건드리지 않음).
  • 커서가 있는 행 하나만 처리하기 — 719줄 rows++; 바로 다음 줄에 break; 를 넣으면 다음 행으로 내려가지 않습니다.

고칠 때 주의

  • 콤마를 넣는 L_fmt 는 소수 둘째 자리에서 반올림합니다(lib 108줄). 그래서 3.14159 처럼 소수 셋째 자리 이상인 숫자는 3.14 로 바뀌어 값이 달라집니다.
  • 행 끝을 TableRightCell 실패로 판단하는데, 같은 라이브러리 주석(lib 265-267줄)은 TableRightCell 이 한 번 실패한 뒤 이어지는 Delete/InsertText 가 무시될 수 있다고 경고합니다. 칸 이동 방식을 바꿀 때는 이 점을 함께 확인하십시오.
  • 병합 칸이 있는 표에서는 TableColBegin/TableLowerCell 이동이 예상과 다를 수 있으니, 고친 뒤에는 병합 표로 꼭 시험해 보십시오.

22표빈칸하이픈채우기 D-표정리-04 Alt+Shift+-

표의 빈 칸을 한 번에 '-'로 채우고 가운데 정렬

매크로 이름 표빈칸하이픈채우기 · 전체 713줄(공통 라이브러리 1~660줄 + 이 매크로 661~713줄) · .msr 59 KB

.msr 다운로드 59 KB
소스 보기 (713줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

공통 라이브러리 L_tableCells() 로 병합 칸을 포함한 표의 모든 칸 목록과 행·열 번호를 먼저 구한 뒤, 커서가 있는 행부터 아래쪽 칸을 한 번씩만 검사합니다. 모든 문단이 비어 있는 칸에만 "-" 를 넣고 ParagraphShape 의 AlignType 을 3(가운데)으로 바꿉니다. 캐럿 이동으로 훑지 않으므로 병합 칸에서 같은 행을 되풀이하는 일이 없습니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 673~676줄① 표 안인지 확인L_inTable() 로 캐럿이 표 칸 안인지 보고, 아니면 안내 후 끝냅니다.
  2. 677~684줄② 칸 목록과 시작 행 구하기L_tableCells() 가 돌려주는 cells 배열(칸마다 list·row·col·rowSpan 등)에서 커서가 있던 칸(List 번호가 같은 칸)을 찾아 그 행 번호를 curRow 로 삼습니다. 병합 칸이면 맨 윗행 번호가 됩니다.
  3. 686~693줄③ 빈 칸 판정 함수cellEmpty(list) 는 칸의 문단을 0번부터 최대 50개까지 차례로 읽어, 앞뒤 공백을 뺀 글자가 하나라도 있으면 false 를 돌려줍니다. 공백만 있는 칸도 빈 칸으로 봅니다.
  4. 695~707줄④ 빈 칸에 "-" 넣고 가운데 정렬칸 목록을 한 번만 돌며, 병합 칸의 마지막 행(row + rowSpan - 1)이 커서 행보다 위인 칸은 건너뜁니다. 빈 칸이면 L_cellSet(c.list, "-") 로 글자를 넣고 ParagraphShape 의 AlignType 을 3 으로 실행해 가운데 정렬합니다.
  5. 708~712줄⑤ 마무리와 결과 안내확인한 행 수를 rowSeen 객체 키 개수로 세고, 캐럿을 원래 칸으로 돌려놓은 뒤 시작 행·확인한 칸 수·채운 칸 수를 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.GetDefault("ParagraphShape", HParameterSet.HParaShape.HSet) — 현재 문단 모양 값을 파라미터 셋으로 읽어 옵니다.
  • HParameterSet.HParaShape.AlignType = 3 — 문단 정렬을 가운데로 지정합니다(코드 주석 기준 오른쪽 = 2, 가운데 = 3).
  • HAction.Execute("ParagraphShape", HParameterSet.HParaShape.HSet) — 바꾼 문단 모양을 캐럿이 있는 문단에 적용합니다.
  • HAction.GetDefault("TablePropertyDialog", HParameterSet.HShapeObject.HSet) (L_tableCells 안) — ShapeType 3(셀)으로 칸의 너비·높이(ShapeTableCell.Width/Height)를 읽어 병합 칸의 위치를 계산하는 데 씁니다.
  • GetTextFile("TEXT", "saveblock") (L_paraText 안) — 선택한 문단 글자를 문자열로 가져와 빈 칸인지 판정합니다.

부르는 공통 라이브러리 함수

  • L_tableCells — 병합 칸 포함 칸 목록·행/열 번호
  • L_paraText — 문단 글자 읽기
  • L_gotoPara — 칸의 n번째 문단으로 이동(성공 여부 반환)
  • L_cellSet — 칸 글자 지우고 새로 쓰기
  • L_trim — 앞뒤 공백 제거
  • L_inTable / L_here — 표 안 확인·캐럿 위치
  • L_msg — 결과 메시지

이렇게 고쳐 쓰세요

  • "-" 대신 다른 표기(예: 전각 "-")로 채우기 — 701줄 L_cellSet(c.list, "-") 의 "-" 를 원하는 글자로 바꾸고, 712줄 안내 문구의 \"-\" 도 함께 고칩니다.
  • 가운데 대신 오른쪽 정렬 — 704줄 AlignType = 3 을 AlignType = 2 로 바꿉니다(숫자 칸 정렬에 쓰는 lib 313줄과 같은 값).
  • 커서 위치와 상관없이 표 전체(제목행 포함) 처리 — 698줄 if (c.row + c.rowSpan - 1 < curRow) { continue; } 한 줄을 지웁니다.

고칠 때 주의

  • 666줄 주석은 공백만 있는 칸을 대상에서 뺀다고 쓰여 있지만, 실제 코드(686·689줄)는 L_trim 후 길이로 판단하므로 공백만 있는 칸도 "-" 로 채웁니다.
  • L_cellSet 은 칸의 첫 문단만 지우고 쓰므로, 빈 문단이 여러 개인 칸은 "-" 아래에 빈 줄이 남을 수 있습니다.
  • 커서를 제목행에 두고 실행하면 제목행의 빈 칸도 채워집니다.

23날짜표기통일 A-서식-02 실행 창(Alt+Shift+L)

2026-7-6, 2026/7/10, 2026.7.3 → 2026. 7. 6. 공문 표기로

매크로 이름 날짜표기통일 · 전체 708줄(공통 라이브러리 1~660줄 + 이 매크로 661~708줄) · .msr 58 KB

.msr 다운로드 58 KB
소스 보기 (708줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

캐럿이 있는 문단 글자를 읽어 정규식으로 '네 자리 연도 + 같은 구분자(-, /, .) + 월 + 일' 꼴을 모두 찾습니다. JavaScript Date 로 실제 있는 날짜인지 검증한 것만 "YYYY. M. D." 꼴로 바꿀 목록(edits)에 담고, 공통 라이브러리 L_applyEdits 로 문단 오른쪽부터 지우고 넣습니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 670~677줄① 캐럿 문단 읽기L_here() 로 List·Para 번호를 얻고 L_paraText() 로 그 문단 글자를 읽습니다. 공백뿐이면 안내 후 끝냅니다.
  2. 679~683줄② 날짜 정규식(\d{4})\s*([-\/.])\s*(\d{1,2})\s*\2\s*(\d{1,2})\.?(?!\d) 는 연도 뒤 구분자를 2번 그룹으로 잡고 \2 역참조로 같은 구분자만 허용합니다. 끝의 점은 있어도 되고, 바로 뒤에 숫자가 오면 맞지 않습니다.
  3. 685~694줄③ 앞 숫자 검사와 날짜 검증찾은 자리 바로 앞 글자가 숫자면 더 긴 숫자의 일부로 보고 건너뜁니다. new Date(y, mo - 1, d) 를 만든 뒤 연·월·일이 그대로인지 비교해 13월이나 2월 30일처럼 넘친 날짜를 걸러냅니다.
  4. 696~699줄④ 바꿀 목록 만들기표준 꼴 문자열 y + ". " + mo + ". " + d + "." 을 만들고, 원문과 같으면 건너뜁니다. 다르면 {pos, del, text} 편집 항목을 배열에 넣습니다.
  5. 701~707줄⑤ 오른쪽부터 적용바꿀 것이 없으면 예시와 함께 안내합니다. 있으면 L_applyEdits() 가 pos 내림차순으로 정렬해 뒤쪽부터 캐럿을 옮겨 Delete 와 InsertText 를 실행하므로, 앞쪽 위치 번호가 밀리지 않습니다.

핵심 한글 API (HAction · HParameterSet …)

  • GetPosBySet() (L_here 안) — 캐럿 위치를 List·Para·Pos 항목이 있는 세트로 돌려줍니다.
  • GetTextFile("TEXT", "saveblock") (L_paraText 안) — MoveSelParaEnd 로 잡은 문단 블록을 평문으로 가져옵니다. CP949 밖 글자는 숫자 엔티티로 오므로 L_unesc 로 되돌립니다.
  • SetPosBySet / HAction.Run("MoveNextChar") (L_setCaret 안) — 문단 시작 Pos 에 글자 인덱스를 더해 캐럿을 바꿀 자리로 옮깁니다.
  • HAction.Run("Delete") — L_applyEdits 안에서 원래 날짜 글자 수만큼 한 글자씩 지웁니다.
  • HAction.Execute("InsertText", HParameterSet.HInsertText.HSet) (L_insertText 안) — 지운 자리에 표준 꼴 날짜 문자열을 넣습니다.

부르는 공통 라이브러리 함수

  • L_here — 캐럿 List/Para/Pos 읽기
  • L_paraText — 문단 글자 읽기(엔티티 복원 포함)
  • L_applyEdits — 편집 목록을 오른쪽부터 적용
  • L_setCaret — 문단 안 n번째 글자로 캐럿 이동
  • L_insertText — 글자 넣기
  • L_trim / L_msg — 공백 제거·메시지

이렇게 고쳐 쓰세요

  • 월·일을 두 자리로 맞추기(2026. 07. 06.) — 696줄을 var fixedTxt = y + ". " + (mo < 10 ? "0" : "") + mo + ". " + (d < 10 ? "0" : "") + d + "."; 로 바꿉니다.
  • 점(.)으로 쓴 날짜는 건드리지 않고 하이픈·슬래시만 바꾸기 — 682줄 정규식의 구분자 묶음 ([-\/.]) 를 ([-\/]) 로 바꿉니다.
  • 결과를 "2026-07-06" 꼴로 통일 — 696줄 fixedTxt 를 원하는 꼴로 만들면 됩니다. 예: y + "-" + (mo < 10 ? "0" : "") + mo + "-" + (d < 10 ? "0" : "") + d. 이때 697줄 비교도 같은 문자열을 쓰므로 그대로 둡니다.

고칠 때 주의

  • 캐럿이 있는 문단 하나만 처리합니다. 여러 줄을 바꾸려면 줄마다 실행해야 합니다.
  • 668줄 주석은 이미 "YYYY. M. D." 인 날짜가 자연히 제외된다고 하지만, 지금 정규식(682줄)은 점 구분자도 잡으므로 실제로는 697줄 비교가 그 날짜를 걸러 줍니다. 696줄 표준 꼴을 바꾸면 기존 "YYYY. M. D." 날짜도 새 꼴로 바뀝니다.
  • 정규식이 네 자리 연도만 잡으므로 "26-7-6" 처럼 두 자리 연도는 대상이 아닙니다.

24좌석표 E-좌석표-01 실행 창(Alt+Shift+L)

명렬표(학년반·번호·이름) → 새 쪽에 교실 좌석표. 배치(5열25명/4열20명)와 출입문 좌/우를 예/아니요로

매크로 이름 좌석표 · 전체 923줄(공통 라이브러리 1~659줄 + 이 매크로 660~923줄) · .msr 79 KB

.msr 다운로드 79 KB
소스 보기 (923줄 · 660줄부터 이 매크로)
심화과정: 소스 분석

학생 명렬표 안에서 실행하면 제목행에서 이름·번호·반 열을 찾아 학생을 읽고, 반별(반 열이 없으면 좌석 수씩) 묶음마다 문서 끝 새 쪽에 TableCreate 로 좌석표 표를 만듭니다. 책상 칸과 통로 칸을 번갈아 둔 격자를 만든 뒤 칸 크기·테두리·배경색·글자를 칸마다 지정하고, 칠판·교탁·출입문 행은 TableMergeCell 로 병합합니다. 660-900줄의 _seat.js 도우미 함수가 실제 작업을 하고, 902줄 진입 함수는 배치와 출입문 방향만 묻습니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 660~691줄① _seat.js 머리말과 열 찾기·질문 함수660줄부터 좌석표 공용 도우미가 포함됩니다. L_seatFindCol 은 첫 행 칸 글자에서 공백을 빼고 후보 이름(이름·성명 등)이 들어 있는 열 번호를 찾습니다. L_seatAsk 는 XHwpMessageBox 의 Flag 를 3 + 32(예/아니요/취소 + 물음표)로 띄워 Result 6 이면 오른쪽, 7 이면 왼쪽, 그 밖은 취소(null)로 돌려줍니다.
  2. 693~752줄② 칸 서식 도우미L_seatBorder 는 CellBorder 로 네 변 테두리 종류·굵기를, L_seatCellProp 는 TablePropertyDialog 로 칸 너비·높이와 '한 줄로 입력'(LineWrap = 1)을, L_seatAlign 은 문단 정렬을, L_seatStyle 은 글자 크기(pt×100)·굵게·색을, L_seatFill 은 셀 블록을 잡고 CellFill 로 배경색을 지정합니다. L_seatMergeRow 는 시작 칸부터 오른쪽 n칸을 블록으로 잡아 병합합니다.
  3. 755~785줄③ 좌석표 표 크기 계산과 만들기열 수는 cols * 2 - 1(책상·통로 번갈아), 행 수는 rows * 2 + 2(칠판·교탁·출입문 + 책상·빈 줄)입니다. 쪽 폭 AW 의 22%를 통로 폭으로 나누고, 높이는 책상:빈 줄 = 2:1 로 나누되 빈 줄은 3500 HWPUNIT 을 넘지 않게 합니다. TableCreate 로 표를 만든 뒤 칸마다 크기와 '테두리 없음'을 넣습니다.
  4. 786~811줄④ 정렬·책상 칸·학생 배치표 전체를 셀 블록으로 잡아 가운데-가운데 정렬하고, 책상 칸마다 얇은 실선(굵기 코드 2)과 연한 크림색 배경을 넣습니다. 학생 i 는 Math.floor(i / rows) 번째 열, i % rows 번째 줄에 놓이며, 출입문이 오른쪽이면 열 순서를 뒤집습니다. 번호가 4자 이상이면 BreakPara 로 번호·이름을 두 줄로 씁니다.
  5. 812~823줄⑤ 칠판·교탁·출입문 행과 병합0행 가운데 칸들에 굵기 코드 6 테두리(칠판), 1행 가운데 세 칸에 회색 배경과 반 이름(12pt 굵게), 2행 첫 칸에 출입문 표시를 넣습니다. 병합은 2행 → 1행 → 0행 순으로 뒤쪽부터 해서 앞 칸의 List 번호가 밀리지 않게 하고, 병합으로 줄어든 칸 수(shrink)를 빼서 첫 책상 칸으로 캐럿을 옮깁니다.
  6. 827~877줄⑥ 명렬표 읽기와 묶기L_tableGeom() 으로 표 크기를 얻고 이름 열(필수)·번호 열·반 열을 찾습니다. 1행부터 이름이 있는 행만 읽어 {no, name, cls} 로 모은 뒤, 반 값이 하나라도 있으면 반 이름별로(빈 칸은 바로 위 반으로), 없으면 좌석 수(cols×rows)씩 끊어 1, 2, 3… 으로 묶습니다. 번호가 없으면 묶음마다 1번부터 매깁니다.
  7. 879~900줄⑦ 쪽 크기 읽기와 장마다 그리기표를 떠나기 전에 PageSetup 의 PageDef 로 용지 크기에서 여백·머리말·꼬리말을 뺀 사용 폭·높이를 구하고, 값이 이상하면 A4 기본값을 씁니다. 묶음마다 MoveDocEnd → BreakPage 로 새 쪽을 만들고, 인원이 좌석보다 많으면 행 수를 늘려 L_seatDraw 를 부릅니다. 끝나면 만든 장 수와 반별 인원을 안내합니다.
  8. 902~923줄⑧ 진입 함수: 배치·출입문 묻기첫 메시지 상자에서 [예] 5열, [아니요] 4열(행은 5)을 고르고, L_seatAsk 로 출입문 방향을 물은 뒤 L_seatChart(cols, 5, right) 를 부릅니다. 전체를 try/catch 로 감싸 오류 설명과 번호를 메시지로 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.GetDefault("TableCreate", HParameterSet.HTableCreation.HSet) — Rows·Cols·WidthType·WidthValue·TableProperties.TreatAsChar 를 정한 뒤 Execute 로 새 표를 만듭니다.
  • HAction.GetDefault("TablePropertyDialog", HParameterSet.HShapeObject.HSet) — ShapeType 3, ShapeCellSize 1 로 현재 칸의 ShapeTableCell.Width/Height 와 LineWrap(1 = 한 줄로 입력)을 바꿉니다.
  • HAction.GetDefault("CellBorder", HParameterSet.HCellBorderFill.HSet) — BorderTypeLeft/Right/Top/Bottom(0 없음, 1 실선)과 BorderWidth* 굵기 코드로 현재 칸 테두리를 정합니다.
  • HAction.GetDefault("CellFill", HParameterSet.HCellBorderFill.HSet) — FillAttr.WinBrushFaceColor 에 COLORREF 색을 넣어 셀 블록 배경을 칠합니다.
  • HAction.GetDefault("PageSetup", HParameterSet.HSecDef.HSet) — PageDef.PaperWidth/PaperHeight 와 각 여백을 읽어 좌석표가 들어갈 크기를 계산합니다.
  • HAction.Run("TableCellBlock") / ("TableCellBlockExtend") / ("TableMergeCell") — 셀 블록을 잡아 넓힌 뒤 하나로 병합합니다. 블록 상태에서 TableCellAlignCenterCenter 로 정렬도 합니다.
  • XHwpMessageBox.Flag = 3 + 32 / XHwpMessageBox.Result — 예/아니요/취소 단추와 물음표 아이콘으로 묻고, 누른 단추를 6(예)·7(아니요)로 받습니다.
  • HAction.Run("BreakPage") / ("BreakPara") — 문서 끝에 쪽 나누기를 넣어 새 쪽에 표를 만들고, 긴 번호 칸에서는 문단을 나눠 이름을 둘째 줄에 씁니다.

부르는 공통 라이브러리 함수

  • L_tableGeom — 명렬표의 행·열 수와 좌상단 List
  • L_cellList — (행, 열) → 칸 List 번호
  • L_cellText — 칸 글자 읽기
  • L_gotoPara — 칸 첫 문단으로 이동
  • L_insertText — 칸에 글자 넣기
  • L_tableRight — 병합 블록을 넓힐 때 오른쪽 이동
  • L_inTable / L_trim / L_msg — 표 안 확인·공백 제거·메시지

이렇게 고쳐 쓰세요

  • 책상 칸 배경색을 연한 하늘색으로 — 792줄 250 + 250 * 256 + 245 * 65536 은 COLORREF(0x00BBGGRR) 계산식이라 빨강 + 초록×256 + 파랑×65536 순서입니다. 하늘색(빨강 220, 초록 235, 파랑 255)은 220 + 235 * 256 + 255 * 65536 으로 바꿉니다.
  • 기본 행 수를 5행에서 6행으로 — 921줄 L_seatChart(cols, 5, right) 의 5 를 6 으로, 919줄 cols + "열×5행(" + (cols * 5) 의 5 두 곳과 913줄 안내 문구도 함께 고칩니다.
  • 교탁 칸 반 이름 글자를 더 크게 — 815줄 L_seatStyle(12, true, 0) 의 12(pt)를 14 로 바꿉니다. 마지막 인자 0 은 검정 COLORREF 입니다.
  • 칠판 테두리를 더 얇게 — 812줄 L_seatBorder(1, 6) 의 굵기 코드 6(주석 기준 0.4mm)을 2(약 0.15mm) 등으로 낮춥니다.

고칠 때 주의

  • 병합(818-820줄)은 뒤 행부터 해야 앞 칸 List 번호가 밀리지 않습니다. 병합 칸 수를 바꾸면 821줄 shrink 계산도 같이 고쳐야 캐럿이 첫 책상 칸으로 갑니다(822줄 주석의 글상자 언급은 지금 코드에 없는 예전 내용입니다).
  • 쪽 크기는 표를 떠나기 전에 읽어야 합니다(879줄 주석: 새 쪽 첫머리에서 읽으면 0). 순서를 바꾸지 마십시오.
  • L_seatFindCol 은 포함 여부(indexOf)로 찾으므로 839줄 후보 "반" 은 '반'이 들어간 다른 제목에도 걸릴 수 있습니다. 또 L_tableGeom 기반이라 병합 칸이 있는 명렬표에서는 열 위치가 어긋날 수 있습니다.

25전체열표계산천원 C-표계산-02 Alt+Shift+4

2027년·2026년처럼 산출기초가 여러 벌이면 한 번에 계산합니다

매크로 이름 전체열표계산천원 · 전체 780줄(공통 라이브러리 1~660줄 + 이 매크로 661~780줄) · .msr 64 KB

.msr 다운로드 64 KB
소스 보기 (780줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

커서가 있는 행부터 표의 마지막 행까지, 각 행을 왼쪽 끝부터 오른쪽 끝까지 훑어 "×" 가 들어 있는 산출기초 칸을 계산합니다. 결과(원 → 천원 반올림)는 오른쪽 칸에 채우거나 검산하고, 그 칸이 행의 마지막 열이면 같은 칸의 "=" 뒤에 씁니다. TableRightCell 실패를 피하려고 한 행의 칸 수를 L_rowColCount 로 미리 구해 '이동이 보장될 때만' 오른쪽으로 갑니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 685~688줄① 표 안인지 확인표 밖이면 산출기초 예시(1,400,000원×2교=)와 함께 안내하고 끝냅니다.
  2. 690~702줄② 카운터와 행 칸 수 준비채움·정상·수정·건너뜀 수를 셀 변수를 만들고, 첫 행에서 한 번만 L_rowColCount(rowBase) 로 한 행의 칸 수 N 을 구해 이후 행에 다시 씁니다.
  3. 704~713줄③ 칸마다 오른쪽 칸 여부 계산현재 칸 List 에서 행 첫 칸 List(rowBase)를 뺀 값이 N-1 보다 작으면 hasRight 입니다. 그다음 칸 글자를 읽습니다.
  4. 714~724줄④ 곱셈기호 통일과 수식 계산L_mulEdits 로 숫자 사이의 *, X, x 를 찾아 L_applyEdits 로 × 로 고친 뒤 다시 읽습니다. 마지막 "=" 앞만 수식으로 보고, × 가 있을 때만 L_calcExpr 로 각 인수의 마지막 숫자를 곱하고 천원 단위면 1000 을 곱해 원 단위 값을 얻습니다.
  5. 726~736줄⑤ 오른쪽 칸에 채우거나 고치기원 단위 값을 1000 으로 나눠 반올림한 천원 값을 want 로 정합니다. 오른쪽 칸이 있으면 TableRightCell 로 가서 L_fillOrMark 로 빈 칸이면 채우고, 맞으면 두고, 틀리면 고친 뒤 빨간 글자로 표시하고 돌아옵니다.
  6. 737~761줄⑥ 마지막 열이면 "=" 뒤에 쓰기오른쪽 칸이 없고 "=" 가 있으면 "=" 뒤가 비었을 때 L_cellSet 으로 채우고, 값이 있으면 L_cellNum 으로 읽어 0.5 미만 차이면 그대로, 아니면 L_applyEdits 로 그 부분만 바꾼 뒤 L_cellRed 로 표시합니다. 계산이 안 되는 칸은 건너뜀으로 셉니다.
  7. 764~775줄⑦ 다음 칸·다음 행hasRight 가 false 면 TableRightCell 을 부르지 않고 행을 끝냅니다. 행이 끝나면 TableColBegin 후 TableLowerCell 로 내려가며, 실패하거나 위치가 같으면 끝냅니다.
  8. 777~779줄⑧ 결과 안내확인한 행 수와 새로 채움·정상 확인·값 수정(적색)·건너뜀 개수를 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.Run("TableColBegin") — 행의 첫 칸으로 이동합니다. 실패하지 않는 안전한 이동이라 행 기준점(rowBase)을 잡을 때 씁니다.
  • HAction.Run("TableRightCell") / ("TableLeftCell") — 오른쪽 결과 칸으로 갔다가 돌아옵니다. hasRight 로 성공이 보장될 때만 부릅니다.
  • HAction.Run("TableLowerCell") — 다음 행으로 내려갑니다. 실패해도 이후 편집에 영향이 없다고 주석에 적혀 있습니다.
  • HAction.Run("Delete") + HAction.Execute("InsertText", HParameterSet.HInsertText.HSet) (L_applyEdits·L_cellSet 안) — 곱셈기호 교체와 "=" 뒤 금액 교체를 글자 단위로 합니다.
  • HParameterSet.HCharShape.TextColor = 255 (L_cellRed 안) — 고친 칸 글자를 빨간색(COLORREF 0x0000FF, BGR 순서라 마지막 바이트가 빨강)으로 칠합니다.
  • HParameterSet.HParaShape.AlignType = 2 (L_alignRight 안) — 채우거나 확인한 결과 칸을 오른쪽 정렬합니다.

부르는 공통 라이브러리 함수

  • L_rowColCount — TableRightCell 없이 한 행의 칸 수 계산
  • L_mulEdits / L_applyEdits — *·X·x 를 × 로 교체
  • L_calcExpr — 곱셈 산출식 계산(천원·원 단위 인식)
  • L_fillOrMark — 결과 칸 채움/확인/수정+적색
  • L_fmtNum / L_cellNum — 숫자 표기·읽기
  • L_cellRed — 칸 글자 빨간색
  • L_cellSet / L_cellText — 칸 글자 쓰기·읽기

이렇게 고쳐 쓰세요

  • 결과를 천원이 아닌 원 단위로 채우기 — 727줄 Math.round(calc.won / 1000) 을 Math.round(calc.won) 으로 바꿉니다. 안내 문구와 매크로 이름의 '천원' 도 함께 고치는 것이 좋습니다.
  • 커서가 있는 행 하나만 계산하기 — 768줄 rows++; 다음 줄에 break; 를 넣습니다.
  • 고친 칸 표시색을 빨강 대신 파랑으로 — 색은 공통 라이브러리 213줄 HParameterSet.HCharShape.TextColor = 255; 에 있습니다. BGR 순서이므로 파랑은 0xFF0000(=16711680)입니다. 이 줄을 바꾸면 L_cellRed 를 쓰는 모든 표 계산 매크로가 함께 바뀝니다.

고칠 때 주의

  • 675-683줄 주석대로 TableRightCell 이 한 번 실패하면 그 뒤 Delete/InsertText 가 조용히 무시될 수 있습니다. 칸 이동 코드를 고칠 때 hasRight 검사 없이 TableRightCell 을 부르지 마십시오.
  • 칸 수 N 은 첫 행에서 한 번만 구하므로(702줄), 행마다 병합으로 칸 수가 다른 표에서는 마지막 열 판단이 어긋날 수 있습니다.
  • L_calcExpr 는 × 로 나눈 각 인수의 마지막 숫자를 곱하기만 합니다. 더하기·나누기가 섞인 식은 맞게 계산되지 않습니다.

26중간합계증감포함표계산천원 C-표계산-04 실행 창(Alt+Shift+L)

가./나. 그룹 중간합계와 전체 합계까지 한 번에

매크로 이름 중간합계증감포함표계산천원 · 전체 806줄(공통 라이브러리 1~660줄 + 이 매크로 661~806줄) · .msr 65 KB

.msr 다운로드 65 KB
소스 보기 (806줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

커서 칸(A 산출기초)부터 오른쪽으로 [예산A][B 산출기초][예산B][증감] 다섯 칸 구조를 가정하고, 행마다 두 산출기초를 계산해 예산·증감 칸을 채우거나 검산합니다. 산출기초가 둘 다 비어 있는 행은 그룹 제목 행으로 보고, 사업명 칸 들여쓰기 깊이로 스택(stack)을 쌓았다가 같거나 얕은 그룹을 만나면 닫으면서 소계를 그 행에 씁니다. 마지막 행은 전체 합계 행으로 채웁니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 676~680줄① 표 안인지 확인표 밖이면 필요한 칸 순서를 안내하고 끝냅니다.
  2. 682~693줄② 상태 변수와 집계 함수열린 그룹을 담는 stack, 전체 합계 grandA/grandB, 결과 개수를 세는 bump() 를 준비합니다. bump 는 L_fillOrMark 의 반환값 filled/kept/corrected 를 셉니다.
  3. 695~711줄③ writeTriple: 예산A·예산B·증감 쓰기A 칸에서 오른쪽 1칸(예산A)에 wantA, 2칸 옆 B 산출기초의 오른쪽(예산B)에 wantB, 다시 2칸 옆(증감)에 wantA-wantB 를 L_fillOrMark/L_fillOrMarkSigned 로 넣습니다.
  4. 713~724줄④ closeFrame: 그룹 닫기그룹 행에 그룹 합계를 쓰고, 상위 그룹이 있으면 그 합계에, 없으면 전체 합계에 더해 위로 넘깁니다.
  5. 730~745줄⑤ 마지막 행 판정과 전체 합계TableLowerCell 로 내려가 봤다가 TableUpperCell 로 돌아와 다음 행이 있는지 확인합니다. 없으면 열린 그룹을 모두 닫고 현재 행에 전체 합계를 쓰고 끝냅니다.
  6. 747~753줄⑥ A·B 산출기초 읽기L_readFormula 로 A 칸과 2칸 오른쪽 B 칸을 읽습니다. 곱셈기호를 × 로 고친 뒤 × 가 있을 때만 계산해 천원 값을 돌려줍니다.
  7. 755~765줄⑦ 그룹 제목 행 처리두 산출기초가 모두 계산되지 않으면 행 첫 칸(사업명)으로 가서 L_level 로 앞 공백 수(indent)를 구합니다. 스택 맨 위 그룹의 indent 가 같거나 크면 닫고, 이 행을 새 그룹으로 쌓습니다.
  8. 766~797줄⑧ 데이터 행 처리와 합계 누적계산된 쪽의 예산 칸과 증감 칸을 채우거나 검산하고, 값을 스택 맨 위 그룹 합계(없으면 전체 합계)에 더합니다.
  9. 799~805줄⑨ 다음 행과 결과 안내A 칸으로 돌아가 TableLowerCell 로 내려갑니다. 끝나면 확인 행 수·중간합계 수·채움/정상/수정 개수를 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.Run("TableLowerCell") / ("TableUpperCell") — 아래로 내려가 봤다가 다시 올라와 다음 행이 있는지(마지막 행인지) 판단합니다.
  • HAction.Run("TableRightCell") / ("TableLeftCell") — A 칸 기준으로 예산·B·증감 칸을 오가며 값을 씁니다. L_tableRight/L_tableLeft 는 이 동작을 n번 반복합니다.
  • HAction.Run("TableColBegin") — 그룹 제목 행에서 사업명이 있는 첫 칸으로 가서 들여쓰기를 읽습니다.
  • HParameterSet.HCharShape.TextColor = 255 (L_cellRed 안) — 틀린 값을 고친 칸 글자를 빨간색(BGR 0x0000FF)으로 표시합니다.
  • HParameterSet.HParaShape.AlignType = 2 (L_alignRight 안) — 숫자를 넣거나 확인한 칸을 오른쪽 정렬합니다.

부르는 공통 라이브러리 함수

  • L_readFormula — 산출기초 칸 계산(천원)
  • L_fillOrMark — 예산 칸 채움/확인/수정+적색
  • L_fillOrMarkSigned — 증감 칸(음수는 △)
  • L_level — 사업명 들여쓰기·글머리 수준
  • L_tableRight / L_tableLeft — n칸 이동
  • L_cellText / L_gotoPara — 칸 읽기·이동
  • L_msg — 결과 메시지

이렇게 고쳐 쓰세요

  • 증감 음수를 "△" 대신 "-" 로 표기 — 708줄과 783줄의 L_fillOrMarkSigned 를 L_fillOrMark 로 바꿉니다(L_fmt 가 음수에 "-" 를 붙임).
  • 증감을 B-A(작년 대비 감소가 양수)로 계산 — 708줄 wantA - wantB 를 wantB - wantA 로, 783줄 aInfo.want - bInfo.want 를 bInfo.want - aInfo.want 로 바꿉니다.
  • 마지막 행을 합계 행으로 쓰지 않기 — 741-742줄을 while (stack.length > 0) { closeFrame(stack.pop()); } 만 남기고 742줄 writeTriple(startList, grandA, grandB); 를 지웁니다. 이 경우 마지막 행은 데이터로 계산되지 않으니 표 끝에 합계 행을 하나 두는 편이 안전합니다.

고칠 때 주의

  • 673줄 주석은 '다르면 값 보존+적색표시' 라고 하지만, 지금 L_fillOrMark(lib 328-336줄)는 틀린 값을 고쳐 쓴 뒤 빨간색으로 표시합니다.
  • 그룹 수준은 사업명 칸의 앞 공백 수(indent)로만 판단합니다. 들여쓰기 없이 글머리 기호만 다른 표는 모두 같은 수준으로 처리됩니다.
  • 커서는 반드시 A 산출기초 칸에 있어야 하며, 오른쪽 다섯 칸 순서가 다르면 엉뚱한 칸에 값이 써집니다.

27구성비열채우기 C-표계산-05 실행 창(Alt+Shift+L)

예산 열 옆에 구성비(%)를 자동으로 (신규)

매크로 이름 구성비열채우기 · 전체 713줄(공통 라이브러리 1~660줄 + 이 매크로 661~713줄) · .msr 59 KB

.msr 다운로드 59 KB
소스 보기 (713줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

L_tableGeom() 으로 표의 행·열 수와 커서 열을 구한 뒤, 제목행을 뺀 커서 열 값을 더해 분모를 만들고 각 값의 구성비(%)를 바로 오른쪽 열에 소수 한 자리로 씁니다. 마지막 행 첫 칸이 '합계/계/총계' 면 합계 행으로 보고, 그 행 값이 있으면 분모로 쓰며 오른쪽 칸에는 100.0 을 넣습니다. 이미 값이 있으면 0.05 이내인지 검산해 다르면 고치고 빨간색으로 표시합니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 669~678줄① 표 확인과 오른쪽 열 확인표 안인지 확인한 뒤 L_tableGeom() 으로 curCol(커서 열)과 N(열 수)을 얻습니다. 커서 열이 마지막 열이면 구성비를 쓸 곳이 없으므로 안내하고 끝냅니다.
  2. 679~683줄② 합계 행 찾기마지막 행 첫 칸 글자를 정규식 /합\s*계|^계$|총계/ 로 검사합니다. 맞으면 데이터 행 범위를 마지막 행 바로 위까지로 줄입니다.
  3. 684~696줄③ 분모(합계) 구하기1행부터 데이터 끝 행까지 커서 열 값을 L_cellNum 으로 읽어 더합니다(숫자가 아니면 null 로 두고 건너뜀). 합계 행에 0보다 큰 값이 있으면 그 값을 분모로 바꿔 쓰고, 분모가 0 이하면 안내 후 끝냅니다.
  4. 697~705줄④ 칸 채우기 함수 put(Math.round(want * 10) / 10).toFixed(1) 로 소수 한 자리 문자열을 만듭니다. 빈 칸이면 채우고, 값이 있으면 % 기호를 뗀 숫자와 0.05 미만 차이일 때 정렬만, 아니면 고쳐 쓰고 L_cellRed 로 표시합니다.
  5. 706~712줄⑤ 구성비 쓰기와 결과 안내숫자가 있는 데이터 행마다 값 / 분모 × 100 을 오른쪽 열에 넣고, 합계 행이 있으면 100 을 넣습니다. 캐럿을 구성비 열 첫 데이터 칸으로 옮기고 분모와 채움/정상/수정 개수를 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.Run("TableColBegin") / ("TableUpperCell") / ("TableLowerCell") (L_tableGeom 안) — TableRightCell 없이 행 시작 칸과 위·아래 이동만으로 표의 좌상단 List·열 수·행 수·커서 행/열을 구합니다.
  • GetTextFile("TEXT", "saveblock") (L_cellText → L_paraText 안) — 칸 첫 문단 글자를 읽어 숫자로 바꿉니다.
  • HParameterSet.HParaShape.AlignType = 2 (L_alignRight 안) — 구성비 칸을 오른쪽 정렬합니다.
  • HParameterSet.HCharShape.TextColor = 255 (L_cellRed 안) — 고친 구성비 칸 글자를 빨간색(BGR 0x0000FF)으로 표시합니다.
  • Number.toFixed(1) — JScript 기본 함수로, 100 이나 12 처럼 딱 떨어지는 값도 "100.0", "12.0" 처럼 소수 한 자리로 씁니다.

부르는 공통 라이브러리 함수

  • L_tableGeom — 표 행·열 수와 커서 열
  • L_cellList — (행, 열) → 칸 List
  • L_cellText / L_cellNum — 칸 글자 읽기·숫자 변환(△, - 음수 인식)
  • L_cellSetNum — 칸에 쓰고 오른쪽 정렬
  • L_alignRight / L_cellRed — 정렬·빨간 표시
  • L_fmt / L_msg — 분모 표기·메시지

이렇게 고쳐 쓰세요

  • 구성비를 소수 두 자리로 — 699줄을 var s = (Math.round(want * 100) / 100).toFixed(2); 로, 703줄 허용 오차 0.05 를 0.005 로 바꿉니다.
  • 구성비 뒤에 % 기호 붙이기 — 699줄 끝에 s = s + "%"; 를 덧붙입니다. 702줄이 이미 replace(/%/g, "") 로 % 를 떼고 검산하므로 다시 실행해도 정상 확인됩니다.
  • 합계 행 이름에 '총합' 도 인정 — 681줄 정규식을 /합\s*계|^계$|총계|총합/ 로 바꿉니다.

고칠 때 주의

  • 합계 행에 값이 있으면 그 값을 분모로 씁니다(691줄). 합계 칸 값이 틀려 있으면 구성비 합이 100 이 되지 않으니 먼저 합계를 확인하십시오.
  • 합계 행은 마지막 행 첫 칸으로만 판단합니다. 표 중간의 소계 행은 데이터로 함께 더해집니다.
  • L_tableGeom 은 모든 행의 칸 수가 같다고 가정하므로 병합 칸이 있는 표에서는 열 위치가 틀어질 수 있습니다.

28가로세로평균 C-표계산-06 실행 창(Alt+Shift+L)

표 평균 한 매크로로 — [아니요] 가로: 행마다 평균을 마지막 열에 / [예] 세로: 커서 열의 평균을 마지막 행에

매크로 이름 가로세로평균 · 전체 740줄(공통 라이브러리 1~660줄 + 이 매크로 661~740줄) · .msr 61 KB

.msr 다운로드 61 KB
소스 보기 (740줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

실행하면 XHwpMessageBox 로 방향을 묻고, [예] 는 커서 열의 데이터 행 평균을 마지막 행에, [아니요] 는 각 행에서 첫 열과 마지막 열을 뺀 숫자 칸 평균을 마지막 열에 씁니다. 표 구조는 L_tableGeom() 으로 구하고, 평균은 소수 한 자리로 반올림합니다. 이미 값이 있으면 0.05 이내인지 확인해 다르면 고쳐 쓰고 빨간색으로 표시합니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 670~673줄① 표 안인지 확인표 밖이면 세로평균은 평균 낼 열에 커서를 두라는 안내와 함께 끝냅니다.
  2. 674~679줄② 방향 묻기XHwpMessageBox 의 Flag 를 3 + 32(예/아니요/취소 + 물음표)로 띄우고 Result 가 6 이면 vertical(), 7 이면 horizontal() 을 부릅니다. 두 함수는 아래쪽에 선언돼 있지만 JScript 함수 선언은 미리 올려지므로(hoisting) 호출할 수 있습니다.
  3. 681~689줄③ fillAvg: 채움/확인/수정평균 칸이 비면 L_fmt(want) 로 채우고 오른쪽 정렬, 값이 0.05 미만 차이면 그대로, 아니면 고쳐 쓰고 L_cellRed 로 표시하며 결과 문자열을 돌려줍니다.
  4. 691~715줄④ 가로평균열이 3개 미만이면 안내 후 끝냅니다. 1행부터 마지막 행까지, 각 행의 1열~N-2열 중 숫자로 읽히는 칸만 더해 평균을 내고, 마지막 열(N-1)에 씁니다. 숫자 칸이 없는 행은 건너뜀으로 셉니다.
  5. 717~739줄⑤ 세로평균행이 3개 미만이면 끝냅니다. 커서 열에서 1행~R-2행(제목행과 마지막 행 제외)의 숫자 칸 평균을 내 마지막 행(R-1)에 쓰고, 열 번호·데이터 수·평균·처리 결과를 안내합니다.

핵심 한글 API (HAction · HParameterSet …)

  • XHwpMessageBox.String / Flag / DoModal() — 안내 문구와 단추 조합(3 = 예/아니요/취소, +32 = 물음표 아이콘)을 정해 메시지 상자를 띄웁니다.
  • XHwpMessageBox.Result — 누른 단추 값을 돌려줍니다. 이 코드에서는 6 = 예, 7 = 아니요로 비교합니다.
  • HAction.Run("TableColBegin") / ("TableUpperCell") / ("TableLowerCell") (L_tableGeom 안) — 표의 열 수·행 수·커서 열을 구할 때 쓰는 안전한 이동입니다.
  • HParameterSet.HParaShape.AlignType = 2 (L_alignRight 안) — 평균 칸을 오른쪽 정렬합니다.
  • HParameterSet.HCharShape.TextColor = 255 (L_cellRed 안) — 고친 평균 칸 글자를 빨간색(BGR 0x0000FF)으로 표시합니다.

부르는 공통 라이브러리 함수

  • L_tableGeom — 표 행·열 수와 커서 열
  • L_cellList / L_gotoPara — 칸 번호 계산·이동
  • L_cellText / L_cellNum — 칸 글자 읽기·숫자 변환
  • L_cellSetNum — 칸에 쓰고 오른쪽 정렬
  • L_cellRed / L_alignRight — 빨간 표시·정렬
  • L_fmt — 콤마·소수 둘째 자리까지 표기
  • L_msg — 결과 메시지

이렇게 고쳐 쓰세요

  • 평균을 소수 두 자리로 — 706줄과 734줄의 Math.round((sum / cnt) * 10) / 10 을 Math.round((sum / cnt) * 100) / 100 으로, 685줄 허용 오차 0.05 를 0.005 로 바꿉니다.
  • 가로평균에서 첫 열(이름 칸)도 숫자로 포함 — 700줄 for (var c = 1; ... 의 시작값 1 을 0 으로 바꿉니다.
  • 묻지 않고 항상 세로평균만 — 674-679줄(메시지 상자와 분기)을 지우고 그 자리에 vertical(); 한 줄을 둡니다.

고칠 때 주의

  • 가로평균은 698줄 반복이 마지막 행까지 돌기 때문에, 표 마지막 행이 세로평균 행이어도 그 행의 가로평균까지 씁니다.
  • L_cellNum 은 칸 글자 안의 첫 숫자 덩어리를 읽으므로 "90점" 은 90 으로, "1-2" 처럼 숫자가 둘 이상인 칸은 첫 숫자만 씁니다.
  • L_fmt 는 소수 둘째 자리에서 반올림하므로 세 자리 이상으로 늘리려면 L_fmt 도 함께 고쳐야 합니다.

29등수정리 C-표계산-07 실행 창(Alt+Shift+L)

점수 열 오른쪽에 등수를 채웁니다(동점은 공동 순위)

매크로 이름 등수정리 · 전체 738줄(공통 라이브러리 1~660줄 + 이 매크로 661~738줄) · .msr 60 KB

.msr 다운로드 60 KB
소스 보기 (738줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

L_tableGeom() 으로 커서 열과 표 크기를 구하고, 오른쪽 열이 데이터 행 전체에서 비어 있을 때만 작업합니다. 커서 열의 숫자를 내림차순으로 정렬해 동점은 같은 등수, 다음 등수는 인원수만큼 건너뛰는 표준 경쟁 순위(1,1,3)를 매기고 오른쪽 열에 씁니다. 표 구조는 바꾸지 않고, 오른쪽 열에 값이 있으면 아무것도 고치지 않고 멈춥니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 672~683줄① 표 확인과 오른쪽 열 확인표 안인지 확인하고 L_tableGeom() 으로 curCol 을 얻습니다. 오른쪽 열이 없으면 빈 열을 먼저 추가하라고 안내하고 끝냅니다.
  2. 685~694줄② 기존 값 보호1행부터 마지막 행까지 오른쪽 열 칸을 읽어 글자가 하나라도 있으면 실행을 멈춥니다. 덮어쓰기를 막는 안전장치입니다.
  3. 696~702줄③ 점수 읽기커서 열의 1행~마지막 행 값을 L_cellNum 으로 읽어 {row, num} 배열에 넣습니다. 숫자가 아니면 num 은 null 입니다.
  4. 704~718줄④ 표준 경쟁 순위 계산숫자 있는 항목만 골라 b.num - a.num 으로 내림차순 정렬합니다. 앞 항목과 값이 같으면 같은 등수를, 다르면 지금까지 지나온 개수+1 을 등수로 매겨 rankOf[행번호] 에 저장합니다.
  5. 720~724줄⑤ 제목 칸 채우기오른쪽 열 제목행(0행)이 비어 있으면 "등수" 를 씁니다.
  6. 726~737줄⑥ 등수 쓰기와 결과 안내등수가 있는 행은 L_cellSetNum 으로 숫자를 쓰고 오른쪽 정렬하며, 숫자가 아니던 행은 건너뜀으로 셉니다.

핵심 한글 API (HAction · HParameterSet …)

  • HAction.Run("TableColBegin") / ("TableUpperCell") / ("TableLowerCell") (L_tableGeom 안) — 표의 좌상단 List·열 수·행 수와 커서 열을 구합니다.
  • GetTextFile("TEXT", "saveblock") (L_cellText 안) — 칸 글자를 읽어 빈 칸 여부와 점수를 판단합니다.
  • HAction.Execute("InsertText", HParameterSet.HInsertText.HSet) (L_cellSet 안) — "등수" 제목과 등수 숫자를 칸에 넣습니다.
  • HParameterSet.HParaShape.AlignType = 2 (L_alignRight 안) — 등수 칸을 오른쪽 정렬합니다.
  • Array.sort(function (a, b) { return b.num - a.num; }) — JScript 배열 정렬로 점수 내림차순 순서를 만듭니다.

부르는 공통 라이브러리 함수

  • L_tableGeom — 표 행·열 수와 커서 열
  • L_cellList / L_gotoPara — 칸 번호 계산·이동
  • L_cellText / L_cellNum — 칸 글자·숫자 읽기
  • L_cellSet — 제목 칸 쓰기
  • L_cellSetNum — 등수 쓰고 오른쪽 정렬
  • L_trim / L_msg — 공백 제거·메시지

이렇게 고쳐 쓰세요

  • 낮은 값이 1등(달리기 기록 등) — 707줄 return b.num - a.num; 을 return a.num - b.num; 으로 바꿉니다.
  • 동점 뒤 등수를 건너뛰지 않기(1,1,2) — 715줄 rankOf[ranked[i].row] = pos + 1; 을 rankOf[ranked[i].row] = (i === 0) ? 1 : rankOf[ranked[i - 1].row] + 1; 로 바꿉니다.
  • 등수 뒤에 "등" 붙이기 — 730줄 String(rankOf[r]) 를 rankOf[r] + "등" 으로 바꿉니다. 제목 문구는 723줄 "등수" 에서 바꿉니다.

고칠 때 주의

  • 마지막 행까지 모두 데이터로 봅니다(687·698·727줄의 r < geom.R). 표 끝에 합계·평균 행이 있으면 그 값도 순위에 들어가 1등이 될 수 있으니 미리 빼거나 반복 끝을 geom.R - 1 로 바꾸십시오.
  • 동점 판정은 숫자가 정확히 같을 때만입니다(712줄 ===). 소수 반올림 차이가 있는 값은 다른 점수로 처리됩니다.
  • 오른쪽 열에 글자가 하나라도 있으면 전체를 멈추므로, 다시 실행하려면 등수 열 데이터를 먼저 지워야 합니다.

30전화번호서식통일 D-표정리-08 실행 창(Alt+Shift+L)

전화번호를 010-1234-5678 로 통일하고, 같은 번호는 빨간색으로 (신규)

매크로 이름 전화번호서식통일 · 전체 753줄(공통 라이브러리 1~660줄 + 이 매크로 661~753줄) · .msr 63 KB

.msr 다운로드 63 KB
소스 보기 (753줄 · 661줄부터 이 매크로)
심화과정: 소스 분석

정규식으로 문자열 속 전화번호 후보를 찾고, 숫자만 뽑아 휴대전화·서울·기타 지역/인터넷전화·대표번호 규칙에 맞춰 하이픈 꼴로 바꿉니다. 표 밖에서는 캐럿 문단만, 표 안에서는 L_tableGeom 으로 모든 칸을 돌며 바꾸고, 통일된 번호가 두 번 이상 나오면 해당 칸들을 빨간 글자로 표시합니다. 하이픈 주민등록번호 꼴(6자리-7자리)과 겹치는 후보는 제외합니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 661~681줄① PH_norm: 번호 하나를 하이픈 꼴로숫자 외 글자를 모두 지운 뒤, 01X 휴대전화(10~11자리), 02 서울, 03X~06X·070·080·050X 지역/인터넷, 15XX~19XX 대표번호 정규식에 차례로 맞춰 봅니다. 맞으면 앞자리·가운데·마지막 4자리를 하이픈으로 잇고, 050X 는 앞자리를 4자리로 자릅니다. 어디에도 안 맞으면 null 입니다.
  2. 683~700줄② PH_find: 문자열 속 후보 찾기먼저 \d{6}-\d{7} 자리를 제외 구간으로 모읍니다. 후보 정규식으로 찾은 것 중 제외 구간과 겹치거나, 앞뒤에 숫자나 "-" 가 붙은 것은 버리고, PH_norm 이 성공한 것만 {pos, del, text, norm} 편집 항목으로 돌려줍니다.
  3. 709~721줄③ 표 밖: 캐럿 문단만 처리표 밖이면 L_paraText 로 문단을 읽어 후보를 찾고, 원문과 다른 것만 L_applyEdits 로 바꾼 뒤 개수를 안내하고 끝냅니다.
  4. 722~741줄④ 표 안: 모든 칸 통일과 빈도 세기L_tableGeom 으로 행·열 수를 얻고 모든 (행, 열) 칸 글자를 읽어 후보를 찾습니다. 통일된 번호별 등장 횟수를 freq 에, 칸별 번호 목록을 cellNums[list] 에 저장하고, 바뀔 것만 L_applyEdits 로 고칩니다.
  5. 742~752줄⑤ 중복 번호 칸 빨간 표시와 결과 안내번호 중 하나라도 freq 가 2 이상인 칸을 L_cellRed 로 빨갛게 표시합니다. 캐럿을 원래 칸으로 돌리고 발견·변경 개수와 중복 번호 목록을 보여 줍니다.

핵심 한글 API (HAction · HParameterSet …)

  • GetTextFile("TEXT", "saveblock") (L_paraText 안) — 문단 또는 칸 글자를 평문으로 읽어 전화번호 후보를 찾습니다.
  • HAction.Run("Delete") + HAction.Execute("InsertText", HParameterSet.HInsertText.HSet) (L_applyEdits 안) — 후보 자리를 오른쪽부터 지우고 통일된 번호를 넣습니다.
  • HParameterSet.HCharShape.TextColor = 255 (L_cellRed 안) — 중복 번호가 든 칸 전체 글자를 빨간색(BGR 0x0000FF)으로 바꿉니다.
  • HAction.Run("TableColBegin") / ("TableUpperCell") / ("TableLowerCell") (L_tableGeom 안) — 표의 행·열 수와 좌상단 칸 List 를 구합니다.
  • RegExp.exec (g 플래그 반복) — /(?:0\d{1,2}|1[5-9]\d{2})[-.\s]?\d{3,4}[-.\s]?\d{4}/g 로 후보 위치(index)와 길이를 차례로 얻습니다.

부르는 공통 라이브러리 함수

  • L_tableGeom / L_cellList — 표 크기와 칸 번호
  • L_cellText / L_paraText — 칸·문단 글자 읽기
  • L_applyEdits — 편집 목록을 오른쪽부터 적용
  • L_cellRed — 칸 글자 빨간색
  • L_inTable / L_here / L_gotoPara — 위치 확인·복귀
  • L_trim / L_msg — 공백 제거·메시지

이렇게 고쳐 쓰세요

  • 하이픈 대신 점(.)으로 통일 — 668·671·675·678줄의 "-" 를 "." 로 바꿉니다. 694줄은 앞뒤 "-" 를 보고 건너뛰므로, 점 꼴이 이미 섞인 문서라면 그 조건도 점에 맞게 손보는 것이 좋습니다.
  • 중복 번호를 빨간색으로 표시하지 않기 — 746줄 if (dup) { L_cellRed(parseInt(key, 10)); dupCells++; } 에서 L_cellRed(parseInt(key, 10)); 만 지웁니다. 안내 문구의 중복 목록은 그대로 남습니다.
  • 060 번호도 인식 — 673줄 정규식 괄호 안에 |60 을 더해 0(3[1-3]|4[1-4]|5[1-5]|6[1-4]|60|70|80|50\d) 로 바꿉니다.

고칠 때 주의

  • 중복 표시는 칸 전체 글자를 빨갛게 하므로, 번호 외 다른 글이 같은 칸에 있으면 함께 빨개집니다.
  • 주민등록번호 제외는 하이픈이 있는 "6자리-7자리" 꼴만 봅니다. 하이픈 없이 붙어 있는 13자리 숫자는 앞뒤 숫자 검사(694줄)로 대부분 걸러지지만, 고칠 때 이 조건을 지우지 마십시오.
  • 표 처리는 L_tableGeom 기반이라 병합 칸이 있는 표에서는 일부 칸을 건너뛰거나 잘못 읽을 수 있습니다.

공통_lib.js 공통 라이브러리 1~660줄

대부분의 매크로 맨 앞(1~660줄)에 그대로 들어 있는 도우미 함수 모음입니다. 붙여넣기 한 번으로 동작하도록 매크로마다 함께 넣었습니다(아래 소스 보기는 03 계산및합계의 앞부분).

소스 보기 (03 계산및합계 전체 중 1~660줄이 라이브러리)
심화과정: 소스 분석

한글 스크립트 매크로 대부분의 앞에 그대로 붙는 JScript(ES3) 공통 함수 모음입니다. 캐럿·문단 위치(GetPosBySet), 문단 글자 읽기(GetTextFile), 글자 넣기·지우기, 숫자 표기와 산출식 계산, 표 칸 이동과 표 구조 파악, 결과 칸 채움/검산/빨간 표시, 계산식 필드 처리, 글자 폭 어림 함수를 L_ 접두어로 제공합니다. 각 매크로는 이 함수를 조합해 자기 기능만 짧게 씁니다.

코드 흐름 (줄 번호를 누르면 소스의 그 부분으로 이동)

  1. 1~15줄① 머리말과 기본 도우미ES3 이라 trim·JSON 등을 쓰지 않는다는 규칙과, Pos 가 문단마다 0 에서 시작하지 않는다는 주의가 적혀 있습니다. L_trim 은 정규식으로 앞뒤 공백(전각 공백 포함)을 지우고, L_msg 는 XHwpMessageBox 에 문구와 Flag 0 을 넣어 DoModal 로 띄웁니다.
  2. 17~100줄② 캐럿·문단 함수L_here(List/Para/Pos 읽기), L_gotoPara(SetPos + MoveParaBegin, 실제로 그 문단에 갔는지 반환), L_base(문단 시작 Pos), L_paraText(MoveSelParaEnd 블록을 GetTextFile 로 읽고 L_unesc 로 숫자 엔티티 복원), L_setCaret, L_insertText, 오른쪽부터 고치는 L_applyEdits, L_lastPara 가 있습니다.
  3. 102~191줄③ 숫자 표기와 산출식L_num(콤마 제거 후 숫자), L_fmt(소수 둘째 자리 반올림 + 천 단위 콤마), L_fmtAmount/L_fmtNum, 숫자 사이 *·X·x 를 × 로 바꿀 목록을 만드는 L_mulEdits/L_normMul, × 로 나눈 인수의 마지막 숫자를 곱하는 L_calcExpr, 줄 안 금액 합 L_sumAmounts 가 있습니다.
  4. 193~307줄④ 표 칸 읽기·쓰기와 표 구조L_inTable(List≠0), L_cellText/L_cellSet, 빨간 표시 L_cellRed, 숫자 읽기 L_cellNum(△·- 음수), n칸 이동 L_tableRight/Left, TableRightCell 없이 칸 수를 세는 L_rowColCount, 표 좌상단·열 수·행 수·커서 행/열을 구하는 L_tableGeom, (행, 열)→List 계산 L_cellList, △ 표기 L_fmtSigned 가 있습니다.
  5. 309~377줄⑤ 결과 칸 채움·검산과 글머리 수준L_alignRight(AlignType 2), L_cellSetNum, 비면 채우고 맞으면 두고 틀리면 고친 뒤 빨갛게 하는 L_fillOrMark/L_fillOrMarkSigned, 공백 정리 L_cleanCellText, 산출기초 칸 계산 L_readFormula, 앞 공백·글머리 기호로 수준을 정하는 L_level 이 있습니다.
  6. 379~481줄⑥ 병합 표 칸 목록 L_tableCells표 첫 칸에서 List 번호를 하나씩 늘리며 같은 표 칸인지 확인하고, 칸마다 TablePropertyDialog 로 너비·높이를 읽습니다. 스카이라인 배치로 각 칸의 x·y 시작점을 정하고, 그 좌표들을 격자선으로 삼아 행·열 번호와 병합 범위, A1 꼴 주소(L_colName)를 계산합니다.
  7. 483~569줄⑦ 사칙연산 계산기 L_evalExpr글자를 숫자(단위 포함)·연산자·괄호·낱말 토큰으로 나누고, 마지막 낱말 뒤만 수식으로 봅니다. sum → term → factor 순서의 재귀 하강 방식으로 계산하며, 금액 단위의 차수(money)를 따라가 결과가 금액인지 비율인지도 알려 줍니다.
  8. 572~612줄⑧ 계산식 필드 L_ctrlMap·L_formulaCommaHeadCtrl 부터 Next 로 컨트롤을 훑어 CtrlID 가 %fmu·%clk 인 것을 칸 List 별로 모읍니다. L_formulaComma 는 숫자 서식에 쉼표가 없는 계산식을 DeleteCtrl 로 지우고 TableFormula 로 같은 식을 %g, 서식으로 다시 넣습니다.
  9. 615~659줄⑨ 글자 폭 어림과 칸 측정글자 폭을 재는 명령이 없어 L_charW 가 한글 1em, 숫자 0.6em 등 어림값을 씁니다. L_cellMeasure 는 칸의 글자 크기(CharShape Height)와 좌우 안여백을 읽고 문단별로 가장 긴 줄 폭을 계산합니다.

핵심 한글 API (HAction · HParameterSet …)

  • XHwpMessageBox.String / Flag / DoModal() — L_msg 에서 Flag 0(확인 단추만)으로 안내 메시지를 띄웁니다.
  • GetPosBySet() / SetPos(list, para, pos) / SetPosBySet(ps) — 캐럿 위치를 List·Para·Pos 로 읽고 옮깁니다. 문단 시작 Pos 가 0 이 아니어서 L_base 로 기준값을 먼저 읽습니다.
  • GetTextFile("TEXT", "saveblock") — 선택 블록을 평문으로 가져옵니다. CP949 밖 글자가 &#10061; 같은 엔티티로 오므로 L_unesc 로 되돌립니다.
  • HAction.GetDefault("InsertText", HParameterSet.HInsertText.HSet) + HAction.Execute — Text 항목에 문자열을 넣어 캐럿 자리에 글자를 삽입합니다(L_insertText).
  • HAction.GetDefault("CharShape", HParameterSet.HCharShape.HSet) — L_cellRed 에서 TextColor = 255(COLORREF 0x0000FF, BGR 순서라 빨강)를 넣어 Execute 합니다. L_cellMeasure 는 Height 로 글자 크기를 읽습니다.
  • HAction.GetDefault("ParagraphShape", HParameterSet.HParaShape.HSet) — L_alignRight 에서 AlignType = 2(오른쪽)로 문단 정렬을 바꿉니다.
  • HAction.GetDefault("TablePropertyDialog", HParameterSet.HShapeObject.HSet) — ShapeType 3 으로 셀 속성을 열어 ShapeTableCell.Width/Height/MarginLeft/MarginRight 를 읽습니다.
  • HeadCtrl / CtrlID / DeleteCtrl + HAction.Execute("TableFormula", HParameterSet.HFieldCtrl.HSet) — 문서 컨트롤을 훑어 계산식 필드를 찾고, 지운 뒤 Command 항목을 바꿔 다시 넣습니다.

부르는 공통 라이브러리 함수

  • L_here / L_gotoPara / L_base — 캐럿 위치 읽기·문단 이동·문단 시작 Pos
  • L_paraText / L_unesc — 문단 글자 읽기·엔티티 복원
  • L_applyEdits / L_setCaret / L_insertText — 오른쪽부터 지우고 넣기
  • L_fmt / L_num / L_calcExpr / L_evalExpr — 숫자 표기·계산
  • L_tableGeom / L_cellList / L_rowColCount — 균일한 표 구조
  • L_tableCells — 병합 표 칸 목록·주소
  • L_fillOrMark / L_cellRed / L_alignRight — 결과 칸 채움·검산·표시
  • L_ctrlMap / L_formulaComma — 계산식 필드

이렇게 고쳐 쓰세요

  • 안내 메시지 상자에 정보 아이콘 넣기 — 13줄 XHwpMessageBox.Flag = 0; 의 값을 바꿉니다. 매크로들은 3 + 32(예/아니요/취소 + 물음표)처럼 단추 값과 아이콘 값을 더해 쓰므로, 같은 방식으로 0 + 64 를 넣어 시험해 보십시오. L_msg 를 쓰는 모든 매크로에 함께 적용됩니다.
  • 오류·수정 표시색을 빨강 대신 파랑으로 — 213줄 HParameterSet.HCharShape.TextColor = 255; 를 0xFF0000(=16711680)으로 바꿉니다. 한글 색 값은 0x00BBGGRR(BGR) 순서라 RGB 의 파랑 #0000FF 와 반대로 씁니다.
  • 새 도우미 추가(예: 칸 글자 굵게) — 216줄(L_cellRed 끝) 다음에 같은 모양으로 function L_cellBold(list) { L_gotoPara(list, 0); HAction.Run("MoveSelParaEnd"); HAction.GetDefault("CharShape", HParameterSet.HCharShape.HSet); HParameterSet.HCharShape.Bold = 1; HAction.Execute("CharShape", HParameterSet.HCharShape.HSet); HAction.Run("Cancel"); } 를 넣습니다. ES3 문법만 쓰고 이름은 L_ 접두어를 지키십시오.
  • 표 계산 결과를 가운데 정렬로 — 313줄 HParameterSet.HParaShape.AlignType = 2; 를 3(가운데)으로 바꿉니다. 함수 이름은 L_alignRight 그대로이므로 다른 사람이 보기 쉽게 주석을 남기십시오.

고칠 때 주의

  • 이 파일은 각 매크로 앞에 그대로 복사되어 들어가므로, 한 곳을 고치면 그 판을 쓰는 매크로마다 동작이 바뀝니다. 매크로 파일 하나만 고치면 다른 매크로와 내용이 달라진다는 점도 기억하십시오.
  • ES3(JScript) 이라 String.trim, Array.indexOf, JSON 이 없습니다(4줄). 새 함수에서도 이런 기능은 정규식이나 반복문으로 직접 구현해야 합니다.
  • TableRightCell 이 한 번 실패하면 이어지는 Delete/InsertText 가 무시될 수 있다는 주석(265-267줄)이 있습니다. 표 이동 도우미를 새로 만들 때는 L_rowColCount·L_tableGeom 처럼 TableColBegin/TableLowerCell/TableUpperCell 위주로 쓰십시오. 또 324줄 주석은 반환값을 "marked" 로 적었지만 실제 반환값은 "corrected" 입니다.

소스·분석: 엑셀과 한글 매크로 · 소스는 배포 파일과 같으며, 고쳐 쓰다 문제가 생기면 배포본(.msr)을 다시 넣으면 원래대로 돌아갑니다.

8.매크로별 사용법 영상 (30종)

매크로마다 언제 쓰는지·순서·결과·주의를 더빙과 함께 설명합니다. 제목을 누르면 영상과 설명이 열립니다(화면은 한글 2024).

01 노란색 (Alt+1)

블록으로 잡은 글자에 노란 바탕(음영)과 빨간 글자를 줍니다. 검토 의견·강조 문구를 형광펜처럼 표시할 때 씁니다. 이미 칠한 글자를 다시 잡아 실행하면 음영을 없애고 글자를 검정으로 되돌립니다(선택의 첫 글자로 판단).

이럴 때

  • 검토 문서에서 고칠 부분을 표시할 때
  • 표시했던 강조를 한 번에 지울 때

순서

  1. 강조할 글자를 블록으로 잡습니다
  2. Alt+1 → 노란 음영 + 빨간 글자
  3. 같은 글자를 다시 잡아 실행하면 원래대로

결과

  • '산출근거를 다시 확인' → 노란 바탕 + 빨간 글자
  • 두 번째 실행 → 검정 글자, 음영 없음(글자 내용은 그대로)

주의

  • 2026-09-24 부터 기본 설치(Alt+1). 여러 색이 섞인 블록은 첫 글자 상태로 켬/끔을 판단합니다
  • 되돌릴 때 글자색은 검정입니다(원래 다른 색이었어도)

실행 중 나오는 버튼별 영상 (2개)

[노란색 ① 켜기] 블록 글자에 노란 음영 + 빨간 글자
검토 의견·강조할 글자를 형광펜처럼 표시합니다.
누르면: ① 강조할 글자를 블록으로 잡기 ② Alt+1
결과: 노란 바탕 + 빨간 글자.

[노란색 ② 끄기] 같은 글자를 블록으로 잡고 한 번 더 → 원래대로
같은 단축키가 켜기/끄기를 번갈아 합니다.
누르면: ① 표시한 글자를 다시 블록으로 ② Alt+1
결과: 검정 글자, 음영 없음.

02 한셀입력 (Alt+2)

커서 칸(F5·마우스로 여러 칸을 골라도 됨)의 글이 한 줄에 들어가게 합니다. 글자 크기는 줄이지 않고, 먼저 장평을 필요한 만큼(최소 80%) 줄이고, 그래도 넘치면 자간을 필요한 만큼(최소 -10%) 줄여 한 줄로 넣은 뒤 그 칸에 셀 속성 '한 줄로 입력'을 켭니다. 장평 80%·자간 -10% 로도 안 들어가면 그 상태로 두고 '한 줄로 입력'을 끄며, 이어지는 글자는 어절 단위로 다음 줄로 넘깁니다(문단 줄 나눔 기준 = 어절). 다시 실행해도 같은 결과(장평·자간을 100·0 으로 되돌린 뒤 다시 계산).

이럴 때

  • 사업명·내용이 길어 표 행 높이가 들쭉날쭉할 때
  • 명단·좌석표처럼 한 칸에 한 줄로 보여야 할 때

순서

  1. 유형 ① 여러 칸: 칸에서 F5 를 누르고 ↓·→ 로 범위를 넓힌 뒤 Alt+2
  2. 유형 ② 한 칸: 칸에 커서만 두고 Alt+2
  3. 긴 글이 글자 크기는 그대로, 장평·자간으로 한 줄에 들어갑니다

결과

  • 범위로 잡은 칸들과 커서 칸 모두 한 줄로 — 글자 크기는 유지

주의

  • 글자 크기는 절대 바꾸지 않습니다(2026-09-24 밤 사용자 요청). 장평·자간 한계는 80%·-10%
  • 글자 폭은 어림값이라 결과가 아쉬우면 칸 너비를 조금 넓히세요(표간격정리 추천)
03 계산및합계 (Alt+3)

블록 없이 실행하면 커서 줄(표 안이면 그 칸) 하나만 계산합니다. × ÷ / + - 와 괄호를 계산하며, '=' 뒤가 비면 결과를 채우고 값이 있으면 검산해 틀리면 고쳐 빨간색으로 표시합니다. 금액÷금액(1,824,740원/2,630,540원)은 비율 0.69, 금액÷인원(600천원/30명)은 20천원처럼 금액으로 적습니다. 여러 줄을 긁어 실행하면 각 줄을 계산하고 합계를 윗줄 ':' 뒤에 '총 1,600천원'으로 적습니다(비율 줄은 합계에서 뺌).

이럴 때

  • 산출기초 한 줄만 빨리 계산할 때(블록 없이)
  • ○ 항목 아래 - 세부 산출기초 여러 줄을 긁어 항목 합계까지 채울 때

순서

  1. '=' 뒤가 빈 줄을 클릭하고 실행 → 그 줄만 계산
  2. 여러 줄을 긁어 실행 → 각 줄 계산 + 윗줄 합계
  3. 나누기 줄도 같은 방법으로 실행

결과

  • 100,000원×3명×2회= → 600천원, 3줄 블록 → '○ 운영비 산출기초: 총 1,600천원'
  • 1,824,740원/2,630,540원= → 0.69 (비율), 600천원/30명= → 20천원
  • (2,630,540-1,824,740)÷1,824,740×100= → 44.16

주의

  • 곱하기는 *, x, X 모두 × 로, 나누기는 / 또는 ÷. 비율은 소수 둘째 자리에서 반올림
  • - 항목 아래 · 세부가 섞이면 첫 줄과 같은 기호의 줄만 합산합니다(이중 계산 방지)

실행 중 나오는 버튼별 영상 (3개)

[계산및합계 ① 커서 줄만] 블록 없이 커서만 → 그 줄의 산출식만 계산
'= ' 뒤가 빈 산출기초 줄에서 그 줄만 계산합니다.
누르면: ① 계산할 줄에 커서 ② Alt+3
결과: 그 줄 '=' 뒤에 금액.

[계산및합계 ② 블록 → 합계] 여러 줄을 블록으로 → 각 줄 계산 + 바로 윗줄에 합계
산출기초 여러 줄을 한 번에 계산하고 합계를 넣습니다.
누르면: ① 산출기초 여러 줄을 블록 ② Alt+3
결과: 각 줄 금액 + 윗줄 합계.

[계산및합계 ③ 나누기] 금액÷금액은 비율, 금액÷인원은 1인당 금액
단위를 보고 나누기 결과를 비율(소수 둘째 자리) 또는 금액으로 적습니다.
누르면: ① 나누기 식 줄에 커서 ② Alt+3
결과: 비율 또는 1인당 금액.

04 표머리두줄HY그래픽 (Alt+4)

커서가 있는 표에 한글 표마당 기본 양식을 입힌 뒤, 제목 행을 HY그래픽 12pt 굵게 + 연한 회색 바탕 + 아래 이중선(0.5mm)으로, 바깥 테두리를 0.4mm 로 바꿉니다. 내용은 그대로 두고 모양만 공문 표 양식으로 맞춥니다.

이럴 때

  • 엑셀·다른 문서에서 붙여 온 표를 공문 양식으로 맞출 때
  • 새로 만든 표의 제목 행을 한 번에 꾸밀 때

순서

  1. 표 안(왼쪽 위 칸)에 커서를 둡니다
  2. Alt+4
  3. 제목 행·테두리 모양을 확인합니다

결과

  • 제목 행: HY그래픽 굵게, 회색 바탕, 아래 이중선
  • 바깥 테두리 0.4mm, 칸 내용은 그대로

주의

  • 2026-09-24 부터 기본 설치(실행 창). 이미 양식이 입혀진 표에 다시 실행해도 같은 모양
  • HY그래픽 글꼴이 없는 PC 에서는 다른 글꼴로 보입니다
05 표간격정리 (Alt+5)

커서가 있는 표의 열 너비를 다시 나눕니다. 첫 열(순번)과 마지막 열(비고), 그리고 숫자·날짜처럼 짧은 열은 가장 긴 내용이 한 줄에 들어갈 만큼만 주고, 남는 너비는 긴 글이 있는 열이 내용 길이에 비례해 가져갑니다. 그래서 빈칸이 넓게 남거나 내용이 여러 줄로 넘쳐 표가 길어지는 일이 줄어듭니다. 표 전체 너비는 바뀌지 않고, 행 높이는 내용에 맞게 자동입니다.

이럴 때

  • 열 너비가 같아 순번·비고가 넓고 사업명이 여러 줄로 넘친 표
  • 엑셀에서 붙여 온 표를 공문 표처럼 다듬을 때

순서

  1. 열 너비가 모두 같은 5열 표 — 순번·비고는 텅 빈 채 넓고, 사업명·주요 내용은 5~6줄로 넘쳐 표가 길어진 상태
  2. 표 안 아무 칸에서 Alt+5 → 표간격정리 실행
  3. 순번·예산·비고는 내용만큼만 좁아지고, 남는 너비를 사업명·주요 내용이 나눠 가져 줄 수가 확 줄어듭니다(표 너비는 그대로)

결과

  • 순번·비고 열은 글자 폭만큼, 예산 열은 '1,744,740'이 한 줄에 들어갈 만큼만
  • 사업명·주요 내용이 남는 너비를 내용 길이에 비례해 나눠 가져 5~6줄 → 1~2줄, 표 길이가 절반 이하로

주의

  • 글자 폭은 어림값(한글 1em, 영문·숫자 0.52em)이라 아주 빽빽한 표는 한 번 더 실행하거나 직접 조정
  • 행 높이를 일부러 크게 둔 표(서명란 등)는 높이가 내용 높이로 줄어듭니다
06 음수를세모로적용합계 (Alt+6)

커서가 있는 열의 데이터 칸에서 '-800' 처럼 빼기 기호로 적힌 음수를 모두 공문 표기 '△800'으로 바꾸고, 그 열의 합계를 마지막 행에 넣습니다. 합계가 음수면 역시 '△500'으로 적습니다.

이럴 때

  • 입금·출금이 섞인 정산표의 합계
  • 증감 열처럼 음수가 나올 수 있는 열을 공문 표기로 정리할 때

순서

  1. 합계 낼 열의 칸을 클릭합니다
  2. Alt+6 을 누릅니다
  3. 안내창에서 바뀐 음수 칸 수와 합계를 확인하고 Enter

결과

  • -800 → △800, -200 → △200, -50 → △50 으로 바뀝니다
  • 500 - 800 - 200 + 100 - 50 = -450 → 합계 행에 △450 이 들어갑니다
  • 계산·정리된 숫자는 모두 칸 오른쪽에 정렬됩니다(2026-09-22 개선)

주의

  • '-800' 처럼 앞에 빼기 기호가 붙은 숫자를 음수로 봅니다(이미 △ 인 칸은 그대로)
  • 마지막 행이 합계 행이어야 합니다
07 번호재정렬 (Alt+7)

본문에서 실행하면 문서 전체 문단을 위에서 아래로 훑어 1단계 1. → 2단계 가. → 3단계 1) → 4단계 가) → 5단계 ① 순서가 맞는지 확인하고 어긋난 번호를 고칩니다. 상위 번호가 올라가면 하위 번호는 1부터 다시 세며, 고친 번호는 빨간 글자로 표시합니다. 표 안에서 실행하면 커서가 있는 열의 2·3번째 값을 씨앗으로 한글 본연의 [표 자동 채우기]로 아래를 다시 매기고(가), ① 처럼 자동 채우기가 못 하는 종류는 직접 이어 채움), 바뀐 칸은 빨간 글자로 표시합니다.

이럴 때

  • 항목을 넣고 빼다가 1. 2. 4. / 가. 다. 처럼 번호가 꼬인 계획서
  • 표의 연번 열이 중간에 비거나 어긋났을 때

순서

  1. 본문 아무 곳에 커서를 두고 실행하면 문서 전체의 계층 번호가 정리됩니다
  2. 고쳐진 번호는 빨간 글자로 표시되어 어디가 바뀌었는지 바로 보입니다
  3. 표 안에서 실행하면 그 열의 번호가 둘째·셋째 값 규칙대로 다시 채워집니다

결과

  • 3) 2) → 2) 3), 다. → 나., 3. 2. → 2. 3., 다) → 나) 처럼 정정되고 고친 번호는 빨강
  • '2026. 10. 12.' 같은 날짜는 번호로 보지 않습니다
  • 표 열: 1, 2, (빈칸), 9, (빈칸), (빈칸) → 1~6 으로 채워지고 바뀐 칸은 빨강

주의

  • 계층 규칙은 1. > 가. > 1) > 가) > ① 입니다. 다른 체계(1.1 등)는 다루지 않습니다
  • ○ · - 같은 기호 글머리는 건드리지 않습니다

실행 중 나오는 버튼별 영상 (2개)

[번호재정렬 ① 본문] 본문에서 실행 → 1. 가. 1) 가) ① 계층 번호 확인·정정(고친 번호 빨강)
본문 아무 줄에서 실행하면 문서의 계층 번호를 위에서 아래로 맞춥니다.
누르면: ① 본문 아무 줄에 커서 ② Alt+7 ③ 안내 [확인]
결과: 어긋난 번호가 고쳐지고 빨간색 표시.

[번호재정렬 ② 표] 표 번호 열에서 실행 → 그 표의 번호 열만 다시 매김
커서가 있는 표의 번호 열만 자동 채우기로 다시 매깁니다(다른 표는 그대로).
누르면: ① 번호 열의 아무 칸에 커서 ② Alt+7
결과: 1, 2, 3 … 순서대로.

08 중복값색처리 (Alt+8)

커서가 있는 열에서 같은 값이 두 번 이상 나오는 칸을 찾아, 중복 묶음마다 빨강·파랑·녹색·청색·감색·갈색·자주·주황·올리브·회색 10가지 진한 색으로 구분해 칠합니다. 다시 실행하면 검정으로 되돌립니다.

이럴 때

  • 명단에서 같은 점수·같은 학번·같은 이름을 찾을 때
  • 동점자 처리 전에 중복을 눈으로 확인할 때

순서

  1. 검사할 열의 칸에 커서를 둡니다
  2. Alt+8 을 누릅니다 → 중복 묶음마다 다른 색
  3. 한 번 더 누르면 모두 검정으로

결과

  • 같은 값끼리 같은 색 — 묶음이 여러 개면 색이 달라 한눈에 구분됩니다

주의

  • 빈 칸은 비교하지 않습니다
  • 묶음이 8개를 넘으면 색이 처음부터 반복됩니다

실행 중 나오는 버튼별 영상 (2개)

[중복값색처리 ① 색 표시] 커서 열의 같은 값 묶음마다 다른 진한 색
커서가 있는 표의 그 열에서 같은 값끼리 색으로 묶습니다.
누르면: ① 값을 볼 열에 커서 ② Alt+8
결과: 묶음마다 빨강·파랑·녹색 ….

[중복값색처리 ② 검정으로] 한 번 더 실행 → 모두 검정으로
색 표시를 지울 때 같은 단축키를 다시 누릅니다.
누르면: ① 같은 열에 커서 ② Alt+8
결과: 모두 검정 글자.

09 오름내림차순정렬 (Alt+9)

커서가 있는 열을 기준으로 표의 데이터 행(제목행 제외)을 다시 배열합니다. 처음 실행하면 작은 값부터(오름차순), 이미 오름차순인 상태에서 다시 실행하면 큰 값부터(내림차순)로 바뀝니다. 기준 열이 모두 숫자면 숫자 비교, 하나라도 글자면 사전순 비교입니다.

이럴 때

  • 점수·예산 열을 기준으로 순위표를 만들 때
  • 같은 표를 오름/내림 두 방향으로 번갈아 볼 때

순서

  1. 기준 열의 칸을 클릭합니다
  2. 매크로를 실행하면 오름차순(60·70·80·90·95)으로 정렬됩니다
  3. 같은 열에서 한 번 더 실행하면 내림차순(95·90·80·70·60)으로 바뀝니다

결과

  • 1회차: 60 → 70 → 80 → 90 → 95 (5명 오름차순)
  • 2회차: 95 → 90 → 80 → 70 → 60 (안내창에 방향이 표시됩니다)

주의

  • 합계 행이 따로 있으면 함께 정렬되니 정렬 후 확인하세요
  • 값이 모두 같으면 순서가 바뀌지 않습니다

실행 중 나오는 버튼별 영상 (2개)

[정렬 ① 오름차순] 커서 열 기준으로 처음 실행 → 오름차순
커서가 있는 표를 그 열 기준으로 정렬합니다(제목 행 제외).
누르면: ① 기준 열에 커서 ② Alt+9
결과: 작은 값부터.

[정렬 ② 내림차순] 같은 열에서 한 번 더 → 내림차순
누를 때마다 오름/내림이 바뀝니다.
누르면: ① 같은 열에 커서 ② Alt+9
결과: 큰 값부터.

10 요일입력 (Alt+0)

커서가 있는 줄의 날짜를 모두 찾아 뒤에 (월) 같은 요일을 붙입니다. 마침표형(2026. 10. 12., 연도 생략 시 앞 연도 상속)뿐 아니라 - / _ , 로 구분한 날짜(2026-10-12, 2026/11/04, 2026_11_13, 2026,11,17)도 인식합니다. 한 줄에 날짜가 여러 개면 전부 처리합니다.

이럴 때

  • 공문·계획서에 행사 기간을 적을 때
  • 엑셀에서 붙여 온 2026-10-30 형식 날짜에 요일을 달 때

순서

  1. 날짜가 적힌 줄을 클릭합니다
  2. 매크로를 실행하면 그 줄의 모든 날짜 뒤에 요일이 붙습니다
  3. 다른 형식의 날짜 줄도 같은 방법으로 처리합니다

결과

  • 2026. 10. 12. ~ 2026. 10. 16. → (월) ~ (금)
  • 2026-10-30(금), 2026/11/04(수), 2026_11_13(금), 2026,11,17(화)

주의

  • 2026. 2. 30. 처럼 없는 날짜는 건드리지 않습니다
  • 기호형은 연도가 있어야 하고 앞뒤 기호가 같아야 합니다(10-12 같은 범위 표기와 구분)
11 개인정보마스킹 (Alt+-)

표 안에서 실행하면 커서가 있는 표 전체의 주민등록번호 뒷자리(*******)와 휴대전화 가운데(010-****-5678)를 가리고, 제목 칸에 '이름/성명'이 있는 열은 이름 가운데 글자를 *로 바꿉니다(홍*동, 남궁*수). 표 밖에서는 커서 줄의 번호만 가립니다.

이럴 때

  • 학생·교사 명단을 외부에 보내거나 게시하기 전
  • 회의 자료·보고서에 실명 대신 마스킹 명단을 붙일 때

순서

  1. 명단 표 안의 아무 칸을 클릭합니다
  2. Alt+- 를 누릅니다
  3. 안내창에서 가린 건수를 확인하고 Enter

결과

  • 이름 5명: 김*수, 남궁*수, 이*희, 박*수, 최*현
  • 휴대전화: 010-****-5678 형식으로 통일해 가림(01098765432, 010.5555.1234, 010 2222 3333 처럼 형식이 달라도)
  • 주민등록번호: 990101-******* 처럼 뒷자리 전부 가림

주의

  • 원본 파일은 따로 보관하고 복사본에서 실행하세요(되돌리기는 Ctrl+Z)
  • 이름 열은 제목 칸 글자(이름·성명·학생명·담당자·교사명)로 알아봅니다
12 표위치확인및제거 (Alt+Shift+1)

표의 칸마다 한글 계산식 주소를 빨간 안내문(누름틀)으로 보여 주고, 한 번 더 실행하면 지웁니다. 안내문은 칸의 글자가 아니어서 합계 계산식이 표시를 숫자로 읽는 일이 없고(값 그대로), 인쇄되지 않습니다. 병합 머리글 표도 한글과 같은 주소를 매기며, F5·마우스로 칸을 골라 실행하면 고른 칸만 표시·제거해 빠릅니다. 쉼표 없는 서식의 계산식 칸은 쉼표 서식(2,474)으로 맞춥니다.

이럴 때

  • 표 계산식(=SUM, 곱셈 등)을 만들 때 칸 주소를 헷갈리지 않으려 할 때
  • 표계산식적용및제거(C-표계산-10)과 짝으로: 주소 확인 → 계산식 타이핑 → 적용

순서

  1. 표 안 아무 칸에서 Alt+Shift+1 → 그 표 전체에 주소 표시
  2. F5·마우스로 칸을 골라 Alt+Shift+1 → 고른 칸만 표시
  3. 같은 방법으로 한 번 더 실행하면 표시가 지워집니다

결과

  • 병합 머리글 예산표: 2026년도 C1, 2027년도 E1, 합계 A8 — 합계 계산식 값은 그대로(2,474)
  • C3:D5 를 골라 실행하면 여섯 칸에만 표시, 다시 실행하면 그 칸만 지움

주의

  • 표시가 있는 채로 칸에 계산식을 쳐도 됩니다(지울 때 안내문만 사라짐)
  • 주소는 한글 상태 표시줄의 셀 주소와 같습니다(병합 칸은 왼쪽 위 칸 주소)

실행 중 나오는 버튼별 영상 (3개)

[표위치 ① 주소 표시] 커서가 있는 표의 칸마다 [A1] [B2] … 빨간 안내문
계산식을 적을 때 칸 주소를 봅니다. 계산식 값은 바뀌지 않습니다.
누르면: ① 표 안 아무 칸에 커서 ② Alt+Shift+1
결과: 칸마다 빨간 주소.

[표위치 ② 표시 지우기] 한 번 더 실행 → 주소 표시가 모두 지워짐
같은 단축키가 표시/지우기를 번갈아 합니다.
누르면: ① 같은 표에 커서 ② Alt+Shift+1
결과: 표시 없음.

[표위치 ③ 고른 칸만] F5로 칸을 골라 실행 → 고른 칸만 표시/지우기(빠름)
큰 표에서 필요한 칸만 볼 때.
누르면: ① F5(또는 마우스)로 칸 고르기 ② Alt+Shift+1(다시 누르면 그 칸만 지움)
결과: 고른 칸만 주소.

13 표계산식적용및제거 (Alt+Shift+2)

커서가 있는 표 전체를 훑어 '='로 시작하는 글자 칸(=C2/B2, =(C2-E2)/E2*100, =C3-C2, =C2+E3 …)이 있으면 한글 표 계산식(필드)으로 바꿔 값을 표시합니다. 단순 합계는 한글 기본 단축키(가로 Ctrl+Shift+H, 세로 Ctrl+Shift+V)로 되므로 나누기·비율·떨어진 칸 계산에 씁니다. '=' 글자 칸이 없고 계산식 필드가 있는 표에서 실행하면 '계산식 N개를 값만 남기고 지울까요?'를 묻고 [예]면 필드를 없애고 보이는 값만 글자로 남깁니다(다른 문서에 붙이거나 행·열을 지울 때 깨짐 방지).

이럴 때

  • 1인당 예산, 증감률(%)처럼 나누기·비율이 필요한 예산표, 떨어져 있는 칸의 합·차
  • 계산이 끝난 표를 제출·복사하기 전에 계산식을 값으로 고정할 때

순서

  1. C-표계산-09 표위치확인및제거로 칸마다 [B2] 같은 주소를 띄우고, =C2/B2 처럼 타이핑한 뒤 표시를 지웁니다
  2. Alt+Shift+2 → 글자 계산식이 진짜 표 계산식(필드)으로 바뀌어 값이 나옵니다
  3. 한 번 더 Alt+Shift+2 → '값만 남기고 지울까요?' [예](Enter) → 계산식은 사라지고 숫자만 남습니다

결과

  • =C2/B2 → 20, =c3/b3 → 45, =(C2-E2)/E2*100 → 20, =(C3-E3)/E3*100 → 12.5, =C3-C2 → 300, =C2+E3 → 1,400
  • 적용된 칸은 원본 숫자를 고치면 다시 계산되고, 제거 뒤에는 값(20, 1,400 …)이 일반 글자로 남습니다. 결과는 검정·오른쪽 정렬

주의

  • 단순 합계는 Ctrl+Shift+H(가로)·Ctrl+Shift+V(세로)가 빠릅니다 — 세로 합계는 제목 칸 숫자('1분기'→1)까지 더하니 주의
  • 2026-09-24 표계산식적용·표계산식다지우기 두 매크로를 하나로 합쳤습니다(슬롯 30개 한도). 제거는 묻고 진행하며 Ctrl+Z 로 되돌릴 수 있습니다

실행 중 나오는 버튼별 영상 (2개)

[적용 — 글자 계산식을 표 계산식으로] 칸에 타이핑한 =C2/B2 같은 글자를 한글 표 계산식(필드)으로
커서가 있는 표에서 '='로 시작하는 글자 칸을 계산식 필드로 바꿔 값을 보여 줍니다.
누르면: ① 칸에 =C2/B2 처럼 입력 ② 표 안에서 Alt+Shift+2
결과: 여섯 칸에 값(20, 45, 12.5 …).

[예] 값만 남기고 제거 계산식 필드가 있는 표에서 다시 실행 → [예]면 값만 남기고 계산식 제거
'=' 글자 칸이 없고 계산식 필드만 있으면 제거할지 묻습니다. [아니요]는 그만두기.
누르면: ① 계산식 필드가 있는 표에서 같은 단축키(Alt+Shift+2) ② 확인 창 [예] ③ 완료 안내 [확인]
결과: 값(20, 1,400 …)만 일반 글자로 남습니다 — 되돌리기 Ctrl+Z.

14 선택셀표계산천원 (Alt+Shift+3)

커서가 있는 산출기초 칸부터 표의 마지막 행까지 '100,000원×3명×2회=' 같은 식을 계산해 바로 오른쪽 칸에 천원 단위로 넣습니다. 한 열(한 짝)만 처리합니다.

이럴 때

  • 예산요구서·검토보고회 사업별 내역표의 예산 칸을 채울 때
  • 이미 적힌 값이 맞는지 검산할 때(틀리면 고치고 빨간색으로 표시)

순서

  1. 표에서 첫 산출기초 칸을 클릭합니다
  2. Alt+Shift+3 을 누릅니다
  3. 안내창에서 채움·검증·수정 개수를 확인하고 Enter

결과

  • 오른쪽 예산(천원) 칸에 600 / 600 / 400 / 180 / 100 이 들어갑니다
  • 이미 값이 있던 칸은 맞으면 그대로, 틀리면 올바른 값으로 고치고 빨간색으로 표시합니다
  • 그룹 제목 행처럼 산출기초가 비어 있는 행은 건너뜁니다
  • 계산·정리된 숫자는 모두 칸 오른쪽에 정렬됩니다(2026-09-22 개선)

주의

  • 곱하기는 *, x, X 어느 것을 써도 되며 실행 후 × 로 통일됩니다
  • 산출기초에 '천원'이 붙어 있어도, '원'만 있어도 결과는 천원 단위입니다
  • 표 밖에서 실행하면 안내창만 뜨고 아무것도 바뀌지 않습니다
15 증감포함표계산천원 (Alt+Shift+4)

커서 칸부터 [산출기초A][예산A][산출기초B][예산B][증감] 다섯 칸을 한 묶음으로 보고 계산합니다. 증감이 음수면 '-' 대신 △로 적고, 마지막 행(합계)에는 누적 합계를 넣습니다.

이럴 때

  • 본예산 대비 증감을 함께 보여 주는 예산요구서·검토보고회 표
  • 합계 행까지 자동으로 맞추고 싶을 때

순서

  1. 첫 데이터 행의 산출기초(A) 칸을 클릭합니다
  2. Alt+Shift+L → 증감포함표계산천원 실행 를 누릅니다
  3. 안내창에서 처리 개수를 확인하고 Enter

결과

  • 예산A 600/600/400/180/100, 예산B 480/450/500/120/50, 증감 120/150/△100/60/50 이 채워지고 합계 행에 1,880 / 1,600 / 280 이 들어갑니다
  • 감소는 △100 처럼 표기됩니다
  • 산출기초가 둘 다 빈 행(가. 나. 같은 제목 행)은 건너뜁니다
  • 계산·정리된 숫자는 모두 칸 오른쪽에 정렬됩니다(2026-09-22 개선)

주의

  • 표의 마지막 행을 합계 행으로 봅니다 — 합계 행이 없으면 마지막 데이터 행에 합계가 들어가니 주의
  • 칸 순서가 [산출기초A][예산A][산출기초B][예산B][증감] 이어야 합니다
16 합계행자동서식 (Alt+Shift+5)

표 안 어디에 커서가 있든 표의 마지막 행을 찾아 글자를 굵게 하고, 그 행 위쪽 테두리를 이중 실선(0.5mm)으로 바꿉니다.

이럴 때

  • 예산표·통계표의 합계 행을 눈에 띄게 할 때
  • 여러 표의 합계 행 서식을 똑같이 맞출 때

순서

  1. 표 안의 아무 칸이나 클릭합니다
  2. Alt+Shift+5 을 누릅니다
  3. 안내창을 확인하고 Enter

결과

  • 5개 항목 아래 합계 행(260 / 360 / 620)이 굵게 되고 위쪽 테두리가 이중 실선 0.5mm 로 바뀝니다
  • 데이터 행의 테두리는 그대로입니다

주의

  • 마지막 행이 합계 행이 아닌 표에서는 실행하지 마세요(그 행이 굵어집니다)
17 금액한글표기 (Alt+Shift+6)

커서 줄(또는 칸)의 금액마다 바로 뒤에 한글 금액 표기를 괄호로 붙입니다. 원 단위뿐 아니라 천원·만원·백만원·천만원·억원 단위 표기도 실제 금액으로 환산합니다(1,234천원 → 금일백이십삼만사천원, 3.5백만원 → 금삼백오십만원). 위변조 방지를 위해 '일'까지 모두 적는 계약서 방식입니다.

이럴 때

  • 계약서·견적서·지출결의서에 한글 금액을 함께 적을 때
  • 큰 금액을 읽을 때 자릿수 실수를 막을 때

순서

  1. 금액이 있는 줄을 클릭합니다
  2. Alt+Shift+6 를 누릅니다
  3. 천원·백만원 단위 줄도 같은 방법으로 실행합니다

결과

  • 계약금액: 1,234,000원 → 1,234,000원(금일백이십삼만사천원)
  • 예산 1,234천원 → 1,234천원(금일백이십삼만사천원), 12백만원 → 12백만원(금일천이백만원), 3.5백만원 → (금삼백오십만원)

주의

  • 이미 '(금'이 붙은 금액은 건너뜁니다
  • 단위 표기의 소수(3.5백만원)는 환산 뒤 원 단위로 반올림합니다
18 엑셀에서표데이터값복사 (Alt+Shift+7)

엑셀에서 셀 범위를 복사(Ctrl+C)한 뒤 본문에서 실행하면 표로 붙여넣고, 모든 칸의 앞뒤 공백과 두 칸 이상 연속된 공백을 정리합니다. 이미 표 안에서 실행하면 그 표만 정리합니다.

이럴 때

  • 엑셀 자료를 한글 공문 표로 옮길 때
  • 복사해 온 표에 이상한 공백이 남아 있을 때

순서

  1. 엑셀에서 셀 범위를 복사(Ctrl+C)합니다
  2. 한글 본문에서 붙여넣을 자리를 클릭하고 Alt+Shift+7 을 누릅니다
  3. 안내창에서 정리된 칸 수를 확인하고 Enter

결과

  • 엑셀 5행(○○기계공고·동아공고·○○자동차고·△△공고·○○관광고)이 표로 붙여지고 ' ○○기계공고', '신규 참여' 같은 앞뒤·중복 공백이 정리됩니다

주의

  • 엑셀에서 복사한 직후에 실행해야 합니다(클립보드에 표가 있어야 함)
  • 단어 사이 공백 한 칸은 그대로 둡니다
19 글자수카운터 (Alt+Shift+8)

생기부 입력 전 글자 수와 바이트 수를 확인합니다. 표 칸에 커서만 두면 그 칸, 블록을 잡으면 그 범위, 아무것도 없으면 문서 전체를 세어 나이스식 바이트 수(한글 2, 영문·숫자 1)까지 안내합니다.

이럴 때

  • 교과 세특·창체 문장을 나이스 입력 한도(바이트)에 맞춰 다듬을 때
  • 보도자료·공모 신청서의 분량 제한을 확인할 때

순서

  1. 표 칸에 커서만 두고 Alt+Shift+8 → 그 칸의 글자 수·바이트 수
  2. 문장을 블록으로 잡고 Alt+Shift+8 → 선택한 범위만
  3. 안내창의 글자 수(공백 포함/제외)·바이트 수를 확인하고 Enter

결과

  • 칸 하나 / 블록 범위 두 경우 모두 글자 수·공백 제외 글자 수·바이트 수 안내창

주의

  • 표 안의 글자도 함께 셉니다
  • 바이트 수는 한글 2바이트 기준의 추정값입니다

실행 중 나오는 버튼별 영상 (2개)

[글자수 ① 칸만] 표 칸에 커서만 두면 그 칸의 글자 수·바이트 수
생기부 칸처럼 한 칸만 셀 때. 블록도 칸도 없으면 문서 전체를 셉니다.
누르면: ① 셀 칸에 커서 ② Alt+Shift+8
결과: 글자 수·바이트 수 안내.

[글자수 ② 블록만] 블록을 잡으면 고른 범위만 셉니다
본문 문장 일부만 셀 때.
누르면: ① 셀 범위를 블록 ② Alt+Shift+8
결과: 고른 범위의 글자 수·바이트 수.

20 기간일수계산 (Alt+Shift+9)

커서 줄의 '날짜 ~ 날짜' 기간을 찾아 시작일과 끝일을 포함한 달력 일수를 '(5일간)'처럼 붙입니다. 요일이 붙어 있어도, 뒤 날짜의 연도가 생략되어도 됩니다.

이럴 때

  • 연수·출장·파견 기간을 적을 때 일수를 같이 표기해야 할 때
  • 여비·수당 산정용 일수를 확인할 때

순서

  1. 기간이 적힌 줄에 커서를 둡니다(연수 기간 2026. 3. 2. ~ 3. 6.)
  2. Alt+Shift+9 를 누릅니다 → (5일간)
  3. 둘째 줄 파견 기간(9. 1. ~ 12. 31.)에서도 실행 → (122일간)

결과

  • 끝 날짜 뒤에 (5일간), (122일간)처럼 총 일수가 붙습니다. 끝 날짜 연도를 생략해도 됩니다.

주의

  • 주말·공휴일을 빼지 않은 달력 일수입니다
  • 이미 '(N일' 표기가 있으면 건너뜁니다
21 숫자자동콤마삽입 (Alt+Shift+0)

커서가 있는 표 전체에서 콤마 없이 적힌 숫자에만 천 단위 콤마를 넣습니다. 글자가 섞인 칸이나 이미 콤마가 있는 숫자는 그대로 둡니다.

이럴 때

  • 엑셀에서 숫자만 복사해 온 표를 공문 서식에 맞출 때
  • 금액 칸의 콤마 누락을 한 번에 고칠 때

순서

  1. 표 안의 아무 칸이나 클릭합니다
  2. Alt+Shift+0 를 누릅니다
  3. 안내창에서 바뀐 칸 수를 확인하고 Enter

결과

  • 1400000 → 1,400,000, 9999 → 9,999, 250000 → 250,000, 75000 → 75,000
  • '2026년' 처럼 연도가 든 글자 칸은 바꾸지 않습니다
  • 계산·정리된 숫자는 모두 칸 오른쪽에 정렬됩니다(2026-09-22 개선)

주의

  • 계산식(합계) 칸은 식을 두고 숫자 서식만 쉼표 서식으로(다시 계산돼도 쉼표 유지)
  • 연도나 번호처럼 콤마가 붙으면 안 되는 순수 숫자 칸이 있으면 실행 후 확인하세요
22 표빈칸하이픈채우기 (Alt+Shift+-)

커서가 있는 표 전체를 훑어 아무 내용도 없는 칸에만 '-'를 넣습니다. 값이 있는 칸은 건드리지 않습니다. 채운 '-'는 칸 가운데에 정렬됩니다.

이럴 때

  • 예산표·현황표에서 해당 없음 칸을 '-'로 통일할 때
  • 제출 전 빈 칸 누락 점검 대신

순서

  1. 표 안의 아무 칸이나 클릭합니다
  2. Alt+Shift+- 을 누릅니다
  3. 안내창에서 채운 칸 수를 확인하고 Enter

결과

  • 빈 칸 6개에 '-'가 들어가고 모두 가운데 정렬됩니다
  • 78,000·85,500·120,000·45,000 처럼 값이 있는 칸은 그대로입니다

주의

  • 공백만 들어 있는 칸도 빈 칸으로 봅니다
  • 표 밖에서 실행하면 안내창만 뜹니다
23 날짜표기통일 (실행 창)

커서가 있는 줄의 날짜를 찾아 공문 표기(2026. 7. 6. — 마침표 뒤 한 칸 띄움)로 바꿉니다. 하이픈, 슬래시, 붙여 쓴 마침표 표기를 모두 알아봅니다.

이럴 때

  • 엑셀·메일에서 가져온 날짜를 공문 서식에 맞출 때
  • 여러 사람이 쓴 문서의 날짜 표기를 통일할 때

순서

  1. 날짜가 있는 줄을 클릭합니다
  2. Alt+Shift+L → 날짜표기통일 실행를 누릅니다
  3. 바뀐 표기를 확인합니다

결과

  • 2026-7-6 · 2026/7/10 · 2026.7.3. · 2026.6.3 이 모두 2026. 7. 6. 형식으로 바뀝니다(커서가 있는 줄만)

주의

  • 이미 공문 표기인 날짜는 그대로 둡니다
  • 요일까지 붙이려면 이어서 A-서식-01 요일입력을 누르세요
24 좌석표 (실행 창)

커서가 있는 학생 명렬표(제목행에 학년반·번호·이름, 여러 쪽에 걸쳐도 됨)를 읽어 문서 끝 새 쪽에 A4 좌석표를 그립니다. 실행하면 두 번 묻습니다 — ① 배치: [예] 5열×5행(25석) / [아니요] 4열×5행(20석), ② 출입문: [예] 오른쪽 열 앞줄이 1번 / [아니요] 왼쪽 열 앞줄이 1번. 위 가운데 칠판(색 채움 없는 굵은선 0.4mm 네모 — 잉크 절약), 교탁 자리에 반 이름, 책상 칸에 '번호 이름'(같은 크기, 한 줄로 입력). 반이 여러 개면 반마다 한 장, 반(학년반) 열이 없으면 좌석 수만큼 끊어 반 이름을 1, 2, 3 … 으로 매깁니다. 수능번호·학번처럼 4자 이상 긴 번호는 칸을 1줄 번호, 2줄 이름으로 나눕니다.

이럴 때

  • 20~25명 학급의 좌석표를 명렬표에서 바로 만들 때(반이 섞인 명렬표는 반마다 한 장)
  • 반 구분 없이 이름만 나열된 명단(고사장·연수 배치), 수능번호가 있는 시험 좌석표

순서

  1. 두 쪽에 걸친 50명 명렬표(번호 20260001…, 반 열 없음) 안 아무 칸을 클릭하고 Alt+Shift+L → 좌석표 실행
  2. 배치는 5열25명이므로 [예](Enter), 출입문은 왼쪽이므로 [아니요](N)
  3. 새 쪽에 좌석표 두 장(반 1, 2)이 생깁니다 — 긴 번호 칸은 번호/이름 두 줄

결과

  • 50명 → 25명씩 두 장. 1장: 20260001 김○준이 왼쪽 앞줄 … 2장: 20260026 배○우부터
  • 교탁 자리에 '1', '2', 위에 칠판(굵은선 빈 네모), '◀ 출입문' 표시. 번호가 짧으면(1~3자) '1 김○준'처럼 한 줄

주의

  • 명렬표 제목행에 '이름' 열이 없으면 실행되지 않습니다. 한 반이 좌석 수를 넘으면 열은 그대로 두고 행을 늘려 모두 넣습니다(23명 → 4열×6행)
  • 2026-09-24 좌석표4열20명·5열25명 두 매크로를 하나로 합쳤습니다(슬롯 30개 한도). 묻지 않는 고정형(4520·5525·5630 × 우·좌)은 매크로\_선택_좌석표고정형

실행 중 나오는 버튼별 영상 (2개)

[예] 5열×5행 · [아니요] 출입문 왼쪽 배치 [예]=5열×5행(25석), 출입문 [아니요]=왼쪽 열 앞줄이 1번
좌석표는 실행하면 두 번 묻습니다: ① 배치 ② 출입문 방향.
누르면: ① 배치 창 [예] → 5열×5행(25석) ② 출입문 창 [아니요] → 왼쪽 ③ 완료 안내 [확인]
결과: 50명 → 25석 좌석표 2장(반 1, 2).

[아니요] 4열×5행 · [예] 출입문 오른쪽 배치 [아니요]=4열×5행(20석), 출입문 [예]=오른쪽 열 앞줄이 1번
교실 책상이 4줄이면 [아니요], 출입문이 오른쪽이면 [예].
누르면: ① 배치 창 [아니요] → 4열×5행(20석) ② 출입문 창 [예] → 오른쪽 ③ 완료 안내 [확인]
결과: 50명 → 20석 좌석표 3장(반 1·2·3).

25 전체열표계산천원 (실행 창)

커서가 있는 행을 왼쪽 끝부터 오른쪽 끝까지 훑어 '산출기초 → 오른쪽 예산 칸' 짝을 전부 계산하고, 표의 마지막 행까지 내려가며 반복합니다.

이럴 때

  • 연도별(A·B) 산출기초 열이 두 벌 이상 있는 예산표
  • 표 전체를 한 번에 채우거나 검산할 때

순서

  1. 표에서 첫 데이터 행의 산출기초 칸을 클릭합니다
  2. Alt+Shift+L 로 [매크로 실행] 창을 열어 '전체열표계산천원' 을(를) 고르고 Enter
  3. 안내창에서 처리 개수를 확인하고 Enter

결과

  • 2027 예산(A) 600/600/400/180/100, 2026 예산(B) 480/450/500/120/50 이 5행 모두 한 번에 채워집니다
  • '×'가 없는 순수 숫자 칸은 산출기초로 보지 않아 잘못 덮어쓰지 않습니다
  • 계산·정리된 숫자는 모두 칸 오른쪽에 정렬됩니다(2026-09-22 개선)

주의

  • 산출기초 바로 오른쪽 칸이 결과 칸이어야 합니다
  • 값이 틀린 칸은 올바른 값으로 고친 뒤 빨간색으로 표시됩니다
26 중간합계증감포함표계산천원 (실행 창)

C-표계산-03(증감포함)과 같은 계산에 더해, 사업명 열의 들여쓰기(가. → 1))로 그룹을 알아보고 그룹 제목 행에 중간합계를, 마지막 행에 전체 합계를 넣습니다.

이럴 때

  • 사업별 내역표처럼 가./나. 아래에 세부 항목이 계층으로 있는 예산표
  • 중간합계 행이 여러 개라 손으로 맞추기 어려울 때

순서

  1. 첫 데이터 행(가. …)의 산출기초(A) 칸을 클릭합니다
  2. Alt+Shift+L → 중간합계증감포함표계산천원 실행 을 누릅니다
  3. 안내창에서 처리 행 수·중간합계 개수를 확인하고 Enter

결과

  • 세부 항목의 예산A·예산B·증감이 채워지고, 가. 행에 1,600 / 1,430 / 170, 나. 행에 880 / 650 / 230 중간합계가 들어갑니다
  • 합계 행에 전체 합계 2,480 / 2,080 / 400 이 들어갑니다
  • 계산·정리된 숫자는 모두 칸 오른쪽에 정렬됩니다(2026-09-22 개선)

주의

  • 커서는 반드시 2027년(A) 산출기초 열에 두세요 — 2026년(B) 열에서 시작하면 칸이 어긋납니다
  • 그룹 판정은 사업명 칸의 들여쓰기 깊이로 합니다
27 구성비열채우기 (실행 창)

커서가 있는 열의 값을 합계로 나눈 비율(%)을 바로 오른쪽 열에 소수 1자리로 채웁니다. 마지막 행이 '합계' 행이면 100.0 을 넣고, 합계 값이 있으면 그것을 분모로 씁니다.

이럴 때

  • 사업별 예산 비중, 학교별 인원 비중 표를 만들 때
  • 구성비 열을 손으로 계산해 넣던 표

순서

  1. 표 오른쪽에 빈 '구성비' 열을 만들어 둡니다
  2. 값 열의 칸을 클릭하고 Alt+Shift+L → '구성비열채우기' → [실행]
  3. 안내창에서 분모(합계)를 확인하고 Enter

결과

  • 300/500/200/600/400 (합계 2,000) → 15.0 / 25.0 / 10.0 / 30.0 / 20.0, 합계 행 100.0
  • 계산·정리된 숫자는 모두 칸 오른쪽에 정렬됩니다(2026-09-22 개선)

주의

  • 이미 값이 있는 칸은 검산해 틀리면 고치고 빨간색으로 표시합니다
  • 합계 행이 없으면 데이터 행의 합을 분모로 씁니다
28 가로세로평균 (실행 창)

실행하면 방향을 묻습니다. [예] 세로 — 커서가 있는 열에서 첫 행(제목)과 마지막 행(평균 행)을 뺀 숫자 칸의 평균을 마지막 행에 넣습니다. [아니요] 가로 — 표의 모든 데이터 행에서 첫 열(이름)과 마지막 열(평균)을 뺀 가운데 숫자 칸의 평균을 마지막 열에 넣습니다. 소수 1자리(딱 떨어지면 정수), 이미 값이 있으면 맞는지 확인해 다르면 고쳐 쓰고 빨간색으로 표시합니다.

이럴 때

  • 과목별 점수표에서 개인 평균(가로)과 과목 평균(세로)을 한 표에서 낼 때
  • 월별 실적표의 행 평균, 반 평균·학교 평균을 표 아래에 넣을 때

순서

  1. 마지막 열을 '평균' 열, 마지막 행을 '평균' 행으로 비워 둡니다
  2. 표 안을 클릭하고 Alt+Shift+L → 가로세로평균 실행 → 가로이므로 [아니요](N) → 5명의 평균이 마지막 열에
  3. 국어 열 칸을 클릭하고 Alt+Shift+L → 가로세로평균 실행 → 세로이므로 [예](Enter) → 국어 평균이 마지막 행에 (다른 열도 같은 방법)

결과

  • 가로: 90 / 81.7 / 70 / 90 / 90 이 평균 열에(정수면 소수점 없이), 세로: 국어 80·70·60·100·85 의 평균 79 가 평균 행에
  • 계산된 숫자는 칸 오른쪽에 정렬됩니다

주의

  • 가로는 첫 열=이름, 마지막 열=평균 칸으로 봅니다(열 3개 이상). 세로는 마지막 행을 결과 칸으로 쓰므로 표 아래에 빈 행이 있어야 합니다
  • 2026-09-24 가로평균·세로평균 두 매크로를 하나로 합쳤습니다(슬롯 30개 한도) — 방향만 예/아니요로 고르면 하는 일은 같습니다

실행 중 나오는 버튼별 영상 (2개)

[아니요] 가로 평균 [아니요] = 가로: 행마다 평균을 마지막 열에
실행하면 방향을 묻습니다. 표 어디에 커서가 있어도 됩니다.
누르면: ① Alt+Shift+L → 가로세로평균 ② 방향 창 [아니요] ③ 완료 안내 [확인]
결과: 평균 열에 90 / 81.7 / 70 / 90 / 90.

[예] 세로 평균 [예] = 세로: 커서가 있는 열의 평균을 마지막 행에
평균을 낼 열의 칸에 커서를 두고 실행합니다.
누르면: ① 국어 열 칸에 커서 ② 방향 창 [예] ③ 완료 안내 [확인]
결과: 평균 행 국어 칸에 79.

29 등수정리 (실행 창)

커서가 있는 열의 값으로 등수를 매겨 바로 오른쪽의 빈 열에 적습니다. 90·90·80이면 1·1·3처럼 동점은 같은 등수, 다음 등수는 건너뜁니다.

이럴 때

  • 대회·평가 결과표에 순위를 넣을 때
  • 정렬(14·15번) 뒤 등수 열을 완성할 때

순서

  1. 표에 빈 '등수' 열을 미리 만들어 둡니다
  2. 점수 열의 칸을 클릭하고 Alt+Shift+L → 등수정리 실행 을 누릅니다
  3. 안내창을 확인하고 Enter

결과

  • 90·90·80·70·60 → 등수 1·1·3·4·5 (동점은 공동 순위, 다음 순위는 건너뜀)
  • 계산·정리된 숫자는 모두 칸 오른쪽에 정렬됩니다(2026-09-22 개선)

주의

  • 오른쪽 열이 없거나 값이 이미 있으면 안내만 하고 바꾸지 않습니다(자료 보호)
30 전화번호서식통일 (실행 창)

커서가 있는 표 전체의 전화번호를 찾아 하이픈 형식으로 통일합니다(01012345678, 010.1234.5678, 010 1234 5678 → 010-1234-5678, 0511234567 → 051-123-4567, 15881234 → 1588-1234). 통일한 뒤 같은 번호가 두 칸 이상에 있으면 그 칸들을 빨간 글자로 표시해 중복 연락처를 바로 잡아냅니다. 표 밖에서는 커서 줄만 통일합니다.

이럴 때

  • 학생·학부모·교사 연락처 명단을 정리해 제출할 때
  • 여러 사람이 입력해 형식이 제각각인 비상연락망
  • 같은 번호가 두 번 들어간 명단을 걸러낼 때

순서

  1. 연락처 표 안의 아무 칸을 클릭합니다
  2. Alt+Shift+L 로 [매크로 실행] 창을 열고 '전화번호서식통일'을 골라 [실행]
  3. 안내창에서 변경 개수와 중복 번호를 확인하고 Enter

결과

  • 01012345678 / 010.9876.5432 / 010 1234 5678 → 모두 010-1234-5678 형식
  • 같은 번호(010-1234-5678)가 든 3칸이 빨간 글자로 표시됩니다
  • 주민등록번호(990101-1234567)는 전화번호로 보지 않아 그대로 둡니다

주의

  • 휴대전화·지역번호(02, 051 …)·070·1588 대표번호를 알아봅니다
  • 빨간색은 표시일 뿐 값은 바꾸지 않습니다 — 중복 여부를 확인한 뒤 직접 정리하세요

9.자주 묻는 질문

단축키가 안 먹어요. 한글 창이 앞에 있는지, Alt+Shift+L 목록에 그 매크로가 있는지, 다른 프로그램(PowerToys 등)이 같은 단축키를 쓰지 않는지 확인하세요.

리본 탭이 안 생겨요. 그 한글에서 [도구 → 사용자 설정]을 열어 아무것이나 하나 바꿔 저장한 뒤(리본 설정 파일 생성) [②]를 다시 누르세요.

원래대로 되돌리려면? 등록기가 안내한 backup 폴더의 파일을 원래 이름으로 복사하면 됩니다(한글은 닫은 상태에서).

다른 사람 PC에 배포하려면? 한글매크로등록기.exe 와 추천순서 msr 폴더(또는 통합매크로.hmi)만 전달하면 3분이면 끝납니다.

백신이 등록기를 막거나 지워요. 서명 없는 새 실행 파일이라 생기는 오탐입니다. 백신의 검역소(격리)에서 복원하고 예외(신뢰) 목록에 넣거나, 등록기 없이 통합매크로.hmi 를 한글 불러오기로 넣으세요.

"한글이 실행 중" 이라고 나와요. 작업 표시줄에 한글 창이 없어도 보이지 않는 Hwp.exe 가 남을 수 있습니다. 작업 관리자에서 끝낸 뒤 다시 누르세요.

설치는 됐는데 매크로가 실행되지 않아요. 한글 [도구 → 환경 설정 → 기타] 의 매크로 보안이 '실행 안 함' 이면 '보통' 이상으로. 기관 PC의 스크립트 차단 정책이면 관리자에게 문의하세요.

한글이 두 버전(2022·2024) 설치돼 있어요. [②] 가 두 버전 저장소 파일을 모두 만들어 둡니다. 리본 탭은 각 버전에서 [도구 → 사용자 설정] 을 한 번 저장한 뒤 [②] 를 누르면 두 쪽 다 생깁니다.

OneDrive·회사 프로필 폴더라 저장이 안 돼요. %AppData% 가 동기화 폴더면 파일이 잠기는 경우가 있습니다. 동기화를 잠시 멈추거나 등록기를 관리자 권한으로 실행해 보세요.

순서(단축키)를 바꾸고 싶어요. 등록기에서 줄을 끌거나 ▲▼ 로 바꾸고 [②] 를 다시 누르면 됩니다. 파일 이름 앞 번호는 처음 등록 순서일 뿐이며 바꿔도 됩니다.

매크로가 끝나지 않아요(계속 돌아요). 페이지가 많은 문서는 오래 걸릴 수 있으니 1~2분 기다려 보고, 그래도 안 끝나면 작업 관리자로 한글을 끝냅니다. 바로 열기: Ctrl + Shift + Esc 를 함께 누르면 작업 관리자가 곧바로 열립니다. 한글 창 제목에 '(응답 없음)'이 보이면 창 오른쪽 위 X → [프로그램 닫기] 로도 끝낼 수 있습니다. 끝내면 저장하지 않은 내용은 사라집니다 — 매크로를 돌리기 전에 Ctrl + S 로 저장해 두세요.

작업 표시줄 오른쪽 클릭 → 작업 관리자

① 방법 1 · 작업 표시줄 빈 곳 마우스 오른쪽 → [작업 관리자] (실제 화면)

Ctrl+Alt+Del → 작업 관리자

① 방법 2 · Ctrl + Alt + Del → [작업 관리자] (예시 그림)

작업 관리자에서 한글 작업 끝내기

② 작업 관리자에서 '한글'을 골라 끝냅니다 — 다른 프로그램은 건드리지 마세요

  • ① 위쪽 검색창에 '한글' 입력 (목록에서 '한글'을 직접 찾아도 됩니다)
  • ② '한글' 줄을 한 번 클릭하고 키보드 Del 키 — 또는 마우스 오른쪽 → [작업 끝내기]
  • ③ 위쪽 [작업 끝내기] 단추를 눌러도 같습니다
  • 끝낸 뒤 한글을 다시 열고, '복구' 안내가 나오면 내용을 확인해 저장하세요

리본 버튼을 손으로 만들고 싶어요. 수동으로 할 때: 도구 → 사용자 설정 → [새 탭] → 명령 검색 '매크로' → 「스크립트 매크로 N」 추가 → [이름 바꾸기]. 슬롯 22~29 는 리본 명령이 없어 못 올립니다 — 등록기로 위쪽 슬롯에 두세요.

사용자 설정 창에서 스크립트 매크로 1 추가

한글 매크로 실무 활용 — 실행 검증 기준: 이 PC 한글 2024(13.0)

등록기 없이 넣고 싶어요. ② 의 폴더에서 원래 파일을 다른 이름으로 백업하고, 추천매크로순서\통합매크로.hmi 를 복사해 원래 파일 이름(예: HWPWMko-KR120.HMI)으로 바꿔 넣습니다. 이름의 숫자는 꼭 내 버전으로. 또는 한글에서 Alt+Shift+L → 폴더 아이콘(불러오기) → 파일 형식 hmi 로 통합매크로.hmi 를 불러옵니다.