Möglichkeit, Excel-Makros über die Befehlszeile oder Batch-Datei auszuführen?


77

Ich habe ein Excel VBA-Makro, das ich ausführen muss, wenn ich aus einer Batchdatei auf die Datei zugreife, aber nicht jedes Mal, wenn ich sie öffne (daher wird das Ereignis zum Öffnen der Datei nicht verwendet). Gibt es eine Möglichkeit, das Makro über die Befehlszeile oder die Batchdatei auszuführen? Ich bin mit einem solchen Befehl nicht vertraut.

Nehmen Sie eine Windows NT-Umgebung an.


1
Ist die Verwendung von vbscript / jscript mit Windows Scripting Host eine Option?
Madaboutcode

Antworten:


83

Sie können Excel starten, die Arbeitsmappe öffnen und das Makro aus einer VBScript-Datei ausführen.

Kopieren Sie den folgenden Code in den Editor.

Aktualisieren Sie die Parameter ' MyWorkbook.xls ' und ' MyMacro '.

Speichern Sie es mit einer vbs-Erweiterung und führen Sie es aus.

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 

Die Schlüsselzeile, in der das Makro ausgeführt wird, lautet:

xlApp.Run "MyMacro"


10
Das habe ich gesucht! Es klappt. Ich sollte ein paar Änderungen hinzufügen, die notwendig sind, damit dies ohne Störungen funktioniert: 1. Es ist "xlApp.Run". 2. Vor dem Beenden sollte xlApp.SaveAs verwendet werden. Andernfalls werden keine vom Makro vorgenommenen Änderungen gespeichert. (Sie können xlApp.DisplayAlerts = False verwenden), um verwandte Popups zu vermeiden.) 3. Vor dem Beenden sollte xlApp.ActiveWorkbook.Close aufgerufen werden oder die Tabelle bleibt geöffnet (obwohl ausgeblendet), wodurch die weitere Bearbeitung deaktiviert wird. Alles in allem ist dies das, wonach ich gesucht habe :)
Polymeron

1
Erwägen xlApp.Visible = TrueSie auch das Hinzufügen , da sonst Excel oder die möglicherweise angezeigten Dialogfelder nicht angezeigt werden.
Rachel Hettinger

1
Der Prozess EXCEL.exewird nicht geschlossen, wenn ich dieses Skript wörtlich ausführe.
André C. Andersen

1
@ Robert Mearns Ich habe dieses VBS verwendet, um ein Makro im Batch-Modus auszuführen (das Makro funktioniert im interaktiven Modus einwandfrei). Ich habe dieses VBS ausgeführt, aber es gab überhaupt keine Antwort. Ich vermute, dass Set xlApp = CreateObject("Excel.Application")es auf meinem System nicht funktioniert. Können Sie mir bitte zeigen, wie ich das zum Laufen bringen kann?
Mubeen Shahid

Welche Ihrer Excel-Dateien ist passwortgeschützt und Sie möchten sie als Lese- / Schreibzugriff öffnen? Was passen Sie Ihren Code an?
Jason Samuels

23

Der einfachste Weg, dies zu tun, ist:

1) Starten Sie Excel aus Ihrer Batchdatei, um die Arbeitsmappe mit Ihrem Makro zu öffnen:

EXCEL.EXE /e "c:\YourWorkbook.xls"

2) Rufen Sie Ihr Makro über das Workbook_OpenEreignis der Arbeitsmappe auf , z.

Private Sub Workbook_Open()
    Call MyMacro1          ' Call your macro
    ActiveWorkbook.Save    ' Save the current workbook, bypassing the prompt
    Application.Quit       ' Quit Excel
End Sub

Dadurch wird das Steuerelement nun an Ihre Batchdatei zurückgegeben, um eine andere Verarbeitung durchzuführen.


3
Ich habe darüber nachgedacht, aber es würde auch dann ausgeführt, wenn ich es nicht über die Batch-Datei öffne, was es unmöglich macht, mit der Datei selbst zu arbeiten, ohne vorher die Makros zu deaktivieren.
Polymeron

1
Dies ist einfach zu lösen, indem Sie eine Registrierungseinstellung ändern, die Excel mitteilt, welche Sicherheitsstufe festgelegt ist.
Bvukas

Natürlich hilft das digitale Signieren der Arbeitsmappe immer, auch mit einem
Testzertifikat

1
Und trotzdem ohne Excel?. Ich meine mit anderen Programmen spezialisierter, um Makros schnell über die Kommandozeile auszuführen?.
Skan

2
Wie würde ich die Datei öffnen, ohne das Makro auszuführen, wenn ich später etwas ändern muss?
Wviana

6

Die unten gezeigte Methode ermöglicht das Ausführen eines definierten Excel-Makros aus einer Batchdatei. Sie verwendet eine Umgebungsvariable, um den Makronamen vom Batch an Excel zu übergeben.

Fügen Sie diesen Code in die Batchdatei ein (verwenden Sie Ihre Pfade zur EXCEL.EXEund zur Arbeitsmappe):

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

Fügen Sie diesen Code in Excel VBA ThisWorkBook Object ein:

Private Sub Workbook_Open()
    Dim strMacroName As String
    strMacroName = CreateObject("WScript.Shell").Environment("process").Item("MacroName")
    If strMacroName <> "" Then Run strMacroName
End Sub

Fügen Sie Ihren Code wie folgt in das Excel VBA-Modul ein:

Sub MyMacro()
    MsgBox "MyMacro is running..."
