Способ запуска макросов Excel из командной строки или пакетного файла?
У меня есть макрос Excel VBA, который мне нужно запустить при доступе к файлу из пакетного файла, но не каждый раз, когда я его открываю (следовательно, не используя событие open file). Есть ли способ запустить макрос из командной строки или пакетного файла? Я не знаком с такой командой.
предположим, что среда Windows NT.
10 ответов:
вы можете запустить 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.Запустить "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
Теперь этот элемент управления будет возвращен в ваш пакетный файл для выполнения другой обработки.
вы можете написать vbscript для создания экземпляра excel с помощью метода createobject (), а затем открыть книгу и запустить макрос. Вы можете либо вызвать vbscript напрямую, либо вызвать vbscript из пакетного файла.
вот ресурс, на который я только что наткнулся: http://www.codeguru.com/forum/showthread.php?t=376401
метод, показанный ниже, позволяет запускать определенный макрос 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=
в пакет.
Если вам удобнее работать в 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
вместо прямого сравнения строк (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
Я всегда проверял количество открытых книг в 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
@ Robert: я попытался адаптировать ваш код с относительным путем и создал пакетный файл для запуска 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
Я удалил " приложение.Выход", потому что мой макрос вызывает пользовательскую форму, заботящуюся об этом.
Ура
EDIT
Я действительно разработал его, на всякий случай, если кто-то хочет запустить userform "alike" автономное приложение:
проблемы, с которыми я столкнулся:
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
в любом случае, спасибо за вашу помощь, и я надеюсь, что это поможет, если кто-то нуждается в нем
вы можете проверить, если 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; } }