办法从命令行或批处理文件运行Excel宏?
-
20-09-2019 - |
题
我有一个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=
该批生产的情况。
可以编写一个VBScript经由CREATEOBJECT()方法来创建Excel的实例,然后打开该工作簿和运行宏。你可以直接调用的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
如果你更舒适的Excel / VBA容器内工作,使用开放的事件和测试环境:要么有一个信号文件,注册表项或环境变量,控制一下打开事件确实
可以创建文件/设置外部和内部测试(使用GetEnviromentVariable对于ENV-VARS)和测试容易。我写的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
代替直接比较字符串(VB不会找到他们相等,因为GetEnvironmentVariable返回长度255的字符串)写:
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 - 我不想使用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
无论如何,感谢您的帮助,我也希望如果有人需要它,这将有助于
您可以检查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;
}
}