End Sub

Starten Sie die Batch-Datei und erhalten Sie das Ergebnis:

Makrodialog

Wenn Sie kein Makro ausführen möchten, geben Sie einfach einen leeren Wert Set MacroName=in den Stapel ein.


4

Sie können ein vbscript schreiben, um eine Excel-Instanz über die Methode createobject () zu erstellen. Öffnen Sie dann die Arbeitsmappe und führen Sie das Makro aus. Sie können entweder das vbscript direkt aufrufen oder das vbscript aus einer Batchdatei aufrufen.

Hier ist eine Ressource, über die ich gerade gestolpert bin: http://www.codeguru.com/forum/showthread.php?t=376401


3

Wenn Sie in Excel / VBA besser arbeiten können, verwenden Sie das offene Ereignis und testen Sie die Umgebung: Sie verfügen entweder über eine Signaldatei, einen Registrierungseintrag oder eine Umgebungsvariable, die die Funktionsweise des geöffneten Ereignisses steuert.

Sie können die Datei / Einstellung außen erstellen und innen testen (verwenden Sie GetEnviromentVariable für env-vars) und einfach testen. Ich habe VBScript geschrieben, aber die Ähnlichkeiten mit VBA machen mir mehr Angst als Leichtigkeit.

[Mehr]

Soweit ich das Problem verstehe, möchten Sie eine Tabelle normalerweise die meiste Zeit verwenden, sie jedoch im Stapel laufen lassen und etwas Besonderes / Anderes tun. Sie können das Blatt über die Befehlszeile von excel.exe öffnen, aber Sie können nicht steuern, was es tut, es sei denn, es weiß, wo es sich befindet. Die Verwendung einer Umgebungsvariablen ist relativ einfach und erleichtert das Testen der Tabelle.

Verwenden Sie zur Verdeutlichung die folgende Funktion, um die Umgebung zu untersuchen. In einem Modul deklarieren Sie:

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 Arbeitsmappe Open Event (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 gegebenenfalls aktiven Code hinzu. Verwenden Sie in der Batch-Datei

set InBatch=TRUE

3

Anstatt die Zeichenfolgen direkt zu vergleichen (VB findet sie nicht gleich, da GetEnvironmentVariable eine Zeichenfolge mit der Länge 255 zurückgibt), schreiben Sie Folgendes:

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

Ich habe immer die Anzahl der geöffneten Arbeitsmappen in Workbook_Open () getestet. Wenn es 1 ist, wurde die Arbeitsmappe über die Befehlszeile geöffnet (oder der Benutzer hat alle Arbeitsmappen geschlossen und diese dann 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

2

@ Robert: Ich habe versucht, Ihren Code mit einem relativen Pfad anzupassen, und eine Batch-Datei zum Ausführen des VBS erstellt.

Der VBS startet und schließt, startet aber das Makro nicht ... Haben Sie eine Vorstellung davon, wo das Problem liegen 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 habe "Application.Quit" entfernt, weil mein Makro ein Benutzerformular aufruft, das sich darum kümmert.

Prost

BEARBEITEN

Ich habe es tatsächlich ausgearbeitet, nur für den Fall, dass jemand ein Benutzerformular "wie" eine eigenständige Anwendung ausführen möchte:

Probleme, mit denen ich konfrontiert war:

1 - Ich wollte das Workbook_Open-Ereignis nicht verwenden, da das Excel schreibgeschützt ist. 2 - Der Batch-Befehl ist darauf beschränkt, dass er meines Wissens das Makro nicht aufrufen kann.

Ich habe zuerst ein Makro geschrieben, um mein Benutzerformular zu starten, während ich die Anwendung versteckte:

Sub open_form()
 Application.Visible = False
 frmAddClient.Show vbModeless
End Sub

Ich habe dann ein vbs erstellt, um dieses Makro zu starten (es war schwierig, es mit einem relativen Pfad zu machen):

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 erstellt, um die VBS auszuführen ...

@echo off
pushd %~dp0
cscript Add_Client.vbs

Beachten Sie, dass ich auch das "Zurück zum Sichtbaren setzen" in mein 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

Wie auch immer, danke für deine Hilfe und ich hoffe, dass dies hilft, wenn jemand es braucht


1

Ich bin Teil von C #. Ich habe folgendes mit linqpad ausgeführt. Es könnte aber genauso gut mit csc kompiliert und über die Befehlszeile aufgerufen werden.

Vergessen Sie nicht, dem Namespace Excel-Pakete 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;
    }
}

Ich habe LINQPad oder CSC noch nie gesehen. Vielen Dank für eine einzigartige Lösung!
HackSlash

0

Sie können überprüfen, ob Excel bereits geöffnet ist. Es ist nicht erforderlich, eine andere Isntance zu 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

0

Im Allgemeinen speichere ich meine Makros in xlamAdd-Ins getrennt von meinen Arbeitsmappen. Daher wollte ich eine Arbeitsmappe öffnen und dann ein separat gespeichertes Makro ausführen.

Da hierfür ein VBS-Skript erforderlich war, wollte ich es "portabel" machen, damit ich es durch Übergeben von Argumenten verwenden kann. Hier ist das endgültige Skript, das 3 Argumente akzeptiert.

  • Vollständiger Pfad zur Arbeitsmappe
  • Makroname
  • [OPTIONAL] Pfad zum Trennen der Arbeitsmappe mit Makro

Ich habe es so getestet:

"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 
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.