3.2k Aufrufe
Gefragt in Tabellenkalkulation von b25812 Mitglied (515 Punkte)
Hallo,
ich habe mehrere Arbeitsmappen geöffnet zb Mappe1;Mappe2..... in diesen Arbeitsmappen befindet sich auch ein Inhalt. Nun möchte ich per VBA alle Arbeitsmappen schließen ohne zu Speichern. Der VBA ist in der Personal.xls hinterlegt. Ist das möglich? Ich habe noch Office 2003.

Gruß Andi

24 Antworten

0 Punkte
Beantwortet von nighty Experte (6.6k Punkte)
hi all ^^

mehrmals Excel zu starten und zu schliessen ist doch ein wenig komplizierter als ich dachte

abfrage der anzahl der gestarteten applicationen
abfrage auf die aktive um einen abschuss des makros zu verhindern

unnoetiges verkommplzieren

daher starte Excel nur einmal(wie es auch sein sollte)

gruss nighty
0 Punkte
Beantwortet von nighty Experte (6.6k Punkte)
hi all ^^

hier ein code eines netten Excel users

abfrage ob Excel mehrmals geoeffnet wurde

das ist nur ein teil der Problemstellung

unnoetiger umfang :-)

gruss nighty

Option Explicit

Private Const TH32CS_SNAPHEAPLIST = &H1
Private Const TH32CS_SNAPPROCESS = &H2
Private Const TH32CS_SNAPTHREAD = &H4
Private Const TH32CS_SNAPMODULE = &H8
Private Const TH32CS_INHERIT = &H80000000
Private Const MAX_PATH = 260
Private Const INVALID_HANDLE_VALUE = -1&

Private Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szExeFile As String * MAX_PATH
End Type

Private Declare Function CreateToolhelp32Snapshot Lib "kernel32" (ByVal lFlags As Long, ByVal lProcessID As Long) As Long
Private Declare Sub CloseHandle Lib "kernel32" (ByVal hPass As Long)
Private Declare Function Process32First Lib "kernel32" (ByVal hSnapshot As Long, sPE32 As PROCESSENTRY32) As Long
Private Declare Function Process32Next Lib "kernel32" (ByVal hSnapshot As Long, sPE32 As PROCESSENTRY32) As Long

Public Function fctProzessMehrfachOffen(sProzess As String) As Boolean
Dim hSnapshot As Long
Dim sPE32 As PROCESSENTRY32
Dim lRet As Long
Dim strProcess As String
Dim iPositionNull As Integer
Dim lngZähler As Long
Dim arrProzesse(2000)
Dim arrZähler As Integer
Dim intProzessZähler As Integer

fctProzessMehrfachOffen = False

hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0&)

If hSnapshot <> INVALID_HANDLE_VALUE Then
sPE32.dwSize = Len(sPE32)
lRet = Process32First(hSnapshot, sPE32)

lngZähler = 1
Do While lRet
iPositionNull = InStr(1, sPE32.szExeFile, Chr(0))
If iPositionNull > 0 Then
strProcess = Left(sPE32.szExeFile, iPositionNull - 1)
Else
strProcess = ""
End If

'Den Array mit laufenden Prozessen befüllen!
arrProzesse(lngZähler) = strProcess

lRet = Process32Next(hSnapshot, sPE32)
lngZähler = lngZähler + 1
Loop
CloseHandle hSnapshot
End If

'Prüfen, ob Excel mehrfach offen ist
For arrZähler = LBound(arrProzesse) To UBound(arrProzesse)
If arrProzesse(arrZähler) = sProzess Then
intProzessZähler = intProzessZähler + 1
If intProzessZähler > 1 Then
fctProzessMehrfachOffen = True
Exit For
End If
End If
Next arrZähler

End Function

Sub Start_ProzessePrüfen()
Const sGesProzess As String = "EXCEL.EXE"

If fctProzessMehrfachOffen(sGesProzess) Then
MsgBox "Der Prozess " & sGesProzess & " ist mehrfach offen!", vbInformation
Else
MsgBox "Es gibt keine Probleme mit mehreren Instanzen des Prozesses " & sGesProzess & "!"
End If
End Sub

