- CVI 정보나눔(www.cvi.kr)
- 스터디
- 강좌,팁,유용한것
강좌,팁
오늘(2007년 4월 6일) 아침에 인터넷으로 귀중한 설교말씀을 들었습니다.
"내가 도움이 절실히 필요할 때, 오히려 도움을 베풀기 바랍니다" 라는 요지의 설교였습니다.
이 설교를 통해 그동안 삶과 일과가 힘들어 차일피일 미루어 온 이번 강좌를 힘과 용기를 내어 작성하게 되었습니다. 조엘 오스틴(Joel Ostin) 목사님의 "씨앗 중심의 삶"이라는 제목의 설교인데요, 기독교인이 아니신 분들도 꼭 들어보시기 바랍니다.
---------------------------------------------------------------------------------------
[강좌:35] 엑셀(Excel) 파일에 출력하기
이용된 버전: LabWindows/CVI 7.1.1(최초작성), 8.1.0(테스트)
강좌분류: KD_Excel2.dll 활용, 따라하기 및 샘플예제
차례
서론
1. 이번 예제 프로그램의 개요
2. 필요한 라이브러리와 자료 파일
3. 작업준비
4. 코딩
4.1 KD_Excel2.dll의 사용 준비단계
4.2 선언과 main() 함수
4.3 Panel 콜백 함수
4.4 Table 콜백 함수
4.5 명령버튼 콜백 함수들
5. 실행
마무리
서론
프로그램의 실행 결과를 자체 포맷의 데이터 파일이나 텍스트 파일로 저장하는 대신 형식이 만들어져 있는 엑셀파일로 출력한다는 것은 많은 분들이 필요로 하실 것입니다. csv와 텍스트 xls 파일로 출력하는 것은 보고서 형식으로는 적절하지 않고, Panel을 프린트하는 방식으로 보고서를 작성하는 것은 번거로우면서도 수정해야할 때에는 매우 귀찮게 느껴집니다.
그래서 이번 강좌에서는 텍스트 정보, 수치 데이터를 이미 형식이 만들어진 엑셀 파일의 원하는 셀에다 기록해 넣는 방법을 다루게 됩니다. 이 방법은 원래 LabWindows/CVI의 Samples\activex\excel 폴더 안에 있는 excel2000dem.prj에서 소개되었고, 이를 쉽고 빠르게 사용하기 위해 객체 비슷한 형태의 KD_Excel2.dll(KD_Excel2 v1.0.001)로 만들었습니다.
1. 이번 예제 프로그램의 개요
이번 따라하기 예제의 결과 프로그램 실행화면을 그림 1.1에 보였습니다.
CVI 프로그램에서 샘플명, 측정 일시 등의 여러 정보들과 데이터를 세팅한 후에, 이미 만들어져 있는 엑셀 양식 파일을 복사해 불러온 다음, 원하는 위치에 그 값들을 기록하는 방식으로 프로그램이 진행될 것입니다.
그림 1.1 본 강좌(엑셀 파일에 출력하기)의 최종 실행화면 미리보기
화면 뒤쪽의 엑셀(Excel) 화면은 CVI로 작성한 프로그램에서 실행시킨 것입니다. 이러한 엑셀 실행화면은 화면상에 보이지 않도록 처리될 수도 있습니다.
2. 필요한 라이브러리와 자료 파일
이번 강좌에서 이용할 라이브러리와 엑셀 양식 샘플 파일, 그리고 데이터 파일을 자료실(CVI정보나눔 자료실)에 아래의 제목으로 올려두었습니다.
그림 2.1에 L035_OutputExcel_materials.zip 파일을 다운로드받아 압축을 해제한 파일들을 보였습니다. KD_Excel2_v1.0.001_lib.zip 파일을 압축해제하시면, 다시 3개의 파일(KD_Excel2.xxx)이 있습니다. 실행시에는 dll 파일만 있으면 되지만, 프로그래밍할 때에는 헤더파일과 Import library가 모두 필요합니다.
그림 2.1 엑셀(Excel) 파일에 출력하기 예제용 재료 파일들
그림 2.2에는 모든 압축을 해제한 화면입니다.
그림 2.2 재료 파일을 모두 압축해제함
3. 작업준비
작업 준비 과정은 "[강좌:21] CVI 프로그래밍 시작단계 정의(2)" 강좌 글의
"2. LabWindows/CVI의 프로그래밍 작업 시작단계" 부분에 따라 아래와 같이 간단히 정리합니다.
프로젝트 파일명: OutputExcel.prj
화면구성은 그림 3.1에 보였습니다. 약간 복잡해 보이지만 크게 분류하면, 엑셀로 보낼 문자열과 데이터 표시부분, 그리고 실행과 관련된 명령버튼들로 이루어져 있습니다.
그림 3.1 OutputExcel 프로젝트의 화면구성
uir 파일 내의 각 컨트롤의 속성은 표 3.1과 같이 설정되었습니다.
표 3.1 컨트롤의 속성값
컨트롤 종류 | Constant Name | Callback Function | Label | Default Value |
비고 |
Text Message |
TEXTMSG |
해당없음 |
엑셀(Excel) 파일에 출력하기 |
Text Style |
|
String |
strSampleName |
|
Sample Name |
테스트샘플-001 |
|
String |
strMeasDate |
|
Meas. Date |
2007-04-06 |
|
String |
strMeasTime |
|
Meas. Time |
12:34:23 |
|
String |
strTester |
|
시험자 |
허창원 |
|
String |
strOutDate |
|
출력일시 |
데이터 출력시에 자동으로 설정됨 |
|
String |
strOutDate |
|
출력일시 |
데이터 출력시에 자동으로 설정됨 |
|
Table |
TABLE |
TableCB |
|
|
Column을 하나 추가해둠 |
Check Box |
chkVisible |
|
Excel 실행화면 보이기 |
On |
|
Graph |
GRAPH |
|
|
|
|
Command Button |
cmdOneStop |
cmdOneStop |
아래의 과정을 한방에(인쇄 제외) |
해당없음 | |
Command Button |
cmdLaunchExcel |
cmdLaunchExcel |
1.엑셀실행하며 양식파일 불러오기 |
해당없음 | |
Command Button |
cmdReplace |
cmdReplace |
2.엑셀로 정보 및 데이터를 출력 |
해당없음 | |
Command Button |
cmdSave |
cmdSave |
3. 엑셀 파일 저장하기 |
해당없음 | |
Command Button |
cmdPrintPreview |
cmdPrintPreview |
4. 인쇄 미리보기 |
해당없음 | |
Command Button |
cmdPrint |
cmdPrint |
5. 바로 인쇄하기 |
해당없음 | |
Command Button |
cmdClose |
cmdClose |
6. 엑셀 문서 닫고 종료하기 |
해당없음 |
Panel의 속성은 표3.2와 같이 설정합니다.
표 3.2 Panel의 속성설정
Panel 속성설정 |
|
Constant Name |
PANEL |
Callback Function |
PanelCB |
Panel Title |
엑셀(Excel) 파일에 출력하기 |
Other Attributes |
Sizable, Can Maximize를 uncheck |
그리고, 기본 소스를 생성합니다. 기본으로 생성된 함수는 main() 함수와 PanelCB(), TableCB(), 그리고 7개의 명령버튼 콜백함수들입니다. 그림 3.2에 프로젝트 창을 보였습니다.
그림 3.2 OutputExcel의 프로젝트 창
4. 코딩
이제 코딩으로 들어갈 차례인데요, 작성된 소스 중에서 KD_Excel2.dll와 관련된 부분부터 먼저 소개하겠습니다.
4.1 KD_Excel2.dll의 사용 준비단계
그림 4.1에는 KD_Excel2.dll에 정의된 구조체를 사용하기 위한 세단계를 보였습니다.
그림 4.1 KD_Excel2 구조체 사용을 위한 3단계(OutputExcel.c 파일)
(소스코드 이미지를 클릭하면 소스 텍스트 창이 나타난다는 거 아시죠?)
7라인에는 헤더파일 include, 8라인은 구조체 변수의 선언, 71라인은 구조체 내의 함수 포인터와 기타 변수에 대한 초기화, 79라인은 마무리에 필요한 처리(일반적으로 할당된 메모리의 해제인데, 이 구조체에는 그런 과정은 없는 걸로 기억됩니다. 별로 하는 일이 없습니다)가 이루어집니다.
4.2 선언과 main() 함수
이제는 OutputExcel.c 파일의 전체 소스 코드를 위에서부터 차례대로 살펴보겠습니다.
그림 4.2 선언부분(OutputExcel.c 파일)
그림 4.2에는 메인함수 윗부분의 선언 부분을 보였습니다. 사용하려는 용도대로 변수명이 부여되어 있으므로, 척~ 보면 짐작이 가실 것입니다.
11~17라인의 변수들은 uir 파일의 String 컨트롤에 입력되는 문자열을 저장할 문자배열입니다. 이번 예제 프로그램만을 위해서라면 각각 지정할 필요는 없습니다만, 통상적으로 프로젝트를 진행하다 보면 이런 정보들을 INI 파일에 저장하든지, 데이터 파일로 저장하곤 하는데, 이럴 때는 배열명들을 별도로 지정하는 것이 우리의 머리를 복잡하지 않게 만들 것 같습니다.
그림 4.3에는 main() 함수의 내용을 보였습니다. 사용할 파일의 경로를 실행파일이 있는 폴더와 해당 파일명으로 초기화하고, 샘플 데이터 파일을 불러와서 Data 라는 double형 배열에 입력한 후, 테이블과 그래프로 표시하고, KD_Excel2 구조체 변수를 초기화합니다.
그림 4.3 main() 함수부분(OutputExcel.c 파일)
4.3 Panel 콜백 함수
그림 4.4에는 Panel의 콜백함수 부분입니다. 기본 생성된 코드 그대로입니다.
그림 4.4 Panel 콜백 함수부분(OutputExcel.c 파일)
4.4 Table 콜백 함수
그림 4.5에는 Table 콜백함수 부분입니다. 테이블의 셀 값을 임의로 수정했을 때, 그 값을 Data 배열의 해당 element로 읽어들이고, 그래프를 갱신합니다.
그림 4.5 Table 콜백 함수부분(OutputExcel.c 파일)
4.5 명령버튼 콜백 함수들
그림 4.6에는 "아래의 과정을 한방에(인쇄 제외)"라는 명령버튼의 콜백함수이며, 이하 1~6까지의 명령버튼 콜백함수를 하나씩 차례대로 호출합니다.
그림 4.6 "아래의 과정을 한방에(인쇄 제외)" 명령버튼의 콜백 함수부분(OutputExcel.c 파일)
그림 4.7에는 엑셀 프로그램을 제어하는 첫 번째 단계의 명령버튼 콜백 함수입니다. 145라인에서 읽어들이는 체크 박스의 값은 엑셀을 실행시킬 때, 그 화면을 보일 것인지 숨길 것인지를 결정하게 됩니다. 실제 프로젝트에서는 숨기는 것이 좋을 것 같고, 이 예제에서는 그 과정을 이해하는 것이 중요하기 때문에 기본으로는 보이도록 하였습니다. 그리고, 148라인에서는 KD_Excel2 구조체의 실행을 위한 초기화 부분인데, 엑셀 양식 파일을 tmp$$$.xls 라는 이름의 엑셀 파일로 복사하게 됩니다.
마지막으로 151 라인에서 엑셀을 실행하게 됩니다.
그림 4.7 "1.엑셀실행하며 양식파일 불러오기" 명령버튼의 콜백 함수부분(OutputExcel.c 파일)
그림 4.8의 콜백함수는 "2.엑셀로 정보 및 데이터를 출력"이라는 명령버튼의 콜백함수입니다. Sample Name부터 비고까지의 문자열 정보를 읽어오고, 테이블의 데이터도 읽어온 다음, 엑셀로 데이터를 내보내게 됩니다. 이 부분은 Proc_export_to_Excel()이라는 별도의 함수를 호출함으로써 수행됩니다.
그림 4.8 "2.엑셀로 정보 및 데이터를 출력" 명령버튼의 콜백 함수부분(OutputExcel.c 파일)
그림 4.9는 엑셀에서 파일을 저장하는 기능을 호출하는 콜백함수입니다.
그림 4.9 "3. 엑셀 파일 저장하기" 명령버튼의 콜백 함수부분(OutputExcel.c 파일)
그림 4.10은 엑셀에서 인쇄 미리보기와 인쇄 기능을 각각 호출하는 콜백함수입니다.
그림 4.10 "4. 인쇄 미리보기", "5. 바로 인쇄하기" 명령버튼의 콜백 함수부분(OutputExcel.c 파일)
그림 4.11은 엑셀 문서를 닫고, 엑셀 프로그램을 종료하는 콜백함수입니다.
그림 4.11 "6. 엑셀 문서 닫고 종료하기" 명령버튼의 콜백 함수부분(OutputExcel.c 파일)
그림 4.12는 CVI 프로그램에서 엑셀 프로그램으로 데이터를 넘기는 처리를 전담하는 함수입니다. 이 부분은 엑셀 양식에 맞추어서 적절히 코딩되어야합니다.
그림 4.12 엑셀로 데이터를 보내는 함수부분(OutputExcel.c 파일)
5. 실행
이제 프로그램을 빌드하여 실행해 보겠습니다. 그림 5.1에 실행된 화면을 보였습니다.
그림 5.1 실행화면
명령버튼 1~6까지를 차례대로 눌러서 실행시켜가며 그때마다의 실행 결과를 확인해 보시면 되겠습니다. "아래의 과정을 한방에(인쇄 제외)"라는 명령버튼도 눌러보시면, 이러한 모든 단계를 한번에 실행하게 됩니다. 이는 실제 프로젝트에서 이용하게 될 방법이 되겠지요.
그림 5.2는 데이터를 임의로 수정해본 화면입니다.
그림 5.2 데이터를 수정한 화면
그림 5.3은 데이터를 수정하여 다시 엑셀로 출력한 엑셀 화면을 보였습니다.
그림 5.3 데이터를 수정하여 엑셀로 전달한 화면
그림 5.4는 인쇄미리보기 버튼을 클릭했을 때, 엑셀에 적용된 인쇄 미리보기 화면입니다.
그림 5.4 인쇄 미리보기가 적용된 엑셀 화면
마무리
이렇게 해서 LabWindows/CVI 프로그램에서 엑셀로 데이터를 내보내는 예제를 만들어 보았습니다. 간단히 만든 예제이므로 수정될 여지가 있는 부분을 잠깐 짚고 넘어가겠습니다.
- 엑셀 양식 파일명
- 엑셀 양식이 변하든지 다른 파일로 변경되었을 때, Proc_Export_to_Excel() 함수 부분
- Excel 실행화면 보이기: 실제 프로젝트에서는 보이지 않도록 하는 것이 자연스럽겠습니다.
- cmdOneStop() 함수 내부: 실제 프로젝트에 적용될 때에는 단계별 콜백함수가 필요없으므로 각 단계의 처리를 그대로 넣어주면 되겠음
- 본 예제의 샘플 데이터와 테이블, 그래프 처리는 실제 적용시에는 달라질 수 있음
오래전부터 생각만 해오던 "엑셀로 출력하기" 강좌를 드디어 마무리하게 되네요. 실전에 잘 활용하셔서 원하시는 목적을 달성하시기를 진심으로 바라마지 않습니다.
엑셀 양식 구상 및 작성: 58분
예제 프로그램 구상 및 작성: 2시간 2분
강좌 문서 작성: 3시간 34분
(총 6시간 34분)
극동테크(www.kdtechno.com) 허창원 드림
허창원
Generating Microsoft Excel Reports with LabWindows/CVI
http://zone.ni.com/devzone/cda/tut/p/id/5835
조영진
------------------------------------------------------------
제가 쓰는 cvi의 버전이 6.0인데 이 버전에서는 안되는 것인지요? 아래와 같은 에러창이 뜹니다.
----------
메시지 팝업창에 제목은 "OutputExcel_dbg.exe - 시작 지점 없음"
메시지 팝업창의 내용은 “프로시저 시작 지점 _UP_PlotPackedDigitallLinesMultiBus을(를) DLL cvirt.dll에서 찾을 수 없습니다.” 라고 나옵니다.
--------
프로젝트 파일 구성은 5개 파일인
Path = "/f/User_File/SW_HW/CVI/Excel/OutputExcel/KD_Excel2.lib"
Path = "/f/User_File/SW_HW/CVI/Excel/OutputExcel/OutputExcel.c"
Path = "/f/User_File/SW_HW/CVI/Excel/OutputExcel/OutputExcel.uir"
Path = "/f/User_File/SW_HW/CVI/Excel/OutputExcel/KD_Excel2.h"
Path = "/f/User_File/SW_HW/CVI/Excel/OutputExcel/OutputExcel.h"
으로 구성되어 있습니다. 다른 버전이 없어서 다른버전에서 시험을 못해봤습니다.
그리고 cvi8.5를 NI사 홈페이지에서 30일 판으로 다운받을수 있던데 혹시 시간 다 되었을 경우 포멧하고 다시 설치하면 다시 사용가능한지 알려주시면 고맙겠습니다. --;;
이현화
메인함수내에 //테이블에 추가함 항목에서
SetTableCellVal (panelHandle, PANEL_TABLE, MakePoint (1, i+1), Data[i]); 구절에서 Data[i] 부분이 자꾸 에러를 내뿜네요.
에러메세지는 다음과 같구요.
FATAL RUN-TIME ERROR: "OutputExcel.c", line 69, col 72, thread id 0x00000A38: Invalid argument type: found 'double', expected 'pointer to char'.
이문장을 주석처리 하고 실항하면 되기는 하는데
엑셀로 데이터가 보내지지 않네요.
어디가 잘못된건지 알수 있을까요?
혹시 버전이 틀려서 그런건가요?
참고로 전 8.5버젼을 쓰고있습니다.
언젠가 꼭 한번 따라 해봐야 겠습니다. 감사합니다.