- 공유 링크 만들기
- X
- 이메일
- 기타 앱
이 글의 목적은 엑셀에서 VBA 실행 중 발생하는 ‘프로젝트 또는 라이브러리를 찾을 수 없습니다(Can’t find project or library)’ 오류를 체계적으로 진단하고, 참조 설정 복구·대체 바인딩·64비트 선언 수정·ActiveX 재등록·레지스트리 확인·배포 표준화까지 실무자가 즉시 적용 가능한 단계별 해결책을 제공하는 것이다.
1. 오류의 핵심 원리 이해
해당 오류는 VBA 프로젝트가 컴파일 시점에 필요로 하는 타입 라이브러리(Type Library)나 참조(References)를 찾지 못해 발생한다. 일반적으로 다음 조건 중 하나 이상이 참일 때 나타난다.
- VBE의 도구 > 참조에서 MISSING:으로 표시되는 끊어진 참조가 존재하다.
- Office 버전 또는 비트수(32비트/64비트)가 변경되어 선언(Declare) 구문이 호환되지 않다.
- MSCOMCTL.OCX, FM20.DLL 등 ActiveX/폼 컨트롤 관련 파일 등록이 해제되었다.
- 배포 환경마다 다른 외부 제품(예: 특정 PDF/메일 클라이언트)의 타입 라이브러리에 의존하는 조기 바인딩(early binding)을 사용한다.
- ADO/DAO/Scripting 등 공용 라이브러리의 버전이 상이하거나 누락되었다.
2. 3단계 신속 복구 절차(현장용 체크리스트)
- VBE 참조 복구 : Alt+F11 → 도구 > 참조 → MISSING: 항목의 체크 해제 또는 올바른 버전으로 교체 → 컴파일.
- 64비트 호환성 점검 : Office 64비트 환경이면 Declare 구문에
PtrSafe와LongPtr반영. - ActiveX/공용 라이브러리 재등록 : 관리자 권한으로
regsvr32로 컨트롤 재등록 후 재부팅.
| 단계 | 점검 포인트 | 조치 | 예상 효과 |
|---|---|---|---|
| 1. 참조 | MISSING 표시 여부 | 체크 해제 또는 동일 기능의 다른 라이브러리로 대체 | 대부분의 컴파일 오류 즉시 해소 |
| 2. 64비트 | Declare, 포인터 크기 | PtrSafe, LongPtr 적용 | 런타임 API 호출 오류 제거 |
| 3. ActiveX | OCX/DLL 등록 상태 | regsvr32 재등록 | 폼·컨트롤 로드 실패 복구 |
3. 참조 설정 문제(MISSING) 해결
3.1 끊어진 참조 제거
- VBE(Alt+F11) 실행 후 도구 > 참조을 연다.
- MISSING:으로 시작하는 항목의 체크를 해제한다.
- 대신 기능적으로 동등한 라이브러리를 선택하거나, 코드를 늦은 바인딩(late binding)으로 변경한다.
- 메뉴 디버그 > VBAProject 컴파일을 눌러 즉시 검증한다.
3.2 조기 바인딩 → 늦은 바인딩 전환 예시
조기 바인딩은 개발 편의성이 크지만 배포 환경마다 참조가 달라 오류를 유발한다. 아래는 대표 전환 예시이다.
' [FileSystemObject] 조기 바인딩 예 ' Requires: Microsoft Scripting Runtime Dim fso As Scripting.FileSystemObject Set fso = New Scripting.FileSystemObject
' 늦은 바인딩 대체
Dim fsoLate As Object
Set fsoLate = CreateObject("Scripting.FileSystemObject")
' [Dictionary] 조기 바인딩 예 ' Requires: Microsoft Scripting Runtime Dim dict As Scripting.Dictionary Set dict = New Scripting.Dictionary ' 늦은 바인딩 대체 Dim dictLate As Object Set dictLate = CreateObject("Scripting.Dictionary") ' [Outlook] 조기 바인딩 예 ' Requires: Microsoft Outlook X.0 Object Library Dim olApp As Outlook.Application Set olApp = New Outlook.Application ' 늦은 바인딩 대체 Dim olAppLate As Object Set olAppLate = CreateObject("Outlook.Application") 3.3 ADO/DAO 버전 호환 전략
- ADO: “Microsoft ActiveX Data Objects x.x Library” 참조 없이
CreateObject("ADODB.Connection")방식 권장하다. - DAO: Access 유무에 영향받는다. 가능하면 ADO로 통일하거나, DAO 필수일 때도 늦은 바인딩 사용을 검토한다.
4. 64비트 Office 호환(Declare/포인터) 점검
Office 64비트에서는 Win32 API 선언에 PtrSafe 지정과 포인터 크기 대응이 필요하다.
' 32비트용 오래된 선언 (문제 발생 소지) Private Declare Function GetTickCount Lib "kernel32" () As Long
' 64비트 호환 선언
#If VBA7 Then
Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else
Private Declare Function GetTickCount Lib "kernel32" () As Long
#End If
핵심은 포인터·핸들을 LongPtr로 선언하는 것이다.
#If VBA7 Then Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" ( _ ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr #Else Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" ( _ ByVal lpClassName As String, ByVal lpWindowName As String) As Long #End If 5. ActiveX/폼 컨트롤 재등록
폼 컨트롤이나 MSCOMCTL.OCX(FlexGrid, ListView 등)과 FM20.DLL(Forms 2.0) 관련 문제가 있으면 등록 상태를 확인한다. 관리자 명령 프롬프트에서 다음을 실행한다.
REM 32비트 Windows\System32, 64비트는 SysWOW64도 고려 regsvr32 MSCOMCTL.OCX regsvr32 FM20.DLL 등록 후 엑셀을 완전 종료하고 재실행한다. 파일이 없다는 메시지가 나오면 해당 구성 요소를 설치하거나 신뢰된 배포 패키지에 포함한다.
6. 끊긴 참조를 코드로 탐지하기
대규모 프로젝트에서는 사람 손으로 모든 참조를 추적하기 어렵다. 다음 매크로로 현재 프로젝트의 참조 상태를 목록화한다.
Sub ListBrokenReferences() Dim r As Reference On Error Resume Next For Each r In ThisWorkbook.VBProject.References Debug.Print r.Description & " | " & r.FullPath & _ IIf(r.IsBroken, " | MISSING", " | OK") Next r End Sub 7. 배포 표준화 전략(환경 의존성 제거)
- 늦은 바인딩 기본화 : Scripting/ADO/Outlook 등은 늦은 바인딩으로 통일한다.
- API 래퍼 모듈 : 32/64비트 분기를 내부 처리하는 래퍼를 두고 호출부는 동일 인터페이스로 유지한다.
- 컨트롤 최소화 : 서드파티 ActiveX 의존도를 줄이고, 가능하면 기본 폼/네이티브 대체로 전환한다.
- 사전 진단 루틴 : 시작 시 필수 참조 유효성 검사 후 사용자에게 자동 복구 또는 가이드를 제공한다.
Function IsTypeAvailable(progId As String) As Boolean Dim o As Object On Error Resume Next Set o = CreateObject(progId) IsTypeAvailable = (Err.Number = 0) Set o = Nothing End Function 8. 원인별 처방 매뉴얼
| 증상 | 가능 원인 | 즉시 조치 | 근본 해결 |
|---|---|---|---|
| 컴파일 시 즉시 오류 | MISSING 참조 | 도구 > 참조에서 체크 해제 | 늦은 바인딩 전환, 배포 표준화 |
| 64비트에서만 실패 | Declare/포인터 불일치 | PtrSafe/LongPtr 적용 | API 래퍼화로 일관성 확보 |
| 폼 열기 실패·컨트롤 없음 | ActiveX 미등록 | regsvr32로 재등록 | 컨트롤 사용 최소화 및 설치 가이드 |
| 다른 PC에서만 오류 | 외부 제품 의존 | 늦은 바인딩으로 대체 | 기능 요구사항 문서화·대체 설계 |
| 특정 DB 연결 실패 | ADO/DAO 버전 차이 | CreateObject로 연결 | ODBC/Driver 버전 표준화 |
9. 선언 샘플 라이브러리(바로 붙여 쓰는 템플릿)
' 32/64 통합 선언 템플릿 #If VBA7 Then Private Declare PtrSafe Function GetUserNameA Lib "advapi32.dll" ( _ ByVal lpBuffer As String, ByRef nSize As Long) As Long #Else Private Declare Function GetUserNameA Lib "advapi32.dll" ( _ ByVal lpBuffer As String, ByRef nSize As Long) As Long #End If
Function CurrentUserName() As String
Dim buf As String * 256, n As Long: n = 256
If GetUserNameA(buf, n) > 0 Then
CurrentUserName = Left$(buf, n - 1)
End If
End Function
10. regsvr32 운용 상세
운영체제와 Office 비트수 혼합 환경에서 경로 착오가 잦다. 다음 기준을 따른다.
- 64비트 Windows에서 32비트 컨트롤은
C:\Windows\SysWOW64\regsvr32.exe로 등록한다. - 64비트 컨트롤은
C:\Windows\System32\regsvr32.exe를 사용한다.
"C:\Windows\SysWOW64\regsvr32.exe" "C:\Windows\SysWOW64\MSCOMCTL.OCX" "C:\Windows\System32\regsvr32.exe" "C:\Windows\System32\MSCOMCTL.OCX" 11. 환경 진단 자동화 스니펫
다음 루틴은 필수 ProgID 가용성과 Office 비트수를 로그로 남겨 초기 진단을 자동화한다.
Sub EnvHealthCheck() Debug.Print "Is 64-bit Office: "; IIf(Application.OperatingSystem Like "*64*", "Maybe", "Unknown") Debug.Print "Scripting.FSO: "; IsTypeAvailable("Scripting.FileSystemObject") Debug.Print "Scripting.Dictionary: "; IsTypeAvailable("Scripting.Dictionary") Debug.Print "ADODB.Connection: "; IsTypeAvailable("ADODB.Connection") Debug.Print "Outlook.Application: "; IsTypeAvailable("Outlook.Application") End Sub 12. 팀 배포 체크리스트
- 필수 참조 제거 또는 늦은 바인딩화 완료 여부.
- 조건부 컴파일(#If VBA7, #If Win64)로 API 호출 통합 여부.
- ActiveX 사용 시 설치·등록 스크립트 제공 여부.
- 시작 매크로에 환경 진단 및 사용자 가이드 포함 여부.
- 테스트 매트릭스: Office 2016~M365, 32/64비트, 관리자/일반 계정.
FAQ
엑셀 재설치로 해결 가능한가?
일부 파일 손상은 복구되나 MISSING 참조나 64비트 선언 문제는 그대로 남는다. 먼저 참조와 선언을 교정한다.
FM20.DLL을 배포 패키지에 넣어도 되는가?
권장하지 않는다. Office 구성품에 종속되는 경우가 많아 설치본을 통한 정식 배포가 안전하다.
Dictionary를 반드시 조기 바인딩해야 하나?
팀 배포 목적이면 늦은 바인딩을 권장한다. 성능 차이는 대부분의 업무 시나리오에서 미미하다.
Office 32/64 혼용 환경에서 공통 코드 유지 방법은?
조건부 컴파일과 래퍼 모듈을 사용하여 포인터·핸들 타입을 내부에서 흡수한다.
ADO/DAO 중 무엇을 선택해야 하나?
호환성과 배포 관점에서는 ADO+늦은 바인딩이 유리하다. 레거시 MDB 기능 의존이 크면 DAO를 유지하되 참조 의존을 최소화한다.