Access Lab

Esperar a que termine una aplicación

Desde Access podemos arrancar otros programas con la función Shell. Hasta aquí no hay problema, solo que Access prosigue la secuencia de comandos sin esperar a que termine el programa arrancado, lo cual puede ser un verdadero problema en algunas ocasiones. Por ejemplo, si la misión del programa llamado es generar un fichero que a continuación queremos importar. Con ésta función, Access 2.0 (más abajo está la solución para 7.0 y 97) esperará a que finalice el programa llamado:

Declare Function ws_GetModuleUsage Lib "kernel" Alias "GetModuleUsage" (ByVal hModule%) As Integer

(La linea anterior debe incluirse en la sección Declaraciones del módulo, y es UNA sola línea)

Function WaitShell(AppName$, mode)
Dim hMod As Integer,AppRoot As String
AppRoot = Left$(AppName$, InStr(AppName$ & " ", " "))
hMod = Shell(AppName$, mode)
If (hMod > 32) Then
    While (ws_GetModuleUsage(hMod))
        DoEvents
    Wend
Else
    MsgBox "No se pudo arrancar " & AppRoot
End If
End Function

Ahora, todo lo que hay que hacer es llamar a la función WaitShell en lugar de Shell.


El ejemplo anterior es para 2.0. Con Access 7.0 y 97, la sección Declaraciones sería:

Private Const SYNCHRONIZE = &H100000
Private Const INFINITE = &HFFFF
Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, _

    ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, _

    ByVal dwMilliseconds As Long) As Long

Y la función WaitShell, además de la Sub WaitForTerm:

Function WaitShell(AppName$, mode)
Dim hMod As Long, AppRoot As String
AppRoot = Left$(AppName$, InStr(AppName$ & " ", " "))
hMod = Shell(AppName$, mode)
If hMod <> 0 Then
   WaitForTerm hMod
Else
   MsgBox "No se pudo arrancar " & AppRoot
End If
End Function


Sub WaitForTerm(pid&)
Dim phnd&
phnd = OpenProcess(SYNCHRONIZE, 0, pid)
If phnd <> 0 Then
   Call WaitForSingleObject(phnd, INFINITE)
   Call CloseHandle(phnd)
End If
End Sub


Volver a AccessLab