Registriert seit: 06.09.2016
Version(en): 2016
Hallo wertes Forum,
ich habe heute ein Problem beim Schließen von mehreren Excel-Instanzen.
Folgende Situation: Ich exportiere per VBA-Makro mehrere Dateien aus SAP. Diese werden (meistens, nicht immer) in einer neuen Excel-Instanz geöffnet. Aufgrund des unklaren Verhaltens möchte ich auch nicht ausschließen, dass ich nach dem Daten-Export mehr als zwei Excel-Instanzen geöffnet habe. Nach dem Durchlauf meines Makros sollen nun alle Excel-Instanzen außer die, in dem das Makro läuft, geschlossen werden.
Wie stelle ich das an?
Ich habe schon versucht die geöffneten Excel-Instanzen (außer der Makro-Instanz) in ein Feld zu lesen und am Ende des Makros alle Instanzen aus dem Feld zu schließen. Leider erhalte ich über die Workbook.Parent-Eigenschaft als Bezeichnung für alle Instanzen "Microsoft Excel". Damit kann ich die zu schließende Instanz beim Einlesen nicht von der Makro-Instanz unterscheiden. Das Einlesen aller Instanzen (inkl. Makro-Instanz) und anschließendes Schließen aller Instanzen außer der Makro-Instanz, bringt das selbe Problem.
Vielen Dank für Eure Hilfe, Lutz
Registriert seit: 08.05.2014
Version(en): Office 2010, Office 365, Office 365 Betakanal
13.02.2020, 14:05
(Dieser Beitrag wurde zuletzt bearbeitet: 13.02.2020, 14:06 von maninweb.)
Hallo, ausgehend davon, dass Du eine Excel-Version verwendest, die jede Mappe als einzelnes Fenster mit Menüband darstellt, wage ich mal zu bezweifeln, dass es sich um echte unabhängige Instanzen handelt. Das würdest Du z.B. im Task Manager sehen, wo dann echte Instanzen als eigene Prozesse (Excel.exe) auftauchen. Insofern, hast Du schon mal probiert, die Workbooks in einer Schleife zu durchlaufen, und die, die nicht der Mappe entsprechen, die der Code ausführt, zu schließen? In etwa so ... Code: Public Sub CloseAllExceptMe()
Dim b As Workbook For Each b In Application.Workbooks If b.Name <> ThisWorkbook.Name Then b.Close End If Next End Sub
Sollten es tatsächlich unabhängige Instanzen sein, wird es (deutlich) komplizierter und geht nur mit Windows API. Gruß
Microsoft Excel Expert · Microsoft Most Valuable Professional (MVP) :: 2011-2019 & 2020-2022 :: 10 Awardshttps://de.excel-translator.de/translator :: Online Excel-Formel-Übersetzer :: Funktionen :: Fehlerwerte :: Argumente :: Tabellenbezeichner
Registriert seit: 06.12.2015
Version(en): 2016
Hallo,
es ist sichr möglich mit einer API durch alle Prozesse zu iterieren. einfacher ist es dies mit MS Word, CMD oder Powershell zu versuchen.
mfg
CMD: Taskslist Tasklist /fi "imagename eq Excel.exe"
Powershell:
Get-Process | Format-Table ProcessName, Id | stop-process | Format-List | select-object Name1 name2
Registriert seit: 06.09.2016
Version(en): 2016
Hallo zusammen,
@Maninweb, ich schließe alle Workbooks inkl. des Makroworkbooks und am Ende bleibt häufig (nicht immer) eine leere Excel-Instanz übrig. Und ich kann die durch SAP exportierten Dateien im Makro auch nicht einfach einer Varaiablen zuweisen, sondern benötige die Zuweisung über GetObject. Und ja, im Task-Manager habe ich zwei Excels...
@Fennek, mit API kenne ich mich überhaupt nicht aus... Schon von gehört, aber dann bin ich fertig. Eigentlich wird mein Makro über ein VB-Script gestartet, das zuvor SAP öffnet. Da könnte ich ans Ende auch das Schließen aller Excels setzen, weiß aber nicht wie.
Gruß, Lutz
Registriert seit: 08.05.2014
Version(en): Office 2010, Office 365, Office 365 Betakanal
13.02.2020, 14:34
(Dieser Beitrag wurde zuletzt bearbeitet: 13.02.2020, 14:35 von maninweb.)
Hallo,
@Fennek: sehr interessant!
mich würde interessieren: bekommst Du per PowerShell auch den Prozess herausgefiltert, der die Mappe X geöffnet hat und dann diesen Prozess eben nicht schließt? Und den Fall abgedeckt, dass Mappe X und weiteren Mappen im aktiven Excel-Prozess drin sind, wovon die weiteren geschlossen werden müsste (ausser Mappe X) + die restlichen Excel Prozesse?
@Lutz: poste mal Deine Makros, wenn es möglich ist (also einmal, wie Du die Dateien öffnest und einmal wie Du die schließt).
Gruß
Microsoft Excel Expert · Microsoft Most Valuable Professional (MVP) :: 2011-2019 & 2020-2022 :: 10 Awardshttps://de.excel-translator.de/translator :: Online Excel-Formel-Übersetzer :: Funktionen :: Fehlerwerte :: Argumente :: Tabellenbezeichner
Registriert seit: 06.12.2015
Version(en): 2016
Hallo, so ganz einfach geht es nicht. In einem Test mit Libre-Office: Code: PS C:\Users\xxxx> Get-Process | where {$_.MainWindowTitle -like "*Office*" }
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName ------- ------ ----- ----- ------ -- -- ----------- 731 42 84416 135768 22,83 2484 1 soffice.bin
Ungeprüft: Wenn man den Handles der gewünschten Instanz ermittlet, sollten die anderen mit Code: Get-Process | where {$_.MainWindowTitle -like "*Office*" } | stop-process -force
beendet werden. mfg
Registriert seit: 06.09.2016
Version(en): 2016
Hallo Maninweb, das Problem ist, dass ich die Datei nicht bewusst öffne, sondern sie nach dem Datenexport aus SAP einfach aufpoppen... Anbei einige Codeschnipsel, die den Ablauf zeigen: VB-Skript zum Öffnen von SAP und starten des VBA-Makros (der Teil zeigt nur Makro-Start und schließen der Makro-Excel-Instanz): Code: set objExcel = CreateObject("Excel.Application") objExcel.Visible = True set workbook = objExcel.Workbooks.Open("\\denbppfs002\lutz.fricke$\Makros\Neues_Produktionsreporting\Makros\Neu Makro OpenProcessOrders Rev.12.xlsm") objExcel.run "A_Ablauf.A_Ablauf" objExcel.DisplayAlerts = False objExcel.Workbooks.Close() objExcel.Quit() objExcel.DisplayAlerts = True
VBA-Skript zum Ansprechen einer der exportierten Dateien (inkl. einlesen der Instanz in Datenfeld): Code: Set WkbOpenOrders = GetObject(StrPfadDaten & "\" & StrOpenOrders) Set WksOpenOrders = WkbOpenOrders.Worksheets("Sheet1")
For IntExlApp = 1 To UBound(ExlApp, 1) If WkbOpenOrders.Parent = ExlApp(IntExlApp) Then ErfolgExlApp = True Exit For End If Next IntExlApp If ErfolgExlApp = False Then AnzahlExlApp = AnzahlExlApp + 1 Set ExlApp(AnzahlExlApp) = WkbOpenOrders.Parent Else ErfolgExlApp = False End If
VBA-Skript zum Schließen einer der exportierten Dateien: Code: WkbOpenOrders.Close savechanges:=False
VBA-Skipt zum Auslesen des Datenfeldes und Schließen aller Instanzen außer der Makro Instanz: Code: For IntExlApp = 1 To UBound(ExlApp, 1) If Not ExlApp(IntExlApp) Is Nothing Then If ExlApp(IntExlApp) <> WkbMatVorgaben.Parent Then ExlApp(AnzahlExlApp).Quit Set ExlApp(AnzahlExlApp) = Nothing End If End If Next IntExlApp
Die Makro-Excel-Instanz wird dann im VB-Skript geschlossen. Gruß, Lutz
Registriert seit: 08.05.2014
Version(en): Office 2010, Office 365, Office 365 Betakanal
Hallo,
@Fennek: Danke!
@Lutz: Insgesamt ist mir der Workflow noch nicht ganz klar. Zum Nachvollziehen, mit VB-Skript meinst Du dann kein VBA-Skript, richtig? Das Makro Neu Makro OpenProcessOrders Rev.12.xlsm speichert die Dateien irgendwo ab, richtig? Und Du liest die später wieder ein?
Jetzt angenommen, Du würdest die Dateien einer Auswertung in einem neu generierten Unterordner abspeichern (ich vermute, das ist nicht so). Dann liessen sich diese Dateien alle wieder öffnen (durch ein Excel-VBA Script) und Du hättest das Instanzen-Problem nicht. Unabhängig davon, zum Öffnen von Excel-Dateien in Excel-VBA, verwende nicht GetObject, sondern Application.Workbooks.Open ...
Gruß
Microsoft Excel Expert · Microsoft Most Valuable Professional (MVP) :: 2011-2019 & 2020-2022 :: 10 Awardshttps://de.excel-translator.de/translator :: Online Excel-Formel-Übersetzer :: Funktionen :: Fehlerwerte :: Argumente :: Tabellenbezeichner
Registriert seit: 06.09.2016
Version(en): 2016
Hallo Maninweb,
VB-Skript wird vom Makro-Recorder von SAP verwendet. Es ist kein VBA. Da ich bisher zu blöd bin, SAP aus Excel heraus zu starten (inkl. Login etc), benötige ich diesen Teil, damit ich im Excel-Makro SAP ansprechen kann.
Das Makro Neu Makro OpenProcessOrders Rev.12.xlsm steuert SAP und generiert damit einen Daten-Export. Diese exportierten Daten werden in einem Ordner abgelegt und automatisch geöffnet (dieses Öffnen passiert ohne Zutun eines Makros, sondern ist scheinbar eine SAP-Eigenheit).
Das bedeutet, diese Dateien sind offen und da, wenn mein Ablauf aus dem SAP zurückkommt. Dagegen kann ich nichts tun.
Mit Workbooks.Open würde ich sie ein zweites Mal öffnen (wenn Excel das zulässt...) und könnte sie bearbeiten, aber am Ende hätte ich trotzdem die von SAP in der neuen Instanz bereitgestellten Dateien offen. Mit GetObject bekomme ich immerhin Zugriff auf die bereits vorhandenen Dateien.
Nochmal zum Ablauf: VB-Skript startet SAP (nicht gepostet) und startet das VBA-Makro (s. 1. Code bis Zeile 4). VBA-Makro steuert SAP und erzeugt mehrere Datenexporte. Diese poppen ohne Zutun auf. VBA-Makro spricht über GetObject die aufgepoppten Dateien an (s. 2. Code). VBA-Makro liest die Dateien in Datenfelder. VBA-Makro schließt die Dateien (s. 3. Code). VBA-Makro wertet die Datenfelder aus. VBA-Makro soll alle Excel-Instanzen außer der Makro-Instanz schließen. VB-Skript schließt die Makro-Instanz (s. 1.Code ab Zeile 5) und schließt SAP (nicht gepostet).
Das Ganze läuft sauber durch, allerdings bleibt meistens am Ende besagte Excel-Instanz offen, die SAP durch den Datenexport erzeugt hat. Und ich bekomme diese Excel-Instanz nicht sauber von der Insatnz getrennt, die das Makro enthält.
Gruß, Lutz
Registriert seit: 29.09.2015
Version(en): 2030,5
13.02.2020, 16:54
(Dieser Beitrag wurde zuletzt bearbeitet: 13.02.2020, 16:54 von snb.)
Statt: Code: set objExcel = CreateObject("Excel.Application") objExcel.Visible = True set workbook = objExcel.Workbooks.Open("\\denbppfs002\lutz.fricke$\Makros\Neues_Produktionsreporting\Makros\Neu Makro OpenProcessOrders Rev.12.xlsm")
Verwende Code: with Workbooks.Open("\\denbppfs002\lutz.fricke$\Makros\Neues_Produktionsreporting\Makros\Neu Makro OpenProcessOrders Rev.12.xlsm")
end with
|