본문 바로가기
질문있어요

[VBA] 이벤트를 통한 업무일지 업데이트

by 일등미노왕국 2023. 8. 31.

이벤트는 자칫 잘못하면 서로가 꼬이기 때문에 Target의 영역과 제한을 컨트럴하지 못하면 이벤트가 

꼬여서 최초에 원하던 모양을 구현하기가 힘들어진다.

 

같은방 크루인 라이언님의 고민을 풀어보는 글을 써보려한다.

 

질문 사항은 이렇다.

1. 각 상태에 따라 셀의 색상이 변경되어야 한다.

2. 주의 마지막은 셀의 상태를 선택시 다음주 월요일로 이월되어야 한다.

 

더보기
Private Sub Worksheet_Activate()
    Application.EnableEvents = True
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)

    Dim rngX As Range: Set rngX = [e7:e60]          '=일반 상태라인
    Dim rngY As Range: Set rngY = [t7:t60]          '=T열 상태라인
    Dim i&
    Dim rngU As Range, rngTemp As Range
    
    
    For i = 1 To 15 Step 3
    
        Set rngTemp = rngX(1, i).Resize(54, 1)
     
        Set rngX = Union(rngX, rngTemp)
    
    Next i
    
    
    Set rngU = Union(rngX, rngY)                    '= 상태라인을 모두 rngU로 영역설정
    
    
        If Intersect(rngU, Target) Is Nothing Then Exit Sub
        
        Application.EnableEvents = False
        
            '= 일반일때의 매개변수의 초기값과 끝열일때의 매개변수를 달리하여 서브 프로시저를 호출
            
            If Intersect(Target, Columns("T")) Is Nothing Then     '= 일반 상태라인을 선택했다면
        
                Call cell_Color(Target)
            Else
                Call cell_Color(Target, 12, -16)                    '= T열 상태라인을 선택했다면
            
            End If
        
        Application.EnableEvents = True

End Sub

Sub cell_Color(Target As Range, Optional i% = 1, Optional j% = 2)

    

    Dim rngX As Range: Set rngX = Union(Target(1, -1).Resize(1, 3), Target(i, j).Resize(1, 2))
    
            Select Case Target.Value

               Case "빈칸"
                   Target.Value = ""
                   rngX.Interior.Color = xlNone

               Case "완료"
                         Target(1, -1).Resize(1, 3).Interior.Color = RGB(255, 255, 0)

               Case "미완료"
                         Target(i, j).Resize(1, 2) = Array(Target(1, -1), Target(1, 0))
                         rngX.Interior.Color = RGB(217, 217, 217)
                   
               Case "진행중"
                         Target(i, j).Resize(1, 2) = Array(Target(1, -1), Target(1, 0))
                         rngX.Interior.Color = RGB(248, 203, 173)

               Case "대기"
                          Target(i, j).Resize(1, 2) = Array(Target(1, -1), Target(1, 0))
                          rngX.Interior.Color = RGB(180, 198, 231)

            End Select
End Sub

코드 진행은 이렇다.

 

메인 프로시저에서는 이벤트를 감지하게 된다. 감지된 영역의 값을 확인해서 주의 마지막이 아니면 target의 위치값을 표시해줄 i,j의 초기값을 각각 1,2로 주어지게 된다. 

만일 주의 마지막이라면 target의 위치값 i,j 값에 각각 12, -16을 넣어주면서 익주 월요일의 값에 들어올 수 있도록 가변적으로 매개변수를 전달하였다..

 

이번 구문은 이게 시작이고 끝이다. 안그럼 불린으로 true / false를 반환하여 구문을 달리하기 때문이다.

매개변수 Optional에 아무값을 넣지 않으면 매개변수를 Null값으로 가져가지만 

 

Sub cell_Color(Target As Range, Optional i% = 1, Optional j% = 2)

이런식으로 Optional값에 아무것도 넣지 않으면 초기값대로 1,2를 반환하는 것이다.

팁을 하나 더 드리면 Optional은 항상 마지막에 넣어야 한다. 안그럼 에러를 뱉어버린다...

 

실제 코드에 많이 활용하기 바란다.

 

그럼 오늘도 맛있는 코드 ~~샥샥

업무일지.xlsm
0.03MB

댓글