사용자 도구

사이트 도구


kb:excelodbc

Excel ODBC

ExcelProgramming 페이지에서도 언급했듯이 프로그램적으로 엑셀 파일을 다루는 방법에는 여러가지가 있다.

그 중에서 C++을 사용하는 경우, 가장 쉬운 방법이 마이크로소프트에서 제공하는 MDAC/JET/ISAM 드라이버를 이용해서, ODBC 형태로 접근하는 방법이다. 적당한 커넥션 스트링을 이용해 데이터베이스 연결을 만든 후에는 그냥 일반적인 데이터베이스 접근하는 것처럼 다루면 되기 때문이다.

다만 어디까지나 데이터베이스이기 때문에, 셀 안에 있는 데이터만 다룰 수 있고, 셀 포맷이라든지, 서식 같은 건 다룰 수 없다는 점이 단점이다.

1. 연결

1.1. 드라이버

SQLGetInstalledDrivers 함수를 호출하면 인스톨되어 있는 드라이버 목록을 알아낼 수 있다. 이 중에서 적당한 드라이버를 골라서 아래에 있는 커넥션 스트링에다 넘기면 된다.

XLS  - Microsoft Excel Driver (*.xls)
XLSX - Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)

1.2. 커넥션 스트링 기본 포맷

1.2.1. READ

DRIVER={%s};DBQ=%s;HDR=YES;IMEX=1
  • DRIVER : 위에서 본 드라이버 이름
  • DBQ : 엑셀 파일 경로
  • HDR은 엑셀 파일 제일 윗줄이 테이블 컬럼 이름 역할을 하는 헤더인지의 여부
  • IMEX: 0일 경우 쓰기, 1일 경우 읽기, 2일 경우 혼합을 뜻한다.

1.2.2. WRITE

DRIVER={%s};DSN='';FIRSTROWHASNAMES=1;READONLY=FALSE;CREATE_DB="%s";DBQ=%s
  • DRIVER : 위에서 본 드라이버 이름
  • FIRSTROWHASNAMES : 엑셀 파일 제일 윗줄이 테이블 컬럼 이름 역할을 하는 헤더인지의 여부
  • READONLY : …
  • CREATE_DB : 엑셀 파일 경로
  • DBQ : 엑셀 파일 경로

1.2.3. 이후 처리

  • 엑셀 워크북 안에 있는 하나의 시트가 하나의 테이블이 된다. 테이블 목록, 즉 워크 시트 목록을 알기 위해서는 SQLTables 함수를 이용한다.

2. 레지스트리

2.1. TypeGuessRows

기본적으로 데이터베이스에서는 한 컬럼이 여러가지 형태의 데이터를 가질 수 없다. 하지만 엑셀은 가능하다.

그렇다보니 드라이버가 엑셀 파일을 읽어들일 때, 어느 정도까지의 행들을 읽어본 다음, 자기 판단 하에 컬럼의 포맷을 정하고, 그 포맷이랑 다른 행/컬럼은 NULL 처리해버린다. 좀 더 쉽게 말하자면 문자열과 정수가 혼용되어 있는 컬럼이 있는데, 8줄까지를 읽어봐서 문자열만 있다고 하면 그 아래에 있는 정수 컬럼들은 드라이버를 통해 접근시 NULL로 나온다는 이야기다.

몇줄까지를 읽어서 컬럼의 포맷을 판단할 지는 레지스트리에 있는 TypeGuessRows 키 값을 변경함으로서 설정할 수 있다. 다만 XLS 파일이냐, XLSX 파일이냐에 따라, 레지스트리 위치가 틀리다.

XLS  - SOFTWARE\Microsoft\Jet\4.0\Engines\Excel
XLSX - HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\12.0\Access Connectivity Engine\Engines\Excel

3. 문제점

3.1. 필터 및 기타 정보 추출

임포트 모드로 파일을 열어보면, 시트가 없는데도 불구하고, 테이블로 튀어나오는 놈들이 있다. 이건 딱히 규칙은 모르겠는데, 피벗 테이블이나, 별도의 이름 정의들이 테이블로 나온다. 이 테이블들을 무시하는 가장 간단한 방법은 테이블 이름이 '$' 문자로 끝나는지 검사하는 것이다.

3.2. 64 비트

2010년 1월 기준으로 아직까지 64비트 JET 드라이버가 존재하지 않는다. 나온다는 이야기는 있는데, 정식 버전은 아직까지는 안타깝게도 없다.

4. 링크

kb/excelodbc.txt · 마지막으로 수정됨: 2014/11/11 14:44 저자 excel96