从命令行使用VBScript在Excel之外运行Excel宏

40

我正在尝试从Excel文件之外运行Excel宏。我目前正在使用从命令行运行的“.vbs”文件,但它一直告诉我找不到宏。这是我正在尝试使用的脚本:

Set objExcel = CreateObject("Excel.Application")
Set objWorkbook = objExcel.Workbooks.Open("test.xls")

objExcel.Application.Visible = True
objExcel.Workbooks.Add
objExcel.Cells(1, 1).Value = "Test value"

objExcel.Application.Run "Macro.TestMacro()"
objExcel.ActiveWorkbook.Close


objExcel.Application.Quit
WScript.Echo "Finished."
WScript.Quit

这是我想要访问的宏:

Sub TestMacro()
'first set a string which contains the path to the file you want to create.
'this example creates one and stores it in the root directory
MyFile = "C:\Users\username\Desktop\" & "TestResult.txt"
'set and open file for output
fnum = FreeFile()
Open MyFile For Output As fnum
'write project info and then a blank line. Note the comma is required
Write #fnum, "I wrote this"
Write #fnum,
'use Print when you want the string without quotation marks
Print #fnum, "I printed this"
Close #fnum
End Sub

我已经尝试过位于Is it possible to run a macro in Excel from external command?的解决方案(当然进行了修改),但似乎并没有起作用。我一直收到错误提示“Microsoft Office Excel:找不到宏'Macro.TestMacro'。

编辑:Excel 2003。


1
你尝试过移除“Macro.”和/或括号,直接像这样调用它 objExcel.Application.Run "TestMacro" 吗? - deusxmach1na
objExcel.Application.Run "test.xls!Macro.TestMacro" objExcel.Application.Run“test.xls!宏.TestMacro” - Tim Williams
@rar:代码中有很多错误。我有三个问题要问你。1)TestMacro()是否驻留在test.xls模块中?2)为什么要添加一个工作簿?3)为什么要写入单元格Cells(1,1)? - Siddharth Rout
  1. 不是,但我把它移到那里后就能够在那里访问了。
  2. 那是我找到的示例代码,在发布之前忘记修改掉那部分了。
  3. 再次说明,那只是示例代码。我已经从我的最终测试用例中删除了它。
- muttley91
1
@rar:好的。我已经发布了我测试和尝试过的代码,但我想这并不重要,因为你已经得到了答案 :) - Siddharth Rout
显示剩余2条评论
8个回答

46

好的,其实很简单。假设你的宏是在一个模块中而不是工作表中,你可以使用:

  objExcel.Application.Run "test.xls!dog" 
  'notice the format of 'workbook name'!macro

对于带有空格的文件名,请用引号将文件名括起来。

如果您将宏放置在工作表下,比如说sheet1,那么就默认sheet1拥有该函数,因为它确实是这样。

    objExcel.Application.Run "'test 2.xls'!sheet1.dog"

注意:你不需要使用你一直在使用的`macro.testfunction`表示法。


我没有意识到它必须在模块中,我把它放在了工作簿中(如果我把它留在其中一个工作表中,我也可以尝试第二部分)。谢谢! - muttley91
宏可以保存在与Excel不同的文件中吗?这样我就可以在其他Excel文件中使用它,而无需将其添加到每个Excel中。谢谢。 - Si8
这考虑从多个Excel文件中调用单个宏。这是你想要的吗?https://dev59.com/zmPVa4cB1Zd3GeqP-fFj - Wolf-Kun

25

这段代码将打开文件 Test.xls 并运行宏 TestMacro,该宏又会将结果写入到文本文件 TestResult.txt

Option Explicit

Dim xlApp, xlBook

Set xlApp = CreateObject("Excel.Application")
'~~> Change Path here
Set xlBook = xlApp.Workbooks.Open("C:\Test.xls", 0, True)
xlApp.Run "TestMacro"
xlBook.Close
xlApp.Quit

Set xlBook = Nothing
Set xlApp = Nothing

WScript.Echo "Finished."
WScript.Quit

5

由于我在整整一天的搜索中都无法解决“宏未找到或禁用”错误,而我的相关问题被正义之手删除了,因此在这里发布我唯一有效的语法(无论我尝试什么,应用程序.运行都不行)。

Set objExcel = CreateObject("Excel.Application")

' Didn't run this way from the Modules
'objExcel.Application.Run "c:\app\Book1.xlsm!Sub1"
' Didn't run this way either from the Sheet
'objExcel.Application.Run "c:\app\Book1.xlsm!Sheet1.Sub1"
' Nor did it run from a named Sheet
'objExcel.Application.Run "c:\app\Book1.xlsm!Named_Sheet.Sub1"

' Only ran like this (from the Module1)

