XL 2021 Forcer Excel à n'ouvrir qu'une seule instance

  • 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,

Lorsque des macros Complément (AddIn) doivent interagir avec plusieurs classeurs il faut que ces classeurs s'ouvrent dans la même instance d'Excel.
S'il y a plusieurs instances, chacune d'elle charge le(s) Complément(s) et tout ce beau monde travaille en parfaite indépendance. Ce que je voudrais éviter.

Donc y a-t-il un moyen de forcer Excel à n'ouvrir qu'une seule instance pour tous les classeurs ?
 
Solution
Voir cette ressource:

Edit: pour ouvrir un fichier Excel dans une nouvelle instance
1- Clic droit / Ouvrir / puis appuyer immédiatement sur <Alt> et rester appuyé jusqu'au prompt pour ouvrir une nouvelle instance
2 - Barre de recherche / Taper Excel.exe /x (ouvre un nouveau classeur dans une nouvelle instance)
Bonjour @Dudu2

Une piste qui se passe dans la BDR pour avoir la valeur pour 2 instances excel si j'ai bien compris donc "en raisonnant à l'envers" tu devrais pouvoir trouver la valeur pour n'avoir qu'une seule instance d'excel ......


A lire avant toute intervention ..... et je ne suis responsable de rien bien sur ..... 😉
 
Merci @Phil69970 pour ton retour.
On trouve l'indication pour forcer une nouvelle instance mais rien pour forcer une seule instance.
Dans les commentaires sur Microsoft ça à énervé pas mal de gens et moi aussi !
Cette fonctionnalité à été introduite à partir de 2010 (?) Et ça à foutu la panade.
 
La 2ème piste peut être intéressante mais c'est indirect.
Il faudrait déclencher un .bat sur l'ouverture d'un fichier Excel. Je sais pas trop faire ça.
Sinon, je n'ai trouvé AUCUN moyen d'éviter ce système mis en place par Microsoft qui bien sûr n'a pas prévu d'option pour l'inhiber.
Et ça emm**de tout le monde, notamment pour les macros qui ont besoin d'avoir la visibilité sur tous les classeurs ouverts.
Sans compter "ability to use Paste Special, linking between different files, copying large amounts of data, etc"
C'est inadmissible !

Reste peut-être l'ouverture du 2ème+ classeur via une macro qui propose un dialogue d'ouverture fichier.
Ou encore un Complément avec de l'API et gérant les évènements d'ouverture de classeur qui scanne les processus Excel et ferme ceux qui ne sont pas le 1er en passant au 1er l'ordre de l'ouvrir via un fonction. Une usine à gaz quoi !
 
Dernière édition:
A relire ta demande et mon post #2 je pense qu'il est possible de récupérer/tester la valeur dans la BDR de la valeur DWORD.

Une piste qui se passe dans la BDR pour avoir la valeur pour 2 instances excel si j'ai bien compris donc "en raisonnant à l'envers" tu devrais pouvoir trouver la valeur pour n'avoir qu'une seule instance d'excel ......

En fonction de la réponse tu devrais savoir si une instance excel ou plusieurs est en cours et agir en conséquence
 
Certes, mais même si je peux lire la valeur de DisableMergeInstance qui sert à forcer le multi-instances, je ne peux rien en faire.
Si c'est 1, chaque classeur possède son instance car le "merge" des instances est désactivé.
Si c'est 0 c'est au gré d'Excel (ou autre cause) la même instance ou une nouvelle instance.
Donc dans les 2 cas, c'est jamais garanti 1 seule instance.

Il faudrait une valeur DisableMutliInstance ou DisableSplitInstance ou EnableSingleInstance mais ça n'existe pas.
D'ailleurs toutes les discussions sur les forums Microsoft constatent qu'il n'est pas possible de forcer 1 seule instance.
Sauf peut-être avec ta 2ème solution, à vérifier, mais ce n'est pas simple car il faut dévier l'ouverture des fichiers Excel vers un script.
 
Au moins dans un cas tu sauras si tu es dans une instance unique et tu pourras continuer dans l'autre cas tu fais un message par exemple pour indiquer la marche à suivre pour l'utilisateur ou tu lui dis que c'est impossible d'aller plus loin avec ton fichier ....

C'est pas top mais c'est un début ...
 
De toutes façons, je ne peux savoir le nombre d'Instances qu'en parcourant les Process actifs.
De plus, lors de l'ouverture d'un classeur, Excel lance une Instance dédié et la fusionne avec l'Instance existante (d'où le clé de registre DisableMergeInstance). Et parfois il ne la fusionne pas sans qu'on sache vraiment comment il décide.

