Chiusura Applicativi (programmi) da Excel.

Sul sito sezione vba, ho presentato come aprire applicativi usando la Shell di sistema. Riporto di seguito una possibile routine per aprire un applicativo. Usiamo il metodo Shell + Run (vedi articolo in questa sezione) al quale dovremo fornire il percorso completo che mira al file da aprire, aprendo contemporaneamente prima l'applicativo predefinito per il tipo di estensione del file scelto, e immediatamente dopo, all'interno dell'applicativo, il file; possiamo usare una variabile con la quale reperire il percorso al file, oppure scriverlo direttamente nell'istruzione. Vediamo un esempio per aprire un file musicale, il cui applicativo predefinito è Windows Media Player:

  • Sub Suona()
    Set myshell = CreateObject("WScript.Shell")
    percorso = "C:\Temp\Beck.asf" 
                             'file da aprire completo di percorso ed estensione
    myshell.Run Chr(34) & percorso & Chr(34), 2   
    'con 2 evitiamo il focus sull'applicativo (MediaPlayer)
    Set myshell = Nothing
    End Sub

Ora, come fare a chiudere l'applicativo aperto insieme a file? In genere le istruzioni Vba che io conosco, non possiedono la capacità di interreagire con applicativi esterni ad Excel, e quindi per esempio a chiudure Windows Media Player (o altro programma). Bisognerebbe conoscere la Programmazione avanzata, che io non conosco, e allora si troverebbero le strade giuste per sfruttare tutte le potenzialità della Programmazione.

