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

[기초방] VBA 100제 #5 [ 영역의 끝찾기 ]

by 일등미노왕국 2023. 1. 2.

 

이번 문제를 풀기전에 End속성값의 상수에 대해서 알아보겠다

 

end(1) -> 기준점에서 공백 전까지의 왼쪽 끝

end(2) -> 기준점에서 공백 전까지의 오른쪽 끝

end(3) -> 기준점에서 공백 전까지의 위쪽 끝

end(4) -> 기준점에서 공백 전까지의 아래쪽 끝

 

문제1번은 공백이 없기 때문에 상수조합만 불려오면 쉽게 풀린다. 

단 0 값에 대해서 end의 상수값에 0이 없기 때문에 0값일 때 어떻게 처리하냐가 문제1번의 풀이이다.

 

Function find_end(rngA As Range, a&, b&)                 '= find_end 함수 rngA는 range타입 / a, b는 long 타입

    Dim rngR As Range

        If a = 0 Then                                    '= 앞에 상수값이 0 이면
           Set rngR = rngA.End(b)                        '= rngR 설정을 rngA.End(b)
           
        ElseIf b = 0 Then                                '= 뒤의 상수값이 0 이면
           Set rngR = rngA.End(a)                        '= rngR 설정을 rngA.End(a)
           
        Else                                             '= 상수값이 0이 아니면
           Set rngR = rngA.End(a).End(b)                 '= rngR 설정을 rngA.End(a).end(b)로 해라
           
        End If
        
        find_end = rngR.Value                            '= rngR값을 find_end로 값을 넘겨라
     
End Function

 

문제2번은 보는것처럼 공백이 많다...

이런 상황에서는 end속성을 이용한 값 찾기가 쉽지않다.

그래서 specialCells(4) -> 영역의 공백부분  / 로 공백을 모두 잡은 후 무의미한 X로 다 채운 후 end속성값으로 값을 찍어내면된다.

 

단, 여기서 마지막 복병인 문제2번을 시계방향으로 회전할 시 상수값 (0,1) 은 4가 아닌 영역의 끝인 X값을 가져오게 된다.

 

해서 이 이슈에 대해서 처리를 해줘야 하는데 그 스위치 역할을 하는게 Bln이다.

X값이 나오면 공백을 채우지 않는 문제1번처럼 풀어야 한다.

문제1번과 문제2번을 구분짓는 방법이  Bln값의 False와 True 이기 때문에 매개 변수의 값 Bln을 False로 넘겨서 다시한번 함수를 호출하게 된다. 

 

그러면 

 

마지막 결과값이 X 나올테고, 거기서 함수를 호출하여 원하는 값인 4를 가져오게 된다.

 Do Until rngx = ""   '= 상수값이 없을 때까지 반복해라                                               
 
        rngx(1, 3) = end_cells(rngA, rngx.Value, rngx.Next.Value, bln)    
       '= end_cells을 함수를 호출하는데 bln 값은 true이다.
        
        If rngx(1, 3) = "X" Then rngx = end_cells(rngA, rngx.Value, rngx.Next.Value, bln = False)
       '= 혹여나 끝값이 X이면
       '= 즉, 공백이면 end_cells함수를 다시 호출하는데 매개변수중 bln 값을 False로 해라
       
        Set rngx = rngx.Offset(1)
        
    Loop

 

 

더보기
Option Explicit
Sub 문제1()

    Dim rngx As Range: Set rngx = [o7]                                   '= 상수 값에 따른 결과값을 추출하기 위한 변수
    Dim rngA As Range: Set rngA = [j14]                                  '= 영역의 중간인 100값의 위치
    Dim bln As Boolean                                                   '= Bln 의 초기값은 False 이다 / 문제1을 표현
    
    Do Until rngx = ""                                                   '= 상수값이 없을 때까지 반복해라
        rngx(1, 3) = end_cells(rngA, rngx.Value, rngx.Next.Value, bln)   '= 결과값을 얻기 위해 end_cells 함수를 호출해라
       '= 함수값의 매개변수로 rngA값 / 상수값1 / 상수값2 / bln값을 넘겨라
        Set rngx = rngx.Offset(1)
    Loop

    문제2                                                                 '= [Call 문제2]랑 같은 구문
    'Call 문제2
End Sub
Sub 문제2()

    Dim rngx As Range: Set rngx = [o25]                                   '= 상수 값에 따른 결과값을 추출하기 위한 변수
    Dim rngA As Range: Set rngA = [j33]                                   '= 영역의 중간인 100값의 위치
    Dim bln As Boolean: bln = True                                        '= Bln 값 True / 문제2를 표현
    
    Do Until rngx = ""                                                    '= 상수값이 없을 때까지 반복해라
        rngx(1, 3) = end_cells(rngA, rngx.Value, rngx.Next.Value, bln)    '= end_cells을 함수를 호출하는데 bln 값은 true이다.
        Stop
        If rngx(1, 3) = "X" Then rngx = end_cells(rngA, rngx.Value, rngx.Next.Value, bln = False)
       '= 혹여나 끝값이 X이면 / 공백이면 end_cells함수를 다시 호출하는데 매개변수중 bln 값을 False로 해라
       
        Set rngx = rngx.Offset(1)
        
    Loop
         bln = False
End Sub

Function end_cells(rngA As Range, a&, b&, bln As Boolean)
                '= 매개변수로 rngA는 range타입 / A는 롱타입 / B는 롱타입 / bln은 Boolean
                
    Dim rngT As Range
    
    If bln = False Then                                 '= bln = false이면 / 즉 문제1번이면
    
        end_cells = find_end(rngA, a, b)                '= end_cells함수에서 find_end함수를 호출해라
                                                        '= 매개변수는 rngA값과 상수 a,b
                                                        
    Else                                                '= 문제2는 bln= true / 즉 문제2라면
    
        Set rngT = rngA.CurrentRegion.SpecialCells(4)   '= 문제2의 공백을 모두 rngT로 설정
        
        rngT = "X"                                      '= rngT에 모두 X 표기
        
        end_cells = find_end(rngA, a, b)                '= end_cells함수에서 find_end함수를 호출해라
        
        rngT.ClearContents                              '= 다음을 위해 rngT를 비워라
       
    End If
    
                                                         '= 문제1에서 함수를 호출했으면 문제1로 돌아간다
                                                         '= 문제2에서 함수를 호출했으면 문제2로 돌아간다

End Function

Function find_end(rngA As Range, a&, b&)                 '= find_end 함수 rngA는 range타입 / a, b는 long 타입

    Dim rngR As Range

        If a = 0 Then                                    '= 앞에 상수값이 0 이면
           Set rngR = rngA.End(b)                        '= rngR 설정을 rngA.End(b)
           
        ElseIf b = 0 Then                                '= 뒤의 상수값이 0 이면
           Set rngR = rngA.End(a)                        '= rngR 설정을 rngA.End(a)
           
        Else                                             '= 상수값이 0이 아니면
           Set rngR = rngA.End(a).End(b)                 '= rngR 설정을 rngA.End(a).end(b)로 해라
           
        End If
        
        find_end = rngR.Value                            '= rngR값을 find_end로 값을 넘겨라
     
End Function

 

 

[기초방] VBA 100제 #5 [ 영역의 끝찾기 ].xlsm
0.02MB

 

함수에서 함수의 호출은 앞으로 조건식에서 많이 사용하려고 한다.

지금은 낯설더라고 그 낯설음이 익숙함이 될 수 있도록 양질의 코드를 많이 올리려 한다.

 

2023도 역시 엑사남과 함께

 

Haja Go!! VBA.

댓글