从命令行或batch file运行Excelmacros的方法?

我有一个Excel VBAmacros,我需要从batch file访问文件时运行,但不是每次打开它(因此不使用打开的文件事件)。 有没有办法从命令行或batch file运行macros? 我不熟悉这样的命令。

假设一个Windows NT环境。

您可以启动Excel,打开工作簿并从VBScript文件运行macros。

将下面的代码复制到记事本中。

更新“ 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 

运行macros的关键是:

xlApp.Run“MyMacro”

最简单的方法是:

1)从batch file中启动Excel以打开包含macros的工作簿:

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

2)从工作簿的Workbook_Open事件调用您的macros,如:

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

这将现在返回到您的batch file进行其他处理的控制。

你可以通过createobject()方法写一个vbscript来创build一个excel的实例,然后打开工作簿并运行macros。 你可以直接调用vbscript,或者从batch file调用vbscript。

这是我刚刚偶然发现的一个资源: http : //www.codeguru.com/forum/showthread.php? t = 376401

如果你更喜欢在Excel / VBA中工作,使用open事件并testing环境:要么有一个信号文件,一个registry项或一个环境variables来控制打开的事件。

您可以创build外部的文件/设置并在里面进行testing(对Env-vars使用GetEnviromentVariable)并轻松testing。 我写了VBScript,但与VBA的相似之处,让我比放松更焦虑。

[更多]

正如我所理解的那样,你想通常使用一个电子表格,通常最多/部分时间是批量运行,并做一些额外/不同的事情。 您可以从excel.exe命令行打开表单,但是除非知道它在哪里,否则无法控制它的function。 使用环境variables相对简单,使testing电子表格变得简单。

为了澄清,使用下面的function来检查环境。 在一个模块中声明:

 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公开活动中(与其他人一样):

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

根据情况添加活动代码。 在batch file中,使用

 set InBatch=TRUE 

而不是直接比较string(因为GetEnvironmentVariable返回一个长度为255的string,所以VB不会find它们)写下:

 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 

我一直在Workbook_Open()中testing打开工作簿的数量。 如果是1,那么工作簿是通过命令行打开的(或者用户closures了所有的工作簿,然后打开这个工作簿)。

 If Workbooks.Count = 1 Then ' execute the macro or call another procedure - I always do the latter PublishReport ThisWorkbook.Save Application.Quit End If 

@ Robert:我试图用相对path调整代码,并创build了一个batch file来运行VBS。

VBS启动和closures,但不启动macros…任何想法可能是什么问题?

 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”,因为我的macros正在调用一个用户窗体来照顾它。

干杯

编辑

我实际上已经完成了,以防万一有人想运行一个用户表单“一样”一个独立的应用程序:

我正面临的问题:

1 – 我不想使用Workbook_Open事件,因为excel被locking在只读状态。 2 – 批处理命令是有限的,(据我所知),它不能调用macros。

我首先写了一个macros来启动我的用户表单,同时隐藏应用程序:

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

然后我创build了一个vbs来启动这个macros(用相对path做这件事一直很棘手):

 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" 

我终于做了一个batch file来执行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 

无论如何,谢谢你的帮助,我希望这将有助于如果有人需要它

下面显示的方法允许从batch file运行已定义的Excelmacros,它使用环境variables将批处理macros名称传递给Excel。

将此代码放入batch file(使用您的path到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 Module中,如下所示:

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

启动batch file并得到结果:

宏的对话框

对于不打算运行任何macros的情况,只需将空值Set MacroName=设置为批处理。

你可以检查Excel是否已经打开。 没有必要创build另一个节点

  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; } }