PDA

Ver la Versión Completa : Esperar hasta que se cierre Excel


Er_Manué
27-10-2005, 13:21:37
Estoy haciendo una aplicación que me genera un informe en Excel manejandolo a pelo ;) Todo vá perfecto, imprimir sin mostrar excel, acceder a los datos, etc... el problema viene cuando formateo el informe y lo abro para que el usuario tenga vista previa, ahi se me descojona la apliación, ya que no se como hacer para que el programa espera hasta que el usuario cierre la hoja excel y así poder liberar correctamente la referencia a excel.

Utilizo el siguiente código para abrir Excel y mostralo:

var
Excel: Variant;
miWBK, miWS : OleVariant;

...

begin
try
Excel := GetActiveOleObject('Excel.Application');
except
Excel := CreateOleObject('Excel.Application');
end;

// Impedimos que se muestre Excel
Excel.Visible := false;

// Abrimos el fichero .xls y obtenemos la hoja que necesitemos
miWBK := Excel.WorkBooks.Open(rutaHojaExcel);
miWS := miWBK.Worksheets.Item[nombreHojaExcel];

// Realizamos todas las operaciones con la hoja excel ---------------------
...

// Mostramos la vista previa del informe
Excel.Visible := true;

¡ Aquí debería esperar hasta que el usuario cierre la aplicación Excel !


// Esté sería el código que emplearía para liberar la referencua a Excel
try
Excel.DisplayAlerts := false;
Excel.Quit;
finally
Excel := Unassigned;
end;
end;


salu2

Er_Manué
27-10-2005, 16:29:08
Ya lo he solucionado :p aunque realmente no espero a que cierre Excel, simplemente espero hasta que el usuario cierre todos los libros ;)

Este sería el código definitivo:

var
Excel: Variant;
miWBK, miWS : OleVariant;

...

begin
try
Excel := GetActiveOleObject('Excel.Application');
except
Excel := CreateOleObject('Excel.Application');
end;

// Impedimos que se muestre Excel, así como sus alertas
// (por ejemplo si deseamos guardar el archivos y cosas similares)
Excel.DisplayAlerts := false;
Excel.Visible := false;

// Abrimos el fichero .xls y obtenemos la hoja que necesitemos
miWBK := Excel.WorkBooks.Open(rutaHojaExcel);
miWS := miWBK.Worksheets.Item[nombreHojaExcel];

// Realizamos todas las operaciones con la hoja excel ---------------------
...

// Mostramos la vista previa del informe
Excel.Visible := true;

// Esperamos a que se cierre excel
try
while Excel.Worksheets.count > 0 do Application.processMessages;
except
// Si hemos cerrado todos los libros abiertos, se produce una excepcion
// saliendo del bucle while
try
// Cerramos Excel
Excel.Quit;
finally
Excel := Unassigned;
end;
end;
end;


Salu2

ferna
28-10-2005, 04:08:18
Hola yo utilizo la siguiente funcion para llamar a un programa externo y esperar hasta que termine.


function WinExecAndWaitEx(FileName: TFileName; TimeOut: DWORD): Boolean;
var
{$IFDEF WIN32}
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
ExCode,Res : DWORD;
{$ELSE}
hAppInstance: THandle;
Msg : TMsg;
aBuf : array[0..255] of Char;
{$ENDIF}
begin
Result := False;
{$IFNDEF WIN32}
hAppInstance := WinExec(StrPCopy(aBuf, FileName), SW_NORMAL);
if (hAppInstance < HINSTANCE_ERROR) then exit
else
repeat
while PeekMessage(Msg, 0, 0, 0, pm_Remove) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
until (GetModuleUsage(hAppInstance) = 0);
Result := True;
{$ELSE}
FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
with StartupInfo do
begin
cb := SizeOf(TStartupInfo);
dwFlags := STARTF_USESHOWWINDOW;
wShowWindow := SW_NORMAL;
end;
if CreateProcess(nil,PChar(FileName),nil,nil,False,NORMAL_PRIORITY_CLASS,
nil,nil,StartupInfo,ProcessInfo) then
begin
Res := WaitforSingleObject(ProcessInfo.hProcess, TIMEOUT);
if (Res = WAIT_TIMEOUT) then
begin
TerminateProcess(ProcessInfo.hProcess,0);
CloseHandle(ProcessInfo.hProcess);
Result := False;
end
else
begin
GetExitCodeProcess(ProcessInfo.hProcess, ExCode);
CloseHandle(ProcessInfo.hProcess);
Result := True;
end;
end;
{$ENDIF}
end;




La llamo asi:


Result := WinExecAndWaitEx(FileName,INFINITE);



Bueno espero que te sirva.
Saludos

Fernando