|
どういう状況下(環境・処理全体…)での処理なのか判りませんが、
御質問の判らん部分は独断と偏見で解釈し、返信させて頂きます。
万一、的ハズレな回答でしたら、ガセネタの1つとして、
読み飛ばして頂くことで、お許し下さい。
さて、Shell関数について、VBE上からヘルプを見ると:
xxxの値については「指定したプログラムが問題なく実行できると、プログラムのタスク ID が返されます。タスク ID は、実行中のプログラムを識別する重複しない番号です。指定されたプログラムが実行できないと、エラーが発生します。」
また「タスク ID は、実行中のプログラムを識別する重複しない番号です。実行可能プログラムを実行し、実行が完了するとプログラムのタスク ID を示すバリアント型 (内部処理形式 Double の Variant) の値を返します。プログラムの実行に問題が発生した場合は、0 を返します。」とあります。
Sendkeys関数のヘルプに使用例があり、「電卓をアクティブにします。」処理で(タイトル バーのタイトルを指定する代わりに)タスクIDを指定しています。
Sub CalcX()
Dim ReturnValue, I
ReturnValue = Shell("CALC.EXE", 1) ' 電卓を実行します。
AppActivate ReturnValue ' 電卓をアクティブにします。
For I = 1 To 20 ' ループ カウンタを設定します。
SendKeys I & "{+}", True ' 電卓にキー コードを転送して、
Next I ' I の値に 1 を加算します。
SendKeys "=", True ' 和を求めます。
SendKeys "%{F4}", True ' Alt + F4 キーを転送して電卓を終了します。
End Sub
同期については「・・・ メモ 既定の設定では、Shell 関数はプログラムを非同期的に実行します。したがって、Shell関数を使用して実行を開始したプログラムが終了しなくても、Shell関数の次のステートメントは実行されます。」とあります。
しかし、ヘルプを見た限りでは、「既定の設定」を変更できる余地はないようです。(VBA上のShell関数に同期・非同期を指定するパラメーター部分がないのです。)
また、市販されている書籍を探すと、著作権の都合で内容は載せませんが…
大村あつし 著「Excel VBAによるWin32 APIプログラミング入門」
エーアイ出版 刊(www.ai-pub.co.jp) 税別2680円
この本の「第4章 プログラムの実行」に
「Shell関数で起動したアプリケーションが終了するまで待機する」節(92頁)に
APIを利用した何やら物々しいVBAコードが載っています。
ここでは、あっさり処理全体をVBAではなくVBScriptを使用して、
WSHの機能で全体の処理を実行したらどうでしょうか?
(WSHは、WindowsMe・WindowsXPに対応。)
VBScriptのShell関数と同等のステートメントでは「終了待ちをする・しない」の指定ができます。
下記のスクリプトを「ファイル名.vbs」(テキスト形式で拡張子に「vbs」を指定して)保存し、これをダブルクリックして起動すれば、御質問に沿えそうな処理ができます。
(但し、Shell関数の戻り値は常に「0」です。呼び出したコマンドの終了待ちをして、終了後の戻り値を得るので、「0」になるということのようです。)
ここでは、「ABC.bat」処理内で「ABCo.txt」ファイルを出力作成し、
最後にWordに読み込むと仮定して、スクリプトは下記の通りになります。
Rem テキスト形式ファイル出力Word読み込み処理VBScript
Option Explicit
Dim WshShell, tmpInt
Dim myWord
'
Set WshShell = WScript.CreateObject("WScript.Shell")
tmpInt = WshShell.Run ("ABC.bat", 1, True) ' True は処理待ち。
MsgBox “WScript.Shellの戻り値:” & tmpInt ' 多分、無意味な表示。
'
Set myWord = WScript.CreateObject("Word.Application")
myWord.Visible = True
myWord.Documents.Open " C:\Documents and Settings\User名\My Documents\ABCo.txt"
'
tmpInt = MsgBox("処理が終了しました。", vbOKonly+vbInformation)
WScript.Quit
この後は全く余談になりますが、
もし「ABC.bat」の処理をこのスクリプトの中に書き込んでしまえば、
(当然ながら)同期を考える必要はなくなります。
「ABC.bat」で何を処理しているのか判りませんが、
御参考までにということで…
下記のスクリプトは、「ABC.txt」ファイルを「ABCo.txt」で出力し、
それをWordで読み込むという処理です。
下記のスクリプトを「ファイル名.vbs」で保存し、
これに「ABC.txt」ファイルをドラッグ&ドロップすると、処理を実行します。
Rem テキスト形式ファイル出力Word読み込み処理VBScript
Option Explicit
Dim objDrop, objFS, objTsIn, objTsOt
Dim tmpInt, tmpTsOt, Txt
Dim myWord
'
If WScript.Arguments.Count <= 0 Then
tmpInt = MsgBox("テキスト形式ファイルのアイコンを、" & vbCrLf _
& WScript.ScriptName & "のアイコン上に、" & _
"ドラッグ&ドロップして下さい。" & vbCrLf _
& "ファイル名に「o」を付けたファイルを作成します。", _
vbOKonly+vbInformation)
WScript.Quit
End If
'
objDrop = Wscript.Arguments(0)
tmpInt = MsgBox("入力元ファイル:" & vbCrLf & objDrop, vbOKCancel+vbInformation)
If tmpInt = 2 Then
WScript.Quit
End If
'
Set objFS = WScript.CreateObject("Scripting.FileSystemObject")
Set objTsIn = objFS.OpenTextFile(objDrop, 1)
'
tmpTsOt = objFS.GetParentFolderName(objDrop) _
& "\" & objFS.GetBaseName(objDrop) & "o." & objFS.GetExtensionName(objDrop)
tmpInt = MsgBox("出力先ファイル:" & vbCrLf & tmpTsOt, vbOKCancel+vbInformation)
If tmpInt = 2 Then
objTsIn.Close
WScript.Quit
End If
Set objTsOt = objFS.CreateTextFile(tmpTsOt, True, False)
'
Do While Not objTsIn.AtEndOfStream
Txt = objTsIn.ReadLine
objTsOt.WriteLine (Txt)
Loop
'
objTsIn.Close
objTsOt.Close
' Microsoft Wordの起動
Set myWord = WScript.CreateObject("Word.Application")
myWord.Visible = True
myWord.Documents.Open tmpTsOt
'
tmpInt = MsgBox("処理が終了しました。", vbOKonly+vbInformation)
WScript.Quit
|
|