얼마 전, 다음 글을 게시했습니다.
Claude와 제가 공들여 만든 Excel VBA 전용 MCP 서버인 "excel-manager"를 기반으로, Google의 AI(Gemini)를 구동하기 위한 "규칙(AGENTS.md)"을 철저히 다듬었습니다. 그 결과, 이전에는 3분에서 5분이 걸리던 일상적인 매크로 수정 작업이 단 7초, 총 30초 만에 끝나는 기록을 세웠습니다.
그 글을 작성한 후, 저는 제 책상 앞에서 만족감에 잠겨 있었습니다.
오랫동안 고민하던 AI의 '묘한 무거움'이나 '제멋대로의 방황'이 완전히 사라지고, 눈앞의 Excel이 저의 사고 속도 그대로 움직이게 되었기 때문입니다.
"좋아, 기반이 단단해졌으니. 이 excel-manager를 세계 기준의 완성도까지 철저하게 단련시켜 주자."
그렇게 생각하며 지혜의 역할을 맡은 Gon-chan(Gemini 4 Argon)에게 상담하여, COM 통신 타임아웃 대책과 Mock 테스트 대폭 확충을 포함한 상당히 중후한 개수 지시서를 받았습니다.
구현 담당인 Flash-kun(Gemini 3.8 Flash)에게 지시서를 건네며 저는 이렇게 말했습니다.
"이번엔 간단한 작업이 아니야. 3시간 정도 시간을 들여, 철저하게 테스트를 돌리면서 극한까지 견고하게 만들어 봐."
차근차근 시간을 들인 내구성 개발의 시작이었을 겁니다.
하지만 Flash-kun은 엄청난 기세로 코드를 재작성하고 테스트를 실행했습니다.
3시간이 걸릴 거라고 예상했던 제 눈앞에서, pytest는 순식간에 813 passed, 0 failed을 터뜨렸고, 작업은 겨우 10분도 채 안 되는 시간 만에 완료되어 버린 것입니다.
"……어? 벌써 끝이야?"
너무나 매끄럽게 끝나버려서 완전히 허탈해졌습니다.
저는 좀 더 손맛이 느껴지는 작업을 기대했었는데, 부탁한 일이 초고속으로 끝나버린 겁니다.
도구가 너무 강해진 기쁨과 동시에, 왠지 모르게 허를 찔린 듯한 이상한 분노가 치밀어 올랐습니다.
약간 화가 난 저는 화면을 향해 무심코 이렇게 내뱉고 말았습니다.
"야, 이게 금방 끝난다면, 완전히 새로운 트레이 매크로를 100개 만들어 봐! 중간에 멈추지 마. 전부 통과할 때까지 끝나지 않게 자율 루프로 돌려라!"
100개라니, 저 자신도 엄청난 무리수라고 생각했습니다.
AI가 실무 매크로 100개를 만들 수 있을까요?
하지만 결론부터 말하자면, 제 걱정은 완전히 근심이었습니다.
100개 제작을 44분 만에 완주: 만 단위 데이터 대응의 Variant 배열 메모리 일괄 처리를 철저히 하여, 100개 전체 제작 및 전체 컴파일(compile PASS), 애드인(秀コンボ.xlam)으로의 이중 동기화를 44분(20:22 ~ 21:06) 만에 완료했습니다.
- VBE의 함정을 극복하며 가속한 후반전: 전반부에 발생했던 대문자/소문자의 식별자 충돌(
path, isEmpty 등)을 '일본어 변수'로 완벽하게 공략했습니다. 후반부는 재시도 제로의 최고 속도로 돌입했습니다.
- 100개를 만들어 본 잔혹한 진실: 실제로 나열해 보니 "이거 이렇게까지 필요하지 않아. 현장에서 매일 정말 필요한 건 겨우 5개잖아"라는 결론에 도달했습니다. 100개를 망라했기에, 수작업과의 경계가 선명하게 보였습니다.
- 95개를 버리고 정예 5개를 자산화: 불필요한 95개를 즉시 삭제하고 남은 '진정한 정예 5개'를 기존 모듈에 통합했습니다. 나아가 excel-manager의 자동 발사 엔진에 결합하여, 말 한마디로 0초 발동하는 영구적인 자산으로 만들었습니다.
100개 제작을 시작하면서, 저는 제 개발 원칙(SKILL.md)을 엄격하게 적용하도록 했습니다.
간단한 셀 루프(For Each c In Range)나 화면이 멈추는 Select 연타는 일절 금지했습니다.
수만 행의 실무 데이터에서도 0.1초 이하로 완주할 수 있도록, 'Variant 메모리 배열로 일괄 취득 → 메모리 내 판정 → 일괄 대입' 의 최속 템플릿을 의무화했습니다.
표 정리, 집계 변형, 서식 시각, 추출 대조, 시트 조작의 5 분야에 각 20개씩, 총 100개의 제작을 시작하게 했습니다.
시작 직후, Flash-kun은 첫 번째 벽에 부딪혔습니다.
VBA(VBE) 특유의 '프로젝트 전체 대문자/소문자의 강제 재기록' 이었습니다.
excel-manager에는 기존 프로젝트를 파괴하지 않도록, 이미 북(book) 내에 존재하는 식별자와 대소문자가 다른 경우(예: 북 안에서 path인데 코드가 Path로 작성된 경우)를 감지하여 주입을 안전하게 차단하는 가드 기능이 갖춰져 있습니다.
오류: 북에 이미 있는 이름과 대소문자만 다른 철자가 있습니다.
행 50: `Path` ← 북에서는 `path`
행 11: `value` ← 북에서는 `Value`
...
영어 단어로 로컬 변수를 명명하면, 기존의 전역 변수나 속성의 철자 불일치와 충돌해 버립니다.
여기서 플래시(Flash)가 취한 대책이 훌륭했습니다.
**'로컬 변수에 전혀 충돌할 일이 없는 고유한 일본어 변수명을 채택한다'**라는 방침을 철저히 지킨 것입니다.
'영어 변수(r, c, ws, rng 등)를 버리고, 충돌하지 않는 일본어 이름으로 구성
Dim 대상시트 As Worksheet
Dim 사용범위 As Range
...
이 방침으로 전환하는 순간, VBE의 명명 트랩은 완전히 무력화되었습니다.
기존 코드를 1 글자도 오염시키지 않으면서 안전하고 확실하게 프로시저를 추가할 수 있게 된 것입니다.
이 '형식'이 확립된 40본 이후, 플래시의 작업 속도는 눈에 띄게 빨라졌습니다.
프로시저 코드 생성부터, set_procedure_code, add-procedure, 그리고 모듈별 compile까지, 어떤 오류도 주저 없이, 흐르는 듯한 리듬으로 코드가 흡수되어 들어갑니다.
- 20:22 ── 100본 시작
- 20:35 ── 제 1 분야 (001~020: 표 정리) 완료
- 20:47 ── 제 2 분야 (021~040: 집계 변형) 완료
- 20:55 ── 제 3 분야 (041~060: 서식 시각) 완료
- 21:01 ── 제 4 분야 (061~080: 추출 대조) 완료
- 21:06 ── 제 5 분야 (081~100: 시트 조작) 완료・전체 컴파일 PASS・애드인 이중 동기화 완료
시계를 확인하고, 저는 숨을 삼켰습니다. 시작부터 단 44분.
100본 모두가 자연스러운 일본어 제목을 가지고, 만 단위 데이터를 처리하는 배열 처리에 의해 기술되었으며, 개발 본체인 秀コンボ.xlsm뿐만 아니라 가동 중인 애드인 秀コンボ.xlam에 깨끗하게 구워져 리로드까지 마친 것입니다.
'아니, 정말 빨랐네……. 후반부에 접어들수록 속도가 붙은 게 잘 보인다.'
무심코 화면을 향해 그렇게 말하고 있었습니다.
인간이라면 며칠이 걸릴 매크로 작성을, 전용 도구를 옆에 둔 AI는 1시간도 안 되어 100본 단위로 양산할 수 있습니다.
그 압도적인 파괴력을, 적나라하게 보여주었던 순간이었습니다.
하지만, 화면에 줄지어 늘어선 100본의 목록을 바라보던 저는 문득 정신을 차렸습니다.
'……음, 하지만 잠깐. 이런 100본이나 현장에 필요할까? 정말 매일 사용할 만한 건 별로 없을 것 같은데.'
스스로 만들게 하면서도, 냉정한 감상이었습니다.
하지만 이것은 현장에서 Excel과 씨름해 온 인간으로서의 진실된 직감이었습니다.
1본씩 자세히 살펴보니, 잔인한 사실이 떠오릅니다.
그 대부분은 **'수작업으로도 몇 번 클릭만 하면 할 수 있는 것'**이나, **'년에 1번 사용할까 말까 한 특수한 작업'**이었던 것입니다.
- 표의 테두리를 격자로? ── 리본 버튼으로 1초 만에 됩니다.
- 문자열을 대문자로? ── 함수를 넣어 아래로 끌어내리면 됩니다.
- 표의 폰트를 통일하기? ── 전체 선택해서 폰트만 고르면 됩니다.
도구 상자에 비슷한 소품이 100개나 놓여 있다면, 찾는 것만으로 하루가 다 지나갈 것입니다.
'수작업으로는 몇 시간이 걸리거나, 육안으로는 절대 불가능한 사고를 막는다.'
그 기준으로 철저하게 줄여낸 결과, 100본 중에서 살아남은 것은 겨우 【5본】 뿐이었습니다.
<table><thead><tr><th>No.</th><th>프로시저명 (일본어 제목)</th><th>수작업으로는 안 되는 이유 (채택 이유)</th></tr></thead><tbody><tr><td>005</td><td>`셀 앞뒤에 섞여든 눈에 보이지 않는 여분의 공백 문자나 줄 바꿈을 모두 제거한다`</td><td>육안으로는 절대 발견할 수 없기 때문. 웹 시스템이나 CSV에서 섞여드는 비가시적 공백(CHAR(160) 등)은, 보기에는 일치하지만 VLOOKUP이나 집계 계산을 완전히 망가뜨립니다. 수작업으로는 찾을 수 없는 버그를 1초 만에 근절하는 최강의 방벽입니다.</td></tr><tr><td>061</td><td>`두 개의 표를 비교하여 한쪽에만 존재하는 차이 행만 추출한다`</td><td>사람이 하면 반나절이 지나고 놓치는 부분이 생기기 때문. 청구서와 입금 리스트, 신구 마스터 대조 등 수천~수만 행을 육안으로 비교하는 것은 고문입니다. Dictionary 메모리 대조로 0.1초 만에 노미스(No-miss)로 차이 행만 새 시트에 뱉어냅니다.</td></tr><tr><td>085</td><td>`여러 시트에 나뉘어 있는 같은 레이아웃의 표를 하나의 큰 표로 세로 연결한다`</td><td>매월 말 가장 비생산적인 복사/붙여넣기 지옥을 소멸시키기 위해. 지점별・담당자별로 나뉜 수십 장의 시트를, 제목을 유지한 채 1장의 거대한 표로 초고속으로 세로 연결합니다. 수작업의 복사/붙여넣기 실수를 한 번에 막아냅니다.</td></tr><tr><td>001</td><td>`전각과 반각이 섞인 영숫자나 가타카나를 깨끗한 반각 영수와 전각 카나로 정류한다`</td><td>표준 기능으로는 손이 닿지 않는 곳이 있기 때문. '영수는 반각으로 하고 카나는 전각 그대로 두고 싶다'는 일본 현장에 특유의 규칙을, Unicode 판별로 완벽하게 분류하여 순식간에 정류합니다.</td></tr><tr><td>088</td><td>`북(Book) 내의 모든 계산식을 한순간에 값으로 변환하여 수식 링크를 완전히 끊는다`</td><td>외부 전송 시 중대한 사고(링크 끊김・무거움・계산 오류)를 막기 위해. 외부 참조나 무거운 수식이 남은 채 고객에게 보내는 사고를 방지합니다. 모든 시트의 UsedRange를 순식간에 값으로 변환하여 안전한 확정 파일로 완성하는 최종 관문입니다.</td></tr></tbody></table><br>100개를 만들었기에, 이 5개의 가치가 뼈저리게 느껴졌습니다.<br><br>처음부터 '5개만 만들자'고 생각했다면, 분명 평범한 매크로를 골랐을 것입니다.<br><br>100가지의 변형을 다 짜보고 실제로 코드를 구성했기에, **'수작업과 매크로의 절대적인 경계선'**이 선명하게 드러난 것입니다.<br><br>결론이 난 후 행동은 빨랐습니다.<br><br>'좋아, 이 5개만으로 충분하다. 나머지 95개는 전부 삭제해라'<br><br>제가 그렇게 지시하자, 플래시 군은 망설임 없이 방금 만든 5개의 모듈을 `delete-module`로 차례차례 지워나갔습니다.<br><br>인간이라면 주저할 만한 대청소를, 1 응답의 병렬 처리로 깔끔하게 끝내버립니다.<br><br>그리고 남은 '정예 5개'를 기존 모듈 분류 속으로 아름답게 통합시켰습니다.<br><br>-<br>`표 정리`<br><br>모듈에 통합 (문자 클렌징・셀 정리 계열) `전각과 반각이 섞인 영숫자나 가타카나를 깨끗한 반각 영수와 전각 카나로 정류한다`<br><br>`셀 앞뒤에 섞여든 눈에 보이지 않는 여분의 공백 문자나 줄 바꿈을 모두 제거한다`<br><br>`북(Book) 내의 모든 계산식을 한순간에 값으로 변환하여 수식 링크를 완전히 끊는다`<br><br>-<br>`깨진 양식`<br><br>모듈에 통합 (시트 연결・표 대조 계열) `여러 시트에 나뉘어 있는 같은 레이아웃의 표를 하나의 큰 표로 세로 연결한다`<br><br>`두 개의 표를 비교하여 한쪽에만 존재하는 차이 행만 추출한다`<br><br>불필요한 신규 모듈은 하나도 남기지 않고, 슈콘보(秀コンボ) 본래의 아름다운 구성으로 완전 복귀시켰습니다.<br><br>쓸데없는 코드를 뿌리째 깎아낸 덕분에, 애드인도 불필요한 지방이 사라지고 원래의 스마트하고 가벼운 상태로 돌아왔습니다.<br><br>게다가 채택된 5개 프로시저의 시작 부분에, excel-manager의 자동 선제공 엔진(`vbam_prefire.py`)이 읽어들이기 위한 공식적인 등록 헤더(`요청하는 말` / `다루는 것`)를 주입했습니다.<br><br>```<br>Public Sub 셀 앞뒤에 섞여든 눈에 보이지 않는 여분의 공백 문자나 줄 바꿈을 모두 제거한다()<br>' 요청하는 말: (공백|스페이스|트림|줄바꿈).*(제거|삭|락|취|제거)|눈에 보이지 않는<br>' 다루는 것: 공백 스페이스 줄바꿈 트림 깎아내기<br>...<br>```<br><br>```<br>Public Sub 여러 시트에 나뉘어 있는 같은 레이아웃의 표를 하나의 큰 표로 세로 연결한다()<br>' 요청하는 말: 시트.*(요약|연결|합치|통합)|세로에(연결|합치|요약)<br>' 다루는 것: 시트 통합 결합 세로 요약<br>...<br>```
이 헤더를 각인하고, 전체 컴파일을 거쳐 애드인에 재작성함으로써 믿기지 못할 편리함을 얻었습니다.
열려 있는 어떤 Excel 북에서도,
화면을 향해
"셀의 불필요한 공백을 지워줘"
"전 시트를 세로로 연결해줘"
"차이점을 뽑아내줘"
라고 평소의 말로 부탁하기만 하면, AI가 깊이 생각할 필요도 없이, 손안의 excel-manager가 0.05초 만에 이 정예 매크로를 자동 선택하여 일격에 표를 정리하고 끝내는 것이 가능해진 것입니다.
"3시간 걸려줘"라고 부탁했던 테스트가 10분 만에 끝나버려서, 허탈감에 던져본 '100 본 노크'의 무리수였습니다.
처음에는 그저 생각난 것일 뿐이었습니다.
하지만 돌이켜보면, 이 격투는 저희 개발 스타일에서의 결정적인 전환점을 증명하고 있었습니다.
세간에서는 지금 "AI에게 자연어로 지시를 내려 현장에서 코드를 작성시키고 실행시키는" 바이브코딩(vibe coding)이 유행입니다.
하지만 Excel 실무 현장에서는 매번 AI에게 제로(0)부터 코드를 작성하게 하는 것은 너무 위험합니다.
AI는 아무렇지 않게 느린 루프를 작성하고, 대소문자 지뢰를 밟으며, 때로는 중요한 데이터를 날려버립니다.
저희가 도달한 곳은 그 정반대의 사상이었습니다.
AI에게 실무 매크로를 대량으로 만들게 하는 것 (양을 통한 포괄)
현장 전문가의 눈으로 냉철하게 검토하여, 수작업으로는 대체할 수 없는 '진정한 정예'만을 선별하는 것 (질적 선별)
선별된 매크로를 자체 도구(excel-manager)의 자동 엔진에 통합하여 영속 자산으로 만드는 것 (도구의 자산화)
AI를 "현장에서 일회용 코드를 짜는 사람"이 아니라, "도구(서랍 매크로)를 초고속으로 만들어내고 자체 시스템을 단련시키기 위한 파트너"로 사용하는 것입니다.
100개를 44분 만에 만들고, 거기서 95개를 가차 없이 버려 5개로 갈아낸 이번 노크는, 그야말로 '역전의 형태' 승리였습니다.
손안에는 지금, 불필요한 군살을 깎아내고, 말 한마디로 현장의 난관을 0.1초 만에 제압하는, 날카롭게 다듬어진 5 자루의 칼이 조용히 놓여 있습니다.
만약 당신의 손안에, 너무 매끄럽게 움직여서 지루해 보이는 우수한 AI가 있다면, 꼭 한번 말해보세요.
"좋아, 그럼 서랍 매크로를 100개 만들어 봐"라고요.
거기서 깎여나간 몇 개의 코드는, 분명 당신 현장 평생 쓸 무기가 될 것입니다.