셀을 고치면 매크로가 저절로 — VBA Worksheet_Change 이벤트

재고 수량 B열을 바꿨을 때 같은 행의 C열에 시각을 남기되, 여러 셀을 붙여넣은 경우도 빠뜨리지 않는 Worksheet_Change 예제입니다. 수량이 5 미만이면 빨간 배경을 넣고, 빈 셀을 만들면 이전 시각도 지웁니다. 타임스탬프는 수량을 검증했다는 증거가 아니라 이 코드가 변경을 처리한 시점입니다.

재고관리 시트의 세 열 준비

Windows 데스크톱 Excel에서 새 통합 문서를 .xlsm으로 저장하고 재고관리 시트를 만듭니다. A1:C3에 다음 값을 입력합니다. 이 자료는 실제 재고가 아닌 합성 입력입니다.

셀 위치 A: 품목 B: 수량 C: 수정 시각
1행 Item Quantity ChangedAt
2행 노트북 10 빈칸
3행 마우스 3 빈칸
수량 B2를12·B3를2로 바꾸면 같은 행 C열 처리 시각과 직접 채우기색을 기록하는 설명 도해
수량 B2를12·B3를2로 바꾸면 같은 행 C열 처리 시각과 직접 채우기색을 기록하는 설명 도해. 가상 예제를 설명하는 도해이며 실제 앱 실행 결과 화면이 아닙니다.

입력은 재고관리 시트 B2:B500의 수량 수정이며, 출력은 같은 행 C열의 수정 시각과 B열 채우기색입니다. B2를 12로 바꾸면 C2에 처리 시각을 쓰고 B2의 직접 채우기색을 제거합니다. B3를 2로 바꾸면 C3에 처리 시각을 쓰고 B3을 빨강으로 표시합니다.

감시 범위는 B2:B500입니다. 이 범위 밖만 수정하면 아래 처리 코드는 실행되지 않습니다. Worksheet_Change 자체가 시트 변경을 받더라도 Intersect 결과가 없으면 바로 종료합니다. 수식의 재계산은 이 이벤트 대상이 아니므로 재계산된 수량의 감사 기록까지 제공한다고 해석하지 마세요.

시트 모듈에 넣는 완성 코드

Alt+F11을 누르고 프로젝트 탐색기의 Microsoft Excel Objects 아래에서 재고관리 시트를 더블클릭합니다. 표준 모듈에 넣으면 이벤트가 자동 연결되지 않습니다. 해당 시트에 기존 Worksheet_Change가 있다면 이름이 같은 프로시저를 둘 만들지 말고 복사본에서 통합해야 합니다.

Worksheet Change가 변경 범위의 각 셀을 처리하고 빈칸·오류·숫자·문자를 구분하는 설명 도해
Worksheet Change가 변경 범위의 각 셀을 처리하고 빈칸·오류·숫자·문자를 구분하는 설명 도해. 가상 예제를 설명하는 도해이며 실제 앱 실행 결과 화면이 아닙니다.
Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim changed As Range, cell As Range
    Dim previousEvents As Boolean, failure As String
    Set changed = Intersect(Target, Me.Range("B2:B500"))
    If changed Is Nothing Then Exit Sub
    previousEvents = Application.EnableEvents
    On Error GoTo Failed
    Application.EnableEvents = False
    For Each cell In changed.Cells
        If IsError(cell.Value2) Then
            cell.Offset(0, 1).ClearContents
            cell.Interior.ColorIndex = xlColorIndexNone
        ElseIf Len(CStr(cell.Value2)) = 0 Then
            cell.Offset(0, 1).ClearContents
            cell.Interior.ColorIndex = xlColorIndexNone
        Else
            cell.Offset(0, 1).Value = Now
            cell.Offset(0, 1).NumberFormat = "yyyy-mm-dd hh:mm:ss"
            If IsNumeric(cell.Value2) Then
                If CDbl(cell.Value2) < 5 Then
                    cell.Interior.Color = RGB(255, 200, 200)
                Else
                    cell.Interior.ColorIndex = xlColorIndexNone
                End If
            Else
                cell.Interior.ColorIndex = xlColorIndexNone
            End If
        End If
    Next cell
CleanUp:
    Application.EnableEvents = previousEvents
    If Len(failure) > 0 Then MsgBox "Stopped; some cells may already be updated. " & failure, vbExclamation
    Exit Sub
