XL 2021 VBA - Recevoir un signal d'une autre Application

  • Initiateur de la discussion Initiateur de la discussion Dudu2
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

Dudu2

XLDnaute Barbatruc
Bonjour,

Existe-t-il un moyen pour une application source d'envoyer "quelque chose" (un signal) à une autre application cible qui déclenche chez elle un évènement ?

Je vois dans l'API la fonction SendMessage ou ce genre de chose mais rien pour en exploiter l'envoi. Ça m'échappe.

J'ai essayé un SendKeys de l'application source vers l'application cible (après l'avoir activée avec un SetForegroundWindow) qui a défini un Application.Onkey sur la clé envoyée. Ça fonctionne sauf évidemment quand l'application cible est en mode édition sur cellule auquel cas la clé arrive en cellule et n'est pas interceptée par le OnKey.
Mais envoyer une clé ça reste assez artisanale. J'aimerais un truc plus évolué.
 
Solution
Bonjour,

Cette version semble fonctionner sur des fichiers multiples lancés en /x dans un .bat.
Grâce aux SaveSetting / GetSetting de @Dranreb, elle a subit de drastiques simplifications et gère la sérialisation de la fusion des instances si besoin. Du moins je le pense !

Toutefois, chez moi, j'ai toujours eu un problème de processus EXCEL.EXE résiduel sans qu'aucun classeur ne soit plus ouvert.
Ça m'a toujours gêné et un peu énervé car ce processus résiduel (à tuer par un .bat) empêche l'ouverture d'un nouveau classeur.
Je n'ai jamais compris d'où ça venait.
Ce phénomène se produit à coup sûr chez moi lorsqu'après fusion d'instances, je ferme tous les classeurs de l'instance unique restante.

J'ai donc ajouté...
@patricktoulon,
Les évènements sont propres à l'instance.
On ne peut pas capter un WorkbookOpen si le classeur appartient à une autre instance.

Comme je l'ai dit plus haut, si on détecte la 2ème instance (il est simple de la détecter sur un Auto_\Open) on peut provoquer la fusion dans la 2ème instance, mais c'est plus complexe (voir Post #3). C'était la discussion sur ce sujet.
Il faut détecter la 2ème instance dans la 2ème instance car on ne peut pas la détecter dans la 1ère instance (sauf boucle qu'on ne veut pas) et faire la fusion dans la 1ère instance. D'où la nécessité de communiquer et surtout de déclencher un évènement dans la 1ère instance.
 
Dernière édition:
Si on peut, finalement mettre en vigilance un classeur géré par une autre instance, tester un module de classe nommé Signal :
VB:
Option Explicit
Private HNotée As Date, Fermé As Boolean
Event Synchro(ByVal H As Date)
Private Sub Class_Initialize()
   HNotée = Now: Fermé = True
   End Sub
Public Sub Actualiser()
   HNotée = Now
   SaveSetting AppName:="Excel", Section:="Synchro", Key:="Heure", Setting:=Format(HNotée, "dd/mm/yyyy hh:mm:ss")
   End Sub
Public Sub AttendreSynchro()
   Dim H As Date
   Fermé = False
   Do
      H = CDate(GetSetting(AppName:="Excel", Section:="Synchro", Key:="Heure", Default:="00/01/1900 00:00:00"))
      If Fermé Then Exit Sub
      If H > HNotée Then Exit Do
      DoEvents
      Loop
   Fermé = True
   HNotée = H
   RaiseEvent Synchro(H)
   End Sub
Public Sub Fermer()
   Fermé = True
   End Sub
Le déclarer Public SignalGéné As Signal dans un module standard pour pouvoir y exécuter sa méthode AttendreSyncro, lancée si possible d'une autre instance, le reprendre en Private WithEvents Sgl As Signal dans le module objet voulant pouvoir prendre en charge son évènement Synchro. L'y initialiser d'abord par un Set Sgl = SignalGéné.
 
Dernière édition:
Remarque: si l'objet Signal est défini dans un .xlam dont le projet est en référence dans tous les classeurs impliqués, ne pas oublier de prévoir pour cette classe, afin qu'elle soit bien connue partout l'instancing : 2 — PublicNotCreatable et de prévoir une fonction pour l'initialiser :
VB:
Public Function Signal()
   Set Signal = New Signal
   End Function
 
J'essaie d'utiliser le Application.WindowResize dans l'instance #1 sur des valeurs particulières (à déterminer) pour déclencher la fusion.
Pour l'instant je n'arrive pas à "Resizer" la fenêtre à partir de l'instance #2 bien que je connaisse son Handle.
Avec SetWindowExtEx ça ne déclenche rien.
Je vais essayer d'autres APIs.

Si ça marchait, dans le pire des cas d'un resize manuel arrivant par hasard aux mêmes valeurs particulières, ça n'aurait pas d'effet puisque la fusion n'est pas exécuté avec 1 seule instance.
 
Si quelqu'un peut me dire pourquoi l'évènement WindowResize ne se déclenche pas dans ce classeur minimal alors que j'arrive à l'avoir dans contexte infiniment plus complexe. Je suis atterré ! Suffit de resizer la fenêtre. En principe !
 

Pièces jointes

J'ai bien compris que ce que je disais ne procurait pas le moindre intérêt mais bon !

MéthodeFonctionne entre deux sessions Excel ?Commentaire
SendKeys✅ OuiBricolage peu fiable, comme tu l’as déjà testé.
Chat SQLite (ou fichier signal)✅ OuiExcellente solution : les deux Excel lisent/écrivent dans une base partagée.
Run via COM (GetObject)❌ NonNe marche que dans la même instance.
Automation Add-In ou RTD✅ OuiTrès pro, mais complexe à mettre en place.
WMI ou Named Pipes✅ OuiRéservé aux développeurs expérimentés.
Windows Messages (SendMessage API)⚠️ CompliquéPas faisable directement en VBA. Nécessite une fenêtre écoutant les messages.

✅ Recommandation simple​

Pour simuler un "signal" inter-session proprement, sans bricolage :

Utilise :​

  • un fichier texte ou SQLite avec un Timer dans le classeur cible (Timer Excel ou API Windows).
  • L’application source écrit "ACTION = faire ceci" dans la base.
  • L’application cible lit toutes les secondes et réagit si une nouvelle commande est trouvée.

 
J'ai bien compris que ce que je disais ne procurait pas le moindre intérêt mais bon !
Je comprends pas pourquoi tu dis ça @dysorthographie, bien sûr que ça compte !
Je me souviens bien des pipes en Unix / C et j'aurais bien aimé le faire en VBA.

@Dranreb, merci, je viens aussi de m'en apercevoir. Je crois que je fatigue.

Mais bon, je finirai par y arriver (cross fingers) avec ce contournement bidouille mais sûr de WindowResize.
Car IL FAUT que ce soit évènementiel et le système "fichier signal" ni aucune des autres méthodes, à part le SendKeys inutilisable ne le permet. Faut toujours une boucle qui écoute.
 
Dernière édition:
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Retour