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

StackOverflow https://stackoverflow.com/questions/2050505

質問

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

Windows NT環境を想定します。

役に立ちましたか?

解決

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

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

「」を更新しますMyWorkbook.xls' そして 'マイマクロ' パラメーター。

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.「MyMacro」を実行

他のヒント

それを行うための最も簡単な方法は、以下のとおりです。

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

このは今、他の処理を行うには、あなたのバッチファイルへのコントロールを返します。

以下に示す方法は、バッチからExcelにマクロ名を渡すために環境変数を使用して、バッチファイルから定義されたExcelマクロを実行することができます。

EXCEL.EXEするためにあなたのパスを使用して、ブックへ)バッチファイルにこのコードを入れます:

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

エクセル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

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

 マクロのダイアログ

あなただけのバッチに空の値Set MacroName=を置く任意のマクロを実行する予定がない場合のために。

あなたは、ブックを開いてマクロを実行する、のCreateObject()メソッドを使ってExcelのインスタンスを作成するために、VBScriptを書くことができます。あなたは直接VBScriptを呼び出す、またはバッチファイルからVBScriptを呼び出すことができます。

ここで私はちょうどaccrossつまずいたリソースは以下のとおりです。 http://www.codeguru.com/forum/showthread.php?t= 376401

私はいつものWorkbook_Openで開いているブックの数をテストしています()。それが1である場合には、ワークブックは、コマンドラインで開かれた(または、ユーザーがすべてのブックを閉じて、その後、この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

は、Excel / VBA内部の作業をより快適にしている場合は、オープンイベントを使用して環境をテスト:信号ファイル、レジストリエントリまたはオープンイベントが何をするかを制御する環境変数を持っているのいずれか

あなたは簡単に、テスト(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

ブックオープンイベントでは(他のものなど)

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

適用可能なアクティブなコードに追加します。バッチファイルでは、使用

set InBatch=TRUE

の代わりに、直接(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 

ロバート@:私は相対パスを使用してコードを適応させることを試みた、と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

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

Excelが既に開いている場合は、確認することができます。別のisntanceを作成する必要はありません。

   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

私は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;
    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top