잘 쓰던 엑셀 주식 함수가 멈췄다: ChatGPT와 Claude로 XLAM 추가기능을 다시 만든 기록

나는 투자 중인 ETF와 주식의 가격을 엑셀에 기록한다. 매번 가격을 직접 입력하기 번거로워 오빠두엑셀 사이트에서 받은 추가기능을 설치하고 NaverFinanceHistory 함수를 사용해 왔다.

내가 사용하던 수식은 다음과 같은 구조였다.

=IF($Y$14="Y",INDEX(NaverFinanceHistory(U5,DATE($Y$15,$Y$16,$Y$17),DATE($Y$15,$Y$16,$Y$17),"종가",TRUE,FALSE),,2))

종목코드와 날짜를 지정하면 해당 날짜의 종가를 가져오는 방식이다. 필요한 셀에 수식을 복사해 두면 보유 종목의 가격을 편리하게 관리할 수 있었다.

그런데 며칠 전부터 종가가 표시되던 셀에 #VALUE! 오류가 나타나기 시작했다. 엑셀 파일이나 수식을 바꾼 것도 없었다.

내가 쓰는 기능만 다시 만들기로 했다

원인을 직접 찾기 어려워 사용하던 XLAM 파일을 ChatGPT에 올리고 분석을 부탁했다. ChatGPT는 엑셀 수식보다 추가기능이 데이터를 가져오는 네이버 증권의 기존 주소가 문제일 가능성이 크다고 봤다. 네이버 증권 사이트가 개편되면서 기존 주소나 응답 구조가 달라졌다는 추정이었다.

추가기능은 기존 데이터 형식을 기준으로 값을 읽는다. 네이버 쪽의 응답이 바뀌면 필요한 값을 찾지 못하고 엑셀에는 #VALUE! 같은 오류가 나타날 수 있다. 오빠두엑셀에서 받은 자료 자체의 문제보다 외부 웹서비스에 의존하는 프로그램이 언젠가는 겪을 수 있는 문제에 가까웠다.

기존 XLAM 전체를 똑같이 복원할 필요는 없었다. 내가 실제로 쓰는 기능은 종목코드와 날짜를 넘기면 특정 날짜의 종가를 돌려받는 것이었다. 목표를 다음처럼 좁혔다.

  • 국내 주식과 ETF의 6자리 종목코드를 사용할 것
  • 지정한 날짜의 종가를 가져올 것
  • 필요하면 날짜와 종가를 배열로 반환할 것
  • 기존 엑셀 시트를 크게 수정하지 않을 것
  • Excel 2013에서 작동할 것
  • 여러 PC에서 같은 경로로 설치할 수 있을 것

여러 PC에서 동일한 엑셀 파일을 사용해야 했기 때문에 추가기능의 공통 설치 경로도 정했다.

C:\Users\Public\Documents\ExcelAddIns

ChatGPT는 새로운 XLAM 파일과 폴더 생성 방법, 엑셀에서 추가기능을 등록하는 절차, 새 함수를 호출하는 방법까지 설명했다. 처음에는 설치하고 함수 이름만 바꾸면 해결될 것으로 생각했다.

#NAME?, #VALUE!, #N/A가 차례로 나타났다

실제 적용은 예상과 달랐다. 새로운 추가기능을 설치하고 함수를 실행해도 원하는 종가는 나오지 않았다. 처음과 같은 #VALUE!이 나타났고, 수정된 파일을 적용하면 #NAME?이나 #N/A가 표시됐다.

#NAME?은 엑셀이 함수를 인식하지 못한다는 의미였다. 추가기능이 제대로 로드되지 않았거나 VBA 함수가 워크시트에서 호출할 수 있는 형태로 만들어지지 않았을 가능성이 있었다.

함수가 인식된 뒤에는 #VALUE!이 나타났다. 디버그 함수를 추가해 확인하던 중 Excel 2013에서는 DATE()의 결과가 VBA에 날짜가 아닌 숫자형 날짜 일련번호로 전달될 수 있다는 사실을 알게 됐다. VBA에서 IsDate()만 검사하면 정상적인 날짜까지 잘못된 입력으로 처리할 수 있었다.

