バッチファイルからファイルにアクセスするときに実行する必要があるExcel VBAマクロがありますが、開くたびに実行する必要はありません(したがって、ファイルを開くイベントを使用しません)。コマンドラインまたはバッチファイルからマクロを実行する方法はありますか?私はそのようなコマンドに精通していません。
Windows NT環境を想定しています。
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"
最も簡単な方法は次のとおりです。
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"
このコードを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
バッチファイルを起動して結果を取得します。
マクロを実行するつもりがない場合は、空の値Set MacroName=
をバッチに追加するだけです。
createobject()メソッドを介してExcelのインスタンスを作成するvbscriptを記述してから、ブックを開いてマクロを実行できます。 vbscriptを直接呼び出すか、バッチファイルからvbscriptを呼び出すことができます。
ここに私が偶然見つけたリソースがあります: http://www.codeguru.com/forum/showthread.php?t=376401
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
文字列を直接比較する代わりに(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
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
@ 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
とにかく、あなたの助けに感謝し、誰かがそれを必要とする場合、これが役立つことを願っています
私は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;
}
}
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