WorkSheet|TopLeftCell|RightBottomCell|Shape|Range|
|Application.Caller|Collection|New|Array()|
|LBound()|UBound()|Redim|Preserve|On Resume Next|
여러장의 시트의 내용을 요약하고 싶다!!
여러장의 시트의 내용을 요약하는 일은 엑셀에서
흔하게 사용되는 일이다
다른 엑셀의 요약기능이 많지만 자동화로 자기가 하고 싶은 방법으로
하기 위하여 엑셀프로그래밍을 익숙하게 하는것이다
아래와 같은 문제가 있다
문제--여러장의 시트의 내용이 똑같지 않다
아래와 같이 만들고 싶다
1--한장의 시트에 요약을 하고
2--버튼을 달아서 크릭하면 해당상세내용이 나타나게..
3--버튼을 달아서 크릭하면 해당상세내용이 나타나게..
4--버튼을 달아서 크릭하면 해당상세내용이 나타나게..
버튼이 존재하는 범위를 찾아내는 TopLeftCell,RightBottomCell속성
Shape오브젝트가 위치하는 셀의 Range오브젝트를 찾아낼 필요가 있을것이다
아래의 구문을 실행해보면 이해가 될것이다
Static blnX As Boolean
Dim btnX As Button
Set btnX = ActiveSheet.Buttons(Application.Caller)
Range(btnX.TopLeftCell, _
btnX.BottomRightCell).Interior.ColorIndex = xlNone
If blnX Then
btnX.TopLeftCell.Interior.ColorIndex = 3
Else
btnX.BottomRightCell.Interior.ColorIndex = 5
End If
blnX = Not blnX
버튼이 위치한 범위를 기준으로 다른 범위에 작업을 할수 있다
매크로가 연결된 오브젝트의 이름을 알아내는 Applcation.Caller속성
버튼을 크릭하였을때 어떤 버튼을 크릭하였는지 알아야 된다
버튼오브젝트를 찾으려면
ActiveSheet.Buttons(버튼이름 혹은 Index)하여야 하는데
먼저 버튼이름 알수 있었으면 좋겠다
이것을 알려주는 속성은 Applcation오브젝트의 속성인
Caller인것이다
그래서
ActiveSheet.Buttons(Application.Caller)
는 크릭된 버튼오브젝트에 접근하게 된다
그래야 그다음으로 접근할수 있는것이 버튼오브젝트의
TopLeftCell은 왼쪽상단 꼭지점이 들어있는 Range
BottomRightCell은 오른쪽하단 꼭지점이 위치한 Range를 얻는것이다
편리한 Collection 오브젝트(배열과 더불어)
VBA는 배열과 더불어 Collection이라는 오브젝트를 제공한다
오브젝트라는 개념은 엑셀에 들어가서 설명을 하도록 한다
여러개의 정보를 다룰때 배열을 사용하던 Collection오브젝트를
사용하던 상관없다
두개의 특징을 충분히 이해한다면 상황에 따라서 선택하여 사용할수있게 된다
예를 들어서 대화상자를 통하여 상품명을 계속 받아들인후
모든 이름을 시트에 담고 싶다고 할때
Dim iX As Integer,strX As String
Dim sNames() As String, blnX As Boolean
strX = InputBox("상품명입력")
Do While strX <> ""
ReDim Preserve sNames(iX)
sNames(iX) = strX
iX = iX + 1
blnX = True
strX = InputBox("상품명입력")
Loop
If blnX Then
MsgBox "모두" & UBound(sNames) + 1 & " 개의 상품명을 입력했습니다"
For iX = LBound(sNames) To UBound(sNames)
Range("A1").Offset(iX, 0) = sNames(iX)
Next
End If
Compare Collection With Array
Collection오브젝트도 역시 정보를 좀더 체계적으로
관리하기 위한 수단이다
배열과 더불어 알고 있으면 편리하다
아래와 같은 경우에 Collection오브젝트가 편리하고 유용하다
아래의 그림과 같이 여러개의 정보가 중복되어 있을때
중복되지 않는 정보만 뽑아내고 싶을때가 있을것이다
배열로 풀어보는 방법과 Collection오브젝트의 특징을 살린 구문을 비교하자
배열로 처리할때
Collection오브젝트로 처리할때
Dim rX As Range, varX As Variant
Dim rData As Range, blnDup As Boolean
Dim sData() As String, iX As Integer
Set rData = Range("A1").CurrentRegion
For Each rX In rData
blnDup = False
If iX = 0 Then
'첫번째값은 그냥 배열에 전달하고
ReDim sData(iX)
sData(iX) = rX
iX = iX + 1
Else
'두번째값부터 중복되는지 확인한다
For Each varX In sData
If varX = rX Then
blnDup = True
Exit For
End If
Next
If Not blnDup Then
ReDim Preserve sData(iX)
sData(iX) = rX
iX = iX + 1
End If
End If
Next
Range(Range("D1"), Range("D1").Offset(UBound(sData))) = _
Application.Transpose(sData)
Dim rX As Range, iX As Integer
Dim rData As Range, varX As Variant
Dim oCol As New Collection
Set rData = Range("A1").CurrentRegion
On Error Resume Next
'Collection오브젝트에 담고
'담을때 Add메소드의 두번째인수가 똑같은 값이면
'에러가 난다..즉 추가되지 않는것이고
'위에서 On Error Resume Next를 하였으므로
'다음작업으로 그냥 통과한다
For Each rX In rData
oCol.Add rX.Value, rX.Value
Next
'범위에 다시 풀어 넣는다
For Each varX In oCol
Range("D1").Offset(iX) = varX
iX = iX + 1
Next
이렇게 중복되지 않는 유일한 정보를 찾아야 할일은 자주 발생한다
위와 같이 Collection오브젝트를 사용하면 편리할것이다
아래도 역시 배열에서 유일한 값을 찾아 낼때도 요령은 마찬가지다
Sub Test()
Dim oCol As New Collection,vEach As Variant
Dim vX As Variant
On Error Resume Next
vX=Array("개나리","도라지","개나리","도라지","개나리","진달래")
For Each vEach In vX
oCol.Add vEach,vEach
Next
For Each vEach In oCol
MsgBox vEach
Next
End Sub
위의 몇가지 기능을 조합하여 아래 화일과 같이 소루션을 만들어 보자
Make Summary Sheet With Button To Show Detail