Q&A

  • 엑셀을 종료하면 죽어야 하는데 죽지를 않아요...
엑셀인데요.. 엑셀을 종료하면 죽어야 하는데 죽지를 않아요
아래는 소스입니다.
procedure TFrmMain.FormShow(Sender: TObject);
Var wnd: HWND;
begin
  try
      XLApp:= CreateOleObject('Excel.Application');
  except
      ShowMessage('엑셀이 설치되어있지 않습니다.');
      exit;
  end;

  XLApp.Visible := True;   //엑셀실행
  wnd := findwindow('XLMAIN', nil );
  Windows.SetParent(wnd, Panel1.Handle); //Panel1.Handle
  SetWindowPos( wnd, Panel1.Handle , 0, -26, Panel1.clientwidth, Panel1.clientheight , SWP_NOZORDER or sWP_SHOWWINDOW );   //엑세을 실행하여.. panel1올려보여줌

end;

//위까지는 문제없습니다.

엑세을 불러서 이제 파일을 선택한다음 다른폼으로 가공하는부분입니다.

procedure TFrmMain.SpeedButton1Click(Sender: TObject);
Var FrmOpt : TFrmOpt;
   CO ,i: integer;
begin
  FrmOpt := TFrmOpt.Create(SELF);
   with FrmOpt do
   begin
       sheetcnt  := XLApp.workbooks.count ;
       Sheet_Name:= XLApp.Workbooks[sheetcnt].WorkSheets[1].Name ;
       Sheet     := XLApp.WorkBooks[sheetcnt].WorkSheets[sheet_name];

       CO := XLAPP.ActiveSheet.UsedRange.Columns.Count;
       for i := 1 to co  do
       begin
           ComboBox1.Items.Add(Sheet.Cells[1,i]);
       end;
     ShowModal ;    //다른폼실행
   end;
end;   //다른폼종료한후 이제 폼을 종료하러갑니다.

procedure TFrmMain.FormDestroy(Sender: TObject);
begin

if not VarIsEmpty(XLApp) then begin
    XLApp.Quit;     //메인폼을 종료하면요  잘못된연산  이라는 에러가 발생하고
end;                 //프로그램이 안죽을때가 있구요..  자꾸 엑셀이 종료가 안되요
end;


진짜로 엑셀을 정상적으로 종료시키고 싶어요

제발 부탁입니다.

무엇이 잘못되었는지 부탁드립니다.

또한 모르시더라고 이런것은 한번쯤 같이 연구좀해주세요


1  COMMENTS
  • Profile
    이추형 2002.08.28 02:22
    //////////////////////////////////////////////////////////////////////////////////
    //  Excel을 create object를 하여 excel을 사용한후에 백그라운드에 살아있는
    //  불사조같은 excel을
    //  완존히 보내버리는 ...악~~ 소리없이..조용히..흐흐흐흐흐흐..나쁜넘..
    //////////////////////////////////////////////////////////////////////////////////

    0. 해당폼에 listbox1를 하나추가해줄것..(실행시는 안보이게설정한다.)

    1. uses 절에 다음을 포함할것.
    Tlhelp32;

    2. 다음을 상수로 선언해줄것.
    PROCESS_TERMINATE = $0001;            // const for killing a proc
    PROCESS_SET_INFORMATION   = $0200;    // const for changing priority  

    3. 선언부문
    (********************************************************************************************)
    procObject = class                    // class for use with Tlistbox.objects
    private
      fProc: TProcessEntry32;             // declare all data private for any future changes
      procedure putProcData(const value: TProcessEntry32);
      function getProcData: TProcessEntry32;
      procedure setPriority(const value: integer);
      function getPriority: Integer;
    public
      constructor create(procinfo: TProcessEntry32);
    published
      property Theproc: TProcessEntry32 read getProcData write putProcData;
      property ProcPriority: Integer read getPriority write setPriority;
    end;
    (********************************************************************************************)

    3. 구현부문

    constructor procObject.create(procinfo: TProcessEntry32);
    begin
    inherited create;                     // need to specify which inherited constructor to call
    theproc := procinfo;                  // since parameter list differ
    end;

    function procObject.getPriority: Integer;
    begin
       result := fProc.pcPriClassBase;
    end;

    function procObject.getProcData: TProcessEntry32;
    begin
       result := fproc;
    end;

    procedure procObject.putProcData(const value: TProcessEntry32);
    begin
       fproc := value;
    end;

    procedure procObject.setPriority(const value: integer);
    var  ProcHandle: THandle;
    begin                                   // setter for property Theproc
    ProcHandle := OpenProcess(PROCESS_SET_INFORMATION, false, fProc.th32ProcessID);
    if not SetPriorityClass(ProcHandle, value) then
      ShowMessage('An error occured while trying to change process priority')
    else
        fProc.pcPriClassBase := value;
    if prochandle > 0 then
      CloseHandle(ProcHandle);
    end;

    5. 실행부문( KillExcel을 Excel Process를 없애고자하는 시점에서 호출해준다.)
    procedure TFrmDbm_BaseImport.KillExcel;
    var
    Proc: TProcessEntry32;
    proc_Kill: procobject;
    Snap: THandle;
    procHandle_Kill : THandle;
    prochandle: procObject;
    tempname: string;
    oldindex: integer;
    ExitCD: integer;
    begin
       //Excel이 실행중인지 아닌지 확인하는 작업을 해줄것....
       try
         Snap := CreateToolHelp32SnapShot(TH32CS_SNAPALL, 0);                                   // API in ToolHelp.pas (dcu)
         Proc.dwSize := SizeOf(TProcessEntry32);
         Process32First(Snap, Proc);
         repeat
               prochandle := procObject.create(proc);
               if length(string(Proc.szExeFile)) > 0 then                                       // check for processes without a description
               begin
                    tempname := proc.szExeFile;
                    if tempname ='C:PROGRAM FILESMICROSOFT OFFICEOFFICEEXCEL.EXE' then
                    begin
                          listbox1.items.addobject(tempname, prochandle);                       // save the process object to the list

                          proc_Kill := procObject(listbox1.items.objects[0]);                   // get handle
                          procHandle_Kill := 0;
                          try                           // and kill process
                            procHandle_Kill := OpenProcess(PROCESS_TERMINATE, false, proc_Kill.Theproc.th32ProcessID);
                            TerminateProcess(procHandle_Kill, ExitCd);
                          except
                            showmessage('Excel process 를 종료하지 못했습니다. ctr + alt + del key를 눌러서 excel 작업을 종료하십시요 !' +
                              #13 + 'Error code :' + inttostr(ExitCD));
                          end;
                          if procHandle_Kill <> 0 then
                            CloseHandle(procHandle_Kill);
                    end;
               end;
         until (not Process32Next(Snap, Proc));
       except
         showmessage('An error occurred while reading task information');
       end;
    end;