Способ запуска макросов Excel из командной строки или командного файла? - PullRequest
67 голосов
/ 12 января 2010

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

Предположим, что среда Windows NT.

Ответы [ 10 ]

76 голосов
/ 13 января 2010

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

18 голосов
/ 12 января 2010

Самый простой способ сделать это:

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

Теперь это вернет элемент управления в ваш командный файл для выполнения другой обработки.

5 голосов
/ 28 декабря 2015

Метод, показанный ниже, позволяет запускать определенный макрос Excel из пакетного файла, он использует переменную среды для передачи имени макроса из пакета в Excel.

Поместите этот код в командный файл (используйте ваши пути к EXCEL.EXE и к книге):

Set MacroName=MyMacro
"C:\Program Files\Microsoft Office\Office15\EXCEL.EXE" "C:\MyWorkbook.xlsm"

Поместите этот код в Excel VBA ThisWorkBook Object:

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

Запустите командный файл и получите результат:

macro's dialog

Для случая, когда вы не собираетесь запускать какой-либо макрос, просто поместите пустое значение Set MacroName= в пакет.

4 голосов
/ 12 января 2010

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

Вот ресурс, на который я наткнулся: http://www.codeguru.com/forum/showthread.php?t=376401

3 голосов
/ 06 февраля 2013

Я всегда проверял количество открытых рабочих книг в 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 голосов
/ 05 января 2014

@ Роберт: Я попытался адаптировать ваш код с относительным путем и создал командный файл для запуска 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», потому что мой макрос вызывает пользовательскую форму, которая позаботилась об этом.

Приветствия

EDIT

Я на самом деле разработал это, на тот случай, если кто-то захочет запустить пользовательскую форму, «похожую» на отдельное приложение:

Проблемы, с которыми я столкнулся:

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

Обратите внимание, что я также включил "Set back to visible" в мой 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

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

2 голосов
/ 27 марта 2012

Вместо непосредственного сравнения строк (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 
2 голосов
/ 12 января 2010

Если вам удобнее работать в Excel / VBA, используйте событие open и протестируйте среду: у вас есть файл сигналов, запись в реестре или переменная среды, управляющая тем, что делает событие open.

Вы можете создать файл / настройку снаружи и протестировать внутри (используйте 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
1 голос
/ 09 декабря 2014

Я неравнодушен к 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;
    }
}
1 голос
/ 11 ноября 2014

Вы можете проверить, открыт ли 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
...