VBAから複数のバッチファイルを実行する際の処理順について

このQ&Aのポイント
  • VBAから複数のバッチファイルを実行する際に、1つの処理が終了するまで次の処理を待機させる方法について教えてください。
  • Shell関数を使って複数のバッチを連続して実行するプログラムを書きたいのですが、前のバッチ処理が終了する前に次のバッチが実行されてしまいエラーになってしまいます。
  • 具体的には、B列に「test_01.txt」「test_02.txt」... といったファイル名が入力されていて、隣のA列に何らかの文字/記号があった場合は、指定されたバッチ(ファイル名.bat)が実行されるということをやりたいと考えています。
回答を見る
  • ベストアンサー

VBAから複数のバッチファイルを実行する際に、1つの処理が終了するまで

VBAから複数のバッチファイルを実行する際に、1つの処理が終了するまで次の処理を待機させる方法について こんにちは。VBA初心者です。 Shell関数を使って複数のバッチを連続して実行するプログラムを書きたいのですが、前のバッチ処理が終了する前に次のバッチが実行されてしまいエラーになってしまいます。 1つのバッチ処理が終了するまで、次の処理を待機させるようなことは可能でしょうか。 具体的には、B列に「test_01.txt」「test_02.txt」... といったファイル名が入力されていて、隣のA列に何らかの文字/記号があった場合は、指定されたバッチ(ファイル名.bat)が実行されるということをやりたいと考えています。 以下のようなプログラムを書いてみましたが、実行するバッチが複数になるとうまくいきせん。 どうしたら問題を回避できるか、ご教示いただけないでしょうか。 よろしくお願いします。 Sub バッチを実行() i = 7 'リストの開始行 Const myPath As String = "D:\sample_batch\"   Const endPath As String = ".bat"  For i = 7 To 200 '7行目から200行目まで実行 If Cells(i, 1).Value <> "" Then Shell (myPath & Cells(i, 2).Value & endPath) End If Next End Sub

質問者が選んだベストアンサー

  • ベストアンサー
  • crossgate
  • ベストアンサー率65% (78/119)
回答No.4

確かに。。。andy_kunさんのおっしゃるように「"」の付け方が怪しかったですね。 バッチファイルまでのパスにスペースが無いならandy_kunさんの回答通りで。 ある(かもしれない)なら  objWShell.Run """" & myPath & Cells(i, 2).Value & endPath & """", 1, True で。 ただ、私の場合  実行時エラー'91' オブジェクト変数または With ブロック変数が設定されていません。 じゃなくてオートメーションエラーになりましたが。。。

Kazu_creator
質問者

お礼

マッチポンプですみません。 objWShell.Run myPath & Cells(i, 2).Value & endPath, 1, True の次に Workbooks("ブック名").Worksheets("シート名").Activate を挿入して、アクティブなブック(シート)をVBAを実行している方に戻したらOKでした。

Kazu_creator
質問者

補足

ありがとうございます! 教えていただいた方法でとりあえずエラーは回避できました。 しかし、処理がループにならずに 1 回で終了してしまいます。 そこで、WScript.Shellを1回ごとに初期化する必要があるのかと思い、以下の例のように「objWShell = null」や「Set objWShell = Nothing」などを挿入してみたのですが、動作に変化がありません。 実行したプログラムの終了コードを参照するのに別途何かコードがいるのでしょうか。 (それとも、バッチの内容が他のエクセルシートとサーバの通信に関するもので、処理に時間がかかるのが原因か??? ※なぜ、一旦バッチを経由してエクセルシートの処理をするのか…というのは聞かないでください。ちょっと、事情があるのです) Sub バッチを実行() Dim objWShell Set objWShell = CreateObject("WScript.Shell") Dim i As Integer i = 7 'リストの開始行 Const myPath As String = "D:\20101006_test\" Const endPath As String = ".bat" For i = 7 To 200 '7行目から200行目まで実行 If Cells(i, 1).Value <> "" Then MsgBox (Cells(i, 2).Value & " をコンバートします。") objWShell.Run myPath & Cells(i, 2).Value & endPath, 1, True End If Set objWShell = Nothing Next End Sub

