web-dev-qa-db-ja.com

コマンドラインまたはバッチファイルからExcelマクロを実行する方法は?

バッチファイルからファイルにアクセスするときに実行する必要があるExcel VBAマクロがありますが、開くたびに実行する必要はありません(したがって、ファイルを開くイベントを使用しません)。コマンドラインまたはバッチファイルからマクロを実行する方法はありますか?私はそのようなコマンドに精通していません。

Windows NT環境を想定しています。

69
Polymeron

Excelを起動し、ブックを開いてVBScriptファイルからマクロを実行できます。

以下のコードをメモ帳にコピーします。

MyWorkbook.xls」および「MyMacro」パラメーターを更新します。

Vbs拡張子で保存して実行します。

Option Explicit

On Error Resume Next

ExcelMacroExample

Sub ExcelMacroExample() 

  Dim xlApp 
  Dim xlBook 

  Set xlApp = CreateObject("Excel.Application") 
  Set xlBook = xlApp.Workbooks.Open("C:\MyWorkbook.xls", 0, True) 
  xlApp.Run "MyMacro"
  xlApp.Quit 

  Set xlBook = Nothing 
  Set xlApp = Nothing 

End Sub 

マクロを実行する重要な行は次のとおりです。

xlApp.Run "MyMacro"

77
Robert Mearns

最も簡単な方法は次のとおりです。

1)バッチファイルからExcelを起動して、マクロを含むブックを開きます。

Excel.EXE /e "c:\YourWorkbook.xls"

2)次のようなワークブックのWorkbook_Openイベントからマクロを呼び出します。

Private Sub Workbook_Open()
    Call MyMacro1          ' Call your macro
    ActiveWorkbook.Save    ' Save the current workbook, bypassing the Prompt
    Application.Quit       ' Quit Excel
End Sub

これにより、コントロールがバッチファイルに返され、他の処理が実行されます。

19
bvukas

以下に示す方法では、バッチファイルから定義済みのExcelマクロを実行できます。環境変数を使用して、マクロ名をバッチからExcelに渡します。

このコードをバッチファイルに配置します(Excel.EXEおよびワークブックへのパスを使用します)。

Set MacroName=MyMacro
"C:\Program Files\Microsoft Office\Office15\Excel.EXE" "C:\MyWorkbook.xlsm"

このコードをExcel VBA ThisWorkBookオブジェクトに追加します。

Private Sub Workbook_Open()
    Dim strMacroName As String
    strMacroName = CreateObject("WScript.Shell").Environment("process").Item("MacroName")
    If strMacroName <> "" Then Run strMacroName
End Sub

次のように、コードをExcel VBAモジュールに配置します。

Sub MyMacro()
    MsgBox "MyMacro is running..."
End Sub

バッチファイルを起動して結果を取得します。

macro's dialog

マクロを実行するつもりがない場合は、空の値Set MacroName=をバッチに追加するだけです。

5
omegastripes

createobject()メソッドを介してExcelのインスタンスを作成するvbscriptを記述してから、ブックを開いてマクロを実行できます。 vbscriptを直接呼び出すか、バッチファイルからvbscriptを呼び出すことができます。

ここに私が偶然見つけたリソースがあります: http://www.codeguru.com/forum/showthread.php?t=376401

4
Fink

Workbook_Open()で開いているワークブックの数を常にテストしました。 1の場合、ブックはコマンドラインで開かれました(またはユーザーがすべてのブックを閉じてから、このブックを開きました)。

If Workbooks.Count = 1 Then

    ' execute the macro or call another procedure - I always do the latter  
    PublishReport

    ThisWorkbook.Save

    Application.Quit

End If
3
Brian Hoffman

文字列を直接比較する代わりに(GetEnvironmentVariableは長さ255の文字列を返すため、VBは文字列が等しいとは見なしません)、これを記述します。

Private Sub Workbook_Open()     
    If InStr(1, GetEnvironmentVariable("InBatch"), "TRUE", vbTextCompare) Then
        Debug.Print "Batch"  
        Call Macro
    Else    
        Debug.Print "Normal"     
    End If 

End Sub 
2
laybmw

Excel/VBA内での作業がより快適な場合は、openイベントを使用して環境をテストします。openファイルの動作を制御するシグナルファイル、レジストリエントリ、または環境変数を用意します。

外部でファイル/設定を作成し、内部でテストし(env-varsにはGetEnviromentVariableを使用)、簡単にテストできます。 VBScriptを作成しましたが、VBAとの類似点により、不安よりも不安を感じています。

[もっと]

