이 문제를 낸 의도는 거추장스런 For문 또는 Find문을 사용하는 것보단 함수식을 사용해서 빠르고 간편하게 사용할 수 있다는 생각에서 문제를 내었지만, 아직까진 속도에서 딕셔너리를 넘길 수 없었다. 이번 딕셔너리처럼 Value값이 배열로 담을 수 있다면 속도는 더 짧아질것이다.
본 문제를 쉽게 접근하게 되면 이렇게 피를 보게 된다.
더보기
Option Explicit
Sub 기초방61()
Dim rngAll As Range: Set rngAll = Range([a2], [a2].End(4))
Dim Vall, VA, vDict
Dim T!, i&, sKey$
Dim Vtemp()
Dim Dict As Object: Set Dict = CreateObject("Scripting.Dictionary")
rngAll.Columns("c:e").ClearContents '= 초기화
T = Timer '= 시간측정
rngAll.Columns(3) = "X" '= 함수구문
rngAll.Columns(4) = "=IFERROR(INDEX(사진정보!$B$2:$B$14212,MATCH(환자정보!B2,사진정보!$A$2:$A$14212,0)),"""")"
rngAll.Columns(5) = "=IFERROR(INDEX(사진정보!$c$2:$c$14212,MATCH(환자정보!B2,사진정보!$A$2:$A$14212,0)),"""")"
rngAll.CurrentRegion.Copy
rngAll.CurrentRegion.PasteSpecial xlPasteValues '= 값으로 붙혀넣기
rngAll.Columns(4).SpecialCells(2, 1).Offset(0, -1) = "O" '= 문자가 있는 곳에 O표시
Application.CutCopyMode = False
MsgBox "함수시간 : " & Format(Timer - T, "#0.00") & " 초가 소요됨"
rngAll.Columns("c:e").ClearContents
T = Timer
Vall = Range(Sheets(2).[a2], Sheets(2).[c2].End(4)) '= 딕셔너리 구문
i = 1
For Each VA In Application.Index(Vall, , 1)
vDict = Array("O", Vall(i, 2), Vall(i, 3))
Dict.Add Format(VA, "00000000"), vDict
i = i + 1
Next VA
Vall = Range(Sheets(1).[b2], [b2].End(4))
ReDim Vtemp(1 To UBound(Vall, 1), 1 To 3)
i = 1
For Each VA In Vall
sKey = Format(VA, "00000000")
If Dict.exists(sKey) Then
vDict = Dict(sKey)
Vtemp(i, 1) = vDict(0)
Vtemp(i, 2) = vDict(1)
Vtemp(i, 3) = vDict(2)
Else
Vtemp(i, 1) = "X"
End If
i = i + 1
Next VA
[c2].Resize(UBound(Vtemp, 1), 3) = Vtemp
MsgBox "딕셔너리시간 : " & Format(Timer - T, "#0.00") & " 초가 소요됨"
End Sub
함수식의 코드는 단순한 index + Match 함수를 사용하여 최소한의 반복문도 피하였다.
딕셔너리의 경우 item들을 배열에 담아 딕셔너리에 추가하였다
중간에
If Dict.exists(sKey) Then
vDict = Dict(sKey)
Vtemp(i, 1) = vDict(0)
Vtemp(i, 2) = vDict(1)
Vtemp(i, 3) = vDict(2)
Else
Vtemp(i, 1) = "X"
End If
vDict = Dict(sKey)와 Dict(sKey)(0), Dict(sKey)(1), Dict(sKey)(2)의 속도차이에서 본인이 언급을 하였고, 같은 크루인 준빠님이 다음과 같이 정리를 하였다.
우리는 vDict에 뭐가 담겨 있는지도 알고 Dict(sKey)(0), Dict(sKey)(1), Dict(sKey)(2) 여기에 각각 뭐가 담겨있는지도 알지만 컴퓨터는 vDict 는 명확하게 뭐가 담겨있는지 알지만 Dict(sKey)(0), Dict(sKey)(1), Dict(sKey)(2)는 각각을 연산하면서 값들을 도출하게 됨으로 가급적 값들을 변수에 담아서 구문을 해결하는 것이 참 개발자의 길이다.
다음은 준빠님이 이러한 현상에 대해서 간단한 예시를 든 내용이다.
'VBA > 엑사남_기초방' 카테고리의 다른 글
[기초방] VBA 100제 #63 [ X축, Y축 최대 최소값 구하기 ] (0) | 2023.09.19 |
---|---|
[기초방] VBA 100제 #62 [ 홀수_짝수차 구별하기 ] (0) | 2023.09.18 |
[기초방] VBA 100제 #60 [ 불일치 / 일치 같은 영역 색칠하기 ] (0) | 2023.09.15 |
[기초방] VBA 100제 #59 [ 불일치 영역 색칠하기 ] (0) | 2023.08.01 |
[기초방] VBA 100제 #58 [ 불일치 영역 색칠하기 ] (0) | 2023.07.11 |
댓글