이번 문제를 풀기전에 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
함수에서 함수의 호출은 앞으로 조건식에서 많이 사용하려고 한다.
지금은 낯설더라고 그 낯설음이 익숙함이 될 수 있도록 양질의 코드를 많이 올리려 한다.
2023도 역시 엑사남과 함께
Haja Go!! VBA.
'VBA > 엑사남_기초방' 카테고리의 다른 글
[기초방] VBA 100제 #9 [ 데이터 영역 선택하기 ] (0) | 2023.01.05 |
---|---|
[기초방] VBA 100제 #7 [ 행렬변환 ] (2) | 2023.01.04 |
[기초방] VBA 100제 #8 [ 데이터 영역 선택하기 ] (0) | 2023.01.04 |
[기초방] VBA 100제 #6 [ 데이터 영역 스위칭 ] (0) | 2023.01.02 |
[기초방] VBA 100제 #3 [ 나를찾아줘 ] (4) | 2022.12.26 |
댓글