wake-up-neo.com

VBScript - Wie kann ich das Programm warten lassen, bis der Vorgang abgeschlossen ist?

Ich habe ein Problem in einem VBScript, das ich mit einem VBA/Excel-Makro und einem HTA verwende. Das Problem ist nur das VBScript, ich habe die anderen beiden Komponenten, d. H. Das VBA-Makro und das HTA-Front-End, die perfekt funktionieren. Aber bevor ich das Problem erkläre, muss ich Ihnen helfen, den Kontext des VBScript zu verstehen, damit Sie mir helfen können.

Im Grunde genommen sind alle Komponenten (VBScript, VBA-Makro und HTA) Teile eines Tools, das ich zur Automatisierung manueller Aufgaben erstelle. Es geht so ziemlich so:

A - HTA

~~~~~~~~~~~~

  1. Der Benutzer wählt einige Dateien aus der HTA/GUI aus.
  2. Im HTML der HTA gibt es einige VBScript innerhalb der "SCRIPT" -Tags, die die 4 Eingabedateien des Benutzers als Argumente an ein VBScript übergeben (ausgeführt von WScript.exe - zur Verdeutlichung wird hier auf Anmerkung 1 verwiesen).
  3. Das Skript nennt es jetzt myScript.vbs und verarbeitet dann die 4 Argumente, von denen 3 bestimmte Dateien sind und das vierte ein Pfad/Ordner, in dem sich mehrere Dateien befinden (siehe auch Hinweis) # 2 für Klarheit)

B - myScript.vbs

~~~~~~~~~~~~

  1. myScript.vbs öffnet die ersten 3 Argumente, die Excel-Dateien sind. Eine davon ist eine * .xlsm-Datei mit meinem VBA-Makro.
  2. myScript.vbs verwendet dann das vierte Argument, das ein PATH für einen Ordner ist, der mehrere Dateien enthält, und weist dies einer Variablen zu, die beim Aufrufen von GetFolder an ein FileSystemObject-Objekt übergeben werden soll, d. h.

    ... 'Other code here, irrelevant for this post
    Dim FSO, FLD, strFolder
    ... 'Other code here, irrelevant for this post
    arg4 = args.Item(3)
    strFolder = arg4
    Set FSO = CreateObject("Scripting.FileSystemObject"
    'Get a reference to the folder you want to search
    Set FLD = FSO.GetFolder(strFolder)
    ...
    
  3. Von hier aus erstelle ich eine Schleife, damit ich die Dateien im Ordner nacheinander öffnen und dann mein Makro ausführen kann, d. H.

    ...
    Dim strWB4, strMyMacro
    strMyMacro = "Sheet1.my_macro_name"
    
    'loop through the folder and get the file names
    For Each Fil In FLD.Files
    
        Set x4WB = x1.Workbooks.Open(Fil)
    x4WB.Application.Visible = True
    
    x1.Run strMyMacro
    
    x4WB.close
    Next 
    ...
    

Bitte beachten Sie, dass wenn die ersten 3 Excel-Dateien geöffnet wurden (gesteuert durch Code vor der Schleife und hier nicht gezeigt, da ich mit diesem Teil kein Problem habe), ich sie offen halten muss.

Es sind die Dateien im Ordner (die als 4. Argument übergeben wurden), die nacheinander geöffnet und geschlossen werden müssen. Aber zwischen dem Öffnen und Schließen benötige ich das VBA/Makro (geschrieben in einer der 3 zuvor geöffneten Excel-Dateien) um jedes Mal ausgeführt zu werden die Schleife iteriert und öffnet eine neue Datei aus dem Ordner (ich hoffe, Sie folgen - wenn nicht bitte lass es mich wissen :)).

Das Problem, das ich habe, ist, dass die Dateien im Ordner n-mal geöffnet und geschlossen, geöffnet und geschlossen werden (n = Anzahl der Dateien im Ordner, natürlich), ohne auf die Ausführung des Makros zu warten. Das will ich nicht. Ich habe die Anweisung WScript.sleep mit einer Verzögerung von 10 Sekunden nach der Anweisung 'x1.Run strMyMacro' ausprobiert, aber ohne Erfolg.

