- 최초 작성일: 2005-09-06
- 최종 수정일: 2026-09-30
- 조회수: 6 회
- 작성자: 권현욱 (엑셀러)
- 강의 제목: 파일을 열지않고 값 읽어오기2
들어가기 전에
오래 전 엑셀 파일로 진행하던 강의를 웹 글로 복원한 것이라, "버튼을 눌러보세요"처럼 엑셀에서 직접 조작하라는 표현이 남아 있을 수 있습니다. 결과는 본문의 그림이나 표로 확인하실 수 있으며, 현재와 맞지 않는 내용은 보완하되 전반적인 스타일은 당시의 갬성(?)을 유지했습니다.
질문 하나
강좌 중 파일을 열지 않고 값 불러오기를 이용하여 제가 엑셀 파일을 만들었는데여 불러 올 외부 데이터의 행이 너무 커서 그런지 시간이 너무 오래 걸리네여....
지금 코드에 행 설정 해준 것들은 최대로 나올 수 있는 최대값을 설정해 준 건데여 이 방법 말고 외부 엑셀 파일에 입력된 데이터 값의 끝부분까지만 받아오는 방법이 없을까여?
그리고 지금까지 성실히 답변해 주셔서 감사드립니다.
덕분에 공부를 하면서 제가 원하던 프로그램을 완성시킬 수 있을 것 같네여
이 프로그램 에러는 안나는데 속도가 너무 느려서 속도를 빨리하는 방법이 없나 질문하는 겁니다. 그리고 원래 외부에서 받아오는 데이터가 4개 정도 더 있는데 (게시판) 용량 제한 때문에 줄여서 올립니다.
파일을 열지않고 값 읽어오기2
핵심 요약: DAO로 닫힌 파일 데이터 읽기
XLM 매크로로 셀 하나씩 읽으면 느리지만, DAO와 SQL 쿼리를 사용하면 A1:W1000 정도의 데이터도 1초 안에 가져옵니다. 조건이나 집계도 쿼리문으로 처리할 수 있습니다.
- 1단계: 도구 - 참조에서 Microsoft DAO 3.6 Object Library를 선택합니다.
- 2단계: OpenDatabase로 파일을 열고 SELECT 쿼리로 Recordset을 만듭니다.
- 3단계: 필드명을 제목으로 적고 CopyFromRecordset으로 데이터를 한 번에 옮깁니다.
Step 1: 무엇이 문제였을까요?
이 강좌의 예제는 실행용 파일과 데이터 파일(주상도관련.XLS), 이렇게 두 개의 파일로 구성되어 있으며 반드시 같은 폴더에 두어야 코드가 제대로 작동합니다.
질문주신 분이 사용하신 코드는 VB0051 강좌에서 소개해 드린 XLM 매크로를 이용한 것이었습니다. 이것을 이용하여 A1:W1000 정도 되는 데이터를 워크시트에 불려오니까… 되기는 되는데… 세월아 네월아 기다려야 된다는 것이지요.
이번에는 데이터 파일을 열지 않고 DAO(Data Access Objects)를 이용해 SQL 쿼리문으로 값을 읽어 오는 방법을 사용합니다. 예제를 실행해 보면 불과 1초도 안 되어 순식간에 처리됩니다.
같은 폴더에 압축을 해제 하였는데도 오류가 발생하는 경우, VB Editor 상태에서 '도구-참조' 메뉴를 선택하신 다음, '사용 가능한 참조' 목록에서 'Microsoft DAO O.O Object Library'를 선택하고 '확인'을 누른 후 다시 실행해 보시기 바랍니다.
Step 2: 코드 살펴보기
Sub ReadValue()
Dim strSQL As String
Dim dbMyDB As DAO.Database
Dim rstRST As DAO.Recordset
Dim sngStart As Single
Dim i As Long
Const SourceFile As String = "주상도관련.XLS"
sngStart = Timer
strSQL = "Select 공번, 심도상부, 심도하부, 토층, 분류, 분류2, 암층, 암종, 터널구간, TCR, RQD, "
strSQL = strSQL & " RQD등급, BRMR, RMR, RMR등급, Q, Q등급, SMR, SMR등급, SCR, 추가1, 추가2, 추가3 "
strSQL = strSQL & "FROM [주상도관련$] "
Set dbMyDB = OpenDatabase(ThisWorkbook.Path & Application.PathSeparator & SourceFile, _
False, True, "excel 8.0;")
Set rstRST = dbMyDB.OpenRecordset(strSQL)
Application.ScreenUpdating = False
Worksheets.Add after:=Worksheets("Preface")
With ActiveSheet
.UsedRange.Clear
For i = 0 To rstRST.Fields.Count - 1
Cells(1, i + 1).Value = rstRST.Fields(i).Name
Next
.Range("A2").CopyFromRecordset rstRST
.UsedRange.Columns.AutoFit
End With
Application.ScreenUpdating = True
MsgBox "불과 " & Format(Timer - sngStart, "0.00") & "초 소요되었습니다!", , "www.iExceller.com"
rstRST.Close
dbMyDB.Close
Set rstRST = Nothing
Set dbMyDB = Nothing
End Sub
그런데... 어떤 연유에서인지는 알기 어려우나, 원본 데이터를 이와 같이 그냥 있는 그대로 불러오는 것은 그다지 의미가 없을 것입니다. 보통의 경우, 원본 데이터 중 조건을 충족하는 특정 항목만 가져온다거나 연산을 수행하고 난 다음 그 결과값만 표시한다거나 하는 경우가 많습니다. 이런 경우는 각종 데이터들을 다루다 보면 비일비재 할 것입니다.
Step 3: 조건에 맞는 결과만 가져오기
다음 버튼을 클릭하면 '공번'별로 소요된 비용을 집계하여 그 결과만을 <실행 결과>와 같은 형태로 보여줍니다.
<실행 결과>
합계를 구하는 과정을 추가하였음에도 불구하고 앞의 코드와 마찬가지로 순식간에 자료가 추출됨을 알 수 있습니다.
코드는 앞의 것과 거의 비슷하고 쿼리(Query)문의 구조가 조금 바뀌었습니다.
strSQL = "Select 공번, Sum(비용) As 비용합계 "
strSQL = strSQL & "FROM [주상도관련2$] "
strSQL = strSQL & "Group By 공번 "
다른 부분은 똑같으니까 설명은 생략합니다.
최신 Office에서의 참고사항: DAO 3.6 라이브러리(Jet 엔진)는 64비트 Office에서는 사용할 수 없습니다. 이런 환경에서는 'Microsoft Office 16.0 Access Database Engine Object Library'를 참조 설정하고 ACE 엔진을 사용하거나, Power Query로 외부 통합 문서를 불러오는 방법을 이용하시기 바랍니다.
데이터를 많이 다루는 분은(특히나 대용량 데이터) 이번 시간에 소개해 드린 내용과 더불어 VB0170, VB0171 강좌 등에 대해서도 잘 정리해 두시기 바랍니다.
다음에 또…
정리 — DAO로 값 읽어오기 코드 핵심
| 구분 | 사용한 코드 | 역할 |
|---|---|---|
| 참조 설정 | Microsoft DAO 3.6 Object Library | DAO 개체 형식 사용 |
| 파일 열기 | OpenDatabase(경로, False, True, "excel 8.0;") | 읽기 전용으로 엑셀 파일 연결 |
| 쿼리 실행 | dbMyDB.OpenRecordset(strSQL) | SELECT 결과를 Recordset에 담음 |
| 데이터 옮기기 | .Range("A2").CopyFromRecordset rstRST | Recordset을 시트에 한 번에 복사 |
| 집계 | Select 공번, Sum(비용) ... Group By 공번 | 공번별 합계만 추출 |
자주 묻는 질문 (FAQ)
Q1. 왜 DAO 방식이 XLM 매크로보다 빠른가요?
XLM 매크로 방식은 셀을 하나씩 읽어 오기 때문에 데이터가 많을수록 시간이 오래 걸립니다. DAO는 SQL 쿼리로 필요한 데이터를 한 번에 가져와 CopyFromRecordset으로 시트에 옮기므로 훨씬 빠릅니다.
Q2. 시트 이름은 SQL에서 어떻게 지정하나요?
FROM 절에 [시트이름$] 형식으로 대괄호와 달러 기호를 함께 지정합니다. 예를 들어 주상도관련 시트는 [주상도관련$]로 씁니다.
Q3. 실행하다가 오류가 나면 어떻게 하나요?
같은 폴더에 데이터 파일이 있는지 확인하고, VB Editor에서 도구 - 참조 메뉴로 들어가 Microsoft DAO 3.6 Object Library 항목에 체크한 다음 다시 실행해 보세요.
마치며
대용량 데이터를 다룰 때는 셀 단위로 읽지 말고 쿼리로 한 번에 가져오는 것이 핵심입니다. 조건 추출이나 합계 같은 연산도 쿼리문에서 끝낼 수 있습니다.