Способ запуска макросов Excel из командной строки или пакетного файла?
-
20-09-2019 - |
Вопрос
У меня есть макрос Excel VBA, который мне нужно запускать при доступе к файлу из пакетного файла, но не каждый раз, когда я его открываю (следовательно, не использую событие open file).Есть ли способ запустить макрос из командной строки или пакетного файла?Я не знаком с такой командой.
Предположим, что это среда Windows NT.
Решение
Вы можете запустить Excel, открыть книгу и запустить макрос из файла VBScript.
Скопируйте приведенный ниже код в Блокнот.
Обновите 'MyWorkbook.xls" и "Мой Макро' параметры.
Сохраните его с расширением 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
Теперь это вернет элемент управления в ваш пакетный файл для выполнения другой обработки.
Метод, показанный ниже, позволяет запустить определенный макрос 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
Запустите пакетный файл и получите результат:
В случае, когда вы не собираетесь запускать какой-либо макрос, просто введите пустое значение Set MacroName=
к партии.
вы могли бы написать vbscript для создания экземпляра Excel с помощью метода createobject(), затем открыть книгу и запустить макрос.Вы могли бы либо вызвать vbscript напрямую, либо вызвать vbscript из пакетного файла.
Вот ресурс, на который я только что наткнулся:http://www.codeguru.com/forum/showthread.php?t=376401
Я всегда проверял количество открытых книг в 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
Если вам удобнее работать в 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
@ Роберт:Я попытался адаптировать ваш код с помощью относительного пути и создал пакетный файл для запуска 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, так как 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
В любом случае, спасибо за вашу помощь, и я надеюсь, что это поможет, если кому-то это понадобится
Вы можете проверить, открыт ли уже 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
Я неравнодушен к 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;
}
}