VBA/ExcelマクロとHTAで使用しているVBScriptに問題があります。問題はVBScriptだけです。他の2つのコンポーネント、つまりVBAマクロとHTAフロントエンドが完全に機能しています。しかし、問題を説明する前に、VBScriptのコンテキストを理解する手助けが必要だと思います。
つまり、基本的にすべてのコンポーネント(VBScript、VBAマクロ、およびHTA)は、手作業を自動化するために構築しているツールの一部です。それはほとんどこのようになります:
~~~~~~~~~~~~
~~~~~~~~~~~~
次に、myScript.vbsは、複数のファイルを含むフォルダーへのPATHである4番目の引数を使用して、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)
...
ここからループを作成して、フォルダー内のファイルを順次開き、マクロを実行できるようにします。
...
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 /マクロが必要です(以前に開いた3つのExcelファイルの1つに書き込まれています)---(毎回実行するループが反復され、フォルダーから新しいファイルを開きます(従います-そうでない場合はお知らせください:))。
私が抱えている問題は、マクロの実行を待たずに、フォルダー内のファイルがn回(n =フォルダー内のファイルの数)開いたり閉じたり、開いたり閉じたりすることです。これは私が欲しいものではありません。 'x1.Run strMyMacro'ステートメントの後に10秒遅れてWScript.sleepステートメントを試しましたが、役に立ちませんでした。
何か案は?
ありがとう、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は、ユーザーの4番目の入力ファイル(HTML:INPUT TYPE = "file")を取り除き、それをHTA内のVBScriptに渡すJavaScriptを使用します。これにより、HTMLでフォルダーを排他的に選択できないという問題を回避できます。
プロセスが終了するまで待機するように実行に指示する必要があります。何かのようなもの:
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/
おそらくこのようなものですか? ([〜#〜] unested [〜#〜])
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