その他の回答 (3)

  • andy_kun
  • ベストアンサー率23% (64/274)
回答No.3

こうかな? objWShell.Run myPath & Cells(i, 2).Value & endPath, 1, True "は不要だと思うけど

  • crossgate
  • ベストアンサー率65% (78/119)
回答No.2

objWShell.Run "myPath & Cells(i, 2).Value & endPath", 1, True かな?

Kazu_creator
質問者

補足

早速のご回答ありがとうございます。 先程の補足で「.Run」抜けていることに気付き、ご指摘のようにしたのですが、 「実行時エラー'91' オブジェクト変数または With ブロック変数が設定されていません。」 となってしまいました。 どこがいけないのか、本当に途方に暮れています。。。 何かわかることがあれば、是非々々ご教示ください。

  • yorozu_ya
  • ベストアンサー率54% (76/140)
回答No.1

Shell関数は非同期ですので、 代わりに WScript.Shellオブジェクトの Runメソッドを使いましょう。

Kazu_creator
質問者

お礼

スミマセン。補足では「.Run」が抜けていました。 objWShell.Run "myPath & Cells(i, 2).Value & endPath", 1, True としたところ、「実行時エラー'91' オブジェクト変数または With ブロック変数が設定されていません。」となってしまいました。 謎です。。。

Kazu_creator
質問者

補足

ご回答ありがとうございます。 WScript.Shellというものがあるんですね。VBEのヘルプを見ても載っていませんでしたが、WEBで調べたら使い方が書いてありました。 そこで、プログラムを以下のように変更してみたのですが、実行すると「コンパイルエラー:Sub, Function, またはproperty が必要です。」となってしまいます。 どこがいけないのかご指摘いただけないでしょうか。 (正直に申し上げて、エラーの意味が分かりません) Sub バッチを実行() Dim objWShell Set objWShell = CreateObject("WScript.Shell") Dim i As Integer i = 7 'リストの開始行 Const myPath As String = "D:\test_path\" Const endPath As String = ".bat" For i = 7 To 200 '7行目から200行目まで実行 If Cells(i, 1).Value <> "" Then MsgBox (Cells(i, 2).Value & " をコンバートします。") objWShell "myPath & Cells(i, 2).Value & endPath", 1, True End If Next End Sub

