Запуск макроса Excel из внешнего Excel с использованием VBScript из командной строки

Я пытаюсь запустить макрос 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

Я пробовал решения, расположенные в: Можно ли запустить макрос в Excel из внешней команды? чтобы получить это далеко (и изменил, конечно), но это не сработало. Я продолжаю получать сообщение об ошибке "Microsoft Office Excel: макрос" Macro.TestMacro "не найден".

РЕДАКТИРОВАТЬ: Excel 2003.

7 ответов

Решение

Хорошо, это на самом деле просто. Предполагая, что ваш макрос находится в модуле, а не на одном из листов, вы используете:

  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, которую вы использовали.

Я думаю, что вы пытаетесь сделать это? (ПОПРОБОВАНО И ИСПЫТАНЫ)

Этот код откроет файл 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

Так как мой связанный с этим вопрос был удален праведной рукой после того, как я целый день убил, пытаясь найти способ преодоления ошибки "макрос не найден или отключен", здесь был указан единственный синтаксис, который работал для меня (application.run этого не делал, неважно что я пробовал)

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

Я пытался адаптировать код @ Сиддхарта к относительному пути, чтобы запустить мой 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

В любом случае, спасибо за вашу помощь, и я надеюсь, что это поможет, если кому-то это нужно

Я пробовал описанные выше методы, но получил ошибку "макрос не найден". Это окончательный код, который работал!

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.

Я обычно храню свои макросы в 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 

Привет, использовал эту ветку, чтобы получить решение, тогда я хотел бы поделиться тем, что я сделал, на случай, если кто-то сможет его использовать.

Я хотел вызвать макрос, который изменяет несколько ячеек и удаляет несколько строк, но мне нужно более 1500 исключений (примерно 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

Если вы пытаетесь запустить макрос из своей личной рабочей книги, он может не работать, поскольку открытие файла Excel с помощью VBScript не приводит к автоматическому открытию файла 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 и запускает оттуда макрос для всех других рабочих книг. Просто подумал, что я должен опубликовать здесь, на случай, если кто-то столкнется с этим, как я, но не могу понять, почему макрос все еще не работает.

Другие вопросы по тегам