Irgendwelche Ideen?

Danke, QF.

ANMERKUNGEN:

1 - Der Einfachheit halber ist dies wie folgt:

    strCMD = cmd /c C:\windows\system32\wscript.exe myScript.vbs <arg1> <arg2> <arg3> <arg4>
    'FYI - This is run by creating a WShell object, wsObj, and using the .run method, i.e. WShell.run(strCMD)

2 Die HTA verwendet ein Stück JavaScript, das die vierte Eingabedatei des Benutzers entfernt (HTML: INPUT TYPE = "file") und diese an das VBScript innerhalb der HTA weiterleitet. Dies bringt mich um das Problem herum, dass ich nicht ausschließlich einen Ordner in HTML auswählen kann.

6
qwerty_face

Sie müssen dem Lauf mitteilen, dass er warten soll, bis der Prozess abgeschlossen ist. So etwas wie:

const DontWaitUntilFinished = false, ShowWindow = 1, DontShowWindow = 0, WaitUntilFinished = true
set oShell = WScript.CreateObject("WScript.Shell")
command = "cmd /c C:\windows\system32\wscript.exe <path>\myScript.vbs " & args
oShell.Run command, DontShowWindow, WaitUntilFinished

Starten Sie Excel im Skript selbst so. Während des Debugging-Starts sichtbar:

File = "c:\test\myfile.xls"
oShell.run """C:\Program Files\Microsoft Office\Office14\Excel.EXE"" " & File, 1, true
16
peter
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2:Win32_Process")
objWMIService.Create "notepad.exe", null, null, intProcessID
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colMonitoredProcesses = objWMIService.ExecNotificationQuery _
    ("Select * From __InstanceDeletionEvent Within 1 Where TargetInstance ISA 'Win32_Process'")
Do Until i = 1
    Set objLatestProcess = colMonitoredProcesses.NextEvent
    If objLatestProcess.TargetInstance.ProcessID = intProcessID Then
        i = 1
    End If
Loop
Wscript.Echo "Notepad has been terminated."
2

Dies kann Ihre lange dreiteilige Frage nicht speziell beantworten, aber dieser Thread ist alt und ich habe dies heute bei der Suche gefunden. Hier ist ein kurzer Weg zu: " Warten Sie, bis ein Prozess abgeschlossen ist ." Wenn Sie den Namen des Prozesses wie "Excel.EXE" kennen

strProcess = "Excel.EXE"    
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colProcesses = objWMIService.ExecQuery ("Select * from Win32_Process Where Name = '"& strProcess &"'")
Do While colProcesses.Count > 0
    Set colProcesses = objWMIService.ExecQuery ("Select * from Win32_Process Where Name = '"& strProcess &"'")
    Wscript.Sleep(1000) 'Sleep 1 second
   'msgbox colProcesses.count 'optional to show the loop works
Loop

Kredit an: http://crimsonshift.com/scripting-check-if-process-or-program-isrunning-and-start-it/

0
jelde015

Wahrscheinlich so etwas? (UNGEPR&UUML;FT)

Sub Sample()
    Dim strWB4, strMyMacro
    strMyMacro = "Sheet1.my_macro_name"

    '
    '~~> Rest of Code
    '

    'loop through the folder and get the file names
    For Each Fil In FLD.Files
        Set x4WB = x1.Workbooks.Open(Fil)
        x4WB.Application.Visible = True

        x1.Run strMyMacro

        x4WB.Close

        Do Until IsWorkBookOpen(Fil) = False
            DoEvents
        Loop
    Next

    '
    '~~> Rest of Code
    '
End Sub

'~~> Function to check if the file is open
Function IsWorkBookOpen(FileName As String)
    Dim ff As Long, ErrNo As Long

    On Error Resume Next
    ff = FreeFile()
    Open FileName For Input Lock Read As #ff
    Close ff
    ErrNo = Err
    On Error GoTo 0

    Select Case ErrNo
    Case 0:    IsWorkBookOpen = False
    Case 70:   IsWorkBookOpen = True
    Case Else: Error ErrNo
    End Select
End Function
0
Siddharth Rout