IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

lourdes les instances multiples


Sujet :

Macros et VBA Excel

  1. #1
    Membre émérite

    Homme Profil pro
    Technicien Métrologie R&D
    Inscrit en
    Janvier 2007
    Messages
    1 610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien Métrologie R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 610
    Points : 2 523
    Points
    2 523
    Billets dans le blog
    1
    Par défaut lourdes les instances multiples
    Bonjour
    la problématique:
    j'ai un logiciel d'analyse de mesure, il s'agit de nuage de point mesurés sur une 3D le logiciel (Smartfit) crée des rapport Excel plusieurs feuilles de données, graphiques et images et, à chaque rapport généré ouvre une instance d'Excel 2007 et y met un classeur avec un pré-nommage générique suivi d'un numéro d'ordre
    ces classeurs sont avec des macros (que l'on n'enregistre pas) et ne sont pas enregistrés.
    j'ai un programme qui repique dans ces classeurs les données intéressant les chef de projets BE.
    Mais celui-ci ne peut travailler que sur des classeurs enregistrés. (j'ai assez souvent une quarantaine de ces classeurs rapports en cours et donc une quarantaine d'instance d'Excel ouverte)
    la question est comment par macro (dans le XLB ) enregistrer tous les classeurs ouvert, quelque soit l'instance ou ils se trouvent

    pour l'instant toutes mes tentatives se sont soldées par la fermeture du fichier dans l'instance pointée... c'est plus rapide de faire des va et viens avec la souris que de rouvrir la fenêtre d’exécution des macros
    Merci
    Daranc

  2. #2
    Membre confirmé
    Homme Profil pro
    conseiller
    Inscrit en
    Janvier 2013
    Messages
    367
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : conseiller
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2013
    Messages : 367
    Points : 649
    Points
    649
    Par défaut
    Bonjour,
    je ne veux pas t'embarquer sur une fausse piste et peut-être y-a-t-il plus simple mais, si j'ai bien compris ton problème, tu devrais faire une recherche sur l'utilisation de l'API AccessibleObjectFromWindow qui te permet justement d'accéder à un objet VBA à partir du Handle (au sens identifiant) de sa fenêtre, et par là même aux propriétés de l'objet que tu pourras ensuite manipuler.

    Tu peux par exemple regarder ici une possibilité qui te permettra de comprendre la manière de procéder.
    A+

    Edit : voir également

  3. #3
    Membre du Club
    Homme Profil pro
    Ingénieur
    Inscrit en
    Juin 2014
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2014
    Messages : 35
    Points : 55
    Points
    55
    Par défaut Xlstart
    Bonjour,

    Personnellement j'aurais créé un fichier dans le dossier xlstart avec le code gérant la fermeture du fichier.

    Éventuellement dans la première session d'Excel j'aurais ouvert un fichier avec une fonction public prenant pour argument un objet Excel.Application qui peut être appeler depuis les autres instances qui enverrai leur propre instance à la premiere session.
    Power Tree - Complément Excel
    www.xl-powertree.com
    Analysez et consolidez vos tableaux Excel

  4. #4
    Membre confirmé
    Homme Profil pro
    conseiller
    Inscrit en
    Janvier 2013
    Messages
    367
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : conseiller
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2013
    Messages : 367
    Points : 649
    Points
    649
    Par défaut
    Bonjour,
    code adapté du lien, à tester de ton côté :
    - la Sub Ouvrir_Instance_Excel ouvre 3 instances d'Excel
    - la Sub Fermer_Instance_Excel ferme les classeurs sans les enregistrer ainsi que les 3 instances.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    Option Explicit
     
    #If Win64 Then
      Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
      (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
      Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" _
      (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
      Declare PtrSafe Function IIDFromString Lib "ole32" (ByVal lpsz As LongPtr, ByRef lpiid As UUID) As Long
      Declare PtrSafe Function AccessibleObjectFromWindow Lib "oleacc" _
      (ByVal hwnd As Long, ByVal dwId As Long, ByRef riid As UUID, ByRef ppvObject As Object) As Long
    #Else
      Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
      (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
      Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _
      (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
      Declare Function IIDFromString Lib "ole32" (ByVal lpsz As Long, ByRef lpiid As UUID) As Long
      Declare Function AccessibleObjectFromWindow Lib "oleacc" _
      (ByVal hwnd As Long, ByVal dwId As Long, ByRef riid As UUID, ByRef ppvObject As Object) As Long
    #End If
     
    Type UUID 'GUID
      Data1 As Long
      Data2 As Integer
      Data3 As Integer
      Data4(7) As Byte
    End Type
     
    Const IID_IDispatch As String = "{00020400-0000-0000-C000-000000000046}"
    Const OBJID_NATIVEOM As Long = &HFFFFFFF0
     
     
    'ouvre 3 instances d'Excel
    Sub Ouvrir_Instance_Excel()
      Dim currentExcel As Excel.Application
      Dim newExcel As Excel.Application
      Dim i As Long
     
      Set currentExcel = GetObject(, "excel.application")
      For i = 1 To 3
        Set newExcel = CreateObject("excel.application")
        newExcel.Visible = True
        newExcel.Workbooks.Add
      Next i
    End Sub
     
     
    Sub Fermer_Instance_Excel()
    On Error GoTo MyErrorHandler
    Dim hWndMain As Long
     
    hWndMain = FindWindowEx(0&, 0&, "XLMAIN", vbNullString)
     
    Do While hWndMain <> 0
      GetWbkWindows hWndMain
      hWndMain = FindWindowEx(0&, hWndMain, "XLMAIN", vbNullString)
    Loop
    Exit Sub
     
    MyErrorHandler:
      MsgBox "GetAllWorkbookWindowNames" & vbCrLf & vbCrLf & "Err = " & Err.Number & vbCrLf & "Description: " & Err.Description
    End Sub
     
     
    Private Sub GetWbkWindows(ByVal hWndMain As Long)
      On Error GoTo MyErrorHandler
     
      Dim hWndDesk As Long
      hWndDesk = FindWindowEx(hWndMain, 0&, "XLDESK", vbNullString)
     
      If hWndDesk <> 0 Then
        Dim hwnd As Long
        hwnd = FindWindowEx(hWndDesk, 0, vbNullString, vbNullString)
     
        Dim strText As String
        Dim lngRet As Long
     
        Do While hwnd <> 0
          strText = String$(100, Chr$(0))
          lngRet = GetClassName(hwnd, strText, 100)
     
          If Left$(strText, lngRet) = "EXCEL7" Then
            GetExcelObjectFromHwnd hwnd
            Exit Sub
          End If
     
          hwnd = FindWindowEx(hWndDesk, hwnd, vbNullString, vbNullString)
        Loop
     
        On Error Resume Next
      End If
     
      Exit Sub
     
    MyErrorHandler:
      MsgBox "GetWbkWindows" & vbCrLf & vbCrLf & "Err = " & Err.Number & vbCrLf & "Description: " & Err.Description
    End Sub
     
     
    Public Function GetExcelObjectFromHwnd(ByVal hwnd As Long) As Boolean
      On Error GoTo MyErrorHandler
     
      Dim fOk As Boolean
      fOk = False
     
      Dim iid As UUID
      Call IIDFromString(StrPtr(IID_IDispatch), iid)
     
      Dim obj As Object, wb As Workbook, ClasseurActif As Boolean
     
      If AccessibleObjectFromWindow(hwnd, OBJID_NATIVEOM, iid, obj) = 0 Then 'S_OK
        Dim objApp As Excel.Application
        Set objApp = obj.Application
     
        'on vérifie si le classeur actif fait ou non partie de l'instance d'Excel traitée
        For Each wb In objApp.Workbooks
          If wb.Name = ThisWorkbook.Name Then ClasseurActif = True: Exit For
        Next wb
     
        For Each wb In objApp.Workbooks
          'si ce n'est pas le classeur contenant la macro on le ferme sans l'enregistrer
          If wb.Name <> ThisWorkbook.Name Then wb.Close False
        Next wb
        If ClasseurActif = False Then objApp.Quit
     
        fOk = True
      End If
     
    GetExcelObjectFromHwnd = fOk
     
    Exit Function
     
    MyErrorHandler:
      MsgBox "GetExcelObjectFromHwnd" & vbCrLf & vbCrLf & "Err = " & Err.Number & vbCrLf & "Description: " & Err.Description
    End Function
    A+

  5. #5
    Membre du Club
    Homme Profil pro
    Ingénieur
    Inscrit en
    Juin 2014
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2014
    Messages : 35
    Points : 55
    Points
    55
    Par défaut XLSTART
    Bonjour,

    Solution intéressante avec l'API.

    Pour illustrer mes propos avec le répertoire XLSTART :

    Créer un fichier xlam à mettre dans le dossier XLSTART (C:\Program Files (x86)\Microsoft Office\Office12\XLSTART) ou en complément à Excel.
    Dans ce fichier, il suffit de dire que si il s'ouvre, il vas chercher la première session d'Excel -> GetObject dans lequel il y aurait le "Manager" qui contiendrait par exemple la fonction permettant de gérer la session Excel en question

    Le manager dans la première session d'excel.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Public Sub ManageXlApp(XlApp As Excel.Application)
     
        'Ici il suffit de gérer XlApp
        MsgBox XlApp.Workbooks.Count
     
    End Sub
    Le code se déclenchant à chaque ouverture de session Excel via XLSTART ou les compléments.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Private Sub Workbook_Open()
     
        On Error GoTo errHandler
     
        Dim FirstXlApp As Excel.Application
        Set FirstXlApp = GetObject(, "Excel.Application")
        Call FirstXlApp.Run("ManageXlApp", Application)
        Set FirstXlApp = Nothing
     
        Exit Sub
     
    errHandler:
        Err.Clear
    End Sub
    Power Tree - Complément Excel
    www.xl-powertree.com
    Analysez et consolidez vos tableaux Excel

  6. #6
    Membre émérite

    Homme Profil pro
    Technicien Métrologie R&D
    Inscrit en
    Janvier 2007
    Messages
    1 610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien Métrologie R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 610
    Points : 2 523
    Points
    2 523
    Billets dans le blog
    1
    Par défaut fermer et enregistrer tous les classeurs ouverts
    Bonjour
    apparemment mon dernier message du 5/02/2016 ne s'est pas enregistré
    donc je reprends
    j'ai un programme d'analyse de mesure 3D (smarfit) qui me permet de sortir des rapport Excel pré nommés (mais non enregistré)
    or ce programme ouvre à chaque nouveau classeur une instance d'Excel
    je me retrouve en fin d'analyse de mes surface avec de 20 à 40 rapports (à enregistrer et fermer) plus tard un prélèvement de divers données présentent sur ces classeurs seront regroupées mais c'est une autre histoire
    comment fermer et enregistrer tous ces classeur sans avoir à placer ma souris sur chaque bouton de fermeture ou passer d'une instance à l'autre pour les fermer?
    Merci

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Data manager
    Inscrit en
    Janvier 2016
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Data manager
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Janvier 2016
    Messages : 20
    Points : 26
    Points
    26
    Par défaut
    Bonjour Daranc,

    La procédure ci-dessous enregistre et ferme tous les classeurs ouverts, sauf le classeur Excel qui contient la macro.
    A placer dans un module.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    Sub Fermer_classeurs()
     
    Dim files() As String
    Dim iCount As Integer
    Dim Max As Integer
     
        Max = Workbooks.Count
     
        ReDim files(1 To Max)
     
            For iCount = 1 To Max
     
                If ActiveWorkbook.Name <> "NomDeTonFichier.xlsb" Then
                    files(iCount) = ActiveWorkbook.FullName ' pour stocker les fichiers
                    ActiveWorkbook.Save
                    ActiveWorkbook.Close
                    Else
                    ActiveWindow.ActivateNext
                End If
     
            Next iCount
     
        n = 1
     
        Erase files()
     
     
    End Sub
    Au plaisir

    Olivier

  8. #8
    Membre émérite

    Homme Profil pro
    Technicien Métrologie R&D
    Inscrit en
    Janvier 2007
    Messages
    1 610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien Métrologie R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 610
    Points : 2 523
    Points
    2 523
    Billets dans le blog
    1
    Par défaut
    merci
    toutes les macros que j'avais tentée fermer un classeur dans une instance
    je teste ça et tien le forum au courant

  9. #9
    Membre émérite

    Homme Profil pro
    Technicien Métrologie R&D
    Inscrit en
    Janvier 2007
    Messages
    1 610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien Métrologie R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 610
    Points : 2 523
    Points
    2 523
    Billets dans le blog
    1
    Par défaut
    Bonjour, je reprends le fil, après plusieurs essais , manip (avec arrachage de cheveux...et déjà qu'il ne m'en reste plus des masses) je tourne sur un constat d'echec. les divers tentatives ferme soit un classeur soit une instance. je vais laisser tomber pendant un bon moment..
    Pas compris pourquoi on ouvre autant d'instance plutôt que d'ouvrir plusieurs fenêtres dans la même instance.
    Ouvrir plusieurs fois le programme doit quand même plus charger la mémoire

Discussions similaires

  1. [kate] interdire les instances multiples
    Par Eusebius dans le forum KDE
    Réponses: 0
    Dernier message: 24/08/2007, 11h45
  2. Comment bien gérer les utilisateurs multiples
    Par Vesta dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 29/06/2006, 08h48
  3. Connaitre toutes les instances d'une classe
    Par miniseb dans le forum Langage
    Réponses: 14
    Dernier message: 09/01/2006, 17h35
  4. Clic sur les select multiple
    Par mic79 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 04/07/2005, 15h44
  5. [VB6]Prob avec les requêtes multiples
    Par cammipascal dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 30/03/2004, 18h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo