VBScript - 如何让程序等到进程完成?

时间:2012-04-23 11:09:58

标签: vba vbscript excel-vba excel-2010 excel

我在使用VBA / Excel宏和HTA的VBScript中遇到问题。问题只是VBScript,我还有其他两个组件,即VBA宏和HTA前端工作正常。但在我解释这个问题之前,我想你帮助我了解VBScript的背景。

因此,基本上所有组件(VBScript,VBA宏和HTA)都是我正在构建的工具的一部分,以自动执行一些手动操作。它几乎是这样的:

A - HTA

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

  1. 用户从HTA / GUI中选择一些文件。
  2. 在HTA的HTML中,“SCRIPT”标签中有一些VBScript将用户的4个输入文件作为参数传递给VBScript(由WScript.exe执行 - 为了清楚起见,您可以参考注释#1)< / LI>
  3. 该脚本,让我们从现在开始调用 myScript.vbs ,然后处理4个参数,其中3个是特定文件,第4个是包含多个文件的路径/文件夹位置 - (为清晰起见,请参阅注释#2)
  4. B - myScript.vbs

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

    1. myScript.vbs打开前3个参数,这些参数是Excel文件。其中一个是带有我的VBA宏的* .xlsm文件。
    2. myScript.vbs然后使用第4个参数作为包含多个文件的文件夹的PATH,并将其分配给变量,以便在调用GetFolder时传递给FileSystemObject对象,即

      ... '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 
      ...
      
    4. 请注意,当前三个Excel文件打开时(由循环前的代码控制,此处未显示,因为我对该部分没有任何问题)我必须保持它们打开。

      文件夹中的文件(作为第4个参数传递)必须按顺序打开和关闭。但是在打开和关闭之间,我需要VBA /宏(在之前打开的3个Excel文件之一中写入)每次运行循环迭代并从文件夹中打开一个新文件(我希望你关注 - 如果不是,请让我知道:))。

      我遇到的问题是文件夹中的文件打开和关闭,打开和关闭n次(n =文件夹中的文件数,当然),而不等待宏运行。这不是我想要的。我在'x1.Run strMyMacro'语句之后尝试了WScript.sleep语句,延迟了10秒,但无济于事。

      有什么想法吗?

      谢谢, QF。

      注意:

      1 - 为了简单/清晰,这是如何:

          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 HTA使用一段JavaScript来剥离用户的第四个输入文件(HTML:INPUT TYPE =“file”)并将其传递给HTA中的VBScript。这让我解决了无法在HTML中专门选择文件夹的问题。

4 个答案:

答案 0 :(得分:16)

您需要告诉运行等待进程完成。类似的东西:

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

答案 1 :(得分:2)

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 :(得分:0)

可能是这样的吗? (的 UNTESTED

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

答案 3 :(得分:0)

这可能没有具体回答你的长篇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/