Set objWorkbook = objExcel.Workbooks.Open("c:\app\Book1.xlsm")
objExcel.Run "Sub1"

Excel 2010, Win 7


非常好的解决方案,谢谢!你可能想要添加 objWorkbook.CloseobjExcel.Application.Quit,否则 Excel 进程仍在运行。 - shosaco

4

我尝试将 @Siddhart 的代码改为相对路径,以运行我的 open_form 宏,但似乎没有成功。这是我的第一次尝试。下面是我的可行解决方案。

Option Explicit

Dim xlApp, xlBook
dim fso
dim curDir
set fso = CreateObject("Scripting.FileSystemObject")
curDir = fso.GetAbsolutePathName(".")
set fso = nothing

Set xlApp = CreateObject("Excel.Application")
'~~> Change Path here
Set xlBook = xlApp.Workbooks.Open(curDir & "Excels\CLIENTES.xlsb", 0, true)
xlApp.Run "open_form"
xlBook.Close
xlApp.Quit

Set xlBook = Nothing
Set xlApp = Nothing

WScript.Echo "Finished."

编辑

我已经解决了问题,如果有人想要运行类似独立应用程序的用户表单:

我遇到的问题:

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

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


很高兴你最终找到了解决方案,但你应该知道你的第一个回答版本并不是一个回答,而是一个问题。在将来,请将问题发布为问题,而不是作为答案。你可能需要再次阅读网站介绍 - Charles

3

我尝试了上述方法,但是出现了“找不到宏”错误。 以下是最终可行的代码!

Option Explicit

Dim xlApp, xlBook

Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = True

  ' Import Add-Ins
xlApp.Workbooks.Open "C:\<pathOfXlaFile>\MyMacro.xla"
xlApp.AddIns("MyMacro").Installed = True

'
Open Excel workbook
Set xlBook = xlApp.Workbooks.Open("<pathOfXlsFile>\MyExcel.xls", 0, True)

' Run Macro
xlApp.Run "Sheet1.MyMacro"

xlBook.Close
xlApp.Quit

Set xlBook = Nothing
Set xlApp = Nothing

WScript.Quit

在我的情况下,MyMacro恰好位于Sheet1下,因此为Sheet1.MyMacro。

谢谢!“导入插件”部分在什么时候需要使用? - DAE

2
我通常将宏存储在 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 

0

如果您正在尝试从个人工作簿运行宏,可能无法正常工作,因为使用VBScript打开Excel文件不会自动打开您的PERSONAL.XLSB。您需要执行类似以下操作:

Dim oFSO
Dim oShell, oExcel, oFile, oSheet
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oShell = CreateObject("WScript.Shell")
Set oExcel = CreateObject("Excel.Application")
Set wb2 = oExcel.Workbooks.Open("C:\..\PERSONAL.XLSB") 'Specify foldername here

oExcel.DisplayAlerts = False


For Each oFile In oFSO.GetFolder("C:\Location\").Files
    If LCase(oFSO.GetExtensionName(oFile)) = "xlsx" Then
        With oExcel.Workbooks.Open(oFile, 0, True, , , , True, , , , False, , False)



            oExcel.Run wb2.Name & "!modForm"


            For Each oSheet In .Worksheets



                oSheet.SaveAs "C:\test\" & oFile.Name & "." & oSheet.Name & ".txt", 6


            Next
            .Close False, , False
        End With
    End If



Next
oExcel.Quit
oShell.Popup "Conversion complete", 10

所以在循环开始时,它会打开personals.xlsb并为所有其他工作簿运行其中的宏。我觉得我应该在这里发布一下,以防有人像我一样遇到了这个问题,但是无法弄清楚为什么宏仍然无法运行。

0

嗨,我使用这个线程找到了解决方案,然后我想分享一下我所做的,以防有人需要。

我想要的是调用一个宏来改变一些单元格并删除一些行,但我需要处理1500多个Excel文件(每个文件大约需要3分钟)。

主要问题: - 当从VBE调用宏时,我遇到了同样的问题,无法从PERSONAL.XLSB中调用宏,当脚本打开Excel时,不会执行personal.xlsb,并且在宏窗口中也没有任何选项。

我通过在执行脚本之前保持打开一个带有加载了宏的Excel文件(a.xlsm)来解决了这个问题。

然后我从脚本打开的Excel中调用宏。

    Option Explicit
    Dim xl
    Dim counter

   counter =10



  Do

  counter = counter + 1

  Set xl = GetObject(, "Excel.Application")
  xl.Application.Workbooks.open "C:\pruebas\macroxavi\IA_030-08-026" & counter & ".xlsx"
  xl.Application.Visible = True
  xl.Application.run "'a.xlsm'!eraserow" 
  Set xl = Nothing


  Loop Until counter = 517

  WScript.Echo "Finished."
  WScript.Quit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接