関連するQ&A

  • バッチファイルの実行方法

    Windows Server 2003で、Robocopy.exe(Resource KitToolsからインストールしたもの)の連続処理のために、下記のようなバッチファイル(.bat)を用意しました。 robocopy "D:\a" "F:\a" /E /copy:DT /NP /LOG:c:\robocopy.txt /TEE robocopy "D:\b" "F:\b" /E /copy:DT /NP /LOG+:c:\robocopy.txt /TEE .... コマンドの各行は間違っていないようです(cmd.exeに各行を打ち込んで実行すると正常に処理されます)。しかし.batをダブルクリックするとコマンドプロンプト画面内でバッチファイルの1行目がすごい勢いで流れるだけで、処理されません(コマンドプロンプトを強制終了するしかありません)。 最初は.batをダブルクリックすると正常に処理されていたのですが、急にこうなりました。なぜでしょうか? command.comから.batファイルを実行すると正常に処理されます。command.comから実行しないといけないものなのでしょうか? バッチファイルの拡張子を.batにするか、.comにするか関係があるでしょうか?

  • バッチファイルについて

    お聞きしたいのですが、 あるディレクトリーに test.bat test.php test.txt があり test.bat で test.php を起動して text.txt を一行一行処理しているのですが、 バッチファイルで、強制終了したとして(Ctrl + C) もう一度起動せずに Entertキー を押して test.txt の次の行から開始したいのですが可能ですか?? 詳しい方がいましたら教えてください。 宜しくお願いします。

  • バッチファイルで他のバッチファイルを呼び出した後、元に戻ってこれない。

    バッチファイルで他のバッチファイルを呼び出した後、元に戻ってこれない。 バッチファイルでほかのバッチファイルを呼び出した後の処理で困っています。 どうぞ教えてください。 「A.bat」というバッチファイルを実行すると、「1.bat」というバッチファイルを 実行させ、「1.bat」の実行結果によって、処理を分岐させたいと考えています。 「1.bat」をcallで呼び出し、実行はできたのですが、「1.bat」は最後にエンタキーを 押さないと終了しないようになっています。そのため、「エンターキーを押して終了させて ください」というメッセージが出たままの画面で終わってしまい、「A.bat」に帰ってくることが できません。 「1.bat」は中身を扱えないようにしてあるバッチファイルなので、こちらでエンターキーを 押さずに終了させるようにはできません。何かいい方法はないでしょうか?

  • Winでバッチファイルで外部処理後、ファイル処理

    全部で3行のバッチファイルを作成しました。一行目で外部プログラムを呼び出し走らせて(30分ほどで終了します)、2行目と3行目でファイル処理をするものです。生成されたファイルをZIPして元のファイルを削除するだけです。 問題は2行目が始まらないので、バッチファイル自体が終了しません。 おそらく.batが一行目の処理終了を認識しないためだと思うのですが、どうしたらよいのでしょうか?バッチファイル自体は手動クリックで開始です。 例えば40分後に強制的に2行目に進む方法とか、外部処理の終了が、外部アプリの終了なのか・・・ よろしくお願いします。

  • VC6.0でクリック時にバッチファイルを実行し、終了したか知りたい

    VC6.0でクリック時にバッチファイルを実行し、終了したか知りたい 開発環境:VC6.0 OS:windowsXP HOME ダイアログのonclick時に バッチファイルを実行したいと思います さらに終了後に次の処理を行うような手順を検討しています バッチファイルを実行させる方法は WinExec(_T("abc.bat"),SW_SHOWNORMAL); のような方法で可能でしたが、 終了する前に次の処理に行ってしまいます。 終了を知る方法はありますでしょうか? よろしくお願いします

  • バッチファイルで実行できたりできなかったり

    こんにちは。 バッチファイルとコマンドプロンプトについて、少々お伺いしたいことがあります。 まず、コマンドプロンプトで以下のコマンドを打ち込んでみたところ、すべて正常に実行することができました。 ping [example.com] > result.txt tracert [example.com] >> tr_result.txt ipconfig /all > ipc_result.txt 次に、各コマンドをテキストファイルに書き込んで、それぞれ "p_test.bat" # 内容は ping コマンド "tr_test.bat" # 内容は tracert コマンド "ipc_test.bat" # 内容は ipconfig コマンド と命名しデスクトップに配置、ダブルクリックで実行してみました。 すると、このうち正常に実行(結果をテキストファイルに出力)されたのは tr_test.bat のみでした。 ここで質問なのですが、なぜこのような違い(バッチファイルにすると実行できるものとできないものに分かれる)が起こるのでしょうか? バッチファイルの作り方やとコマンドプロンプトについて調べてみましたが、説明を見つけることが出来ませんでした。 この辺の理論について詳しい方がおりましたら、ご教示頂きたく思います。 ちなみに、OS は Windows XP SP2 です。 よろしくお願いいたします。

  • バッチでのSQL実行結果の分岐処理について。

    バッチでのSQL実行結果の分岐処理について。 お世話になっております。 バッチからsqlを実行してその結果によってそれ以降のバッチ全体の処理を停止させる方法を考えています。 手がかりがつかめずまったく先に進めないためアドバイスをいただけますでしょうか。 バッチの内容(start_del.bat) -------------------------------------------------------- osql -i.\del.sql -o c:\wk\log.txt -S gold -E osql -i.\create.sql -o c:\wk\log.txt -S gold -E ------------------------------------------------------------ SQLの内容(del.sql) ------------------------------------------------------------ BEGIN TRANSACTION; DELETE FROM LDDB.dbo.test WHERE b='0'; IF @@ERROR = 0 <--エラー判定にこのコマンドを使おうと考えました BEGIN *********************** END ELSE BEGIN ********************** END COMMIT TRANSACTION; ------------------------------------------------------------ 処理の概要: 1.バッチで最初にdel.sqlを実行します。 2.del.sqlの実行が失敗すれば、2つ目のバッチであるcreate.sqlは実行ささずに、バッチを終了させます。 *ポイントはdel.sqlの結果というのは、バッチからdel.sqlを実行できたかではなく、del.sqlの実行結果を判断するという点です。 教えていただきたいこと ・del.sqlの実行後、制御がバッチに戻ったときに、結果を確認してバッチを継続させるか終了させるかを判断させる方法はどのような仕組みを作ればいいのでしょうか。 Windows2003サーバーで、SQLServerは2005です。 初心者のためよく分かっていないことが多すぎで申し訳ありませんが、アドバイスをいただけますでしょうか。 よろしくお願いいたします。

  • エクセルVBAで、バッチ処理を起動すると・・・

    Windows/XP/pro、エクセル2002 使用です。 c:\autocsvフォルダーに、MS-DOSコマンドを使ってFTPを自動実行しサーバーからCSVを自動的に取得する.TXTファイルと、バッチファイルの.batファイルをおいています。 参考URL http://www.ponko2.com/ftp_bat.html この.batファイルをVBAから呼び出して実行させるように下記のコードを記述ましたが、ファイルは起動するものの、CSVファイルを取得(またはLogin)できません。Openメソッドを使ってもうまくいきませんでした。実行する関数の間違いと思っていますが、それとも、VBAからバッチファイルを実行する場合の何か決まりごと等があるのでしょうか? Sub test() Dim str As Variant str = Shell("c:\autocsv\auto.bat", vbNormalFocus) Application.Wait Now + TimeValue("00:00:10") End Sub (VBAの実行をステップインを使って1行ずつ実行してもファイルを取得できません) なお、.batファイルを単独で起動させた場合は、問題なくcsvファイルの取得はできています。 お手数ですが、ご指導いただけますようお願いします。

  • VBAでネットワーク上のバッチジョブを実行したい

    クライアントPCのVBAからサーバなどのネットワーク上のバッチジョブを実行するにはどのようにすればよいでしょうか?   Dim WshShell Set WshShell = CreateObject("WScript.Shell") WshShell.Run "\\サーバ名\AAAAA\BAT\TEST.bat", , True MsgBox "終了!" Set WshShell = Nothing 上記を参考にしたのですが、どうもうまくいかないのです。 何かが足りないのですか?

  • 外部ファイルを実行するには?

    お世話になります。 vb6で外部のバッチファイルを起動して、それを動作させようとしているのですが、うまくいきません。特にエラーにはならず、一瞬DOSプロントは立ち上がるんですが、バッチ処理しているログにはなにも書き込まれません。普通にバッチファイルをダブルクリックさせるか、コマンドからバッチファイルの入っているフォルダまでいって、バッチファイルを実行すれば書き込まれるのですが。 どこがまちがっているのでしょうか?shellじゃなくて、違う関数を使わなければいけないのでしょうか?ご教授よろしくお願いします。 なお、vb6でテストするときは▸マークの実行を押して、テストしました。 サンプル用のものです。 ↓test 現在の時間をログに記入 ■バッチファイルの中身(test.bat) echo test >> log.txt time/t >> log.txt ■vb6のファイルの中身 Private Sub Command1_Click() Dim ret as long ret = shell("cmd.exe /c C:\test\test.bat",4) End Sub