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.
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"
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.
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:
Für den Fall, dass Sie kein Makro ausführen möchten, geben Sie einfach den leeren Wert Set MacroName=
zum Batch.
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
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
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
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
@ 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
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;
}
}
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