VBScript-как заставить программу ждать, пока процесс не закончится?
у меня проблема в VBScript, который я использую с макросом VBA/Excel и HTA. Проблема заключается только в VBScript, у меня есть два других компонента, т. е. макрос VBA и интерфейс HTA работают отлично. Но прежде чем я объясню проблему, я думаю, что для вас, чтобы помочь мне, я должен помочь вам понять контекст VBScript.
Итак, в основном все компоненты (VBScript, VBA macro и HTA) являются частями инструмента, который я создаю для автоматизации некоторых ручных работ. Это довольно много идет так:
A-HTA
~~~~~~~~~~~~
- пользователь выбирает некоторые файлы из HTA / GUI.
- в HTML HTA есть некоторый VBScript в тегах "SCRIPT", который передает пользователям 4 входных файла в качестве аргументов VBScript (выполняется WScript.exe - вы можете обратиться к примечанию № 1 для ясности здесь)
- скрипт, назовем это именем MyScript.vbs С этого момента обрабатывает 4 аргумента, 3 из которых конкретные файлы и 4-й путь/папку с несколькими файлами в ней (см. Также примечание № 2 для наглядности)
Б - универсальный.vbs
~~~~~~~~~~~~
- именем MyScript.vbs открывает первые 3 аргумента, которые являются файлами Excel. Один из них-а *.xlsm-файл с моим макросом VBA.
-
именем MyScript.затем vbs использует 4-й аргумент, который является путем к папке, содержащей несколько файлов, и присваивает его переменной для переход к объекту FileSystemObject при вызове GetFolder, т. е.
... '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) ...
-
отсюда я создаю цикл, чтобы я мог последовательно открывать файлы в папке а затем запустите мой макрос, т. е.
... 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 ...
обратите внимание, что когда первые 3 файла Excel открыты (управляются кодом до цикла, а не показываются здесь, поскольку у меня нет проблем с этой частью), я должен держать их открытыми.
Это файлы в папка (которая была передана как 4-й аргумент), которая должна последовательно открываться и закрываться. Но между Открытием и закрытием мне нужен VBA/macro (записанный в одном из 3 ранее открытых файлов Excel) для запуска каждый раз цикл повторяется и открывает новый файл из папки (надеюсь, вы следуете - если нет, пожалуйста, дайте мне знать :) ).
проблема в том, что файлы в папке открываются и закрываются, открываются и закрываются, n количество раз (n = # файлов в папке, естественно), не дожидаясь запуска макроса. Это не то, чего я хочу. Я пробовал WScript.оператор sleep с 10-секундной задержкой после ' x1.Запустите оператор strMyMacro, но безрезультатно.
какие идеи?
спасибо, ФК.
Примечания:
1 - Для простоты / ясности вот как:
strCMD = cmd /c C:windowssystem32wscript.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 HTA использует кусок JavaScript, который удаляет 4-й входной файл пользователей (HTML: INPUT TYPE= "file") и передает его в VBScript в HTA. Это заставляет меня обойти проблему невозможности исключительно выбрать папку в HTML.
4 ответов
вам нужно запустить дождаться окончания процесса. Что-то вроде:
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
в самом скрипте запустите Excel так. При запуске отладки видно:
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."
Это может не конкретно ответить на ваш длинный вопрос 3 части, но этот поток старый, и я нашел это во время поиска сегодня. Вот один более короткий способ:" дождитесь завершения процесса."Если вы знаете название процесса, например" EXCEL.EXE-файл"
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
кредит: http://crimsonshift.com/scripting-check-if-process-or-program-is-running-and-start-it/
наверное, что-то вроде этого? (непроверенные)
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