Excel Sheet per Makro öffnen und schliessen

Hallo Leute,

Hab ein code der mir bei bedarf Excel Sheet(s) laden soll. Nicht benötigte Sheet(s) schliessen. Er sieht so aus.

Sub Mappe_öffnen()

Dim a As Integer
Dim ZuLDatei As New Collection
Dim OffeneDatei As New Collection
Dim ZuLZeile As New Collection

ZuLDatei.Add „10.12.2006-09.12.2007.xls“
ZuLDatei.Add „09.12.2007-14.12.2008.xls“
ZuLZeile.Add 18
ZuLZeile.Add 18

'Setzt den counter von offene excel sheets und benötigte excel sheets gleich
If OffeneDatei.Count 0 Then
For a = 1 To ZuLDatei.Count
Workbooks(OffeneDatei.Item(a)).Close Speichern
Next a
End If
End If

End Sub

Das erste Excel Sheet „10.12.2006-09.12.2007.xls“ wird geladen.
beim zweiten Excel Sheet öffnen kommt

Laufzeitfehler"9"

Index auserhalb des gültigen Bereichs

bleibt bei

If Not LCase(OffeneDatei.Item(a)) = LCase(ZuLDatei.Item(a)) Then

hängen
Danke Fred

Hi Manfred,

zunächst mal, da Counter immer auf 0 bleibt kannst du

If OffeneDatei.Count 
auch gleich so schreiben:


    
    For a = 1 To ZuLDatei.Count
     OffeneDatei.Add a
    Next a



Weiterhin, da ZuLDatei.Item(a) immer ein längerer String ist und
OffeneDatei.Item(a) immer eine kleine Zahl
verstehe ich die Abfrage
If Not LCase(OffeneDatei.Item(a)) = LCase(ZuLDatei.Item(a)) Then
sowieso nicht, denn die Wenn-Bedingung wird immer erfüllt!?

Und der Fehler wird vorbereitet durch OffeneDatei.Remove (a)


    
    For a = 1 To ZuLDatei.Count
     If Not LCase(OffeneDatei.Item(a)) = LCase(ZuLDatei.Item(a)) Then
     '...
     '...
     '...
     End If
     OffeneDatei.Remove (a)
    Next a



Beim zweiten For-Durchgang steht ja im Vergleich:
If Not LCase(OffeneDatei.Item(2)) = LCase(ZuLDatei.Item(2)) Then
und das muß krachen da du grad mit OffeneDatei.Remove (a) das Item
OffeneDatei.Item(2) entfernt hast.

Nicht wichtig, aber ich würde

If ThisWorkbook.Worksheets("Einstellungen").Range("L8").Value = "Abfrage" Then Speichern = ""
ElseIf ThisWorkbook.Worksheets("Einstellungen").Range("L8").Value = "Ja" Then Speichern = "SaveChanges:=True"
ElseIf ThisWorkbook.Worksheets("Einstellungen").Range("L8").Value = "Nein" Then Speichern = "SaveChanges:=False"
End If

so schreiben (für mich ein bißchen übersichtlicher und es wird auch abgefangen wenn in L8 z.b "Abfage" steht):
(Eine case-Select Abfrage wäre auch eine Option)

Speichern = ""
If ThisWorkbook.Worksheets("Einstellungen").Range("L8").Value = "Ja" Then Speichern = "SaveChanges:=True"
If ThisWorkbook.Worksheets("Einstellungen").Range("L8").Value = "Nein" Then Speichern = "SaveChanges:=False"

Oder, um schmäleren Code zu bekommen With benutzen



    With ThisWorkbook.Worksheets("Einstellungen").Range("L8")
     Speichern = ""
     If .Value = "Ja" Then Speichern = "SaveChanges:=True"
     If .Value = "Nein" Then Speichern = "SaveChanges:=False"
    End With



Im Anhang ist ein Beispiel wie das dann aussieht.

Vielleicht kannst du mal sagen was da eigentlich im Code geschehen soll, mir ist da einiges nicht klar 

Gruß
Reinhard



    
    '...
    Dim Datei As String
    '...
    With ThisWorkbook.Worksheets("Einstellungen")
     If .Range("K8").Value = "Ja" Then
     For a = 1 To ZuLDatei.Count
     If Not LCase(OffeneDatei.Item(a)) = LCase(ZuLDatei.Item(a)) Then
     Datei = IIf(.Range("I8") = "", ThisWorkbook.Path, .Range("I8").Value)
     Datei = Datei & "\" & .Range("C" & ZuLZeile.Item(a)).Value & "\" & ZuLDatei.Item(a)
     Workbooks.Open FileName:=Datei
     End If
     'löscht die die bereits geöffnete Excel datei aus der Liste OffeneDateien
     OffeneDatei.Remove (a)
     Next a
     'Prüft ob die Excel vor'n schliessen geschpeichert werden soll
     Speichern = ""
     If .Value = "Ja" Then Speichern = "SaveChanges:=True"
     If .Value = "Nein" Then Speichern = "SaveChanges:=False"
     'schliest nicht benö¶tigte Excel Dateien
     If OffeneDatei.Count \> 0 Then
     For a = 1 To ZuLDatei.Count
     Workbooks(OffeneDatei.Item(a)).Close Speichern
     Next a
     End If
     End If
    End With

Hi Manfred,

zunächst mal, da Counter immer auf 0 bleibt kannst du

If OffeneDatei.Count
auch gleich so schreiben:

For a = 1 To ZuLDatei.Count
OffeneDatei.Add a
Next a

Der counter ist nur da zu da, wenn die anzahl der benötigten sheets nicht gleich der offnen sheets ist. um offene und benötigte anzugleichen.

