본문 바로가기
VBA

[VBA] ArrayList 로 배열 고유값과 중복 횟수 구하기

by 일등미노왕국 2022. 4. 8.

 

https://1stminokingdom.tistory.com/84

 

[VBA] 배열을 정렬해라(feat. 버블정렬)

https://1stminokingdom.tistory.com/83 [VBA] 배열내 중복된 값들을 도출하고 중복값을 구해라 배열 또는 셀의 영역 데이터 중 고유값을 구하고 중복된 값을 구하는 것은 보통 딕셔너리로 구한다. 또는 어레

1stminokingdom.tistory.com

이전 글에는 배열의 고유값을 구한 뒤에 버블정렬을 통한 배열의 정렬 방법을 알아보았다.

버블정렬은 글에서도 서술했듯이 쉽지만 비효율적인 코드이다.

단적으로 정렬을 위해 고유값끼리의 비교를 하기 위해 For문을 순환하게 되는데 For문이 다중 포문이기 때문에 처리 속도가 현저히 떨어진다.

 

본 코드는 ArrayList를 통해 고유값을 구하면서 임시 배열에 키값과 중복횟수를 추가해가면서 코드를 진행하게 된다.

전체 배열을 모두 순환하게 되면 ArrayList를 정렬한 다음 배열로 ArrayList 키값을 한번에 넘겨버린다.

 

ArrayList의 정렬된 키값과 그에 해당하는 Value값을 Application.Vlookup으로 찾은 후 셀에 한번에 뿌리는 코드이다.

 

물론 셀에 뿌린 후 Sort 명령어를 통해 정렬하는 방법도 있지만

셀 기반을 최대한 줄이고 배열과 ArrayList를 사용함으로서 처리 속도의 향상을 가져오는 코드를 진행하였다.

Option Explicit
Sub Haja_배열속_중복횟수()

    Dim Vall: Vall = [g2:g20]             '= 영역을 배열로 담아라
    Dim i&, n&, H&, Vnum&                 '= Vall 순환할 변수 i , 임시 배열에 담을 변수 n
    Dim Vresult(), Vtemp(), V
    
    Dim Al As Object: Set Al = CreateObject("system.collections.arraylist")
                                           '= 어레이리스트 선언
    Vnum = UBound(Vall)                    '= Vnum에 전체 영역의 배열의 갯수를 담아라
    ReDim Vtemp(1 To Vnum, 1 To 2)
    
    Columns("m:n").ClearContents            '= 초기화
    
    For i = LBound(Vall) To UBound(Vall)    '= 배열을 순환해라
        
        If Not Al.contains(Vall(i, 1)) Then '= 어레이리스트에 포함되어 있지 않는다면 
                                            '= 즉, 고유값이면
            
           n = n + 1                        '= 배열의 크기를 +1해라
           Al.Add Vall(i, 1)                '= 어레이리스트에 배열값을 추가해라
           Vtemp(n, 1) = Vall(i, 1)         '= 임시배열에 해당값을 넣고
           Vtemp(n, 2) = 1                  '= 중복횟수는 1로 시작해라
           
        Else                                '= 고유값이 아니면
            
          H = Application.Match(Vall(i, 1), Application.Index(Vtemp, , 1), 0) 
                                            '= 일치값의 위치를 H 에 담아라
          Vtemp(H, 2) = Vtemp(H, 2) + 1     '= 임시배열의 크기를 +1해라
            
        End If
        
    Next i
    
    Al.Sort                                  '= 어레이리스트 정렬
    V = Al.toarray                           '= 어레이리스트의 값을 V에 모두 담아라
    
    ReDim Vresult(1 To Al.Count, 1 To 2)     '= 결과배열 선언
    
    For i = 0 To Al.Count - 1
    
        Vresult(i + 1, 1) = V(i)             '= 어레이리스트의 키값들을 배열에 담아라
        Vresult(i + 1, 2) = Application.VLookup(V(i), Vtemp, 2, 0)
                                             '= 임시배열에서 키값의 중복횟수를 가져와라
        
    Next i
    
    [m2].Resize(n, 2) = Vresult               '= 셀에 출력

End Sub

배열내정렬하기_ArrList(22.04.08).xlsm
0.02MB

댓글