2017-10-03 11 views
0

J'ai ce code:Excel Ole objet Liste des processus encore après quitter

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; 

mais après arrêter de fumer avec la commande Quitter, le processus reste toujours dans la liste, les considérations: je fis des recherches et compris que s'il y a un objet référencé il reste dans la liste, mais je crois que j'ai tous libéré.

+1

Je ne peux pas reproduire le comportement que vous décrivez. Peut-être une seconde après la fin de l'application, Excel disparaît de la liste des tâches. Si vous commentez 'Sheet.Cells.SpecialCells (xlCellTypeLastCell, EmptyParam) .Activate; [...] RangeMatrix: = Unassigned;' obtenez-vous toujours le comportement? Si vous le faites, alors je soupçonnerais que c'est spécifique au contenu de votre WorkBook, donc les lecteurs ne pourraient pas aider, sauf si vous pouviez fournir du code pour le générer à partir de zéro. – MartynA

+0

Wow, j'ai oublié de faire en partie, je n'ai vraiment pas essayé cela, voyant maintenant après avoir commenté les actions que j'ai remarqué que le Variable RangeMatrix qui génère l'erreur d'ouvrir le processus, pourrait-il fonctionner pour le nettoyer? sans être juste pour définir Non affecté? –

+0

Je n'arrive toujours pas à reproduire votre problème. Je ne pense pas que les lecteurs téléchargent volontiers un exemple de feuille de calcul qui pourrait contenir des logiciels malveillants, donc la seule chose que je peux suggérer est d'ajouter à votre q le code nécessaire pour générer un fichier qui présente le problème. – MartynA

Répondre

5

La commande Quit() d'Excel n'est pas synchrone, le processus peut prendre du temps à se terminer.

Et oui, vous pouvez avoir des références d'objet actives. Vous n'effacez pas RangeMatrix si une exception se produit dans votre boucle repeat, elle peut donc ne pas être désactivée avant la fin de XlsToStringGrid(). Vous devez utiliser plusieurs blocs try/finally, un pour chaque objet.

Et s'il vous plaît, n'appelez PAS FreeAndNil() sur (Ole)Variant variables! Cela ne fonctionne que sur les pointeurs TObject.

Essayez ceci:

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

Merci pour l'explication, je ne connaissais pas cette restriction de l'utilisation de FreeAndNil, mais même après l'échange de la fonction par mentionné le processus reste dans la liste. Peut-être que du contenu de feuille de calcul spécifique gère cela? note: J'ai fermé l'application et le processus reste dans la liste. –