날짜 문제를 고친 뒤에는 #N/A가 나왔다. 네이버에서 데이터를 가져오지 못했거나 가져온 데이터에서 지정한 날짜를 찾지 못할 때 발생할 수 있는 오류였다. 디버그 매크로에서는 런타임 오류 1004도 발생했다. 자동으로 추가기능을 만들려고 작성한 VBS 파일은 AhnLab V3의 앱 격리 검사 대상이 되기도 했다.

특정 종목을 조회하면 네이버에서 다음과 비슷한 JSON이 반환되는 것까지는 확인했다.

[
  {
    "localTradedAt": "2026-09-17",
    "closePrice": "256,000"
  }
]

Excel 2013 워크시트에서 WEBSERVICE()를 직접 사용했을 때 JSON이 정상적으로 들어왔다. 별도의 VBA 함수로 날짜와 종가를 파싱했을 때도 삼성전자의 2026년 9월 17일 종가인 256000이 반환됐다. 네이버에서 데이터를 가져와 필요한 종가를 찾는 핵심 로직은 작동했다.

문제는 이를 짧은 함수 형태로 묶어 XLAM 추가기능으로 만드는 과정이었다. 추가기능으로 만들면 다시 로드 오류나 #N/A가 발생했다. VBA 내부에서 시도한 여러 네트워크 호출 방식도 내 Excel 2013 환경에서는 정상적으로 작동하지 않았다.

수정된 파일을 받고 설치한 뒤 결과를 확인하고 오류를 다시 전달하는 작업을 열 번 넘게 반복했다. #NAME?을 해결하면 #VALUE!이 나타났고, 그것을 고치면 #N/A가 나왔다. 어떤 파일은 추가기능을 로드하는 단계부터 오류가 발생했다.

ChatGPT는 지치지 않았겠지만 나는 지쳤다. 파일을 내려받고 기존 추가기능을 교체한 다음 엑셀을 다시 열어 수식을 테스트하는 일은 결국 사람이 해야 했다.

ChatGPT의 실패 기록을 Claude에게 넘겼다

같은 과정을 반복하는 대신 Claude에게 작업을 맡겨보기로 했다. 처음부터 모든 상황을 다시 설명하고 싶지는 않았다. 지금까지의 실패도 중요한 정보였기 때문이다.

  • 원하는 함수의 입력과 출력 구조
  • Excel 2013에서 발생한 오류
  • 날짜 일련번호 처리 문제
  • 정상적으로 확인한 네이버 JSON 구조
  • 실패한 VBA 네트워크 호출 방식
  • 테스트에서 256000이 정상적으로 반환된 조건
  • 바이너리로 수정한 XLAM과 VBS 방식에서 발생한 문제

이 정보가 빠지면 Claude도 같은 시행착오를 반복할 수 있었다. ChatGPT에게 성공 조건과 실패 사례, 원하는 결과를 정리해 Claude에게 전달할 작업지시서를 만들어 달라고 요청했다.

정리된 지시서를 받은 Claude(Opus 5)는 완성된 XLAM 파일부터 만들지 않았다. 내 Excel 2013 환경에서 핵심 기능이 작동하는지 확인할 VBA 모듈 하나를 먼저 작성했다. 안내에 따라 모듈을 넣고 테스트 결과를 알려주자, 그 결과를 토대로 최종 VBA 모듈과 설치 방법을 정리했다.

이번에는 별도의 오류 없이 내가 원했던 종가가 표시됐다. 열 번 넘게 파일 전체를 바꿔가며 테스트했던 앞선 과정과 달리, Claude와는 검증용 모듈을 한 번 테스트하고 결과를 전달한 뒤 최종 결과를 얻었다.

이번 작업만 놓고 보면 Claude Opus 5가 더 잘했다는 느낌을 받았다. ChatGPT에서 사용한 GPT-5.6 Sol은 여러 차례 파일을 수정했지만 최종 추가기능을 완성하지 못했다. Claude는 전달받은 작업지시서를 토대로 검증용 모듈을 제시했고, 사실상 한 번의 확인 과정으로 원하는 결과를 만들었다.

다만 공정한 성능 비교는 아니다. Claude에게 전달한 지시문에는 ChatGPT와 열 번 넘게 시행착오를 겪으며 확인한 실패 원인과 정상 작동 조건이 모두 포함돼 있었다. ChatGPT와의 과정이 없었다면 Claude도 비슷한 문제를 겪었을 수 있다.

