VBA 에서 .Value가 필요한 경우
1. 문제
아래와 같이 지출 내역이 있을 때
구분이 몇 가지 있는지 추출하려면 아래와 같이 데이터 탭의 '중복된 항목 제거'를 하는 것이 간결하지만
VBA에서 Dictionary를 이용해 중복된 것은 하나만 추출하는 것을 해보겠습니다.
'중복된 항목 제거'를 하려면
먼저 구분을 다른 범위에 복사해서 붙여넣고
데이터 탭을 선택한 후 '데이터 도구 그룹'의 '중복된 항목 제거' 명령을 누르고,
중복된 항목 제거 기준이 '구분'으로 되어 있으므로,
확인 버튼을 누르면 됩니다.
그러면 "중복 값 3개가 발견되어 제거되었다"고 합니다.
2. 성공 - Range 다음에 .Value를 붙인 경우
VBA에서 중복값을 제거할 때는 여러 가지 방법이 있을 수 있지만
Dictionary를 이용하는 것이 제일 편합니다.
개발도구 탭에서 Visual Basic을 눌러 VB Editor로 들어갑니다.
그리고, '사용자 정의 폼' 콤보 상자 버튼을 눌러 펼친 후 모듈을 눌러 모듈을 추가합니다.
그리고, 오른쪽 코드 창ㄷ에 아래 코드를 복사해서 붙입니다.
Sub 중복값제거()
Dim c As Range
Dim dicA As Object
Dim n As Long
Dim key As Variant
Set dicA = CreateObject("Scripting.Dictionary")
n = 0
For Each c In Range("B1:B" & Range("b1").End(xlDown).Row)
If Not dicA.exists(c.Value) Then
dicA.Add c.Value, n
n = 1
End If
Next
Range("g1").Select
For Each key In dicA.keys
Selection = key
Selection.Offset(1, 0).Select
Next
End Sub
그리고, 실행 메뉴의 실행을 누르거나 F5키 또는 '매크로 실행' 아이콘을 누르고
파일에서 '엑셀로 돌아가기' 메뉴를 누르거나, '엑셀 보기' 아이콘을 눌러 엑셀로 돌아가면
F열과 같은 값이 G열에 추가된 것이 보입니다.
3. 실패 - Range 다음에 .Value를 붙이지 않은 경우
VB Editor를 수정한 후 아래 코드를 복사해서 붙여 넣습니다.
Sub 중복값제거2()
Dim c As Range
Dim dicA As Object
Dim n As Long
Dim key As Variant
Set dicA = CreateObject("Scripting.Dictionary")
n = 0
For Each c In Range("B1:B" & Range("b1").End(xlDown).Row)
If Not dicA.exists(c) Then
dicA.Add c, n
n = 1
End If
Next
Range("g1").Select
For Each key In dicA.keys
Selection = key
Selection.Offset(1, 0).Select
Next
End Sub
차이점은 C.Value를 C로 .value를 제거한 것입니다.
그리고 실행 한 후 엑셀로 돌아가면 '유류비'가 제거되지 않습니다.
If Not dicA.exists(c) Then의 왼쪽 기둥을 마우스로 클릭해서 중단점을 설정한 후 실행하면
그 줄에서 실행이 멈추는데, 한번 더 실행(▶) 아이콘을 눌러 실행한 후
직접 실행 창에서 ? c 라고 입력하고 엔터 키를 눌러도 유류비 지출이라고 표시되고,
? c.value라고 입력한 후 엔터키를 눌러도 값을 같은데,
Dictionary에서 사용할 때는 c가 아니라 c.value라고 value(값)이라는 것을 명확히 해야 합니다.
4. 성공 - Range 다음에 .Value를 붙이지 않아도 되는 경우
아래 코드를 VBA 코드 창에 붙여 넣고 실행하면
Sub 중복값제거3()
Dim c As Range
Range("g1").Select
For Each c In Range("B1:B" & Range("b1").End(xlDown).Row)
If Application.WorksheetFunction.CountIf(Range("b1:b" & c.Row), c) = 1 Then
Selection = c
Selection.Offset(1, 0).Select
End If
Next
End Sub
.Value를 붙이지 않았는데도 문제 없이 잘 작동합니다.
그야말로 경우에 따라 다르네요.
Range만 썼을 때 원하는 결과가 나오지 않는다면 .value를 붙이는 것을 잊지 말아야 하겠습니다.
이제 엑셀로 돌아간 후 파일 - 다른 이름으로 저장 메뉴를 선택한 후
파일 형식을 '매크로 포함 통합 문서(*.xlsm)으로 저장합니다.