我有一个Excel VBA宏,从批处理文件访问文件时需要运行它,但不是每次我都打开它(因此不使用打开文件事件)。有没有办法从命令行或批处理文件运行宏?我对这样的命令不熟悉。
假定为Windows NT环境。
Answers:
您可以启动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”
xlApp.Visible = True
,否则您将不会看到Excel或其任何可能出现的对话框。
EXCEL.exe
我逐字运行此脚本时,该过程不会关闭。
Set xlApp = CreateObject("Excel.Application")
我的系统上没有工作。您能指导我如何使它工作吗?
最简单的方法是:
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=
到批处理中即可。
您可以编写一个vbscript通过createobject()方法创建excel实例,然后打开工作簿并运行宏。您可以直接调用vbscript,也可以从批处理文件中调用vbscript。
这是我偶然发现的资源:http : //www.codeguru.com/forum/showthread.php? t = 376401
如果您更喜欢在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
在工作簿打开事件中(与其他事件一样):
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-我不想使用Workbook_Open事件,因为Excel处于只读状态。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;
}
}
我通常将宏xlam
与工作簿分开存储在外接程序中,因此我想打开工作簿,然后运行单独存储的宏。
由于这需要VBS脚本,因此我想使其成为“可移植的”,以便可以通过传递参数来使用它。这是最终的脚本,它包含3个参数。
我这样测试:
"C:\Temp\runmacro.vbs" "C:\Temp\Book1.xlam" "Hello"
"C:\Temp\runmacro.vbs" "C:\Temp\Book1.xlsx" "Hello" "%AppData%\Microsoft\Excel\XLSTART\Book1.xlam"
runmacro.vbs:
Set args = Wscript.Arguments
ws = WScript.Arguments.Item(0)
macro = WScript.Arguments.Item(1)
If wscript.arguments.count > 2 Then
macrowb= WScript.Arguments.Item(2)
End If
LaunchMacro
Sub LaunchMacro()
Dim xl
Dim xlBook
Set xl = CreateObject("Excel.application")
Set xlBook = xl.Workbooks.Open(ws, 0, True)
If wscript.arguments.count > 2 Then
Set macrowb= xl.Workbooks.Open(macrowb, 0, True)
End If
'xl.Application.Visible = True ' Show Excel Window
xl.Application.run macro
'xl.DisplayAlerts = False ' suppress prompts and alert messages while a macro is running
'xlBook.saved = True ' suppresses the Save Changes prompt when you close a workbook
'xl.activewindow.close
xl.Quit
End Sub