A supposer que je scanne les Process actifs, encore faudrait-il discriminer une Instance temporaire qui sera fusionnée et une Instance réellement distincte. A la limite ce doit être possible en gérant les évènements de l'Application sur Workbook_Open mais la difficulté c'est de demander à l'instance unique qu'on veut conserver (la 1ère) de ré-ouvrir le classeur ouvert dans la 2ème Instance qu'on veut fermer (le tout via API).
Peut-être avec un fichier Texte indiquant le PID de la 1ère instance et un nom de classeur à ouvrir placé dans le fichier par une 2ème instance ou nième instance. Quelle usine à gaz !
 
Dernière édition:
Hello,
voici un code qui liste toutes les instances d'Excel, qui récupère l'objet Application de chaque Instance et qui liste les classeurs ouverts dans les instances.
VB:
#If VBA7 Then
  Private Declare PtrSafe Function AccessibleObjectFromWindow Lib "oleacc" ( _
    ByVal hwnd As LongPtr, ByVal dwId As Long, riid As Any, ppvObject As Object) As Long

  Private Declare PtrSafe Function FindWindowExA Lib "user32" ( _
    ByVal hwndParent As LongPtr, ByVal hwndChildAfter As LongPtr, _
    ByVal lpszClass As String, ByVal lpszWindow As String) As LongPtr
#Else
  Private Declare Function AccessibleObjectFromWindow Lib "oleacc" ( _
    ByVal hwnd As Long, ByVal dwId As Long, riid As Any, ppvObject As Object) As Long

  Private Declare Function FindWindowExA Lib "user32" ( _
    ByVal hwndParent As Long, ByVal hwndChildAfter As Long, _
    ByVal lpszClass As String, ByVal lpszWindow As String) As Long
#End If

Sub Test()
  Dim xl As Application, Wb
  For Each xl In GetExcelInstances()
    Debug.Print "Instance de: " & xl.ActiveWorkbook.FullName
    For Each Wb In xl.Workbooks
       Debug.Print "Classeur :", Wb.Name
    Next Wb
    Debug.Print "============================="
  Next
End Sub

Public Function GetExcelInstances() As Collection
  Dim guid&(0 To 3), acc As Object, hwnd, hwnd2, hwnd3
  guid(0) = &H20400
  guid(1) = &H0
  guid(2) = &HC0
  guid(3) = &H46000000

  Set GetExcelInstances = New Collection
  Do
    hwnd = FindWindowExA(0, hwnd, "XLMAIN", vbNullString)
    If hwnd = 0 Then Exit Do
    hwnd2 = FindWindowExA(hwnd, 0, "XLDESK", vbNullString)
    hwnd3 = FindWindowExA(hwnd2, 0, "EXCEL7", vbNullString)
    If AccessibleObjectFromWindow(hwnd3, &HFFFFFFF0, guid(0), acc) = 0 Then
      GetExcelInstances.Add acc.Application
    End If
  Loop
End Function

Ami calmant, J.P
 
Bonjour à tous,

@jurassic pork :
Ta proposition est très intéressante.
Chez moi, elle m'a renvoyé des "doublons d'application". J'avais 2 instances Excel ouvertes, et ton code en voyait 6.
J'ai légèrement retouché ta fonction GetExcelInstances ainsi et le problème semble résolu :
VB:
Public Function GetExcelInstances() As Collection
  Dim guid&(0 To 3), acc As Object, hwnd, hwnd2, hwnd3
  guid(0) = &H20400
  guid(1) = &H0
  guid(2) = &HC0
  guid(3) = &H46000000

  Set GetExcelInstances = New Collection
  Do
    hwnd = FindWindowExA(0, hwnd, "XLMAIN", vbNullString)
    If hwnd = 0 Then Exit Do
    hwnd2 = FindWindowExA(hwnd, 0, "XLDESK", vbNullString)
    hwnd3 = FindWindowExA(hwnd2, 0, "EXCEL7", vbNullString)
    If AccessibleObjectFromWindow(hwnd3, &HFFFFFFF0, guid(0), acc) = 0 Then
      On Error Resume Next
       GetExcelInstances.Add acc.Application, CStr(acc.Application.Hwnd)
      On Error GoTo 0
    End If
  Loop
End Function

En tout cas, merci encore pour ta contribution.
Je mets ton code de côté 👍

A+
 
- 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

Z
Réponses
2
Affichages
4 K
Z
Retour