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

Excel Discussion :

[VBA-E] Excel attend la fin de l'exécution d'une action OLE d'une autre app


Sujet :

Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Inscrit en
    Juillet 2005
    Messages
    141
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 141
    Par défaut [VBA-E] Excel attend la fin de l'exécution d'une action OLE d'une autre app
    Bonjour à tous
    Voici mon problème: j'ai une macro qui dialogue avec un programme de simulation afin d'automatiser les calculs. Pour cela, l'installeur du programme ajoute des références à la bibliothèue VBA. La macro lance donc le programme en créant un objet .application. Puis elle rentre des données dans le programme. Elle lance ensuite une boucle pour calculer une série de débit pour une série de pression d'entrée en lançant à chaque fois la fonction de calcul du programme qui doit renvoyer un numéro.
    Mon problème est que pour certaines valeurs le programme met un peu de temps à calculer le débit correpondant et que au bout d'un moment, Excel s'impatiente et me renvoie l'erreur:
    Microsoft Excel attend la fin de l'exécution d'une action OLE d'une autre application
    A partir de là, le dialogue entre les deux programmes est rompu et Excel n'arrive plus à récupérer les résultats (d'autant que ca fait planter après mon autre logiciel.

    Est-ce qu'il est possible d'augmenter le temps d'attente d'excel?? sachant que lorsque je fais tourner la simulation en question directement, le programme réussit à le faire (mais lentement)
    J'ai tenté de régler le problème en désactivant les messages d'alertes avant et les réactivant après avec display alert= enabled mais ca me règle pas le problème (ca arrete juste de mafficher le msg d'alerte (logique).

    J'ai vu le topic (http://www.developpez.net/forums/sho...pplication)qui conseillait de fermer et d'ouvrir le programme à chaque itération mais mon pb est que ce programme est assez long et que je dois écrire des données qui ne change pas d'un calcul à l'autre donc si je dois les écrire à chaque fois, je vais vraiment augmenter mon tps d'attente

    Merci d'avance de vos réponses
    bonne journée et bonne semaine
    rémi

  2. #2
    Inactif  
    Avatar de ouskel'n'or
    Profil pro
    Inscrit en
    Février 2005
    Messages
    12 464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 12 464
    Par défaut
    Je crois que SilkyRoad a répondu à cette question il y a deux mois à peu près. Il testait l'exécution dans une boucle Do While, c'est tout ce dont je me souviens. Une recherche sur le forum VBA n'a rien donné ?

  3. #3
    Membre éprouvé
    Inscrit en
    Juillet 2005
    Messages
    141
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 141
    Par défaut
    non dans le forum jai trouvé que le sujet dont je parlais mais je vais essayer de creuser un peu plus
    sinon j'avais répéré cette fonction Waitforsibleobject qui me parait être ce que je cherche mais je comprend pas trop ce qu'est le premier argument hHandle par rapport au programme lancé.
    En même temps j'avais pas vu la fonction open process.
    Bon je regarde comment je peux assayer d'adapter tous ca sachant que je ne me sers pas d'un shell donc que j'ai pas d'Id
    pour ce qui est de la fonction sleep elle fait quoi en fait?
    merci à tout à l'heure
    rémi

  4. #4
    Inactif  
    Avatar de ouskel'n'or
    Profil pro
    Inscrit en
    Février 2005
    Messages
    12 464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 12 464
    Par défaut
    Sleep fait dormir la procédure en millisecondes

  5. #5
    Membre éprouvé
    Inscrit en
    Juillet 2005
    Messages
    141
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 141
    Par défaut
    bon apres un bon déjeuner et qq recherches
    Voici qq lignes de code simplifiées pour bien cibler de quel type d'objet je parle
    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
    Private function (arguments)
    Set fm = New Flowmaster2.Application 'ouverture du programm
    Set proj = fm.Project(projet) 'ouverture du fichier voulu dans ce programme
    Set net = proj.Network(reseau)
    'ici il ya des données fixes qui sont inscrites
    'on récupère aussi un tableau (calcul_pression) qui contient toutes les valeurs de pression pour lesquelles on souhaite faire une simulation
    On lance un boucle sur ces différentes pressions
    For calcul = 1 To Nb_Step
    
    For k = 1 To Nb_Pression
           'On commence par copier la pression dans tous les endroits requis
                ComponentID = Pression(k, 1)
                Set comp = net.Component(ComponentID)
                If (comp Is Nothing) = True Then GoTo Error_composant2
                comp.UseAppUnitSet = True
                
                DataItemValue = Calcul_Pression(calcul) + g * eau(Calcul_Pression(calcul), temperature) * Pression(k, 2) / 100000
                blnfound = comp.SetLineBySearch("", "Total Pressure")
                If blnfound = False Then GoTo Error_composant2
                comp.SetCLValue (DataItemValue)
                comp.SaveChanges
            Next k
    
    'Puis on lance le calcul de cette manière
            resnb = net.RunAnalysis2("FRAMATOME-ANP", description_calcul, "SS", 0, 0, 0, 0, 0)
    'et on récupère ici le numéro du résultat qui sert ensuite pour aller chercher les résultats voulus
    
    next step
    set fm=Nothing
    end function
    Pour utiliser OpenProcess et WaitForSingleObject j'ai besoin donc besoin du code windows de l'application.
    J'ai cependant pu récupérer une fonction établie précédemment par je sais pas qui, qui listait tout les process en cours du gestionnaires des taches
    et j'ai pu l'adapter en ajoutant une fonction de test sur le process que je cherchais.
    Il faut rajouter qq référénces.
    Je ne suis pas vraiment sur que tout dans cette fonction soit utile mais vu que je ne saisi pas tout j'ai préféré ne pas écrémer.
    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
     Public Declare Function CloseHandle Lib "Kernel32.dll" _
             (ByVal Handle As Long) As Long
     
          Public Declare Function OpenProcess Lib "Kernel32.dll" _
            (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, _
                ByVal dwProcId As Long) As Long
     
          Public Declare Function EnumProcesses Lib "psapi.dll" _
             (ByRef lpidProcess As Long, ByVal cb As Long, _
                ByRef cbNeeded As Long) As Long
     
          Public Declare Function GetModuleFileNameExA Lib "psapi.dll" _
             (ByVal hProcess As Long, ByVal hModule As Long, _
                ByVal ModuleName As String, ByVal nSize As Long) As Long
     
          Public Declare Function EnumProcessModules Lib "psapi.dll" _
             (ByVal hProcess As Long, ByRef lphModule As Long, _
                ByVal cb As Long, ByRef cbNeeded As Long) As Long
     
          Public Const PROCESS_QUERY_INFORMATION = 1024
          Public Const PROCESS_VM_READ = 16
          Public Const MAX_PATH = 260
          Public Const STANDARD_RIGHTS_REQUIRED = &HF0000
          Public Const SYNCHRONIZE = &H100000
          'STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF
          Public Const PROCESS_ALL_ACCESS = &H1F0FFF
     
     
    Sub Idprocess()
             Dim cb As Long
             Dim cbNeeded As Long
             Dim NumElements As Long
             Dim ProcessIDs() As Long
             Dim cbNeeded2 As Long
             Dim NumElements2 As Long
             Dim Modules(1 To 200) As Long
             Dim lRet As Long
             Dim ModuleName As String
             Dim FMmodname As String
             Dim FMmodname12 As String
             Dim FMmodname15 As String
             Dim FMmodname16 As String
             Dim nSize As Long
             Dim hProcess As Long
             Dim i As Long
             Dim handleanalyse As Long
             'Get the array containing the process id's for each process object
             cb = 8
             cbNeeded = 96
             Do While cb <= cbNeeded
                cb = cb * 2
                ReDim ProcessIDs(cb / 4) As Long
                lRet = EnumProcesses(ProcessIDs(1), cb, cbNeeded)
             Loop
             NumElements = cbNeeded / 4
     
             For i = 1 To NumElements
                'Get a handle to the Process
                hProcess = OpenProcess(PROCESS_QUERY_INFORMATION _
                   Or PROCESS_VM_READ, 0, ProcessIDs(i))
                'Got a Process handle
                If hProcess <> 0 Then
                    'Get an array of the module handles for the specified
                    'process
                    lRet = EnumProcessModules(hProcess, Modules(1), 200, _
                                                 cbNeeded2)
                    'If the Module Array is retrieved, Get the ModuleFileName
                    If lRet <> 0 Then
                       ModuleName = Space(MAX_PATH)
                       nSize = 500
                       lRet = GetModuleFileNameExA(hProcess, Modules(1), _
                                       ModuleName, nSize)
                       FMmodname = Left(ModuleName, lRet)
                       FMmodname16 = Right(FMmodname, 16) 'check for FM2_analysis.exe
                       FMmodname12 = Right(FMmodname, 12) 'check for FM2_anal~1.exe
     
                       If FMmodname16 = "FM2_analysis.exe" Then handleanalyse = ProcessIDs(i)
                       If FMmodname12 = "FM2_AN~1.EXE" Then handleanalyse = ProcessIDs(i)
        'car le nom du process de l'analyse est l'un ou l'autre de ces noms 
                    End If
                End If
              'Close the handle to the process
             lRet = CloseHandle(hProcess)
             Next
     
     
    End Sub
    mon problème maintenant c'est que comme on peut le voir dans le premier code, je lance mon calcul en mettant resnb = net.RunAnalysis2 donc je sais pas trop comment insérer ma recherche de openprocess la dedans puis ma fonction WaitForSingleObject sachant que le process n'apparaitra pas tant que je ne l'ai pas lancé mais qu'une fois lancé, Excel va attendre qu'il se finisse (et va s'impatienter) avant de faire quoique ce soit d'autre

    qqun aurait-t-il une idée??
    merci
    rémi

  6. #6
    Membre éprouvé
    Inscrit en
    Juillet 2005
    Messages
    141
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 141
    Par défaut
    finalement j'ai résolu ca en désactivant l'affichage du message d'erreur (et avec la bonne syntaxe ). ainsi ca a le même effet que si l'utilisateur cliquait sur OK lorsque le message d'erreur s'affichait et vu que le programme externe continuais a tourner, le problème venait du fait que si l'utilisateur mettait trop de temps à cliquer sur OK alors la liaison entre les deux prog était perdue. Mais avec cette solution tout va bien

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
       Application.DisplayAlerts = False
     
            resnb = net.RunAnalysis2("FRAMATOME-ANP", description_calcul, "SS", 0, 0, 0, 0, 0)
       Application.DisplayAlerts = True
    merci ouskel'

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 05/05/2015, 16h22
  2. Réponses: 3
    Dernier message: 04/05/2012, 22h41
  3. Réponses: 3
    Dernier message: 29/04/2012, 21h26
  4. [VBA-E] [Excel] Tri automatique
    Par bovi dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 01/10/2002, 10h19
  5. [VBA-E] [Excel] Filtrer le donnees d'une sheet
    Par donia dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 27/09/2002, 10h55

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