Way Excel-Makros von der Kommandozeile oder Batch-Datei ausführen?
-
20-09-2019 - |
Frage
Ich habe ein Excel-VBA-Makros, die ich ausführen müssen, wenn Sie die Datei aus einer Batch-Datei zugreifen, aber nicht jedes Mal, wenn ich es öffnen (also nicht das geöffnete Datei Ereignis verwenden). Gibt es eine Möglichkeit das Makro von der Kommandozeile oder Batch-Datei ausführen? Ich bin nicht vertraut mit einem solchen Befehl.
Nehmen Sie eine Windows NT-Umgebung.
Lösung
Sie können Excel starten, die Arbeitsmappe öffnen und das Makro aus einer VBScript-Datei ausführen.
Kopieren Sie den Code unten in den Editor.
Aktualisieren Sie die ' MyWorkbook.xls ' und ' MyMacro ' Parameter.
Speichern, um es mit einer vbs Verlängerung und führen Sie es.
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
Der Schlüssel Linie, die das Makro läuft, ist:
xlApp.Run "MyMacro"
Andere Tipps
Der einfachste Weg, es zu tun ist:
1) Starten Sie Excel aus Ihrer Batch-Datei zum Öffnen der Arbeitsmappe enthält Ihr Makro:
EXCEL.EXE /e "c:\YourWorkbook.xls"
2) Rufen Sie das Makro aus dem Workbook_Open
Veranstaltung Arbeitsmappe, wie zum Beispiel:
Private Sub Workbook_Open()
Call MyMacro1 ' Call your macro
ActiveWorkbook.Save ' Save the current workbook, bypassing the prompt
Application.Quit ' Quit Excel
End Sub
Dies wird nun die Steuerung auf Ihre Batch-Datei zurückzukehren andere Verarbeitung zu tun.
Das Verfahren unten ermöglicht definierte Excel-Makro aus Batch-Datei auszuführen, es Umgebungsvariable verwendet von Charge zu Excel Makronamen zu übergeben.
Setzen Sie diesen Code auf die Batchdatei (verwenden Sie Ihre Pfade zu EXCEL.EXE
und an der Arbeitsmappe):
Set MacroName=MyMacro
"C:\Program Files\Microsoft Office\Office15\EXCEL.EXE" "C:\MyWorkbook.xlsm"
Setzen Sie diesen Code in Excel VBA Thisworkbook Objekt:
Private Sub Workbook_Open()
Dim strMacroName As String
strMacroName = CreateObject("WScript.Shell").Environment("process").Item("MacroName")
If strMacroName <> "" Then Run strMacroName
End Sub
Und setzen Sie den Code in Excel VBA-Modul, wie wie folgt:
Sub MyMacro()
MsgBox "MyMacro is running..."
End Sub
die Batch-Datei starten und das Ergebnis erhalten:
Für den Fall, wenn Sie nicht beabsichtigen, alle Makro auszuführen leeren Wert Set MacroName=
zum Ansatz bringen.
könnten Sie eine VBScript schreiben Sie eine Excel-Instanz über die Create () -Methode zu erstellen, öffnen Sie die Arbeitsmappe und das Makro auszuführen. Sie könnten entweder die Vbscript direkt anrufen, oder die Vbscript aus einer Batch-Datei aufrufen.
Hier ist eine Ressource, die ich gerade accross gestolpert: http://www.codeguru.com/forum/showthread.php?t= 376.401
Ich habe immer die Anzahl der geöffneten Arbeitsmappen in Workbook_Open getestet (). Wenn es gleich 1 ist, dann wurde das Arbeitsbuch durch die Befehlsleitung geöffnet (oder der Benutzer geschlossen, all Arbeitsbücher, dann ist diese eine geöffnet).
If Workbooks.Count = 1 Then
' execute the macro or call another procedure - I always do the latter
PublishReport
ThisWorkbook.Save
Application.Quit
End If
Wenn Sie mehr komfortables Arbeiten innerhalb Excel / VBA sind, verwenden Sie die offene Veranstaltung und die Umwelt testen. Entweder eine Signaldatei haben, einen Registrierungseintrag oder eine Umgebungsvariable, dass die Kontrollen, was die offene Veranstaltung funktioniert
Sie können die Datei / Einstellung außerhalb und Test innen (Verwendung GetEnviromentVariable für env-VARs) erstellen und testen leicht. Ich habe VBScript aber die Ähnlichkeiten zu VBA Ursache ich mehr Angst als Leichtigkeit geschrieben ..
[mehr]
Wie ich das Problem zu verstehen, Sie wollen eine Tabelle verwenden, die normalerweise die meisten / einen Teil der Zeit noch haben sie im Batch laufen und etwas extra / anders. Sie können das Blatt von der excel.exe Befehlszeile öffnen, aber Sie können nicht kontrollieren, was es tut, wenn es weiß, wo es ist. eine Umgebungsvariable ist relativ einfach und macht einfach die Tabelle zu testen.
Um zu klären, benutzen Sie die Funktion unter der Umwelt zu untersuchen. In einem Modul declare:
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
In der offenen Ereignis-Arbeitsmappe (wie andere):
Private Sub Workbook_Open()
If GetEnvironmentVariable("InBatch") = "TRUE" Then
Debug.Print "Batch"
Else
Debug.Print "Normal"
End If
End Sub
Fügen Sie im aktiven Code als anwendbar. In der Batchdatei verwendet
set InBatch=TRUE
Statt direkt die Saiten zu vergleichen (VB nicht finden sie gleich da GetEnvironmentVariable eine Zeichenfolge der Länge zurückgibt 255) schreiben Sie:
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
@ Robert: Ich habe versucht, den Code mit einem relativen Pfad anzupassen, und eine Batch-Datei erstellt, die VBS ausführen
.Das VBS beginnt und schließt aber nicht das Makro nicht starten ... Jede Idee, wo das Problem sein könnte?
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
Ich entfernte die „Application.Quit“ weil mein Makro ist eine Userform kümmert sich um sie anrufen.
Prost
Bearbeiten
Ich habe es funktionierte tatsächlich aus, falls jemand ein Userform „gleich“ eine Stand-alone-Anwendung auszuführen:
Issues Ich war vor:
1 - Ich wollte nicht das Workbook_Open Ereignis verwenden, wie die Excel nur in Lese gesperrt sind. . 2 - Der Batch-Befehl ist, dass dadurch begrenzt, dass (mein Wissen) ist es das Makro nicht aufrufen kann
Ich schrieb zuerst einen Makro meine Userform zu starten, während die Anwendung versteckt:
Sub open_form()
Application.Visible = False
frmAddClient.Show vbModeless
End Sub
ich dann ein vbs erstellt dieses Makro starten (mit einem relativen Pfad zu tun hat heikel):
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"
Und ich habe endlich eine Batch-Datei, die VBS auszuführen ...
@echo off
pushd %~dp0
cscript Add_Client.vbs
Beachten Sie, dass ich auch die „Set zurück zu sichtbar“ in meinem Userform_QueryClose
enthalten:
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
Wie auch immer, vielen Dank für Ihre Hilfe, und ich hoffe, dies wird Ihnen helfen, wenn jemand braucht es
Sie können überprüfen, ob Excel bereits geöffnet ist. Es gibt keine Notwendigkeit, eine andere isntance
erstellen 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
Ich bin teilweise zu C #. Ich lief die folgende using LINQPad. Aber es könnte genauso gut mit csc und laufen durch die von der Kommandozeile aufgerufen kompiliert werden.
Vergessen Sie nicht, Excel-Pakete Namensraum hinzuzufügen.
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;
}
}