Word VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


122 / 308 ツリー ←次へ | 前へ→

【23】shellの終了と同期させるには? てけてけ 03/4/25(金) 21:00 質問[未読]
【25】Re:shellの終了と同期させるには? H. C. Shinopy 03/4/27(日) 23:32 回答[未読]
【30】Re:shellの終了と同期させるには? 追加... H. C. Shinopy 03/5/11(日) 8:22 回答[未読]
【377】Re:shellの終了と同期させるには? 追加... Z(ゼーター) 05/11/19(土) 6:01 お礼[未読]
【524】Re:shellの終了と同期させるには? 追加... FJ 07/3/22(木) 10:55 お礼[未読]

【23】shellの終了と同期させるには?
質問  てけてけ  - 03/4/25(金) 21:00 -

引用なし
パスワード
   こちらには初めて書込ます。
ワードマクロの中で

テキストファイルに書き出す
xxx=shell(abc.bat)
abc.batで出力されたファイルを読み込む

のように外部のバッチを実行し、このバッチでできたファイルを読み込む場合、
shellの完了を待つ必要がありますが、xxxの値をどう利用したら可能かわかりません。
コーディング例を教えて頂けるとありがたいです。
宜しくお願い致します。

【25】Re:shellの終了と同期させるには?
回答  H. C. Shinopy  - 03/4/27(日) 23:32 -

引用なし
パスワード
   どういう状況下(環境・処理全体…)での処理なのか判りませんが、
御質問の判らん部分は独断と偏見で解釈し、返信させて頂きます。
万一、的ハズレな回答でしたら、ガセネタの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

【30】Re:shellの終了と同期させるには? 追...
回答  H. C. Shinopy  - 03/5/11(日) 8:22 -

引用なし
パスワード
   先にVBScriptでの処理を書き込みしましたが、
Word VBAで処理する方法があることが判りました。
(不勉強で、すみません。)

後日、Excel VBAの本を見ていたら、使えそうなコードを発見しました。
(メモ帳を起動して、その終了を待つというものでした。)
それを使い回そうとしたのですが、いろいろ試した結果、
下記のコードとなりました。

1.デスクトップにABC.batがあるものとします。
  (この処理でABCo.txtが出力されるものとします。)

2.VBE上から[ツール]の[参照設定...]で、
  [Windows Script Host Object Model]をチェックして下さい。

3.「ChDir …」で「ABC.bat」のあるフォルダを指定します。
  これを指定しない場合、マイドキュメントの中を見にいくようです。

Sub AbcVBA()
  '参照設定:Windows Script Host Object Model
  Dim myWsh As IWshRuntimeLibrary.WshShell
  Set myWsh = CreateObject("Wscript.Shell")
  '
  ChDir "C:\Documents and Settings\User\デスクトップ"
  myWsh.Run "ABC.bat", 1, True
  '
  MsgBox "ABC.batが終了しました。"
  Documents.Open "C:\Documents and Settings\User\My Documents\ABCo.txt"
  Set myWsh = Nothing
End Sub
[終わり]

【377】Re:shellの終了と同期させるには? 追...
お礼  Z(ゼーター)  - 05/11/19(土) 6:01 -

引用なし
パスワード
    私も同じ悩みでここにたどりつきました。
関係ないですが
H. C. Shinopyさんありがとうございました。
私も解決しました。お礼だけいいたかったので。
失礼します。

【524】Re:shellの終了と同期させるには? 追...
お礼  FJ  - 07/3/22(木) 10:55 -

引用なし
パスワード
   私も同様に他アプリケーションの終了チェックの
壁にぶつかり、このログを教えてもらいました。

一言お礼を残したくレスを書きました。

H. C. Shinopy さん ありがとうございます。

以上

122 / 308 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
207137
(SS)C-BOARD v3.8 is Free