web-dev-qa-db-de.com

Möglichkeit zum Ausführen von Excel-Makros über die Befehlszeile oder Batch-Datei?

Ich habe ein Excel VBA-Makro, das ich ausführen muss, wenn ich von einer Batch-Datei auf die Datei zugreife, aber nicht jedes Mal, wenn ich sie öffne (daher wird das Open File-Ereignis nicht verwendet). Gibt es eine Möglichkeit, das Makro über die Befehlszeile oder die Batchdatei auszuführen? Ich kenne einen solchen Befehl nicht.

Nehmen Sie eine Windows NT-Umgebung an.

69
Polymeron

Sie können Excel starten, die Arbeitsmappe öffnen und den 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"

77
Robert Mearns

Der einfachste Weg dies zu tun ist:

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

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

2) Rufen Sie Ihr Makro aus der Arbeitsmappe Workbook_Open Ereignis, 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

Dadurch wird das Steuerelement in Ihre Batchdatei zurückgeführt, um eine andere Verarbeitung durchzuführen.

19
bvukas

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

Fügen Sie diesen Code in die Batch-Datei ein (verwenden Sie Ihre Pfade zu Excel.EXE und zur Arbeitsmappe):

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

Fügen Sie diesen Code in das Excel VBA ThisWorkBook-Objekt 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:

macro's dialog

Für den Fall, dass Sie kein Makro ausführen möchten, geben Sie einfach den leeren Wert Set MacroName= zum Batch.

5
omegastripes

sie könnten ein vbscript schreiben, um eine Instanz von Excel mit der Methode createobject () zu erstellen, dann die Arbeitsmappe öffnen und den Makro ausführen. Sie können entweder das vbscript direkt aufrufen oder das vbscript aus einer Stapeldatei aufrufen.

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

4
Fink

Ich habe immer die Anzahl der offenen 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
3
Brian Hoffman

Anstatt die Zeichenfolgen direkt zu vergleichen (VB findet sie nicht gleich, da GetEnvironmentVariable eine Zeichenfolge 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 
2
laybmw

Wenn Sie in Excel/VBA besser arbeiten können, verwenden Sie das open-Ereignis und testen Sie die Umgebung: Sie verfügen entweder über eine Signaldatei, einen Registrierungseintrag oder eine Umgebungsvariable, die steuert, was das open-Ereignis bewirkt.

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

[Mehr]

Wie ich das Problem verstehe, möchten Sie in der Regel eine Kalkulationstabelle verwenden, die jedoch im Stapelbetrieb ausgeführt wird, und etwas Besonderes 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:

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 öffnen Veranstaltung (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 Batchdatei

set InBatch=TRUE
2
Chris Chambers

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

Der VBS wird gestartet und geschlossen, aber das Makro wird nicht gestartet. Wissen Sie, 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 das "Application.Quit" entfernt, weil mein Makro ein Benutzerformular aufruft, das sich darum kümmert.

Prost

EDIT

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

Probleme, mit denen ich konfrontiert war:

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

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

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 auszuführen):

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 schließlich habe ich eine Batch-Datei erstellt, um das VBS auszuführen ...

@echo off
pushd %~dp0
cscript Add_Client.vbs

Beachten Sie, dass ich in meinem Userform_QueryClose Auch "Zurück zum Sichtbaren" eingefügt habe:

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 Ihre Hilfe, und ich hoffe, dass dies hilft, wenn jemand es braucht

2
Axn40

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

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

Sie können überprüfen, ob Excel bereits geöffnet ist. Es ist nicht erforderlich, eine weitere Instanz 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
1
Adam Law