Q&A

  • 프로그램 종료전에 만든 excel이 안 읽혀요
프로그램에서 그리드의 내용을 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;





4  COMMENTS
  • Profile
    하윤철 2000.04.12 21:40
    답을 얻으셨나요? 꽤 늦은 답입니다만....

    변환 작업 후에 프로그램 종료시점까지 Excell 인스턴스종료로직이 없네요.

    이런 상황이 되면 파일을 띄워도 엑셀 테두리만 보이게 되는데 엑셀을 종료해도 메모리에 인스턴스는 남게 됩니다. (종료해도 Ctrl+Alt+Del 해보면 Excel 이라고 뻔뻔하게 남아있습니다.)



    마지막 라인쯤에 있는 Excel 종료로직을 변환작업, 저장후에 한번 실행하도록 하면 프로그램 사용중에도 그파일을 띄우는데 문제가 없습니다...



  • Profile
    최용일 2000.03.16 01:28
    아마도 열기 전에 저장을 안하신것 같은데... 대강 코드를 보니까



    프로그램을 종료할 때 만들어진 엑셀파일을 저장하는것 같더군요.



    먼저 읽기 전에 저장을 해야 되지 않을까요...





    한현정 wrote:

    > 프로그램에서 그리드의 내용을 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;

    >

    >

  • Profile
    한현정 2000.03.16 02:08
    아래 소스는 컴포넌트의 소스입니다.

    호출할 때는 아래와 같이 하구요



    MsgBar1.ShowMessage('excel로 변환중입니다.');//패널에 메시지를 뿌리는 컴포넌트

    Try

    // 호출하는 부분임

    GridPrint1.ToExcel(gf_GetAccountPath+'dataAC'+IntToStr(Tag));

    Finally

    MsgBar1.ShowMessage('변환되었습니다.');

    end;



    변환이 종료한 후에 엑셀을 열어보면 안 열립니다.

    좋은 방법 없을까요?



    최용일 wrote:

    > 아마도 열기 전에 저장을 안하신것 같은데... 대강 코드를 보니까

    >

    > 프로그램을 종료할 때 만들어진 엑셀파일을 저장하는것 같더군요.

    >

    > 먼저 읽기 전에 저장을 해야 되지 않을까요...

    >

    >



  • Profile
    최용일 2000.03.16 05:01
    제가 김영대님의 TGridXLS컴포넌트를 써보지 못해서 제대로 답변을

    못드리겠군요. 김영대님에게 메일을 보내보십시요... 성실히 답변해

    줄것입니다... 죄송합니다...



    • 오종환
    • 2000.03.16 03:02
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 구창민
      2000.03.16 03:10
      오종환 wrote: > 저는 델파이를 막 접한 초보입니다 > > 제가 원하는것은 SpeedButton으로 기존의 메뉴...
    • 빡수홍
      2000.03.16 03:53
      J Wraw wrote: > MSSQL6.5를 쓰고있는데 DB connection시 UserId혹은 Password가 잘못입력시 > EDBEEngi...
    • 최용일
      2000.03.16 03:11
      메소드가 아니라 일반 프로시저나 펑션에서 호출하는 방법을 묻는 것입니까? 뭐 여러가지 방법이 있겠지만...
    • 강동길
    • 2000.03.16 02:01
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 류종택
      2000.03.16 02:11
      Calulated Field를 사용하세요.. Table을 더블클릭하시고 생긴 윈도우에서 오른쪽 마우스 클릭.. Add All...
    • 김진석
    • 2000.03.16 01:55
    • 2 COMMENTS
    • /
    • 0 LIKES
    • blueSky
      2000.03.16 02:51
      김진석 wrote: > 프로그램을 짜다 보니깐.... | 신 문| > ...
    • 조피디
      2000.03.16 02:00
      김진석 wrote: > 프로그램을 짜다 보니깐.... | 신 문| > ...
    • 초보
    • 2000.03.16 01:44
    • 4 COMMENTS
    • /
    • 0 LIKES
    • 류종택
      2000.03.16 02:04
      천리안 프로그래머 포럼에서 주어왔습니다.. From 류.. --------- unit Link; interface ...
    • 초보
      2000.03.17 10:27
      류종택님 답변 감사드립니다만. 답변 주신 소스를 보고 어떻게 해야할지 막막하네요 복사해서 실행해도 ...
    • 모질이
      2000.07.31 22:24
      바탕화면에 단축아이콘을 만들려면 인스톨쉴드에서 간단하게 할수가 있거덜랑요. specify folders and ic...
    • 최용일
      2000.03.16 14:49
      한델의 강좌란을 보세요...
    • 한현정
    • 2000.03.16 01:13
    • 4 COMMENTS
    • /
    • 0 LIKES
    • 하윤철
      2000.04.12 21:40
      답을 얻으셨나요? 꽤 늦은 답입니다만.... 변환 작업 후에 프로그램 종료시점까지 Excell 인스턴스종료로...
    • 최용일
      2000.03.16 01:28
      아마도 열기 전에 저장을 안하신것 같은데... 대강 코드를 보니까 프로그램을 종료할 때 만들어진 엑셀...
    • 한현정
      2000.03.16 02:08
      아래 소스는 컴포넌트의 소스입니다. 호출할 때는 아래와 같이 하구요 MsgBar1.ShowMessage('excel...
    • 최용일
      2000.03.16 05:01
      제가 김영대님의 TGridXLS컴포넌트를 써보지 못해서 제대로 답변을 못드리겠군요. 김영대님에게 메일을 보...
    • topsman
    • 2000.03.16 00:35
    • 2 COMMENTS
    • /
    • 0 LIKES
    • blueSky
      2000.03.16 01:17
      topsman wrote: > 현재 사용자가 사용하고 있는 OS가 어떤건지 알려면... > > 어떤 함수를 써서...정보...
    • 하얀까마귀
      2000.03.16 01:03
      안녕하세요 하얀까마귀 입니다. 그런 정보는 레지스트리에 있어요... HKEY_LOCAL_MACHINE SoftwareM...
    • 하얀까마귀
      2000.03.16 00:53
      안녕하세요 하얀까마귀 입니다. 이건 전에 제가 비슷한 내용을 올린것 같은데.... 어디 올렸지???? ...
    • 문영봉
    • 2000.03.15 23:16
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 류종택
      2000.03.16 00:08
      현재 위치에서 'f1'이라는 키를 오픈하는 것입니다.. 뒤에오는 불린은 해당 키가 없을 때 생성을 할 것인...
    • 최용일
      2000.03.16 00:03
      OpenKey는 레지스트리에 있는 키값을 열때 사용합니다. TRegistry서 값을 읽거나 쓰는 함수(TRegistry.Rea...
    • hjcho
    • 2000.03.15 23:08
    • 0 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2000.03.15 23:54
      동적으로 링크하는 방법도 있습니다. LoadLibrary함수를 DLL을 적재하시면 됩니다. 성공적으로 적재되었...
    • 윤정선
      2000.03.17 01:25
      자세한 설명을 부탁드려도 되는지요. 저는 LoadLibrary와 FreeLibrary를 이용해서 해볼려고 했는데 안되...
    • 최용일
      2000.03.17 06:14
      안녕하세요. 최용일입니다. 먼저 헬프를 사용하는 방법부터 알려드리지요. GetProcAddress과 같은 Windo...
    • neocity
    • 2000.03.15 22:34
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 화랑
      2000.03.16 02:59
      neocity wrote: > 다중 채팅을 만들었는데. > 여러 채팅 프로그램처럼 여러개의 방을 만들려구 하는데 >...
    • 하얀까마귀
      2000.03.16 00:38
      안녕하세요 하얀까마귀 입니다. c하고는 문법이 조금 다르죠... c를 windows c++을 하셧는지는 모르...
    • 백록화
      2000.03.16 00:22
      yo~ ^^*^~ exit나 break 같은 제어문을 적절히 사용하시면 됩니다. exit는 그냥 중단하는것이고..... ...
    • 강인규
      2000.03.15 22:39
      우선 저는 C는 못합니다. 그점 염두하시고 보아주시기 바랍니다. return이 어떤 형태로 작업열로 복귀하...
    • blueSky
      2000.03.15 22:24
      이수정 wrote: > 다른데 자료실에서.. 컴포넌트 파일이라며.. > > .pas 파일 두개를 받았는데.. > ...