이번 사례에서 받은 개인적인 인상은 분명하다. Claude Opus 5가 Excel 2013과 VBA의 제약을 고려해 문제를 단계적으로 확인하고 실제로 작동하는 결과를 만드는 과정에서는 좀 더 안정적이고 능숙해 보였다. 모델 전체의 우열에 대한 결론이 아니라 이번 한 가지 작업에서 받은 느낌이다.

완성품보다 작은 검증이 먼저였다

이번 경험에서 가장 크게 확인한 것은 코드가 있다는 것과 내 PC에서 실제로 작동한다는 것은 다른 문제라는 점이다. 특히 Excel 2013처럼 오래된 환경에서는 최신 환경과 다른 제약이 나타난다.

오류도 정확히 전달해야 했다. “안 된다”는 설명만으로는 부족했다. #NAME?, #VALUE!, #N/A, 런타임 오류 1004는 각각 의미가 다르다. 실제 사용한 수식과 오류 메시지를 그대로 전달해야 원인을 좁힐 수 있었다.

처음부터 완성품을 만들기보다 핵심 기능부터 검증하는 접근도 효과적이었다. 네트워크 조회, JSON 파싱, 날짜 처리처럼 불확실한 부분을 작은 VBA 모듈로 먼저 확인한 뒤 추가기능으로 만드는 편이 빨랐다.

AI 사이에도 인계 문서가 필요했다. 이전에 시도한 방법과 실패한 이유를 정리하지 않으면 새로운 AI도 같은 작업을 반복한다. AI는 지치지 않지만 사람은 지친다. 반복이 길어질 때는 진행 상황을 정리하고 접근 방법이나 모델을 바꾸는 편이 낫다.

XLAM 파일 대신 작업지시서를 공개한다

최종적으로 종가를 조회하는 추가기능은 완성했지만 XLAM 파일 자체를 블로그에 공개하지 않기로 했다.

이번에 사용한 주소는 네이버가 개발자용으로 공식 제공하고 장기적인 작동을 보장하는 주식 API가 아니다. 현재 접근 가능한 JSON 응답을 개인 엑셀에서 저빈도로 조회하는 방식이므로 네이버 서비스가 다시 변경되면 언제든 작동하지 않을 수 있다.

특정 날짜의 종가 몇 건을 개인적으로 조회하는 것과 여러 종목의 장기간 데이터를 반복적으로 수집해 재배포하는 것도 성격이 다르다. 완성된 실행 파일보다 문제를 해결한 과정과 Claude에게 전달한 실제 작업지시서를 참고 자료로 공유한다. 비슷한 문제가 있다면 자신의 환경과 데이터 이용 조건을 확인한 뒤 필요한 부분만 참고하는 편이 좋다.

이번 작업은 HTML 웹페이지 전체를 긁는 일반적인 크롤링보다 엑셀의 WEBSERVICE()와 VBA를 이용해 JSON 응답에서 필요한 값을 읽는 방식에 가깝다. 공식 API가 아닌 주소는 언제든 변경되거나 사용이 제한될 수 있다는 점은 같다.

처음에는 고장 난 XLAM 파일 하나만 고치면 된다고 생각했다. 외부 사이트의 변경, Excel 2013의 제약, VBA 네트워크 호출, 날짜 형식과 추가기능 설치 문제가 차례로 나타났다.

열 번이 넘는 실패에서 확인한 정보가 다음 작업의 정확도를 높였다. ChatGPT는 문제를 분석하고 실패 조건을 확인한 뒤 다른 AI가 이해할 수 있는 작업지시서로 정리했다. Claude는 그 지시서를 받아 검증용 모듈부터 확인하고 실제로 작동하는 결과를 만들었다.

이번 경험에서 AI를 잘 활용한다는 것은 하나의 모델만 고집하는 일이 아니었다. 실패 과정까지 다음 작업의 재료로 만들고, 필요할 때 다른 모델에 제대로 인계하는 일이었다.

부록: 실제 Claude에게 전달한 작업지시서

아래는 ChatGPT와의 시행착오를 정리한 뒤 Claude에게 실제로 전달한 내용이다.

Excel 2013용 네이버 종가 조회 추가기능 제작 요청

환경

Windows용 Excel 2013

