Як запустити макроси Excel з командного рядка або командного файлу?


77

У мене є макрос Excel VBA, який мені потрібно запустити під час доступу до файлу з пакетного файлу, але не кожного разу, коли я його відкриваю (отже, не використовуючи подію відкритого файлу). Чи є спосіб запустити макрос із командного рядка або командного файлу? Я не знайомий з такою командою.

Припустимо середовище Windows NT.


1
Чи є використання vbscript / jscript з хостом сценаріїв Windows опцією?
madaboutcode

Відповіді:


84

Ви можете запустити 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"


10
Це те, що я шукав! Це працює. Я повинен додати пару змін, необхідних для того, щоб це працювало без збоїв: 1. Це "xlApp.Run". 2. Перш ніж вийти, слід використовувати xlApp.SaveAs, інакше зміни, внесені макросом, не будуть збережені. (можна використовувати xlApp.DisplayAlerts = False), щоб уникнути пов'язаних спливаючих вікон) 3. Перед виходом із системи слід викликати xlApp.ActiveWorkbook.Close або електронна таблиця залишається відкритою (хоча і прихованою), що відключає подальше редагування. Загалом, це те, що я шукав :)
Полімерон

1
Також подумайте про додавання xlApp.Visible = True, інакше ви не побачите Excel або будь-яке діалогове вікно, яке може з’явитися.
Рейчел Хеттінгер

1
Процес EXCEL.exeне закривається, коли я запускаю цей сценарій дослівно.
Андре К. Андерсен

1
@ Robert Mearns Я використовував цей VBS для запуску макросу в пакетному режимі (макрос чудово працює в інтерактивному режимі). Я запускаю цей VBS, але відповіді взагалі не було. Я підозрюю Set xlApp = CreateObject("Excel.Application"), що не працює в моїй системі. Чи можете ви люб'язно допомогти мені, як це зробити?
Мубін Шахід

Який із ваших файлів Excel захищений паролем, і ви хочете відкрити його як читання-запис? Що ви коригуєте свій код?
Джейсон Самуельс

23

Найпростіший спосіб зробити це:

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

Це поверне елемент керування у ваш командний файл для подальшої обробки.


3
Думав про це, але він запуститься, навіть якщо я відкриваю його не через пакетний файл, що робить сам файл неможливим для роботи без попереднього відключення макросів.
Полімерон

1
Це легко вирішити, змінивши параметр реєстру, який повідомляє Excel, який рівень безпеки встановлено.
bvukas

Звичайно, цифровий підпис робочої книги завжди допомагає, навіть із сертифікатом про тестування :)
bvukas

1
А в будь-якому випадку робити це без Excel ?. Я маю на увазі з іншою програмою, більш спеціалізованою для швидкого виконання макросів із командного рядка ?.
skan

2
Як мені відкрити файл, не запустивши макрос, якщо мені доведеться щось змінити пізніше?
wviana

6

Метод, показаний нижче, дозволяє запускати визначений макрос 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=в пакет.


4

Ви можете написати vbscript для створення екземпляра Excel за допомогою методу createobject (), а потім відкрити книгу та запустити макрос. Ви можете або викликати vbscript безпосередньо, або зателефонувати vbscript з командного файлу.

Ось ресурс, який я щойно натрапив: http://www.codeguru.com/forum/showthread.php?t=376401


3

Якщо вам зручніше працювати в 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

У відкритому заході Workbook (як і інші):

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

Додайте активний код відповідно. У командному файлі використовуйте

set InBatch=TRUE

3

Замість прямого порівняння рядків (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 

3

Я завжди перевіряв кількість відкритих книг у 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

2

@ Роберт: Я намагався адаптувати ваш код із відносним шляхом і створив пакетний файл для запуску 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 Event, оскільки 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

У будь-якому випадку, дякую за вашу допомогу, і я сподіваюся, це допоможе, якщо комусь це буде потрібно


1

Я прихильний до 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;
    }
}

Я ніколи не бачив LINQPad або CSC, тож дякую за унікальне рішення!
HackSlash

0

Ви можете перевірити, чи Excel вже відкритий. Немає необхідності створювати інший існенс

   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

0

Я зазвичай зберігаю свої макроси в 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 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.