리플을 달아주시면 피드백이 되고 더 좋은 글을 남길 수 있도록 제가 노력하게 되니 그리하여 주시면 감사하겠습니다.
의외로 많은 분들이 관심을 가져 주는 것 같아서 나름대로 어깨도 무겁네요. ^^;
리플에 어렵다는 말씀이 있으셔서 나름대로 이번 강좌에는 그림을 많이 넣어봤는데요.
쉽다고 느끼시는 분들이 게시물 만족도에 보통 낮은 점수를 주니 간혹 그런 분들도 있는 것 같은데
어느 수준으로 진행해야 하는지 감을 통 못잡겠네요. 마음에 들지 않으시면 리플로 표현해 주셨으면 좋겠는데...
오늘은 Workbooks 컬렉션과 Sheets(또는 Worksheets) 컬렉션에 대해서 알아보겠습니다. 별로 재미없는 부분이긴 하지만 안짚고
넘어갈 수는 없습니다.

Workbooks 컬렉션은 열려진 엑셀 문서가 모인 것을 의미합니다.
그림에서 보는 바와 같이 전화번호부2.xls, book2, Book1 를 총칭하여 Workbooks 컬렉션이라고 합니다.
현재 엑셀에 열려진 모든 문서들을 의미합니다.
체크 표시된 Book2 가 ActiveWorkbook, 즉 활성화된 문서 또는 작업문서라고 생각하시면 됩니다.
Sheets 는 Sheet(실제 코딩에는 존재하지 않습니다.)의 집합을 의미하고 Worksheets 는 Worksheet 의 집합을 나타냅니다.
아래 그림과 같이 엑셀의 왼쪽 하단 시트탭에서 마우스 우측 버튼 눌러서 삽입메뉴를 선택하면 Worksheet, Chart, MS Excel 4.0
Macro, MS Excel 5.0 Dialog 등이 나오게 됩니다.
일반적으로 제일 많이 쓰는 시트 형태는 Worksheet 입니다. 그림에서 보는 것과 같이 Worksheet가 모이면 Worksheets 이고
Chart 시트, Macro 시트, Dialog 시트를 모두 합한 것이 Sheets 입니다.
그림에서 워크시트의 개수는 3개이고 시트의 개수는 6개입니다. 선택된 Sheet1 이 ActiveSheet 입니다.
위의 내용은 별로 중요한 내용은 아니니까 그냥 가볍게 읽어주시기 바랍니다.
이번엔 모든 워크시트의 이름을 알아내는 방법에 대해서 설명드리겠습니다.
혹시라도 For Each 구문을 아예 모르시는 분은 다음 강좌를 잠깐 보시고 나서 다시 이 글을 읽어주시기 바랍니다.
다음은 Workbooks 및 Sheets 컬렉션을 순환해서 시트 하나, 하나의 이름을 메세지 박스로 표시하는 예제입니다.
Option Explicit
Private Sub Command1_Click()
Dim xlApp As New Excel.Application '엑셀 어플리케이션 개체 선언
Dim wbkTmp As Excel.Workbook '워크북 개체 선언
Dim shtTmp As Excel.Worksheet '워크시트 개체 선언
xlApp.Workbooks.Add '워크북 추가
xlApp.Workbooks.Add '워크북 추가
xlApp.Workbooks.Add '워크북 추가
For Each wbkTmp In xlApp.Workbooks '워크북 컬렉션 순환
MsgBox wbkTmp.Name '워크북 이름 표시
Next
For Each shtTmp In xlApp.ActiveWorkbook.Sheets '시트 컬렉션 순환
MsgBox shtTmp.Name '시트 이름 표시
Next
Set shtTmp = Nothing '시트 개체 삭제
Set wbkTmp = Nothing '워크북 개체 삭제
xlApp.Quit '엑셀 종료
Set xlApp = Nothing '엑셀 어플리케이션 개체 삭제
End Sub
임의로 3개의 워크북을 추가시켰고 MsgBox wbkTmp.Name 으로 각각의 워크북을 표시하게 하고
마지막에 추가된 워크북이 ActiveWorkbook 이 되므로 이에 속하는 시트들을 순환해서 각각의 시트 이름을 MsgBox 로 표시하게 하는
예제 입니다.
소스 중에 xlApp.ActiveWorkbook.Sheets 는 xlApp.Sheets 로 생략할 수 있습니다.
첫회에 설명드린 주요개체는 Application_Object.Workbook_Object.worksheet_Object.Range_Object 형태로 표시할 수 있는데 각각은
생략할 수 있지만 VBA가 아닌 VB에서 핸들링 하는 경우에는 되도록 생략을 하지 말고 써주는 습관을 길러 두시다보면 나중에 어느 경우
에 생략할 수 있는지 스스로 감이 잡히실 것입니다. 첫회 강좌 리플 내용을 읽어보시면 이 부분이 무슨 말씀인지 이해가 되시리라 생각하고
생략하는 경우가 보통은 잘 성립이 되나 참고로 Worksheet 개체를 생략해서 Workbook_Object.Range_Object 형태는 불가능합니다.
생략형이 또 까다로운 이유가 VB에서 엑셀 개체를 참조하여 상위 개체를 생략하는 경우에는 ActiveWorkbook 이나 ActiveSheet 가
보통 되지만 엑셀 VBA 를 이용해서 코딩하면 ActiveWorkbook, ActiveSheet 이 되거나 경우에 따라서는 해당 모듈에 기술된 Parent 개체,
예를 들어서 ThisWorkbook을 의미하는 경우가 있습니다. 더 깊이 들어가면 정신 건강에 별로 안좋을 것 같아서 여기까지만
설명드리겠습니다.
또하나 설명드려야 할 것은 개체 제거, 즉 Nothing 부분을 살펴보시면 하위개체부터 Nothing 시키는 것을 보실 수 있습니다. DB도
마찬가지로 레코드셋 제거하고나서 데이터베이스 개체(DAO) 또는 컨넥션 개체(ADO) 를 제거하듯이 엑셀 개체도 반드시 하위 개체부터
제거하시기 바랍니다. 이렇게 하지 않으면 엑셀 개체가 메모리에서 제거가 되지 않는 사태가 발생할 수도 있습니다.
여하튼 위의 컬렉션을 쓰면 시트 및 워크북의 존재여부, 시트 및 워크북 이름의 일괄 변경 등의 작업이 가능하게 됩니다.
하나만 예를 들면 다음과 같습니다. 일부러 다양하게 응용하시라고 For Each 쓰지 않고 만들어봤습니다.
'시트명 일괄 변경
Option Explicit
Dim xlApp As New Excel.Application '엑셀 어플리케이션 개체 선언
Private Sub Command1_Click()
Dim i As Integer
xlApp.Workbooks.Add '워크북 추가
For i = 1 To Sheets.Count '시트의 개수만큼 루프
xlApp.Sheets(i).Name = "시트" & i '시트명을 시트1, 시트2... 로 바꿈
Next
xlApp.Visible = True '엑셀 표시
End Sub
이번엔 어떤 워크시트가 존재하는지 체크하는 예제를 만들어봤습니다.
'워크시트 존재여부
Option Explicit
Dim xlApp As New Excel.Application
Private Sub Command1_Click()
Dim strTmp As String
strTmp = "Sheet3"
xlApp.Workbooks.Add '워크북 추가
If IsSheet(strTmp) Then
MsgBox strTmp & "이 존재합니다."
Else
MsgBox strTmp & "이 존재하지 않습니다."
End If
strTmp = "Sheet10"
If IsSheet(strTmp) Then
MsgBox strTmp & "이 존재합니다."
Else
MsgBox strTmp & "이 존재하지 않습니다."
End If
xlApp.Visible = True '엑셀 표시
End Sub
Private Function IsSheet(strSheet As String) As Boolean 'True:시트가 존재, False:시트가 존재하지 않음
Dim shtTmp As Excel.Worksheet
For Each shtTmp In xlApp.ActiveWorkbook.Sheets '워크시트 컬렉션 순환
If shtTmp.Name = strSheet Then '해당 시트 이름이 존재하면
IsSheet = True
End If
Next
Set shtTmp = Nothing '워크시트 개체 제거
End Function
이것보다 더 좋은 방법은 Error 개체를 이용하는 방법입니다. 시트가 존재하는지 여부는 에러개체를 응용하시는 것이 좋습니다.
꼭 이렇게 코딩할 필요는 없고 Name 속성을 디버깅 창에 찍어도 되고 다양하게 에러를 발생시켜서 응용하시면 됩니다.
Private Function IsSheet(strSheet As String) As Boolean 'True:시트가 존재, False:시트가 존재하지 않음
on Error Resume Next '에러가 발생하면 다음 구문으로 이동
IsSheet = CBool(Len(xlApp.ActiveWorkbook.Sheets(strSheet).Name)) '해당시트의 이름이 존재하면 True
If Err.Number > 0 Then '에러가 발생하면
Err.Clear '에러 지움
End If
on Error GoTo 0 '이 이후에 에러가 발생하면 다시 에러를 발생하도록 설정
End Function
워크북이 존재하는 여부는 응용하실 수 있다고 생각하고 넘어가겠습니다.
예전에 누가 '워크북이 존재하는지 코딩으로 알 수 있냐'라는 질문에 '왜 그것을 알고 싶냐'라고 물어봤더니 '워크북이 존재하고 있지
않으면 해당 문서를 열려고 한다'라는 말에 간단히 on Error 문 쓰고 해당 문서를 오픈하는 구문을 넣어서 답변 준 적이 있습니다.
굳이 우리가 생각하는 방법이 항상 옳은 것은 아니고 때론 생각을 바꾸면 모든 것이 아주 간단하게 해결 될 수 있습니다.
오늘 말씀드린 내용은 실무에서 활용도가 그렇게 높지는 않으나 개념적으로는 중요한 부분이니 설명 드리게 되었습니다. 다음에는
슬슬 재미있고 활용도가 높은 것을 다뤄보도록 하죠. 정리된 내용을 발표하는 것이 아니고 하면서 정리하다 보니까 많이 벌려만 놓고
이거 나중에 수습이 될지 모르겠네요.^^
제가 술을 좋아하는 관계로 항상 다음 강좌는 언제 올린다는 보장 못합니다. ^^;;
출처2 : http://blog.naver.com/pdc222/140037854305
'개발 > VB' 카테고리의 다른 글
Form_QueryUnload 의 UnloadMode 설명 (0) | 2015.03.10 |
---|---|
[Delphi] 그리드 데이타를 엑셀로 저장하자(vb개발시 일부 항목 참조) (0) | 2010.01.04 |
Modules: Sample Excel Automation (0) | 2009.12.09 |
function 사용시 := 로 값 지정하기 (0) | 2009.11.25 |
VB 함수정리 (0) | 2009.10.21 |