2020.04.23 : 셀의 내용을 삭제한 경우도 횟수에 상관없이 이전 단계로 돌아가기 가능한 전체 명령문을 업데이트 하였습니다. 자세한 내용은 3번째 항목을 확인해주세요.
2020.04.23 추가 : 댓글로 문의주신 분이 많아, 완성파일 시트를 두개로 분리하였습니다. 완성파일을 다운받으시면 2개의 시트가 있습니다. [완성예제#1] 시트에는 데이터 추가/삭제시 모두 실시간으로 업데이트되는 명령문이 입력되어 있습니다. 따라서, 데이터 삭제 후 이전단계로 돌아가기가 불가능하다는 단점이 있습니다. [완성예제#2] 시트는 '데이터 추가' 시에만 실시간으로 업데이트 됩니다. 데이터 삭제후에는 횟수에 상관없이 이전단계로 돌아갈 수가 있습니다.
강의 설명
실무자가 엑셀에서 가장 많이 사용하는 기능 중 하나, 바로 '피벗테이블' 입니다. 피벗테이블은 엑셀에서 아주 훌륭한 도구이지만, 원본데이터 업데이트가 실시간으로 안 되는 문제가 있는데요. 그러다보니 주기적으로 데이터가 추가되는 자료에서, 매번 '새로고침' 작업을 해줘야 하는 번거로움이 있었습니다.
피벗테이블은 '새로고침'이 되어야만 자료가 업데이트 됩니다.
피벗테이블 자동 업데이트를 쉽게 구현할 수 있는 방법, 어디 없을까요?
간단한 명령문 복사/붙여넣기로 피벗테이블 자동 업데이트를 구현할 수 있습니다.
이번 강의에서는 명령문 복사/붙여넣기만으로 할 수 있는 각 상황별 피벗테이블 자동 업데이트 방법을 3단계로 나눠서 자세히 알아봅니다.
매크로를 사용하여 피벗테이블 자동 업데이트를 구현할 경우 한가지 문제점이 있습니다. 바로 매크로가 동작된 시점부터 '이전 단계로 돌아가기' 작업이 모두 초기화 된다는 점인데요.
이는 새로운 자료를 추가할 때는 별 문제되지 않지만, 자료를 잘못 삭제하여 이전단계로 돌아가야 할 경우에는 큰 문제가 될 수 있습니다.
이 문제는 명령문을 약간만 변형하면 쉽게 해결할 수 있습니다. 아래 코드를 복사하여 각 명령문에 붙여넣기하면, 데이터가 삭제되어도 이전 단계로 돌아갈 수가 있게 됩니다. (아래 명령문은 통채로 복사해서 시트모듈에 그대로 붙여넣기 합니다.)
단, 이전단계로 돌아가기 시 돌아가는 순서는 삭제된 순서와 동일해야 합니다. 즉, 이전단계로 돌아가는 도중 키보드나 마우스로 다른 셀을 클릭하거나 이동하게 되면 이전단계로 돌아가기 기록이 초기화되는 것에 주의합니다.
' nVal : Change Event로 받아온 셀에 입력된 최종 값' oVal : Selection Change Event로 받아온 최종 수정 전 입력된 값' tVal : 삭제된 값이 원복된 것인지 확인하기 위한 임시 값' DeleteFlag : 셀이 삭제 될 경우 발동되는 TriggerDim nVal As Variant: Dim oVal As Variant
Dim DeleteFlag AsBoolean: Dim tVal As Variant
PrivateSub Worksheet_SelectionChange(ByVal Target As Range)
oVal = Target.ValueEndSubPrivateSub Worksheet_Change(ByVal Target As Range)Dim pvTbl As PivotTable
' 오류가 발생할 경우 EH로 넘어가면서 명령문이 바로 종료됩니다.OnErrorGoTo EH:
nVal = Target.Value' Target이 비어있을 경우 오류가 발생하면서 명령문 종료 (셀 완전 삭제시)If nVal <>""Then' DeleteFlag (셀 삭제여부 Trigger) 가 False 이거나 빈칸일 경우 피벗테이블 업데이트를 진행합니다.If DeleteFlag =FalseOrIsEmpty(DeleteFlag)ThenIf oVal <> nVal Then
Application.EnableEvents=FalseForEach pvTbl InMe.PivotTables
pvTbl.RefreshTableNext
Application.EnableEvents=TrueEndIfElseSelectCaseTrue' DeleteFlag가 True이고 새로입력된값 = 임시값 이면 PassCase nVal = tVal
' DeleteFlag가 True이고 임시값 = 이전값일 경우 삭제된 값이 복원된 상태이므로' 임시값을 새로운 값으로 치환하고 PassCase oVal = tVal
tVal = nVal
' 위 두가지 상황이 아닐 경우 새로 입력된경우이므로 피벗테이블 업데이트 후 DeleteFlag 를 False로 리턴CaseElse
Application.EnableEvents=FalseForEach pvTbl InMe.PivotTables
pvTbl.RefreshTableNext
Application.EnableEvents=True
DeleteFlag =FalseEndSelectEndIfElseIf DeleteFlag =FalseOrIsEmpty(DeleteFlag)Then
DeleteFlag =True
tVal = oVal
Else
tVal = oVal
EndIfEndIfExitSub
EH:
EndSub
단, 위의 명령문을 사용할 경우 주의사항이 있습니다.
'셀을 완전히 삭제' 하는 작업(=우클릭하여 삭제 또는 단축키 Ctrl + - 키)은 횟수에 상관없이 이전단계로 돌아가기가 가능합니다.
셀을 완전히 삭제하는 작업은 횟수에 상관없이 이전단계로 돌아가기가 가능합니다.
하지만, '셀 안의 내용만 지우는 작업'(=← 또는 Delete 키)은 한번만 이전단계로 돌아가기가 가능하다는 점을 주의해야 합니다. 그 이유는, 셀의 내용만 지운 작업을 이전단계로 돌아가기 할 경우, 셀의 내용이 '입력' 되면서 매크로가 실행됩니다. 따라서 피벗테이블 자동 업데이트 매크로가 돌게되고, 이전의 모든 작업이 초기화됩니다.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
oVal = Target.Value
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
Dim pvTbl As PivotTable
' 오류가 발생할 경우 EH로 넘어가면서 명령문이 바로 종료됩니다.
On Error GoTo EH:
' Target이 비어있을 경우 오류가 발생하면서 명령문 종료 (셀 완전 삭제시)
If Target.Value "" Then
' Target의 값이 빈칸("")일 경우 IF문 통과 못하고 명령문 종료 (셀 내용만 지울경우)
' 이전값과 새로운값을 비교하여, 이전값이 빈칸이 아니고 (삭제한 값이 리턴됨)
' 그리고 현재 값이 empty(기존에 값이 삭제된 경우)가 아닐때에만 명령문 실행
If Not (IsEmpty(nVal) And oVal "") Then
Application.EnableEvents = False
For Each pvTbl In Me.PivotTables
pvTbl.RefreshTable
Next
Application.EnableEvents = True
End If
End If
Exit Sub
EH:
End Sub
이걸 다 긁어서 넣으라는 걸까요? 다 넣으니깐 안되는 것 같아서요 ㅠ
오빠두엑셀작성자2020.04.23 13:31
안녕하세요?^^ 네 맞습니다.
1. 피벗테이블이 있는 시트개체를 더블클릭합니다.
2. 안에 명령문이 있다면 모두 지워주세요.
3. 아래 명령문을 복사하여 붙여넣기합니다.
세번째로 알려드린 셀 내용 삭제시의 이전단계로 돌아가기 문제 해결을 위한 코드는 '원본데이터와 피벗테이블'이 같은 시트에 있을경우에만 적용하시면 됩니다.
원본데이터와 피벗테이블이 다른 시트에 있을 경우는 두번째 방법으로만 적용하시면 되겠습니다.^^
답변이 도움이 되셨길 바랍니다.
감사합니다.
' nVal : Change Event로 받아온 셀에 입력된 최종 값
' oVal : Selection Change Event로 받아온 최종 수정 전 입력된 값
' tVal : 삭제된 값이 원복된 것인지 확인하기 위한 임시 값
' DeleteFlag : 셀이 삭제 될 경우 발동되는 Trigger
Dim nVal As Variant: Dim oVal As Variant
Dim DeleteFlag As Boolean: Dim tVal As Variant
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
oVal = Target.Value
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
Dim pvTbl As PivotTable
' 오류가 발생할 경우 EH로 넘어가면서 명령문이 바로 종료됩니다.
On Error GoTo EH:
nVal = Target.Value
' Target이 비어있을 경우 오류가 발생하면서 명령문 종료 (셀 완전 삭제시)
If nVal "" Then
' DeleteFlag (셀 삭제여부 Trigger) 가 False 이거나 빈칸일 경우 피벗테이블 업데이트를 진행합니다.
If DeleteFlag = False Or IsEmpty(DeleteFlag) Then
If oVal nVal Then
Application.EnableEvents = False
For Each pvTbl In Me.PivotTables
pvTbl.RefreshTable
Next
Application.EnableEvents = True
End If
Else
Select Case True
' DeleteFlag가 True이고 새로입력된값 = 임시값 이면 Pass
Case nVal = tVal
' DeleteFlag가 True이고 임시값 = 이전값일 경우 삭제된 값이 복원된 상태이므로
' 임시값을 새로운 값으로 치환하고 Pass
Case oVal = tVal
tVal = nVal
' 위 두가지 상황이 아닐 경우 새로 입력된경우이므로 피벗테이블 업데이트 후 DeleteFlag 를 False로 리턴
Case Else
Application.EnableEvents = False
For Each pvTbl In Me.PivotTables
pvTbl.RefreshTable
Next
Application.EnableEvents = True
DeleteFlag = False
End Select
End If
Else
If DeleteFlag = False Or IsEmpty(DeleteFlag) Then
DeleteFlag = True
tVal = oVal
Else
tVal = oVal
End If
End If
안녕하세요?^^
이전에 올려드린 코드에 문제가 있어서, 어제 저녁에 코드를 새로 수정하였습니다.
완성파일안에 시트를 2개로 나눠 다시 올려드렸으니 확인해보시겠어요?
#2 시트안의 명령문을 확인해보시면 될 듯 합니다.
답변이 도움이 되셨길 바랍니다.
감사합니다.
화이트러쉬안2021.12.24 14:07
강의에서 사용한 명령문과 많이 다른 것 같은데..이걸 그대로 복붙하는게 맞나요?
오빠두엑셀작성자2021.12.26 09:47
화이트러쉬안님 안녕하세요?
네 그대로 사용하셔도 좋습니다. 게시글 3번째 섹션 명령문을 복사/붙여넣기 후 테스트해보시거나, 완성파일을 참고해보세요.
뀨우2022.09.26 01:46
저는 이대로 했는데 전혀 반응이 없어요...ㅠㅠ
Jeba2020.04.24 02:20
Some one please translate me in English. English translation mode is not working in this page.
오빠두엑셀작성자2020.04.24 15:41
Hi, Jeba :)
I recommend you to use Chrome and enable the auto-translation function(it's built-in) to see the english version of this page ! :)
Hopefully it helps.
Thanks
MACHO2020.04.26 01:35
완성파일에 #1시트 데이터를 기초로 다른 시트에서 업데이트 하기를 만들었을때, 자동 업데이트가 한번만 실행되고 난 후 다시는 자동업데이트가 안되는 에러가 있습니다. 다른 시트에서 업데이트 할때도 계속하여 동작이 되는 방법은 없을까요?
오빠두엑셀작성자2020.04.26 23:44
안녕하세요?^^
예를 들어, [시트1] 에 원본데이터가 있고 [시트2]에 피벗테이블이 있을 경우,
시트1의 WorkSheet_Change 이벤트로 아래 명령문을 추가해보시겠어요?
Dim pvTbl As PivotTable
Application.EnableEvents = False
For Each pvTbl In WorkSheets("시트2").PivotTables
pvTbl.RefreshTable
Next
Application.EnableEvents = True
위 WorkSheets("시트2") 를 시트명에 맞춰 변경하시면 됩니다.^^
답변이 도움이 되셨길 바랍니다.
감사합니다.
박용준2020.04.26 01:43
좋은 강의 정말 감사합니다.
질문이 있는데요...?
다은시트에 있는 피벗에 WorkSheet Activate 아닌 Change로 이벤트를 적용해도 실시간으로 적용이 되나요???
오빠두엑셀작성자2020.04.26 23:45
안녕하세요?^^
아래 답변을 참고해보시겠어요?
https://www.oppadu.com/%ec%97%91%ec%85%80-%ed%94%bc%eb%b2%97%ed%85%8c%ec%9d%b4%eb%b8%94-%ec%9e%90%eb%8f%99-%ec%97%85%eb%8d%b0%ec%9d%b4%ed%8a%b8/#comment-2906
감사합니다.
엑셀배우자2020.04.28 13:46
좋은 강의 감사합니다! 원하던 기능이었어요!
주난이2020.05.09 09:45
"피벗테이블분석"메뉴는 엑셀버전에 따라 다르나요? ㅇ안보이는데?????
오빠두엑셀작성자2020.05.09 19:09
안녕하세요?^^
엑셀 버전에 따라 화면구성이 다를 수 있습니다.
예를들어 엑셀 2010을 사용중이실 경우, 피벗테이블 선택 시, '옵션' 과 '디자인'으로 표시되는데요. 화면표시형식만 다를 뿐 사용방법은 동일합니다.
답변이 도움이 되셨길 바랍니다.
감사합니다.
SEANPAUL2020.05.09 10:02
몇번을 돌려봐도 감탄이 절로 나옵니다. 감사합니다.
콘투리맨2020.05.11 08:59
항상 너무 감사하게 잘보고있습니다 이번 강의랑은 번외적인 질문인데 피벗테이블 하면서 항상 너무 궁금했던내용이 값항목에 들어가는 내용이 20~30개가 넘어갈때 해당 카테고리별로 개수가 아닌 합계로 한번에 변경할 수 있는 방법이 있을까요..??ㅠㅠ
오빠두엑셀작성자2020.05.12 04:46
안녕하세요?^^
엑셀은 기본적으로 '텍스트' 값은 필드합계로 '개수'를 구합니다. 해결책은 2가지인데요.
각 필드의 '빈칸'을 모두 숫자 '0'으로 변경하시면 필드요약이 합계로 출력됩니다.
또는 VBA를 이용하셔야 합니다.^^
답변이 도움이 되셨길 바랍니다.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
oVal = Target.Value
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
Dim pvTbl As PivotTable
' 오류가 발생할 경우 EH로 넘어가면서 명령문이 바로 종료됩니다.
On Error GoTo EH:
' Target이 비어있을 경우 오류가 발생하면서 명령문 종료 (셀 완전 삭제시)
If Target.Value "" Then
' Target의 값이 빈칸("")일 경우 IF문 통과 못하고 명령문 종료 (셀 내용만 지울경우)
' 이전값과 새로운값을 비교하여, 이전값이 빈칸이 아니고 (삭제한 값이 리턴됨)
' 그리고 현재 값이 empty(기존에 값이 삭제된 경우)가 아닐때에만 명령문 실행
If Not (IsEmpty(nVal) And oVal "") Then
Application.EnableEvents = False
For Each pvTbl In Me.PivotTables
pvTbl.RefreshTable
Next
Application.EnableEvents = True
End If
End If
Exit Sub
EH:
End Sub
이걸 다 긁어서 넣으라는 걸까요? 다 넣으니깐 안되는 것 같아서요 ㅠ
2. 안에 명령문이 있다면 모두 지워주세요.
3. 아래 명령문을 복사하여 붙여넣기합니다.
세번째로 알려드린 셀 내용 삭제시의 이전단계로 돌아가기 문제 해결을 위한 코드는 '원본데이터와 피벗테이블'이 같은 시트에 있을경우에만 적용하시면 됩니다.
원본데이터와 피벗테이블이 다른 시트에 있을 경우는 두번째 방법으로만 적용하시면 되겠습니다.^^
답변이 도움이 되셨길 바랍니다.
감사합니다.
이전에 올려드린 코드에 문제가 있어서, 어제 저녁에 코드를 새로 수정하였습니다.
완성파일안에 시트를 2개로 나눠 다시 올려드렸으니 확인해보시겠어요?
#2 시트안의 명령문을 확인해보시면 될 듯 합니다.
답변이 도움이 되셨길 바랍니다.
감사합니다.
네 그대로 사용하셔도 좋습니다. 게시글 3번째 섹션 명령문을 복사/붙여넣기 후 테스트해보시거나, 완성파일을 참고해보세요.
I recommend you to use Chrome and enable the auto-translation function(it's built-in) to see the english version of this page ! :)
Hopefully it helps.
Thanks
예를 들어, [시트1] 에 원본데이터가 있고 [시트2]에 피벗테이블이 있을 경우,
시트1의 WorkSheet_Change 이벤트로 아래 명령문을 추가해보시겠어요?
Dim pvTbl As PivotTable
Application.EnableEvents = False
For Each pvTbl In WorkSheets("시트2").PivotTables
pvTbl.RefreshTable
Next
Application.EnableEvents = True
위 WorkSheets("시트2") 를 시트명에 맞춰 변경하시면 됩니다.^^
답변이 도움이 되셨길 바랍니다.
감사합니다.
질문이 있는데요...?
다은시트에 있는 피벗에 WorkSheet Activate 아닌 Change로 이벤트를 적용해도 실시간으로 적용이 되나요???
아래 답변을 참고해보시겠어요?
https://www.oppadu.com/%ec%97%91%ec%85%80-%ed%94%bc%eb%b2%97%ed%85%8c%ec%9d%b4%eb%b8%94-%ec%9e%90%eb%8f%99-%ec%97%85%eb%8d%b0%ec%9d%b4%ed%8a%b8/#comment-2906
감사합니다.
엑셀 버전에 따라 화면구성이 다를 수 있습니다.
예를들어 엑셀 2010을 사용중이실 경우, 피벗테이블 선택 시, '옵션' 과 '디자인'으로 표시되는데요. 화면표시형식만 다를 뿐 사용방법은 동일합니다.
답변이 도움이 되셨길 바랍니다.
감사합니다.
엑셀은 기본적으로 '텍스트' 값은 필드합계로 '개수'를 구합니다. 해결책은 2가지인데요.
각 필드의 '빈칸'을 모두 숫자 '0'으로 변경하시면 필드요약이 합계로 출력됩니다.
또는 VBA를 이용하셔야 합니다.^^
답변이 도움이 되셨길 바랍니다.