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 :

Shell et enchainement de lignes de code


Sujet :

Macros et VBA Excel

  1. #1
    Membre averti
    Inscrit en
    Juillet 2007
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 25
    Par défaut Shell et enchainement de lignes de code
    Bonjour,

    J'ai créé un code qui crée un fichier '*.bat', lance ce fichier dans un shell, puis doit executer d'autres actions.

    Cependant, pour pouvoir executer les autres actions, j'ai besoin que mon fichier .bat ait fini de tourner.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    open Chemin & "commande.bat" for output as #1
    print #1, left(Chemin,2)
    print #1, "cd " & Chemin
    print #1, "executable.exe"
    close #1
    shell Chemin & "commande.bat",1
    'reste du code
    connaissez vous une méthode afin que mon code se mette en attente tant que le .bat n'a pas fini de tourner.

    Merci d'avance

  2. #2
    Inactif  

    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    4 555
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4 555
    Par défaut
    Bonjour,

    Tu ne crois pas que pour lancer un exe avec Shell, il y a quand même plus adroit que de passer par un batch qui le lancerait ?

  3. #3
    Membre averti
    Inscrit en
    Juillet 2007
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 25
    Par défaut
    c'est pas un executable, j'ai mis ça pour illustrer mon code...

    je ne peux pas utiliser autre chose qu'un shell...

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2006
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 288
    Par défaut
    Une possibilité serait qu'à la fin de ton batch tu écrives un indicateur dans un fichier tiers.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    print #1, "cd " & Chemin
    print #1, "executable.exe"
    print #1, "@echo fini > fichier2.txt"
    close #1
    Ainsi le mot "fini" sera mis dans fichier2.txt seulement quand executable.exe sera terminé.

    Ensuite, il faut lancer le batch et vérifier périodiquement dans une boucle si la chaîne "fini" a été mise dans le fichier2.txt
    Dès que c'est le cas, le code sort de la boucle et se poursuit.
    Evidemment il ne faut pas oublier de liquider fichier2.txt ensuite sinon la prochaine exécution de ce code croira que c'est fini alors que ça ne l'est pas...

    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
     
    'lancement du batch :
    shell Chemin & "commande.bat",1
     
    'pour attendre la fin du batch, on vérifie périodiquement la présence de "fini" dans le fichier créé pour ça
    retVal = 0
    Do While retVal = 0
        Start = Timer   ' Définit l'heure de début de la pause.
        Do While Timer < Start + 1 'une seconde de pause
            DoEvents 'libère le processeur
        Loop
        Open "fichier2.txt" For Input As #1
            Line Input #1, textLine
        Close #1
        If Trim(textLine) = "fini" Then retVal = 1
    Loop
     
    Kill "fichier2.txt"
    Il y a peut-être une gestion d'erreur à faire ou un test d'existence de fichier2.txt dans la boucle puisqu'il ne sera créé qu'à la fin du batch (d'ailleurs tu peux aussi considérer que la simple existence de fichier2.txt signifie la fin du traitement).

    Tout ça n'est pas très "élégant", mais ça peut dépanner dans certains cas.

    Edit : je m'étais aussi trouvé dans l'obligation de procéder via un batch car je n'ai pas trouvé de commande VBA qui permette au code d'attendre la fin de l'exécution de l'exécutable lancé.
    Mais si une telle commande existe (en étant fiable), signalez-le ça m'intéresse aussi...

  5. #5
    Membre éclairé Avatar de tomy7
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    540
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 540
    Par défaut
    fais un test sur ton fichier .bat pour voir si il est fermer???

    je le ferai comme ca...je ne l ai jamais fais mais je le ferai comme ca.

  6. #6
    Membre averti
    Inscrit en
    Juillet 2007
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 25
    Par défaut
    Bon, j'ai opté pour la solution de neupont

    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
    '## necessite la référence Microsoft Scripting Runtime
     
    Sub test()
    Dim oFSO As New Scripting.FileSystemObject
     
        'supprime le fichier si celui ci existe déja
        If oFSO.FileExists(ThisWorkbook.Path & "\fini.txt") Then
            oFSO.DeleteFile ThisWorkbook.Path & "\fini.txt"
        End If
     
        ' crée le fichier .bat
        Open ThisWorkbook.Path & "\test.bat" For Output As #1
        Print #1, Left([path], 2)
        Print #1, "cd " & [path]
        Print #1, "execute un truc long"
        Print #1, Left(ThisWorkbook.Path, 2)
        Print #1, "cd " & ThisWorkbook.Path
        Print #1, "ECHO fini >> fini.txt"
        Close #1
     
        Shell ThisWorkbook.Path & "\test.bat", vbMaximizedFocus
     
        While Not oFSO.FileExists(ThisWorkbook.Path & "\fini.txt")
            DoEvents
        Wend
        oFSO.DeleteFile ThisWorkbook.Path & "\fini.txt"
        oFSO.DeleteFile ThisWorkbook.Path & "\test.bat"
     
    End Sub
    je vois pas bien comment voir si le fichier est fermé...

  7. #7
    Expert confirmé
    Avatar de cafeine
    Inscrit en
    Juin 2002
    Messages
    3 904
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 3 904
    Par défaut
    Hello,

    il y a une solution plus élégante avec l'API waitforsingle
    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
    Option Explicit
     
    Private Type STARTUPINFO
             cb As Long
             lpReserved As String
             lpDesktop As String
             lpTitle As String
             dwX As Long
             dwY As Long
             dwXSize As Long
             dwYSize As Long
             dwXCountChars As Long
             dwYCountChars As Long
             dwFillAttribute As Long
             dwFlags As Long
             wShowWindow As Integer
             cbReserved2 As Integer
             lpReserved2 As Long
             hStdInput As Long
             hStdOutput As Long
             hStdError As Long
    End Type
     
    Private Type PROCESS_INFORMATION
             hProcess As Long
             hThread As Long
             dwProcessID As Long
             dwThreadID As Long
    End Type
     
    Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal _
             hHandle As Long, ByVal dwMilliseconds As Long) As Long
     
    Private Declare Function CreateProcessA Lib "kernel32" (ByVal _
             lpApplicationName As Long, ByVal lpCommandLine As String, ByVal _
             lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
             ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
             ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _
             lpStartupInfo As STARTUPINFO, lpProcessInformation As _
             PROCESS_INFORMATION) As Long
     
    Private Declare Function CloseHandle Lib "kernel32" (ByVal _
             hObject As Long) As Long
     
    Private Const NORMAL_PRIORITY_CLASS = &H20&
    Private Const INFINITE = -1&
     
    Private Declare Function OpenProcess Lib "kernel32" _
        (ByVal dwDesiredAccess As Long, _
        ByVal bInheritHandle As Long, _
        ByVal dwProcessID As Long) As Long
     
    Private Declare Function GetExitCodeProcess Lib "kernel32" _
        (ByVal hProcess As Long, _
        lpExitCode As Long) As Long
    '...end
     
     
    Public Sub ShellPatient(vCommand As String)
    Dim proc As PROCESS_INFORMATION
    Dim start As STARTUPINFO
    Dim ReturnValue As Integer
     
    DoCmd.Hourglass True
     
    ReturnValue = CreateProcessA(0&, vCommand, 0&, 0&, 1&, NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc)
    Do
        ReturnValue = WaitForSingleObject(proc.hProcess, 0)
        DoEvents
        DoEvents
    Loop Until ReturnValue <> 258
     
    ReturnValue = CloseHandle(proc.hProcess)
     
    DoCmd.Hourglass False
     
     
    End Sub
     
    ' un exemple
    Sub testShell()
     
    ShellPatient "C:\winnt\system32\cmd.exe"
    ShellPatient "C:\winnt\system32\cmd.exe"
     
    End Sub

  8. #8
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2006
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 288
    Par défaut
    Elle est géniale cette api, je viens de l'utiliser et ça marche impec'.
    Au début j'étais rétif because je ne comprenais pas le code, mais finalement je l'ai collée dans un module à part et je me contente de l'utiliser, et ça c'est très simple .
    Super.

Discussions similaires

  1. Comptabiliser les lignes de code d'un projet
    Par JPigKeud dans le forum Qualimétrie
    Réponses: 5
    Dernier message: 07/01/2005, 14h09
  2. [Debutant(e)]ligne de code sous eclipse
    Par skywalker3 dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 05/01/2005, 17h37
  3. Shell pour supprimer des lignes d'un fichier
    Par nelsa dans le forum Autres langages
    Réponses: 2
    Dernier message: 20/09/2004, 12h26
  4. [netbeans][Linux] Nombre de lignes de codes
    Par sylvain_neus dans le forum NetBeans
    Réponses: 5
    Dernier message: 13/08/2004, 10h09
  5. Calculeur de ligne de code
    Par Bernybon dans le forum Autres éditeurs
    Réponses: 9
    Dernier message: 05/03/2004, 16h29

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