2017-10-03 33 views
0

을 종료 : 나는 검색을 수행하고있는 경우 있음을 이해 : 엑셀 OLE 개체 여전히 프로세스 목록 후이 코드를

function XlsToStringGrid(AGrid: TStringGrid; AXLSFile: string): Boolean; 
const 
    xlCellTypeLastCell = $0000000B; 
var 
    XLApp, Sheet: OLEVariant; 
    RangeMatrix: Variant; 
    x, y, k, r: Integer; 
begin 
    Result:=False; 
    //Cria Excel- OLE Object 
    XLApp:=CreateOleObject('Excel.Application'); 
    try 

     XLApp.Visible:=False; 

     XLApp.Workbooks.Open(AXLSFile); 
     Sheet:=XLApp.Workbooks[ExtractFileName(AXLSFile)].WorkSheets[1]; 
     Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate; 

     x:=XLApp.ActiveCell.Row; 

     y:=XLApp.ActiveCell.Column; 

     AGrid.RowCount:=x; 
     AGrid.ColCount:=y; 

     RangeMatrix:=XLApp.Range['A1', XLApp.Cells.Item[X, Y]].Value; 

     k:=1; 
     repeat 
      for r:=1 to y do 
       AGrid.Cells[(r - 1),(k - 1)]:=RangeMatrix[K, R]; 
      Inc(k,1); 
     until k > x; 
     RangeMatrix:=Unassigned; 
     Result:=True; 

    finally 

     if not VarIsEmpty(XLApp) then 
     begin 
      Sheet:=Unassigned; 
      XLApp.Workbooks[ExtractFileName(AXLSFile)].Close; 
      XLApp.Quit; 
      XLAPP:=Unassigned; 
     end; 
     try freeandnil(XLAPP) except; end; 
     try freeandnil(Sheet) except; end; 
    end; 
end; 

하지만 종료 명령을 종료 한 후에, 프로세스가 여전히 목록에 고려 남아

그것은 목록에 남아있는 참조 된 객체이지만, 나는 그것이 모두 공개되었다고 믿습니다.

+1

당신이 설명하는 동작을 재현 할 수 없습니다. 응용 프로그램이 종료 된 후 1 초가 지나면 Excel이 작업 목록에서 사라집니다. 'Sheet.Cells.SpecialCells (xlCellTypeLastCell, EmptyParam) .Activate; [...] RangeMatrix : = Unassigned;를 주석 처리하면 여전히 동작을합니까? 그렇게한다면 독자는 워크 북의 내용과 관련이 있다고 의심 할 수 있습니다. 따라서 처음부터 코드를 생성 할 수있는 독자가 없으면 독자는 도움을받을 수 없습니다. – MartynA

+0

와우, 부품에서 잊어 버렸습니다. 실제로 이것을 시도하지 않았습니다. 프로세스를 열어 보는 오류를 생성하는 Variable RangeMatrix가이를 정리하는 기능을 수행한다는 것을 알았던 작업을 주석 처리 한 후 보았습니까? 할당되지 않은 상태로 설정하지 않고도? –

+0

여전히 문제를 재현 할 수 없습니다. 나는 독자들이 악성 코드를 포함 할 수있는 샘플 스프레드 쉬트를 기꺼이 다운로드 할 것이라고 생각하지 않는다. 그래서 내가 제안 할 수있는 유일한 것은 문제를 나타내는 파일을 생성하는 데 필요한 코드를 q에 추가하는 것이다. – MartynA

답변

5

Excel의 Quit() 명령이 동기가 아닙니다. 프로세스가 실제로 종료 될 때까지 시간이 걸릴 수 있습니다.

예, 활성 개체 참조가있을 수 있습니다. repeat 루프에서 예외가 발생하면 RangeMatrix을 지우지 않으므로 XlsToStringGrid()이 종료 될 때까지 지워지지 않을 수 있습니다. 각 개체에 대해 하나씩 복수 try/finally 블록을 사용해야합니다.

그리고 (Ole)Variant 변수에 FreeAndNil() 전화하지 마세요. 그것은 TObject 포인터에서만 작동합니다.

대신을 시도해보십시오

function XlsToStringGrid(AGrid: TStringGrid; AXLSFile: string): Boolean; 
const 
    xlCellTypeLastCell = $0000000B; 
var 
    XLApp, WorkBook, Sheet: OLEVariant; 
    RangeMatrix: Variant; 
    x, y, k, r: Integer; 
begin 
    Result := False; 

    XLApp := CreateOleObject('Excel.Application'); 
    try 
    XLApp.Visible := False; 

    XLApp.Workbooks.Open(AXLSFile); 
    try 
     WorkBook := XLApp.Workbooks[ExtractFileName(AXLSFile)]; 
     try 
     Sheet := WorkBook.WorkSheets[1]; 
     try 
      Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate; 

      x := XLApp.ActiveCell.Row; 
      y := XLApp.ActiveCell.Column; 

      AGrid.RowCount := x; 
      AGrid.ColCount := y; 

      RangeMatrix := XLApp.Range['A1', XLApp.Cells.Item[X, Y]].Value; 
      try  
      k := 1; 
      repeat 
       for r := 1 to y do 
       AGrid.Cells[(r - 1),(k - 1)] := RangeMatrix[K, R]; 
       Inc(k); 
      until k > x; 
      finally 
      RangeMatrix := Unassigned; 
      end; 

      Result := True; 
     finally 
      Sheet := Unassigned; 
     end; 
     finally 
     WorkBook.Close; 
     WorkBook := Unassigned; 
     end; 
    finally 
     XLApp.Workbooks.Close; 
    end; 
    finally 
    XLApp.Quit; 
    XLAPP := Unassigned; 
    end; 
end; 
+0

설명 주셔서 감사합니다. FreeAndNil의 사용에 대한이 제한을 알지 못했지만 언급 한대로 기능을 교환 한 후에도 프로세스가 목록에 남아 있습니다. 일부 특정 스프레드 시트 콘텐츠가이를 관리합니까? note : 응용 프로그램을 닫았지만 프로세스가 여전히 목록에 남아 있습니다. –