Weiterhin, da ZuLDatei.Item(a) immer ein längerer String ist
und
OffeneDatei.Item(a) immer eine kleine Zahl
verstehe ich die Abfrage
If Not LCase(OffeneDatei.Item(a)) = LCase(ZuLDatei.Item(a))
Then
sowieso nicht, denn die Wenn-Bedingung wird immer erfüllt!?

falls bereits offene sheets vorhanden sind, das sie nicht noch mal geladen werden.

Und der Fehler wird vorbereitet durch OffeneDatei.Remove (a)

danke, das hab ich total übersehen.
wenn ich statt
For a = 1 To ZuLDatei.Count
For a = ZuLDatei.Count To 1 Step -1
erledigt sich von selber
danke

For a = 1 To ZuLDatei.Count
If Not LCase(OffeneDatei.Item(a)) = LCase(ZuLDatei.Item(a))
Then
'…
'…
'…
End If
OffeneDatei.Remove (a)
Next a

Beim zweiten For-Durchgang steht ja im Vergleich:
If Not LCase(OffeneDatei.Item(2)) = LCase(ZuLDatei.Item(2))
Then
und das muß krachen da du grad mit OffeneDatei.Remove (a) das
Item
OffeneDatei.Item(2) entfernt hast.

Nicht wichtig, aber ich würde

If ThisWorkbook.Worksheets(„Einstellungen“).Range(„L8“).Value
= „Abfrage“ Then Speichern = „“
ElseIf
ThisWorkbook.Worksheets(„Einstellungen“).Range(„L8“).Value =
„Ja“ Then Speichern = „SaveChanges:=True“
ElseIf
ThisWorkbook.Worksheets(„Einstellungen“).Range(„L8“).Value =
„Nein“ Then Speichern = „SaveChanges:=False“
End If

so schreiben (für mich ein bißchen übersichtlicher und es wird
auch abgefangen wenn in L8 z.b „Abfage“ steht):
(Eine case-Select Abfrage wäre auch eine Option)

Speichern = „“
If ThisWorkbook.Worksheets(„Einstellungen“).Range(„L8“).Value
= „Ja“ Then Speichern = „SaveChanges:=True“
If ThisWorkbook.Worksheets(„Einstellungen“).Range(„L8“).Value
= „Nein“ Then Speichern = „SaveChanges:=False“

Oder, um schmäleren Code zu bekommen With benutzen

With
ThisWorkbook.Worksheets(„Einstellungen“).Range(„L8“)
Speichern = „“
If .Value = „Ja“ Then Speichern = „SaveChanges:=True“
If .Value = „Nein“ Then Speichern = „SaveChanges:=False“
End With

Im Anhang ist ein Beispiel wie das dann aussieht.

Vielleicht kannst du mal sagen was da eigentlich im Code
geschehen soll, mir ist da einiges nicht klar

Gruß
Reinhard

'…
Dim Datei As String
'…
With ThisWorkbook.Worksheets(„Einstellungen“)
If .Range(„K8“).Value = „Ja“ Then
For a = 1 To ZuLDatei.Count
If Not LCase(OffeneDatei.Item(a)) =
LCase(ZuLDatei.Item(a)) Then
Datei = IIf(.Range(„I8“) = „“, ThisWorkbook.Path,
.Range(„I8“).Value)
Datei = Datei & „“ & .Range(„C“ &
ZuLZeile.Item(a)).Value & „“ & ZuLDatei.Item(a)
Workbooks.Open FileName:=Datei
End If
'löscht die die bereits geöffnete Excel datei aus der
Liste OffeneDateien
OffeneDatei.Remove (a)
Next a
'Prüft ob die Excel vor’n schliessen geschpeichert
werden soll
Speichern = „“
If .Value = „Ja“ Then Speichern = „SaveChanges:=True“
If .Value = „Nein“ Then Speichern = „SaveChanges:=False“
'schliest nicht benö¶tigte Excel Dateien
If OffeneDatei.Count > 0 Then
For a = 1 To ZuLDatei.Count
Workbooks(OffeneDatei.Item(a)).Close Speichern
Next a
End If
End If
End With

Hi Manfred,

Der counter ist nur da zu da, wenn die anzahl der benötigten
sheets nicht gleich der offnen sheets ist. um offene und
benötigte anzugleichen.

da du die Variable Counter nie veränderst kannst du sie auch weglassen, 0 anstelle hinschreiben o.ä.
Das meine ich.

Weiterhin, da ZuLDatei.Item(a) immer ein längerer String ist
und
OffeneDatei.Item(a) immer eine kleine Zahl
verstehe ich die Abfrage
If Not LCase(OffeneDatei.Item(a)) = LCase(ZuLDatei.Item(a))
Then
sowieso nicht, denn die Wenn-Bedingung wird immer erfüllt!?

falls bereits offene sheets vorhanden sind, das sie nicht noch
mal geladen werden.

Entweder ich übersehe was gravierendes oder du *gg*
So wie ich es sehe kannst du die Bedingung komplett einfach weglassen.

Und der Fehler wird vorbereitet durch OffeneDatei.Remove (a)

danke, das hab ich total übersehen.
wenn ich statt
For a = 1 To ZuLDatei.Count
For a = ZuLDatei.Count To 1 Step -1
erledigt sich von selber
danke

Nix zu danken, dieser Remove-Befehl muß irgendwie kleiner geschrieben sein als alles Andere, wahrscheinlich ein Bug in der Bildschirmdarstellung von Microsoft *gg*, oder irgendsowas, denn ich übersah den auch ziemlich lange und konnte mir sehr lange den Fehler nicht erklären :smile:

Gruß
Reinhard