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:
~~~~~~~~~~~~
~~~~~~~~~~~~
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)
...
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.
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
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."
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/
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