본문 바로가기
VBA/엑사남_기초방

[기초방 [기초방] VBA 100제 #72 [ 조건에 맞는 숫자 반환 및 정렬 ]

by 일등미노왕국 2023. 10. 12.

 

 

영역을 순환하면서 50보다 큰 수를 vtemp 배열에 담아라

or Each rngA In rngAll           
    
        If rngA > 50 And TypeName(Application.Match(rngA, vtemp, 0)) = "Error" Then
                                      
            i = i + 1                
            
            vtemp(i, 1) = rngA        
        
        End If
        
    Next rngA

 

이렇게 하면 vtemp 에 50보다 큰 값들이 모두 쌓이게 되고 / i 변수에는 실제 숫자가 몇개 담겨 있는지 그 갯수가 나온다.

 

자 여기서 가장 핵심구문이다.

반환되는 영역이 11 x 4 이지 여기에 정확하게 50보다 큰수가 몇개 들어갈지는 모른다.

구해보면 11 x 4 = 44개중 실제로 값은 42개만 들어가게 된다.

 

그렇다면 vtemp(43,1) 과 vtemp(44,1) 의 값은 비어 있는 상태이다.

 

이것을 셀에 그냥 반환한다고 하면 

 

[i6].resize(i,1) = vtemp  뭐이런식으로 하면 될것이다.

 

하지만 문제와 같이 구해진 값으로 출력을 해야 하기 때문에 우린 두가지 방법중 하나를 사용하여야 한다.

1. 실제 출력할 영역을 순환하면서 정렬한 배열을 하나씩 꺼내서 출력하는 방법

2. 배열상수를 이용한 한방에 영역에 뿌리는 방법

 

1번같은 경우는 그동안 많이 해온 For each 구문으로 구하면 된다.

 

2번 같은 경우는 기초방 68번에 사용한 ArrayToText를 이용해서 구해진 배열상수로 배열로 뿌려보려 한다.

더보기
Option Explicit

Sub 기초방72()

    Dim rngAll As Range: Set rngAll = [a6].CurrentRegion
    Dim rngA As Range
    Dim vtemp(), rowV, V
    Dim i&
    
    ReDim vtemp(1 To 11 * 4, 1 To 1)  '= 11 x 4 배열로
    
    For Each rngA In rngAll           '= 영역을 순환
    
        If rngA > 50 And TypeName(Application.Match(rngA, vtemp, 0)) = "Error" Then
                                      '= 50보다 크고 현재 배열에 값이 없다면
            i = i + 1                 '= 실제 숫자가 담기는 배열크기 카운팅
            
            vtemp(i, 1) = rngA        '= 해당 숫자를 배열에 담아라
        
        End If
        
    Next rngA

    
    rowV = Application.Sequence(i)     '= 배열 슬라이싱을 위한 rowV 배열
    V = Application.Sort(Application.Index(vtemp, rowV, 1))  '= i 크기만큼 배열 슬라이싱
    
    [n6].Formula2 = "=WRAPROWS(" & Application.ArrayToText(V, 1) & ",4," & """없음""" & ")"
    
    '= Application.ArrayToText(V, 1) 로 구해진 배열 상수를 4열씩 끊어서 출력..
    '= 빈공간은 [없음]으로 표기
    
    
End Sub

 

배열상수를 사용하며면 Formula2를 사용해야 한다.

 

 

 

함수로 설명을 추가한다.

 

MAP(A6:G30, (LAMBDA(A, IF(A > 50, A, #N/A))))

 

1. MAP 함수로 영역을 람다 함수로 하나씩 인자를 넘겨서 그 값이 50보다 크면 A를 반환하고 안그럼 #N/A를 반환한다.

2. 앞서 #N/A를 반환한 이유는 TOCOL 함수는 배열을 하나의 열로 반환하는 함수인데, 빈칸을 무시하는 옵션도 있지만 여기서는 해당되지 않아서 에러를 강제로 반환받고 그 에러를 무시해서 실제 TOCOL로 출력된 배열에는 50보다 큰수만 자리잡게 된다.

3. 이렇게 구해진 값을 유니크 함수와 SORT함수로 중복제거 및 정렬을 한후 

4. IFNA (=IFERROR) 로 에러를 "없음"으로  표기하기 하게 되는것이다.

 

 

그럼 ...

 

기초방72.xlsm
0.02MB

 

댓글