VBAでdosのcompコマンドの実行結果を得たい

このQ&Aのポイント
  • Excel2010のVBAで、MS-DOSのcompコマンドの実行結果を取得する方法を教えてください。
  • 現在、file1とfile2のパスを指定してcompコマンドを実行していますが、うまくいきません。
  • どのようにすれば正しくcompコマンドの実行結果を取得できるでしょうか?
回答を見る
  • ベストアンサー

VBAでdosのcompコマンドの実行結果を得たい

Excel2010のVBAで、 MS-DOSのcompコマンドの実行結果を取得したいのですが、 以下の方法ではうまくいきませんでした。 どのようにすればよいでしょうか。(Windows7) ------------------------------------------------------------ Sub test()  Dim wshShell As Object  Dim wshExec As Object  Dim command As String  Dim file1 As String  Dim file2 As String  Dim result As String  file1 = "C:\test\0128\test.xlsx"  file2 = "C:\test\0129\test.xlsx"  'command = "dir /d " & file1 & " " & file2     '(OK)  'command = "fc /b " & file1 & " " & file2      '(OK)  command = "comp " & file1 & " " & file2      '(NG)  'command = "echo n | comp " & file1 & " " & file2  '(NG)  Debug.Print command  Set wshShell = CreateObject("WScript.Shell")  Set wshExec = wshShell.exec("%ComSpec% /c " & command)  Do Until wshExec.Status   DoEvents  Loop  If wshExec.StdErr.AtEndOfStream = False Then   'エラー   result = wshExec.StdErr.ReadAll  Else   '正常   result = wshExec.StdOut.ReadAll  End If  Set wshExec = Nothing  Set wshShell = Nothing  MsgBox result End Sub ------------------------------------------------------------

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

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8519/19365)
回答No.2

compコマンドは ほかのファイルを比較しますか (Y/N)? と言うプロンプトを「標準エラー出力」に出力します。 ですので  If wshExec.StdErr.AtEndOfStream = False Then が「真」になり   'エラー   result = wshExec.StdErr.ReadAll だけが実行されます。 そして、resultには ほかのファイルを比較しますか (Y/N)? と言う文字列が返って来ます。 なので MsgBox result とやっても ほかのファイルを比較しますか (Y/N)? しか表示されず、欲しい結果は得られません。 なので「標準エラー出力になにか出力されても、無視する」ようにして下さい。 つまり  '判定しない  ’If wshExec.StdErr.AtEndOfStream = False Then   'エラー   'result = wshExec.StdErr.ReadAll  'Else   '正常   result = wshExec.StdOut.ReadAll  'End If のように、if文をコメントアウトして下さい。 なお「compコマンドは、プロンプトを出して、yかnが入力されるまで、待ってしまう」ので  command = "echo n | comp " & file1 & " " & file2 にしないといけません。じゃないと「手でnを入力しないとcompコマンドが終了しない」です。

yam2012
質問者

お礼

エラーが発生した時だけ wshExec.StdErr.AtEndOfStream = False が「真」になると思い込んでいました。 教えていただきました方法で、 compコマンドの実行結果を正しく 取得することができました。 ありがとうございました。

その他の回答 (2)

  • Prome_Lin
  • ベストアンサー率42% (201/470)
回答No.3

私が調べたサイトでは、以下のようになっていました。 Sub Test() Dim w, x As Object Dim c, r As String Set w = CreateObject("WScript.Shell") c = "comp D:\Programming\Book1.csv D:\Programming\Book2.csv" Set x = w.Exec("%ComSpec% /c " & c) Do While x.Status = 0 DoEvents Loop r = x.StdOut.ReadAll MsgBox r End Sub ただ、そのサイトの説明では「%ComSpec% /c」の「/c」で実行後、コマンドプロンプトの画面が閉じる、ということでしたが、私が試したところ、閉じませんでしたが、エクセルの画面上に結果は表示されていましたので、文字列変数「r」には、間違いなく、コマンドプロンプト上で「comp」が実行され、その結果までの内容が格納されています。

yam2012
質問者

お礼

上記のコードを試してみました。 コマンドプロンプトの画面は開いた状態のままで Do~Loopの所で x.Status = 0 の条件が満たされずに ループし続けていますので、 その後の MsgBox r は実行されず 結果は表示されませんでした。 なお、f272さん、chie65535さんから 頂きました方法で解決できました。 ありがとうございました。

  • f272
  • ベストアンサー率46% (8005/17110)
回答No.1

If wshExec.StdErr.AtEndOfStream = False Then で分けなくてもいいんじゃないの? 単に,コマンドを command = "echo n | comp " & file1 & " " & file2 これにして result = wshExec.StdOut.ReadAll これだけ

yam2012
質問者

お礼

result = wshExec.StdOut.ReadAll だけにしてみたらうまくいきました。 最初、このようにしなければならない理由が よく分からなかったのですが その後のchie65535さん頂いた回答で この理由が理解できました。 ありがとうございました。

