[중급] 엑셀 자동화 런타임 오류 1004, 91 박살내는 법

[중급] 엑셀 자동화 런타임 오류 1004, 91 박살내는 법

결론부터 말한다. 런타임 오류 ‘1004’와 ’91’은 당신의 코드 설계가 근본부터 틀렸다는 신호다.

엑셀 좀 만져서 자동화하겠다는 사람들, 열에 아홉은 이 두 에러 앞에서 무릎 꿇는다. 나도 그랬다. 몇 시간 동안 모니터만 쳐다보며 머리를 쥐어뜯었다. 하지만 원인은 언제나 같다. 개체(Object)를 제대로 다루지 못해서다.

런타임 오류 ’91’: 개체 변수가 설정되지 않았습니다.

이건 아주 기초적인 실수다. 코드로 비유하면 이렇다.

‘나는 이제부터 ‘내상자’라는 이름의 상자를 쓸 거야’ 라고 선언만 하고 (Dim 내상자 As Box), 정작 창고에 가서 실제 상자를 가져오지 않은 상태(Set 내상자 = 창고.가져오기("튼튼한상자"))에서, 그 상자에 물건을 담으려고 하는 꼴이다. 당연히 시스템은 ‘상자가 없는데 어디에 담으라는 거냐’며 소리친다. 이게 오류 ’91’의 본질이다.

Dim ws As Worksheet는 그냥 이름표를 만드는 행위다. 실제 엑셀 시트라는 실체를 담으려면 반드시 Set 키워드로 연결해줘야 한다. Set ws = ThisWorkbook.Sheets("데이터") 이런 식으로 말이다. 이 한 줄을 빼먹고 ws.Range("A1").Value = "Hello" 같은 코드를 실행하니 에러가 터지는 거다.

런타임 오류 ‘1004’: 응용 프로그램 정의 또는 개체 정의 오류입니다.

오류 ’91’의 단계를 통과했다고 치자. 이제 당신 손에는 실제 ‘상자’가 들려있다. 그런데 이번엔 그 상자에 코끼리를 넣으려고 한다. 당연히 안 들어간다. 또는 ‘데이터’라는 이름의 시트를 가져오라고 했는데, 엑셀 파일에는 ‘RawData’ 시트만 있다. 이것도 마찬가지다.

시스템 입장에서 보면 말도 안 되는 명령이다. ‘네가 준 개체(Worksheet)로는 그 일을 할 수 없거나, 네가 말한 그 개체는 존재하지 않는다’는 뜻이다. 이게 오류 ‘1004’다. 매우 광범위한 에러지만, 결국 원인은 하나다. 존재하지 않거나, 논리적으로 불가능한 작업을 개체에 요구하는 것.

실무에서 가장 많이 터지는 오류 패턴 5가지와 해결책

이론은 이쯤하고, 실전에서 마주하는 삽질 패턴을 보자.

Q1. 분명히 Set으로 변수를 할당했는데 왜 ’91’ 오류가 뜨는가?

A: 루프(Loop)나 조건문 안에서 할당이 실패했을 가능성이 높다. 예를 들어 특정 조건일 때만 시트를 할당하게 했는데, 그 조건이 충족되지 않은 채로 다음 코드로 넘어간 경우다. 변수는 선언만 된 빈 껍데기 상태로 남는다. 모든 경우의 수를 따져서 개체 할당이 누락되는 구간이 없는지 F8 키를 눌러 한 줄씩 실행하며 직접 확인해야 한다.

Q2. 어제까지 잘 되던 코드가 오늘 ‘1004’ 오류를 뿜는다. 왜 그런가?

A: 당신이 아니라 다른 누군가가 엑셀 파일의 시트 이름이나 표(Table) 이름을 바꿨을 확률이 99%다. 코드는 죄가 없다. 하드코딩된 이름(예: “Sheet1”)을 참조하는 코드는 이런 외부 변화에 극도로 취약하다. 코드네임(예: Sheet1.Name)을 쓰거나, 이름을 바꿀 수 없도록 시트 보호를 거는 등의 방어 로직이 필요하다.

Q3. 통합 문서를 여러 개 다룰 때 특히 오류가 잦다.

A: Workbooks("A.xlsx").Sheets("Data").Range("A1") 처럼 어떤 문서의 어떤 시트인지 풀 경로를 명확히 지정하지 않았기 때문이다. 그냥 Sheets("Data") 라고만 쓰면 현재 활성화된(Active) 통합 문서를 기준으로 삼는다. 자동화 코드가 실행되는 찰나에 어떤 문서가 활성화되어 있을지 보장할 수 없다. 모든 개체는 소속을 명확히 밝혀야 한다.

Q4. 셀 병합(Merge) 관련 코드에서 ‘1004’ 오류가 터진다.

A: 이미 병합된 셀이 포함된 영역을 또 병합하려고 할 때 발생한다. 혹은 표(Table)로 지정된 범위 안에서 셀 병합을 시도할 때도 마찬가지다. 표 기능과 셀 병합은 상극이다. 코드를 실행하기 전에 먼저 병합을 풀거나(UnMerge), 표 서식을 해제하는 로직을 추가해야 한다.

Q5. 분명 존재하는 범위인데 자꾸 ‘1004’ 오류가 난다.

A: 시트가 보호(Protected)되어 있을 가능성이 크다. 보호된 시트의 셀은 기본적으로 수정할 수 없다. 코드 맨 위에 ActiveSheet.Unprotect "비밀번호"를, 코드 맨 마지막에 ActiveSheet.Protect "비밀번호"를 추가해서 작업하는 동안만 잠시 보호를 해제하는 로직이 필요하다.


결론: 코드는 정직하다.

이 두 가지 오류는 결국 기본기의 문제다. 코드 맨 위에 Option Explicit 한 줄 추가해서 변수 선언을 강제하고, 모든 개체는 Set으로 명확하게 생명을 불어넣어라. 그리고 그 개체가 누구 소속인지(어느 통합 문서의 어느 시트인지) 항상 명시적으로 지정하는 습관을 들여야 한다. 이 원칙만 지키면 저 두 에러를 볼 일은 거의 없다. 틀린 건 언제나 시스템이 아니라 나 자신이다.


PipeMaster-Lab 운영정책 및 제보 안내

① 공개된 모든 기록은 특정 기업이나 개인의 청탁 또는 금전적 지원 없이, 시스템 아키텍트의 독립적인 연구 및 실험 결과를 바탕으로 작성됩니다.
② 인용된 외부 콘텐츠 해석에 이의가 있는 경우,
연구실 직통 메일 pipemaster.lab@gmail.com
으로 연락 주시면 24시간 내 회신 및 즉각 조치합니다.
③ 게시된 내용 중 버전 변경으로 인한 정보 불일치나 치명적인 로직 오류를 제보해 주시는 분께는 내부 검토 후 소정의 기프티콘 등 바운티를 지급합니다.
④ 기업 단위의 시스템 아키텍처 컨설팅, 비즈니스 제휴 및 고도화 제안 역시 해당 공식 메일로만 수신 및 회신합니다.
verified

PIPEMASTER RESEARCH LAB

20년 IT 내공과 AI가 결합된 실전 무인 수익 자동화 시스템 연구소
본 콘텐츠는 PipeMaster-Lab 내부 Certified 규격을 엄격히 통과하였음을 증명합니다.

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다