VBScript-как заставить программу ждать завершения процесса?



У меня есть проблема в VBScript, который я использую с макросом VBA/Excel и HTA. Проблема только в VBScript, у меня есть два других компонента, то есть макрос VBA и HTA front-end работают отлично. Но прежде чем я объясню проблему, я думаю, что для того, чтобы вы помогли мне, я должен помочь вам понять контекст VBScript.



Таким образом, в основном все компоненты (VBScript, VBA macro и HTA) являются частями инструмента, который я создаю для автоматизации некоторых ручных работ. Это в значительной степени идет как это:

A-HTA



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




  1. пользователь выбирает некоторые файлы из HTA / GUI.

  2. в HTML HTA есть некоторый VBScript в тегах "SCRIPT", который передает пользователям 4 входных файла в качестве аргументов VBScript (выполняется WScript.exe-вы можете обратиться к примечанию #1 для ясности здесь)

  3. скрипт, назовем его myScript.vbs теперь обрабатывает 4 аргумента, 3 из которых являются конкретными файлами, а 4-Путь / папка расположение, в котором есть несколько файлов - (Также см. Примечание #2 для ясности)


B-myScript.vbs



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




  1. мистический текст.vbs открывает первые 3 аргумента, которые являются файлами Excel. Один из них-это *.xlsm-файл, содержащий мой макрос VBA.


  2. Мистический текст.затем 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)
    ...



  3. Отсюда я создаю цикл, так что я могу последовательно открывать файлы в папке
    а затем запустите мой макрос, т. е.



    ...
    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.заявление о сне с 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.

916   4  

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

Comments

    Ничего не найдено.