関連するQ&A

  • VBAで外部プログラムを非表示で実行するには

    VBAとVBScriptを混同しているのかもしれませんがよく分からないので教えてください。 Excel2010のVBAから、外部プログラム(test.exe)をコマンドプロンプトを非表示の状態で実行して、外部プログラムの実行が終了するのを待ってから、次の処理をさせたいのですが、test1のプログラムでは(A)の部分でエラーになってしまいます。また、test2のプログラムでは正しく実行されるのですがコマンドプロンプトのウインドウを非表示にする方法がよく分かりません。 test1のプログラムでエラーをでなくする方法、または、test2のプログラムでコマンドプロンプトのウインドウを非表示にする方法がありましたら教えてください。 ------------------------------------------------------- Sub test1()  Dim ws As Object  Dim we As Object  Dim command As String  command = "C:\test.exe"  Set ws = CreateObject("WScript.Shell")  Set we = ws.Run("%ComSpec% /c " & command, 0, False) '<===(A)  Set we = Nothing  Set ws = Nothing End Sub ------------------------------------------------------- Sub test2()  Dim ws As Object  Dim we As Object  Dim command As String  command = "C:\test.exe"  Set ws = CreateObject("WScript.Shell")  Set we = ws.exec("%ComSpec% /c " & command)  Do Until we.Status   DoEvents  Loop  Set we = Nothing  Set ws = Nothing End Sub -------------------------------------------------------

  • アクセスからエクセルのマクロを実行したいのですが

    Sub エクセルのVBA実行する() Dim xlsWB As Object Dim MyFileName As String MyFileName = "C:\test.xlsx" Set xlsWB = GetObject(MyFileName) xlsWB.Application.Run xlsWB.Name & "!マクロ" Set xlsWB = Nothing End Sub と言うコードを作ったのですが エクセルファイルにはパスワードがかかっています。 パスワード付のエクセルファイルを開きマクロを実行するにはどうすればいいでしょうか?

  • エクセルVBAで配列ができなかった時の処理

    エクセルでコマンドラインでデータを配列に 落としていますがデータがなかった時 配列もできていないようなのですがその時の書式がわかりません。 Dim cmd As String Dim filedata() As String Dim i As Integer cmd = dosのコマンド Set Result = WSH.exec("%ComSpec% /c " & cmd) Do While Result.Status = 0 DoEvents Loop filedata = Split(Result.StdOut.ReadAll, vbLf) '配列データができなかった時の処理 例えば  IF filedata(0)=""  IF filedata=""  IF filedate IS Nothing など いづれもエラーになります。 なにか書式ありますでしょうか

  • VBAでDOS プロンプトを使いたいのですが・・・

    デスクトップの\dataフォルダに、名前を付け替えたいファイルが多数あります。 それらのファイル名(旧名)と、変更したい名前(新名)は、エクセル上の2列に 入力済みです。VBAを使って、dosプロンプトのRENを実行しようとしましたが、 多くのファイル名にスペースが含まれるせいか、大半が変更できませんでした。 良い方法があれば、教えてください。どうかよろしくお願いします。 ※作成したプロシージャは以下の通りです。 Sub ファイル名変更() Dim カウンタ As Integer For カウンタ = 2 To 1000 Dim wsh As Object, wexec As Object, cmd As String Dim 旧名 As String, 新名 As String Set wsh = CreateObject("wscript.shell") 旧名 = Cells(カウンタ, 1).Value     '旧名はA列にある 新名 = Cells(カウンタ, 2).Value    '新名はB列にある cmd = "ren c:\users\me\desktop\data\" & 旧名 & " " & 新名 Set wexec = wsh.Exec("%comspec% /c " & cmd) Set wexec = Nothing Set wsh = Nothing Next End Sub

  • Excel VBAでbatファイルを実行

    ExcelのVBAでbatファイルを実行し、 batファイル内でセットした環境変数を取得することは可能でしょうか? batファイルの内容は set MYDRIVE=E: set MYDIR=%MYDRIVE%\WORK のような感じです。 環境変数「MYDIR」の値をVBA側で取得できないかと思い、 ' 参照設定: Windows Script Host Object Model Sub ボタン1_Click() Dim myWshShell As New WshShell Dim myLong As Long Dim myWshEnvironment1 As WshEnvironment Dim myWshEnvironment2 As WshEnvironment Dim myWshEnvironment3 As WshEnvironment Dim myWshEnvironment4 As WshEnvironment myLong = myWshShell.Run("E:\work\test.bat") Set myWshEnvironment1 = myWshShell.Environment("System") Set myWshEnvironment2 = myWshShell.Environment("User") Set myWshEnvironment3 = myWshShell.Environment("Volatile") Set myWshEnvironment4 = myWshShell.Environment("Process") ' ブレークポイントを設定して内容確認 Set myWshShell = Nothing Set myWshEnvironment1 = Nothing Set myWshEnvironment2 = Nothing Set myWshEnvironment3 = Nothing Set myWshEnvironment4 = Nothing End Sub のようなコードを書いてみて「myWshEnvironment1」~「myWshEnvironment4」の内容を ウォッチ式で確認してみましたが、batファイルの中でセットした「MYDIR」の値は 含まれておりませんでした。 batファイルで設定した環境変数の値を取得する方法があれば 教えていただけないでしょうか?

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

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

  • VBAでコマンドプロンプトの結果を変数に代入

    コマンドラインソフトのffmpegを使って、動画の再生時間などを取得したいのですが VBAでコマンドプロンプトの結果を変数に代入する方法について教えてください。 "D:\xxxx\ffmpeg\bin\ffmpeg" -i "d:\xxxx\aaff.mp4" 2>&1 | grep Duration これをコマンドプロンプトで実行すると d:\xxxx\aaff.mp4の再生時間などがコマンドライン上に表示されます。 これを変数に代入するために、 http://officetanaka.net/excel/vba/tips/tips27.htm このページを参考にして Sub Sample1() Dim WSH, wExec, sCmd As String, Result As String Set WSH = CreateObject("WScript.Shell") ''(1) sCmd = """D:\xxxx\ffmpeg\bin\ffmpeg"" -i ""d:\xxxx\aaff.mp4"" 2>&1 | grep Duration" Set wExec = WSH.Exec("%ComSpec% /c " & sCmd) ''(3) Do While wExec.Status = 0 ''(4) DoEvents Loop Result = wExec.StdOut.ReadAll ''(5) MsgBox Result Set wExec = Nothing Set WSH = Nothing End Sub を実行しました。 しかしResultには何の文字列も代入されませんでした。 恐らく、このページのタイトルにもあるように「MS-DOSコマンドの標準出力を取得する」 とあるので、標準出力しか取得できないのではないかと思います。 それでは一般的なコマンドラインソフトの実行結果を変数に代入するにはどうしたら良いでしょうか?

  • エクセルVBAでPDF/実行時エラー

    以下はネットで検索して見つけたPDFのプリント用VBAですがやってみるとSet acroApp = CreateObject("AcroExch.APP")のところで実行時エラー「インターフェイスがサポートされていません」になります。 Adibe Acrobat 10.0 Type Liblaryも参照設定しました。 Windows11でエクセルは2019です。Acrobat Readerも入っています。 どうすればいいのでしょう? https://ziomatrix18.blog.fc2.com/blog-entry-406.html Sub test01() Dim ret As Integer Dim filePath As String filePath = "C:\Temp\Test.pdf" Dim acroApp As CAcroApp Dim pdDoc As CAcroPDDoc Dim avDoc As CAcroAVDoc Set acroApp = CreateObject("AcroExch.APP") Set pdDoc = CreateObject("AcroExch.PDDoc") Set avDoc = CreateObject("AcroExch.AVDoc") ret = acroApp.Show ret = avDoc.Open(filePath, "") Set pdDoc = avDoc.GetPDDoc() Dim numPage As Long numPage = pdDoc.GetNumPages ret = avDoc.PrintPages(0, numPage - 1, 2, 0, 0) ret = avDoc.Close(False) acroApp.Exit Set avDoc = Nothing Set pdDoc = Nothing Set acroApp = Nothing End Sub

  • Workbooks.Open VBA

    Dim xlApp As Object Dim xlWbk As Object Set xlApp = CreateObject("Excel.Application") xlApp.Visible = True Set xlWbk = xlApp.Workbooks.Open("C:\Users\test.xlsx") の後に、 xlWbk.Sheets("1").Select とするのと、 xlApp.Sheets("1").Select とするのでは、 同じ意味ですか? どちらも C:\Users\test.xlsx の シートを選択することになりますか?

  • Excelで、WScript.Shell、標準出力

    Excelで、WScript.Shellを使って、標準出力を経由してデータを取得 Excelで、CreateObject("WScript.Shell")を使って、標準出力を経由してデータを取得したいと考えたのですが、サイズに制限がありそうです。 標準出力のサイズが4096バイトを超えると、DOS窓が閉じず、強制的に終了させると超えた分はどこかへ消えました。 下記のコードで確かめたのですが、何かこの容量の制限を取り払う方法はないでしょうか? Sub Sample1標準出力0() Dim WSH, wExec Dim sCmd As String Dim Result As String Set WSH = CreateObject("WScript.Shell") sCmd = "type D:\t.txt" Set wExec = WSH.Exec("%ComSpec% /c " & sCmd) Do While wExec.Status = 0 DoEvents Loop Result = "" Result = wExec.StdOut.ReadAll Debug.Print Len(Result) MsgBox Result Set wExec = Nothing Set WSH = Nothing End Sub

専門家に質問してみよう