여러 PC에서 동일한 엑셀 파일 사용

추가기능 설치 경로:

C:\Users\Public\Documents\ExcelAddIns\NaverStockClose2013.xlam

목적

기존 함수와 비슷한 형태로 네이버 주식 종가를 조회하는 VBA 추가기능을 만들어 주세요.

원하는 함수 형식:

=NaverStockClose(종목코드,시작일,종료일,”종가”,배열반환,헤더포함)

실제 사용 수식:

=IF($Y$14=”Y”,INDEX(NaverStockClose(U5,DATE($Y$15,$Y$16,$Y$17),DATE($Y$15,$Y$16,$Y$17),”종가”,TRUE,FALSE),1,2))

필요한 기능은 현재 다음으로 한정합니다.

국내주식 종목코드

종가 조회

시작일과 종료일이 같은 단일 날짜 조회

TRUE이면 날짜와 종가의 2열 배열 반환

FALSE이면 종가 숫자 하나 반환

숫자로 입력된 종목코드는 6자리로 변환

거래일 데이터가 없으면 #N/A

잘못된 인수이면 #VALUE!

확인된 네이버 API

https://m.stock.naver.com/api/stock/{종목코드}/price?pageSize=50&page={페이지}

응답 예:

[ { “localTradedAt”: “2026-09-17”, “closePrice”: “256,000” } ]

아래 수식은 Excel 2013에서 정상적으로 JSON을 가져옵니다.

=WEBSERVICE(“https://m.stock.naver.com/api/stock/005930/price?pageSize=1&page=1”)

또한 JSON을 VBA에서 파싱하는 함수는 정상 작동했으며, 다음 테스트에서 256000이 반환되었습니다.

=NaverStockCloseJson2013( WEBSERVICE(“https://m.stock.naver.com/api/stock/005930/price?pageSize=50&page=1”), DATE(2026,9,17), FALSE, FALSE )

반드시 고려할 문제

Excel 2013에서는 DATE() 결과가 VBA UDF에 Excel 날짜 일련번호로 전달될 수 있습니다. 따라서 날짜 검사 시 IsDate()만 사용하면 안 됩니다.

숫자인 경우에도 다음과 같이 처리해야 합니다.

If IsNumeric(value) Then parsedDate = CDate(CDbl(value)) ElseIf IsDate(value) Then parsedDate = CDate(value) Else ‘ 잘못된 날짜 End If

기존 테스트에서 다음 VBA 네트워크 방식은 모두 #N/A가 발생했습니다.

MSXML2.ServerXMLHTTP.6.0

MSXML2.XMLHTTP.6.0

WinHttp.WinHttpRequest.5.1

URLDownloadToFile

VBA 내부의 Application.Evaluate(“WEBSERVICE(…)”)

하지만 워크시트에서 직접 사용하는 WEBSERVICE()는 정상 작동합니다.

요청 사항

우선순위 1:

Excel 2013에서 직접 컴파일하고 저장한 정상적인 .xlam 파일을 만들어 주세요. 파일을 바이너리 수준에서 임의 수정하는 방식은 사용하지 마세요. 이전에 그렇게 만든 파일은 추가기능 로드 오류 또는 #NAME? 오류가 발생했습니다.

다음 테스트가 성공해야 합니다.

=NaverStockClose(“005930″,DATE(2026,9,17),DATE(2026,9,17),”종가”,FALSE,FALSE)

예상 결과:

256000

우선순위 2:

VBA UDF 내부에서 네트워크 호출이 불가능하다면, 검증된 WEBSERVICE()와 JSON 파서 함수를 사용하되 사용자에게 보이는 수식은 짧게 만들어 주세요.

예를 들어 통합문서 정의 이름이나 숨김 보조 셀을 이용하여 최종 사용 수식이 다음 정도가 되도록 구성해 주세요.

=IF($Y$14=”Y”,NaverStockCloseValue)

배포 시 VBS나 별도 실행파일은 사용하지 마세요. AhnLab V3에서 앱 격리 대상으로 탐지되었습니다.

최종 산출물에는 다음을 포함해 주세요.

Excel 2013에서 생성한 .xlam 파일

전체 VBA 소스

여러 PC에 설치하는 방법

신뢰할 수 있는 위치 설정 방법

위 테스트 수식의 검증 결과