0 Punkte
Beantwortet von b25812 Mitglied (515 Punkte)
Hallo all
erstmal danke für die Vorschläge und Tipps.

Nighty: Leider ist es nicht möglich nur 1x Excel zu öffnen, da ich aus einem anderen Programm, Excel Tabellen exportiere.
Dadurch entstehen immer mehrere Mappen. Genau wegen diesem Problem möchte ich gerne diese Funktion haben.

M.O.: Dein VBA werde ich mal Testen, aber wenn es möglich ist sollte kein Excel mehr offen sein. Egal ob das Mkro da drin steht oder nicht.

und der letzte VBA sieht sehr komplex aus. Hat den schonmal einer getestet?

Gruß Andi
0 Punkte
Beantwortet von m-o Profi (22.7k Punkte)
Hallo Andi,

wenn alles geschlossen werden soll, dann ergänze den Code wie folgt:

Sub Schliessen()

Dim wkb As Workbook
'erst alle anderen Arbeitsmappen schließen
For Each wkb In Workbooks
If wkb.Name <> ThisWorkbook.Name Then
wkb.Close (False)
End If
Next wkb
'dann Excel beenden
Application.Quit

End Sub

Gruß

M.O.
0 Punkte
Beantwortet von flupo Profi (17.7k Punkte)
Lies dich mal hier durch: www.supportnet.de/t/2376221.
Das ist genau dein Problem und eine mögliche Lösung gibt es auch.


Gruß Flupo
0 Punkte
Beantwortet von m-o Profi (22.7k Punkte)
Hallo,

nochmal ich ;-).

Mein Makro funktioniert nur, wenn alles in einer Instanz geöffnet ist :-(.. Bei mehreren Instanzen müsste man mal Nightys Code probieren (müsste aber für 64Bit-Systeme angepasst werden).

Gruß

M.O.
0 Punkte
Beantwortet von flupo Profi (17.7k Punkte)
@M.O.: Die Idee hatte ich auch schon, wahrscheinlich scheitert das aber daran, dass man per Makro nicht an die
Arbeitsmappen in einer anderen Instanz herankommt. Ich glaube nicht, dass sich die Mappen "sehen". Testen kann ich es
nicht, da Excel bei mir nur eine Instanz öffnet.

Gruß Flupo
0 Punkte
Beantwortet von b25812 Mitglied (515 Punkte)
Hallo all
also das Problem schein wirklich die verschiedenen Instanzen zu sein. Öffne ich aus Excel nur eine neue Arbeitsmappe, kann man dieses zusammen auch schließen. Werden die Excel Tabellen aber von dem anderen Programm generiert dann geht es nicht. Den VBA von Nighty habe ich mal mit einer Schaltfläsche verknüpft, ( in der Personl .xls) aber so richtig hat es nicht funktioniert.
:-( Aber erstmal danke für eure Mühe, den anderen Beitrag muß ich mir mal durchlesen, ob das eine Lösung sein könnte.
0 Punkte
Beantwortet von
Hallo,

wie werden denn eigentlich die verschiedenen Instanzen geöffnet? Hast du da Einfluss drauf? Du schreibst von einem anderen
Programm, das Excel Tabellen exportiert. Kommst du dort an den Code? Falls ja solltest du statt CreateObject lieber GetObject
verwenden, da CreateObject immer eine neue Instanz erzeugt. Allerdings ist die Verwendung von GetObject etwas komplizierter,
weil es sich auf ein bereits laufendes Excel bezieht. Ein Beispiel wie man das verwenden kann findest du
hier
0 Punkte
Beantwortet von nighty Experte (6.6k Punkte)
hi all ^^

um es unnötig schwer zu machen ein code um ALLE Excel Task zu schliessen

von meinem Excel Guru Nepumuk ... *Verneigung* :-)

gruss nighty

Sub test()
Dim objWMI As Object, objProcessList As Object, objProcess As Object
Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
".\root\cimv2")
Set objProcessList = objWMI.ExecQuery("Select * from Win32_Process " & _
"Where Name = 'excel.exe'")
For Each objProcess In objProcessList
objProcess.Terminate (0)
Next
End Sub
[
...