프로그램에서 그리드의 내용을 excel화일로 만든 후
프로그램을 종료하지 않은 상태에서
그 만들어진 엑셀화일을 open하면 엑셀의 틀만 모이고 data부분은 보이질 않습니다.
(그 부분은 바탕의 내용이 그대로 보이지요)
프로그램을 종료 후 엑셀 화일을 열면 제대로 열립니다.
프로그램이 엑셀화일을 계속 잡고 있는 건 아닌지 모르겠습니다.
이유를 정말 왜 그런지 모르겠습니다.
소스도 첨부합니다.
//=============================================================================
{Export to Excel}
{ TGridXLS for Delphi by 김영대 }
{ E-mail: cozy@hanmail.net }
{ HomePage: http://www3.shinbiro.com/cozykyd/index.htm }
procedure TGridPrint.ExportToExcel(sFileName : string);
var
CurRow, CurCol,RowCnt,ColCnt : Integer;
CurMark: TBookmark;
FieldValue: Variant; {cell = field}
begin
{Excel Instance 생성}
CreateExcelInstance;
if IsExcelCreated = False then
begin
MessageBox(0,PChar('Excel을 사용할 수 없는 상태입니다.')
,PChar('오류')
,MB_ICONWARNING);
Exit;
end;
CurRow := 0;
//DBGrid
try
for CurCol :=0 to FDBGrid.Columns.Count -1 do
ExcelIns.ActiveSheet.Cells[1, CurCol+1].Value
:= FDBGrid.Columns[CurCol].Title.Caption;
CurRow := 3; // Title은 첫번째 행에 자료는 3번째 행부터 출력
with FDBGrid.DataSource.DataSet do
begin
DisableControls;
CurMark := GetBookmark; {현재 레코드 포인터 저장}
First;
while not EOF do
begin
for CurCol := 0 to FDBGrid.Columns.Count-1 do
begin
FieldValue := ''''+FDBGrid.Columns[CurCol].Field.DisplayText; {필드값}
ExcelIns.ActiveSheet.Cells[CurRow, CurCol+1].Value := FieldValue;
end;
Next;
Inc(CurRow);
Application.ProcessMessages;
end;
GotoBookmark(CurMark);
EnableControls;
end;
ExcelIns.ActiveWorkBook.SaveAs(sFileName); {파일로 저장}
finally
QuitExcelInstance; {Excel instance 해제}
end;
end;
{Excel instance 생성}
procedure TGridPrint.CreateExcelInstance;
begin
IsExcelCreated := False;
try
{CreateOLEObject('Excel.Application') 줄이 실행되면 EXCEL이 background 에서
시작되기 때문에 사용자에게 보이지 않는다.(automation 이므로)
보통 EXCEL 객체의 엔진만 사용하는 경우라면 이렇게 생성한 객체를 직접 사용해서
원하는 작업을 하면 된다. EXCEL로 자료를 전송할때는 Visible 프로퍼티를 False 로 한 후
전송 후 사용자에게 보여주도록 Visible 프로퍼티를 True 로 하는것이 속도 증진에 좋다.
그리고 FExcel := CreateOLEObject('Excel.Application') 의 의미는 Excel 의 Application
이라는 COM 객체에 대한 인스턴스를 생성하고, 이 인스턴스를 가리키는 IDispatch 인터페이스
를 FExcel 이라는 가변형 변수에 대입하는 것이다.}
{instance 생성 후 인터페이스를 받는다, 50여개의 다른 객체도 있음}
ExcelIns := CreateOLEObject('Excel.Application');
IsExcelCreated := True;
except
IsExcelCreated := False; {생성여부는 IsCreated 함수로 알 수 있다}
end;
if IsExcelCreated = True then
begin
ExcelIns.WorkBooks.Add; {FExcel 객체에 WorkBook 객체 생성, Add = Create 기능}
{Application 객체 = Excel 자신을 가리킨다
WorkBook 객체 = 실제 데이터 파일을 포함하고 있다. 즉 여러개의 Sheet 를 포함하고 있는 Excel의 .XLS 파일이
WorkBook 객체인 것이다. 이 객체에는 Open, NewSheet 와 같은 Excel 파일 수준에서 일어나는
이벤트 핸들러와 프로퍼티, 메소드 등을 제공한다
WorkSheet 객체 = Sheet 하나에 대한 객체로 Sheet 객체는 Sheet 에서 일어날 수 있는 모든 이벤트와 프로퍼티, 메소드
Chart 객체 = Excel Chart 객체
등을 제공한다
}
ExcelIns.DisplayAlerts := False; {Excel 종료시 저장 여부를 물어보지 않도록 한다}
end;
end;
procedure TGridPrint.QuitExcelInstance;
begin
if not IsExcelCreated then Exit;
if not VarIsEmpty(ExcelIns) then ExcelIns.Quit;
end;
변환 작업 후에 프로그램 종료시점까지 Excell 인스턴스종료로직이 없네요.
이런 상황이 되면 파일을 띄워도 엑셀 테두리만 보이게 되는데 엑셀을 종료해도 메모리에 인스턴스는 남게 됩니다. (종료해도 Ctrl+Alt+Del 해보면 Excel 이라고 뻔뻔하게 남아있습니다.)
마지막 라인쯤에 있는 Excel 종료로직을 변환작업, 저장후에 한번 실행하도록 하면 프로그램 사용중에도 그파일을 띄우는데 문제가 없습니다...