- 공유 링크 만들기
- X
- 이메일
- 기타 앱
이 글의 목적은 엑셀에서 UDF(사용자 정의 함수)가 셀에서 #NAME? 오류를 반환할 때 원인별 진단과 실무 복구 절차를 체계적으로 제시하여 현장에서 즉시 해결하도록 돕는 것이다.
문제 정의와 핵심 개념
#NAME? 오류는 엑셀이 수식의 함수 이름 또는 이름 정의를 인식하지 못할 때 발생한다. UDF에서 #NAME?이 나타나면 대개 함수가 메모리에 로드되지 않았거나 VBA 컴파일 오류로 함수가 비활성화되었거나 접근 범위가 잘못 지정된 경우이다. 또한 매크로가 차단된 상태이거나 모듈 배치가 잘못되었을 때도 동일 증상이 발생한다. 아래의 표준 절차를 순서대로 점검하면 대부분의 사례를 해결할 수 있다.
빠른 진단 흐름도
다음 순서대로 확인한다.
- 파일 신뢰 및 매크로 실행이 허용되어 있는지 확인한다.
- VBA 프로젝트가 정상 컴파일되는지 확인한다.
- 함수의 선언 범위와 모듈 위치가 올바른지 점검한다.
- 함수가 포함된 통합 문서 또는 추가 기능이 로드되어 있는지 확인한다.
- 다른 통합 문서에서 호출 시 참조 방식이 올바른지 검토한다.
- API 선언 및 64비트 호환성 문제가 없는지 점검한다.
- 이름 충돌, 숨겨진 정의, 함수 명칭 오타 여부를 확인한다.
#NAME?으로 평가될 수 있다. 반드시 전체 프로젝트를 컴파일하여 오류를 제거해야 한다.원인별 증상과 조치 요약
| 증상 | 주요 원인 | 해결 조치 |
|---|---|---|
모든 시트에서 해당 UDF가 #NAME?로 표시됨 | 매크로 차단, VBA 컴파일 오류, 모듈 위치 오류 | 신뢰 센터에서 매크로 허용, 디버그 → VBAProject 컴파일, 표준 모듈 배치 확인 |
특정 통합 문서에서만 #NAME? | UDF가 포함된 파일이 미로드, 참조 불일치 | UDF 파일 열기 또는 추가 기능 등록, 도구 → 참조의 MISSING 해제 |
다른 PC에서만 #NAME? | 신뢰 위치 미설정, 경로 변경, 라이브러리 누락 | 신뢰 위치 등록, 파일 차단 해제, 필요한 라이브러리 설치 |
특정 함수만 #NAME? | Private 선언, Option Private Module, 이름 충돌, 오타 | Public Function으로 변경, 시트 이름 정의 확인, 함수명 정정 |
VBA에서 실행은 되나 셀에서만 #NAME? | 클래스 모듈 함수, 인스턴스 필요, 범위 밖 | 표준 모듈로 이동 또는 Book1.xlsm!함수명()처럼 한정 호출 |
| 64비트 환경에서만 발생 | WinAPI 선언 비호환, PtrSafe 누락 | Declare PtrSafe 및 포인터형 LongPtr 사용 |
1. 파일 신뢰 및 매크로 실행 허용
- 파일 속성에서 차단 해제를 체크한 뒤 다시 연다.
- 엑셀의 신뢰 센터에서 신뢰할 수 있는 위치에 UDF 파일 경로를 추가한다.
- 매크로 설정에서 VBA 프로젝트 개체 모델에 대한 신뢰 액세스를 사용 환경에 맞게 검토한다.
- 회사 보안 정책으로 그룹 정책이 매크로를 차단할 수 있으므로 정책 예외 또는 서명된 매크로 사용을 검토한다.
#NAME?이 발생한다. 반드시 편집 사용과 콘텐츠 사용을 허용해야 한다.2. VBA 프로젝트 컴파일
UDF가 포함된 통합 문서에서 VBA 편집기를 열고 다음을 수행한다.
- 도구 → 참조에서 MISSING으로 표시된 항목을 해제하거나 올바른 버전으로 교체한다.
- 디버그 → VBAProject 컴파일을 실행한다.
- 오류가 발생하면 해당 모듈을 수정한 뒤 다시 컴파일한다.
' 예시: 잘못된 API 선언이 포함된 UDF는 전체 컴파일 실패를 유발한다. #If VBA7 Then Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long #Else Private Declare Function GetTickCount Lib "kernel32" () As Long #End If
Public Function MyUDF()
MyUDF = GetTickCount()
End Function
PtrSafe 키워드와 LongPtr 타입을 적절히 사용해야 한다. 선언 불일치가 있으면 컴파일이 중단되고 셀에서는 #NAME?이 발생한다.3. 모듈 위치와 접근 범위 점검
UDF는 표준 모듈(Module) 안의 Public 함수여야 셀에서 호출 가능하다.
' 잘못된 배치 예: 시트 모듈 또는 ThisWorkbook에 배치하면 셀에서 인식되지 않는다. ' Sheet1(코드명) 안: Public Function SumHidden(rng As Range) As Double ' ... End Function
' 올바른 배치 예: 표준 모듈(Module1.bas)
Public Function SumHidden(rng As Range) As Double
Dim c As Range, s As Double
For Each c In rng
If c.EntireRow.Hidden = False And c.EntireColumn.Hidden = False Then
s = s + Val(c.Value)
End If
Next c
SumHidden = s
End Function
Public Function으로 선언해야 한다.Private Function인 경우 셀에서 인식하지 못한다.- 모듈 상단의
Option Private Module이 설정되어 있으면 외부 호출이 차단된다. - 클래스 모듈의 메서드는 인스턴스가 필요하므로 셀에서 직접 호출되지 않는다.
4. 통합 문서 로드와 참조 방식
UDF가 A통합 문서에 있고 B통합 문서의 셀에서 사용하려면 다음 중 하나가 필요하다.
- A통합 문서를 함께 연다. 이 경우 일반적으로 셀에서 함수 이름만으로 호출 가능하다.
- A를 추가 기능(.xlam)으로 저장하고 엑셀 추가 기능에서 로드한다.
- 또는
=A통합문서.xlsm!함수명(인수)처럼 파일 한정자를 포함하여 호출한다.
' 예시: 다른 파일의 UDF 명시 호출 =Book1.xlsm!SumHidden(A1:A10) #NAME?이 발생할 수 있다. 경로가 고정되지 않는 환경에서는 추가 기능 배포가 안정적이다.5. 이름 충돌과 오타 점검
- 함수명 철자를 다시 확인한다. 유사한 문자 대체(영문 O와 숫자 0 등)로 인한 오타가 잦다.
- 시트의 이름 관리자에 동일한 이름의 정의가 존재하면 충돌이 발생할 수 있다. 불필요한 이름 정의를 삭제한다.
- 엑셀 기본 함수와 동일 또는 유사한 이름을 피한다. 예를 들어
COUNT,SUMIFS와 같은 이름은 사용하지 않는다.
6. 64비트 호환성과 API 선언
UDF 내부에서 WinAPI 또는 외부 DLL을 호출한다면 32/64비트 호환을 보장해야 한다.
' 64비트 안전 선언 패턴 #If VBA7 Then Private Declare PtrSafe Function GetSystemTime Lib "kernel32" (lpSystemTime As Any) As Long #Else Private Declare Function GetSystemTime Lib "kernel32" (lpSystemTime As Any) As Long #End If 포인터 또는 핸들 타입은 LongPtr로 선언한다. 잘못된 선언은 컴파일 오류를 유발하고 결과적으로 #NAME?로 나타난다.
7. 참조 라이브러리 누락 복구
다음 순서로 누락 참조를 복구한다.
- VBA 편집기에서 도구 → 참조를 열고 MISSING 항목을 찾는다.
- 대체 가능한 최신 버전으로 체크하거나 해당 항목을 해제한다.
- 필요시 늦은 바인딩으로 전환하여 버전 의존성을 낮춘다.
' 이른 바인딩(버전 의존성 높음) ' Dim xlApp As Excel.Application
' 늦은 바인딩(버전 의존성 낮음)
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
#NAME?을 반환한다.8. 배포 전략: 추가 기능(.xlam)로 패키징
조직 배포 시 .xlsm로 배포하면 경로와 파일명에 의존한다. .xlam 추가 기능으로 패키징하면 로드 여부만 관리하면 되므로 안정적이다.
- 다른 이름으로 저장에서 파일 형식을
Excel 추가 기능(.xlam)으로 저장한다. - 파일 → 옵션 → 추가 기능에서 관리 대상 Excel 추가 기능을 선택하고 이동 후 해당 파일을 추가한다.
- 기업 환경에서는 네트워크 공유의 읽기 전용 경로에 배치하고 신뢰 위치로 등록한다.
9. PERSONAL.XLSB 활용 시 주의점
- UDF를
PERSONAL.XLSB에 두면 기본적으로 모든 통합 문서에서 사용 가능하다. - 해당 파일이 숨김 상태로 로드되지 않으면
#NAME?이 발생한다. 엑셀 시작 시 자동 로드되도록 XLSTART 폴더를 점검한다. - 개인용 파일에 의존하는 UDF는 배포성에 한계가 있다. 팀 공유가 필요하면 추가 기능으로 이관한다.
10. 재계산과 UDF 재로드
코드를 수정한 뒤 수식이 여전히 #NAME?이면 다음을 시도한다.
Ctrl+Alt+F9로 강제 전체 재계산을 수행한다.- 통합 문서를 저장 후 닫았다가 다시 연다.
- UDF가 포함된 파일을 닫았다가 다시 로드한다.
Application.Volatile은 재계산 빈도를 높이지만 #NAME? 자체를 해결하지는 않는다. 근본 원인은 로드와 컴파일이다.
11. 보안 정책과 서명
기업 보안 정책에서 서명되지 않은 매크로가 차단되면 사용자 환경에서 UDF가 로드되지 않는다. 신뢰된 게시자의 디지털 서명을 적용하고 배포한다.
예시 절차: 1) 자체 CA 또는 공인 인증서로 코드 서명 인증서를 발급한다. 2) VBA 프로젝트 서명 메뉴에서 인증서를 적용한다. 3) 사용자 PC의 신뢰 센터에서 "신뢰할 수 있는 게시자" 정책을 확인한다. 12. 자주 발생하는 실수 사례
- 함수명이 시트 이름 정의와 동일하여 이름 관리자 충돌이 발생한 사례이다.
- 클래스 모듈 함수로 작성해 셀에서 직접 호출하려다
#NAME?이 발생한 사례이다. - VBA7 64비트에서
Declare구문에PtrSafe를 누락해 전체 프로젝트가 컴파일되지 않은 사례이다. - 외부 .dll 경로가 바뀌어 선언은 남아 있으나 런타임 전에 컴파일이 실패한 사례이다.
- 추가 기능을 로드했지만 동일 이름의 구 버전이 먼저 로드되어 새 함수가 가려진 사례이다.
13. 표준 점검 체크리스트
| # | 점검 항목 | 상태 | 조치 |
|---|---|---|---|
| 1 | 파일 차단 해제 및 신뢰 위치 등록 | ||
| 2 | 매크로 설정 및 콘텐츠 사용 허용 | ||
| 3 | VBAProject 컴파일 이상 없음 | ||
| 4 | 참조 라이브러리 MISSING 없음 | ||
| 5 | 표준 모듈 배치 및 Public 선언 | ||
| 6 | Option Private Module 비활성 | ||
| 7 | 64비트 PtrSafe 및 LongPtr 적용 | ||
| 8 | 이름 관리자 충돌 없음 | ||
| 9 | 외부 통합 문서/추가 기능 로드 확인 | ||
| 10 | 강제 재계산 및 재로드 수행 |
14. 실전 UDF 템플릿
다음 템플릿은 범용 합계 UDF로, 숨겨진 행과 열을 제외하고 합계를 계산한다. 표준 모듈에 배치하고 Public으로 선언한다.
Option Explicit
Public Function SumVisible(ByVal rng As Range) As Double
Dim c As Range
Dim acc As Double
Application.Volatile False
For Each c In rng.Cells
If Not c.EntireRow.Hidden And Not c.EntireColumn.Hidden Then
If IsNumeric(c.Value) Then acc = acc + c.Value
End If
Next c
SumVisible = acc
End Function
배치 후 =SumVisible(A1:A100) 형태로 사용한다. 만약 셀에서 #NAME?이 나오면 앞 절의 체크리스트로 복구한다.
15. 다른 통합 문서에서 안전하게 호출하는 방법
' 방법 1: 동일 세션에서 원본 파일 열기 =SumVisible(A1:A100)
' 방법 2: 파일 한정자 사용
='C:\UDF\Tools.xlsm'!SumVisible(A1:A100)
' 방법 3: 추가 기능 등록 후 일반 함수처럼 사용
=SumVisible(A1:A100)
16. 트러블슈팅 심화: 수식 기록 복구
외부 참조가 끊어져 #NAME?이 된 대량 수식을 일괄 복구하려면 다음 절차를 사용한다.
- 이름 관리자에서 끊어진 외부 경로를 파악한다.
- 찾기 및 바꾸기에서 오래된 경로를 새 경로로 교체한다.
- 추가 기능으로 전환하여 경로 의존을 제거한다.
17. 성능 팁
Application.Volatile사용을 최소화하여 재계산 부담을 줄인다.- 대량 범위 반복 시 배열로 값을 받아 연산 후 한 번에 반환한다.
- 에러 처리를 명시적으로 작성하여 예외 시
#VALUE!등 명확한 오류를 반환한다.
Public Function MeanSafe(ByVal rng As Range) As Variant On Error GoTo EH Dim v, i As Long, n As Long, s As Double v = rng.Value If IsArray(v) Then For i = 1 To UBound(v, 1) If IsNumeric(v(i, 1)) Then s = s + v(i, 1): n = n + 1 End If Next Else If IsNumeric(v) Then s = v: n = 1 End If If n = 0 Then MeanSafe = CVErr(xlErrDiv0) Else MeanSafe = s / n Exit Function EH: MeanSafe = CVErr(xlErrValue) End Function FAQ
VBA에서 F5로 호출하면 동작하는데 셀에서는 #NAME?이 나온다. 왜 그런가?
셀에서 호출하려면 함수가 표준 모듈의 Public이어야 하다. 시트 모듈이나 클래스 모듈의 메서드는 셀에서 직접 호출되지 않는다. Option Private Module 설정도 해제해야 하다.
추가 기능으로 배포했는데 일부 PC에서만 #NAME?이 보인다.
해당 PC에서 추가 기능이 실제로 로드되었는지와 파일 경로가 신뢰 위치인지 확인해야 하다. 기업 보안 정책으로 매크로가 차단되었을 수 있으며 디지털 서명 적용이 필요하다.
64비트 전환 후 기존 UDF가 전부 #NAME?이 되었다.
WinAPI 선언에서 PtrSafe와 LongPtr을 적용해야 하다. 선언 불일치로 컴파일 실패 시 모든 UDF가 비활성화된다.
다른 통합 문서에서 UDF를 부르면 경로가 자동으로 붙는다. 어떻게 해야 하나?
경로 의존을 피하려면 추가 기능(.xlam)으로 배포하여 로드 후 일반 함수처럼 사용해야 하다. 또는 동일 세션에서 원본 파일을 함께 열어 둔다.
UDF 이름과 동일한 이름 정의가 시트에 있다. 영향이 있는가?
있다. 이름 관리자에 동일 이름이 있으면 충돌로 #NAME? 또는 예상치 못한 참조가 발생한다. 이름을 변경하거나 삭제한다.