Ma girando girando, ho trovato delle istruzioni che permettono di poter chiudere un'applicativo aperto tramite Excel. L'autore è Roberto Lancetti, Rob@tiscalinet.it  al quale rivolgo sentiti ringraziamenti per aver reso disponibili i suoi sforzi. Le istruzioni si basano sul riconoscimento dell'Handle del programma aperto (Handle :valore intero univoco definito dall'ambiente operativo e utilizzato dal programma per identificare e accedere a un oggetto). Per ottenere l'handle si usa il metodo Hwnd dell'oggetto Application (la proprietà Hwnd restituisce un oggetto Long che indica l'handle della finestra di livello superiore della finestra di Microsoft Excel. Proprietà di sola lettura).

Per posizionare le istruzioni, suggerisco di usare un modulo standard, vuoto, dove incollare il codice sottostante; le istruzioni si posizioneranno automaticamente nella sezione "Generale - Dichiarazioni" del modulo stesso ma, attenzione, con le nuove versioni di Sistemi Operativi e  anche di Excel a 64 bit (quindi vba 7), è necessario fare una piccola modifica alla sintassi da usare per lanciare una "dichiarazione" di apertura di una funzione: è necessario inserire la parola chiave "PtrSafe" appena dopo l'istruzione "Declare". Una dichiarazione del genere ( contenente quindi PtrSafe) sarà quindi eseguita sia su sistemi a 32 che a 64 bit

istruzione per sistemi a 32 bit

nuove istruzione per sistemi a 32/64 bit

Declare Function FindWindow Lib "user32" _
Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Declare Function PostMessage Lib "user32" _
Alias "PostMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long
Public Const WM_CLOSE = &H10

'-----------------------------------------------------------
Public Function CloseApplication(ByVal sAppCaption As String) As Boolean
Dim lHwnd As Long
Dim lRetVal As Long
lHwnd = FindWindow(vbNullString, sAppCaption)
If lHwnd <> 0 Then
lRetVal = PostMessage(lHwnd, WM_CLOSE, 0&, 0&)
End If
End Function

Declare PtrSafe Function FindWindow Lib "user32" _
Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Declare PtrSafe Function PostMessage Lib "user32" _
Alias "PostMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long
Public Const WM_CLOSE = &H10

'----------------------------------------------------------------
Public Function CloseApplication(ByVal sAppCaption As String) As Boolean
Dim lHwnd As Long
Dim lRetVal As Long
lHwnd = FindWindow(vbNullString, sAppCaption)
If lHwnd <> 0 Then
lRetVal = PostMessage(lHwnd, WM_CLOSE, 0&, 0&)
End If
End Function

la guida in linea riporta, per l'istruzione Declare, queste note:

Le istruzioni Declare contenti la parola chiave PtrSafe sono la sintassi consigliata. Le istruzioni Declare che includono la parola chiave PtrSafe funzionano correttamente nell'ambiente di sviluppo di VBA7 sia su piattaforme a 32 bit che a 64 bit solo dopo che tutti i tipi di dati nell'istruzione Declare (parametri e valori restituiti) che devono contenere quantità a 64 bit sono stati aggiornati per l'utilizzo di LongLong per gli integrali a 64 bit o LongPtr per i puntatori e punti di controllo. Per garantire la compatibilità con le versioni precedenti di VBA, versione 6 e precedenti, utilizzare il costrutto seguente:

#If Vba7 Then
Declare PtrSafe Sub...
#Else
Declare Sub...
#EndIf

Nota

Per eseguire codice in versioni di Microsoft Office a 64 bit, tutte le istruzioni Declare devono includere la parola chiave PtrSafe e tutti i tipi di dati nell'istruzione Declare (parametri e valori restituiti) che devono contenere quantità a 64 bit devono essere aggiornati per l'utilizzo di LongLong per integrali a 64 bit o LongPtr per puntatori e punti di controllo

 

 

Queste istruzioni, per poter funzionare, (cioè chiudere l'applicativo) hanno bisogno di identificare il nome che viene posto nella Label del programma, cioè quella zona posta nella barra superiore blu, che in genere descrive il nome del programma, e, in alcuni programmi, anche il nome del file aperto in quel momento; vediamo tre immagini: le frecce rosse identificano la label

Come si vede, dipende dal programma il come vengono posti nomefile aperto e nome programma; dovremo rispettare assolutamente la sintassi usata, compreso gli spazi e/o lineette, se questi fanno parte della Label, perchè saranno queste voci che dovremo usare per ottenere la chiusura.

Come sfruttiamo quindi, le istruzioni viste sopra, e poste in un modulo? useremo un'istruzione che richiami la Funzione CloseApplication , indicando il nome che appare nella label del programma da chiudere, così:

  • sAppCaption = "Windows Media Player"  ' si assegna all'argomento sAppCaption il nome presente nella label
    Run CloseApplication(sAppCaption)
     'quindi si lancia la funzione per chiudere l'applicativo

Queste due righe potranno essere inserite in una macro, messa magari nello stesso modulo, e a cui assegneremo un nome, che poi chiameremo da un pulsante apposito, e potremo intervenire a nostro piacere per chiudere l'applicativo, oppure potremo piazzarle nell'evento Workbook_BeforeClose in modo che alla chiusura della cartella o di Excel, si attivino e chiudino l'applicativo precedetemente aperto.

Nell'esempio sopra facciamo chiudere il Media Player, se dovevamo chiudere Word ed il file aperto, avremmo dovuto impostare ciò che figura nella Label, ad esempio:

  • sAppCaption = "Documento1 - Microsoft Word"  ' si assegna all'argomento sAppCaption il nome della label
    Run CloseApplication(sAppCaption)

Non è difficile sapere come si presenta una Label di un programma, basta lanciarlo al di fuori di Excel, leggere come viene impostata la scritta nella Label, e impostare di conseguenza l'istruzione vba. Se poi volessimo aprire più file in sequenza, il nome di questi file lo avremo a disposizione nel momento in cui lo apriamo, magari assegnato ad una variabile, di conseguenza sapremo come sarà composta la label.

 Il tutto non è difficile, funziona almeno su XP, ma sicuramente anche su altri sistemi operativi. E' tutto, per ora.

Buon lavoro.

prelevato sul sito www.ennius.altervista.org