Failed:
    failure = CStr(Err.Number) & ": " & Err.Description
    Resume CleanUp
End Sub

changed.Cells를 순회하므로 B2:B3 두 셀 붙여넣기는 두 행 모두 처리합니다. 코드는 C열 쓰기가 다시 이벤트를 부르지 않도록 처리 구간에서 이벤트를 끄고, 정상·오류 경로가 같은 정리 라벨로 이동하게 합니다. 삭제 입력과 오류값은 남아 있던 시각과 채우기색을 지웁니다.

같은 입력으로 단일 수정·붙여넣기·삭제 대조

붙여넣기·삭제·문자 N/A·오류값·범위 밖·수식 재계산의 이벤트 기대 동작을 비교하는 설명 도해
붙여넣기·삭제·문자 N/A·오류값·범위 밖·수식 재계산의 이벤트 기대 동작을 비교하는 설명 도해. 가상 예제를 설명하는 도해이며 실제 앱 실행 결과 화면이 아닙니다.
입력 또는 동작 C열 기대 결과 B열 기대 결과
B2를 10에서 12로 수정 C2에 실행 당시 시각 채우기 없음
B3를 3에서 2로 수정 C3에 실행 당시 시각 RGB(255,200,200)
B2:B3에 12와 2를 함께 붙여넣기 C2와 C3 모두 갱신 B2 없음, B3 빨강
B2 내용 삭제 C2도 빈칸 채우기 없음
B3에 N/A 입력 C3 시각 갱신 채우기 없음
A2만 수정 C2 변경 없음 B2 변경 없음

시각은 Now로 얻으므로 특정 날짜나 초가 합격 값은 아닙니다. 실행 당시 PC 시계와 대응하는지 확인하고, 두 셀을 빨리 처리하면 같은 초가 기록될 수도 있습니다. 시트에 조건부 서식이 있으면 직접 설정한 색이 화면에 그대로 보이지 않을 수 있으므로 처음 검산할 때는 별도 서식 없는 복사본을 사용합니다.

첨부와 본문의 코드는 같으며 위 표는 실행 후 대조할 기대 동작입니다. Excel/VBA에서 실제 이벤트 실행을 확인한 기록은 아직 없습니다. 코드의 정적 검토만으로 모든 Excel 환경의 실행 성공을 보장하지 않습니다.

입력 검증과 기록을 구분하는 이유

IsNumeric은 이 예제에서 색상 분기에만 쓰입니다. 음수나 숫자처럼 읽히는 텍스트를 업무상 유효한 재고로 승인하지 않습니다. 수량 범위와 정수 여부는 별도 데이터 유효성 검사나 입력 검증 규칙으로 결정하세요. 오류 셀에서는 CDbl을 호출하지 않도록 먼저 IsError로 분리합니다.

5 이상일 때의 xlColorIndexNone은 이전 회색을 복원하는 명령이 아니라 채우기색을 제거하는 명령입니다. 원래 색상이 의미를 가진 시트에는 그대로 적용하지 말고 조건부 서식 방식이나 원래 서식 보관 정책부터 정해야 합니다.

반응이 없거나 중간에 멈출 때

먼저 매크로 사용 형식인지, 코드가 정확한 시트 개체 모듈에 있는지, 수정 범위가 B2:B500인지 확인합니다. 그다음 VBA 직접 실행 창에서 ?Application.EnableEvents로 이벤트 켜짐 여부를 확인합니다. 이 연습 때문에 False로 남았다고 확인했을 때만 Application.EnableEvents = True로 복원합니다.

실행 도중 오류가 나면 이미 앞에서 처리한 셀까지 자동 롤백하지 않습니다. 안내 메시지를 읽고 복사본과 비교하여 부분 변경을 확인한 뒤 입력을 다시 적용합니다. 단순히 VBA 편집기를 닫았다는 이유만으로 이벤트가 반드시 꺼졌다고 단정하지 않습니다.

이벤트 적용 범위의 근거

Microsoft Worksheet.Change 문서에서 API 범위를 확인할 수 있습니다. 변경 범위가 여러 셀일 수 있고 재계산은 다른 이벤트라는 범위를 확인할 수 있습니다. 입력을 막는 폼이 필요한 경우 VBA 입력 검증으로 이어집니다.

Worksheet.Change의 변경 범위는 여러 셀일 수 있으며 재계산은 이 이벤트 대상이 아닙니다.

출처 원문 수집일: S1 2026-09-23.

작성자 소개