私は問題を理解しているので、ほとんどの場合/通常はスプレッドシートを使用したいが、バッチで実行して、余分な/異なることをします。 Excel.exeコマンドラインからシートを開くことはできますが、シートの場所がわからない限り、シートの動作を制御することはできません。環境変数の使用は比較的簡単で、スプレッドシートのテストが簡単になります。

明確にするために、以下の機能を使用して環境を調べてください。モジュールで宣言:

Private Declare Function GetEnvVar Lib "kernel32" Alias "GetEnvironmentVariableA" _
    (ByVal lpName As String, ByVal lpBuffer As String, ByVal nSize As Long) As Long

Function GetEnvironmentVariable(var As String) As String
Dim numChars As Long

    GetEnvironmentVariable = String(255, " ")

    numChars = GetEnvVar(var, GetEnvironmentVariable, 255)

End Function

Workbook openイベントで(他の人として):

Private Sub Workbook_Open()
    If GetEnvironmentVariable("InBatch") = "TRUE" Then
        Debug.Print "Batch"
    Else
        Debug.Print "Normal"
    End If
End Sub

必要に応じてアクティブコードを追加します。バッチファイルでは、

set InBatch=TRUE
2
Chris Chambers

@ Robert:コードを相対パスに適合させ、VBSを実行するバッチファイルを作成しようとしました。

VBSが開始および終了しますが、マクロを起動しません...問題がどこにあるのか考えていますか?

Option Explicit

On Error Resume Next

ExcelMacroExample

Sub ExcelMacroExample() 

  Dim xlApp 
  Dim xlBook 

  Set xlApp = CreateObject("Excel.Application")
  Set objFSO = CreateObject("Scripting.FileSystemObject")
  strFilePath = objFSO.GetAbsolutePathName(".") 
  Set xlBook = xlApp.Workbooks.Open(strFilePath, "Excels\CLIENTES.xlsb") , 0, True) 
  xlApp.Run "open_form"


  Set xlBook = Nothing 
  Set xlApp = Nothing 

End Sub

「Application.Quit」を削除しました。マクロがそれを処理するユーザーフォームを呼び出しているからです。

乾杯

編集

誰かがスタンドアロンのアプリケーションと同じようにユーザーフォームを実行したい場合に備えて、実際にそれを解決しました:

私が直面していた問題:

1-Excelが読み取り専用でロックされているため、Workbook_Openイベントを使用したくありませんでした。 2-バッチコマンドは、(私の知る限り)マクロを呼び出せないという事実に制限されています。

最初に、アプリケーションを非表示にしている間にユーザーフォームを起動するマクロを作成しました。

Sub open_form()
 Application.Visible = False
 frmAddClient.Show vbModeless
End Sub

次に、このマクロを起動するvbsを作成しました(相対パスで実行するのは難しいです):

dim fso
dim curDir
dim WinScriptHost
set fso = CreateObject("Scripting.FileSystemObject")
curDir = fso.GetAbsolutePathName(".")
set fso = nothing

Set xlObj = CreateObject("Excel.application")
xlObj.Workbooks.Open curDir & "\Excels\CLIENTES.xlsb"
xlObj.Run "open_form"

そして最後に、VBSを実行するバッチファイルを作成しました...

@echo off
pushd %~dp0
cscript Add_Client.vbs

Userform_QueryCloseには「表示に戻す」も含まれていることに注意してください。

Private Sub cmdClose_Click()
Unload Me
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    ThisWorkbook.Close SaveChanges:=True
    Application.Visible = True
    Application.Quit
End Sub

とにかく、あなたの助けに感謝し、誰かがそれを必要とする場合、これが役立つことを願っています

2
Axn40

私はC#に不満です。 linqpadを使用して次を実行しました。ただし、cscを使用して簡単にコンパイルし、コマンドラインから呼び出されたものを実行することもできます。

Excelパッケージを名前空間に追加することを忘れないでください。

void Main()
{
    var oExcelApp = (Microsoft.Office.Interop.Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
    try{
        var WB = oExcelApp.ActiveWorkbook;
        var WS = (Worksheet)WB.ActiveSheet;
        ((string)((Range)WS.Cells[1,1]).Value).Dump("Cell Value"); //cel A1 val
        oExcelApp.Run("test_macro_name").Dump("macro");
    }
    finally{
        if(oExcelApp != null)
            System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcelApp);
        oExcelApp = null;
    }
}
1
t3dodson

Excelが既に開いているかどうかを確認できます。別のインスタンスを作成する必要はありません

   If CheckAppOpen("Excel.application")  Then
           'MsgBox "App Loaded"
            Set xlApp = GetObject(, "Excel.Application")   
   Else
            ' MsgBox "App Not Loaded"
            Set  wrdApp = CreateObject(,"Excel.Application")   
   End If
1
Adam Law