Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Anzeige
Inhaltsverzeichnis

Warum wird Schleife nur einmal durchlaufen

Forumthread: Warum wird Schleife nur einmal durchlaufen

Warum wird Schleife nur einmal durchlaufen
22.01.2025 20:09:06
Christian
Hallo,

eins voraus, Datei hat 19MB, würde also sehr lange dauern daraus eine 300 KB Datei zu machen, die immer noch alles enthält was benötigt wird, aber vielleicht hat trotzdem jemand eine Idee wo mein Fehler im Code liegt

Sub DeleteFilesBasedOnNames()


Dim wsRechnung As Worksheet
Dim dict As Object
Dim i As Long

Set wsRechnung = ThisWorkbook.Sheets("Rechnung")

letzteZeileRechnungAJ = wsRechnung.Cells(wsRechnung.Rows.Count, 36).End(xlUp).Row
Debug.Print "Letzte Zeile AJ: " & letzteZeileRechnungAJ 'gibt 3885 aus

' Füllt das Dictionary mit den Daten aus Spalte AJ und AK
Set dict = CreateObject("Scripting.Dictionary")
For i = 2 To lezteZeileRechnungAJ
If wsRechnung.Cells(i, "AK").Value = 0 Then
dict.Add wsRechnung.Cells(i, "AJ").Value, 0
Debug.Print "Hinzugefügt zum Dictionary: " & wsRechnung.Cells(i, "AJ").Value
End If
Next i

...

End Sub


Die Schleife wird nur einmal durchlaufen, obwohl lezteZeileRechnungAJ den Wert 3885 hat. Nullen in Spalte AK sind auch reichlich vorhanden (303).
Das Debug.Print "Hinzugefügt zum Dictionary: " & wsRechnung.Cells(i, "AJ").Value gibt demnach auch nichts aus.

Habe Testweise noch das hier daraus gemacht,

If Not dict.exists(wsRechnung.Cells(i, "AJ").Value) Then

dict.Add wsRechnung.Cells(i, "AJ").Value, 0
Debug.Print "Hinzugefügt: " & wsRechnung.Cells(i, "AJ").Value


weil ich gelesen habe, dass das Dictionary keine doppelten Werte enthalten darf, aber in Spalte AJ Texte mehrfach vorkommen, hat aber auch nicht geholfen.

Was mache ich falsch?

Danke
Christian
Anzeige

18
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Warum wird Schleife nur einmal durchlaufen
22.01.2025 20:24:37
Kuwer
Hallo Christian

deklariere die Variable letzteZeileRechnungAJ und versuche es dann noch mal.

Gruß, Uwe
AW: For i läßt sich um 100 Zeilen austricksen
22.01.2025 23:28:40
Piet
Hallo

du hast die Frage gestellt, ob du 100 Zeilen überspringen kannst. - Ja, sehr einfach, mit If Then "i" hochsetzen!!
Das mag einige Kollegen erstaunen, habe ich schon öfters verwendet. Excel läßt sich austricksen.
Vor Next i diesen Befehl setzen, damit klappt es --> If i = xxx Then i = i + 100

mfg Piet
Anzeige
AW: Warum wird Schleife nur einmal durchlaufen
22.01.2025 20:29:35
Christian
ok, das war wirklich ein Flüchtigkeitsfehler, aber das Problem besteht trotzdem noch.

Falls es hilft, der komplette Code:

Beim Auführen der Einzelschritte springt er sofort von der Zeile For i = 2 To lezteZeileRechnungAJ zur Zeile For Each folderPath In folderPaths. Bis zu dem Punkt, wo das Dictionary gefüllt werden soll, läuft alles nach Plan

Sub DeleteFilesBasedOnNames()

Dim wsRechnung As Worksheet, wsFilme As Worksheet, wsLeute As Worksheet
Dim searchText As Variant
Dim folderPaths As Variant
Dim folderPath As Variant
Dim file As Object
Dim fs As Object
Dim dict As Object
Dim i As Long
Dim letzteZeileRechnungAJ

' Bildschirmaktualisierung und Berechnung deaktivieren
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False

' Setzt das Arbeitsblatt und die Ordnerpfade
Set wsRechnung = ThisWorkbook.Sheets("Rechnung")
Set wsLeute = ThisWorkbook.Sheets("Leute")
Set wsFilme = ThisWorkbook.Sheets("Filme")
folderPaths = Array("E:\Videos", "D:\Bilder")
Set fs = CreateObject("Scripting.FileSystemObject")

' Erstelle ein Dictionary, um die Namen und Status aus Spalten AJ und AK zu speichern
Set dict = CreateObject("Scripting.Dictionary")

wsRechnung.ListObjects("Dateinamen").QueryTable.Refresh BackgroundQuery:=False

letzteZeileFilme = wsFilme.Cells(wsFilme.Rows.Count, 2).End(xlUp).Row
letzteZeileLeute = wsLeute.Cells(wsLeute.Rows.Count, 1).End(xlUp).Row
letzteZeileRechnungV = wsRechnung.Cells(wsRechnung.Rows.Count, 22).End(xlUp).Row
letzteZeileRechnungAJ = wsRechnung.Cells(wsRechnung.Rows.Count, 36).End(xlUp).Row
Debug.Print "Letzte Zeile AJ: " & letzteZeileRechnungAJ

wsRechnung.Range("Y2:Y" & letzteZeileRechnungV).FormulaLocal = "=XVERWEIS(W2;Filme!B$2:B$" & letzteZeileFilme & ";Filme!C$2:C$" & letzteZeileFilme & ";"""";0;1)"
wsRechnung.Range("Z2:Z" & letzteZeileRechnungV).FormulaLocal = "=XVERWEIS(W2;Filme!B$2:B$" & letzteZeileFilme & ";Filme!E$2:E$" & letzteZeileFilme & ";"""";0;1)"
wsRechnung.Range("AA2:AA" & letzteZeileRechnungV).FormulaLocal = "=XVERWEIS(X2;Leute!B$2:B$" & letzteZeileLeute & ";Leute!C$2:C$" & letzteZeileLeute & ";"""";0;1)"
wsRechnung.Range("AB2:AB" & letzteZeileRechnungV).FormulaLocal = "=XVERWEIS(X2;Leute!B$2:B$" & letzteZeileLeute & ";Leute!D$2:D$" & letzteZeileLeute & ";"""";0;1)"
wsRechnung.Range("AC2:AC" & letzteZeileRechnungV).FormulaLocal = "=DATEDIF(AB2;Z2;""Y"")"
wsRechnung.Range("AD2:AD" & letzteZeileRechnungV).FormulaLocal = "=DATEDIF(AB2;Z2;""YD"")"
wsRechnung.Range("AE2:AE" & letzteZeileRechnungV).FormulaLocal = "=Z2-AB2"
wsRechnung.Range("AF2:AF" & letzteZeileRechnungV).FormulaLocal = "=""MRS ""&TEXT(AE2;""00000"")&"" ""&WECHSELN(WECHSELN(WECHSELN(WECHSELN(Y2;""?"";"""");"":"";"""");""/"";"""");""*"";"""")&"" (""&TEXT(Z2;""TT.MM.JJJJ"")&"") - ""&AA2&"" (""&TEXT(AB2;""TT.MM.JJJJ"")&"") ""&AC2&""-""&AD2"
wsRechnung.Range("AH2:AH" & letzteZeileRechnungV).FormulaLocal = "=ZÄHLENWENN(AJ$2:AJ$" & letzteZeileRechnungAJ & ";AF2)"
wsRechnung.Range("AK2:AK" & letzteZeileRechnungAJ).FormulaLocal = "=ZÄHLENWENN(AF$2:AF$" & letzteZeileRechnungV & ";AJ2)"
wsRechnung.Range("Y2:AH" & letzteZeileRechnungV).Value2 = wsRechnung.Range("Y2:AH" & letzteZeileRechnungV).Value2
wsRechnung.Range("AK2:AK" & letzteZeileRechnungAJ).Value2 = wsRechnung.Range("AK2:AK" & letzteZeileRechnungAJ).Value2

' Füllt das Dictionary mit den Daten aus Spalte AJ und AK
Set dict = CreateObject("Scripting.Dictionary")
For i = 2 To lezteZeileRechnungAJ
If wsRechnung.Cells(i, "AK").Value = 0 Then
dict.Add wsRechnung.Cells(i, "AJ").Value, 0
Debug.Print "Hinzugefügt zum Dictionary: " & wsRechnung.Cells(i, "AJ").Value
End If
Next i

' Durchläuft die beiden Ordner
For Each folderPath In folderPaths
' Durchsucht alle Dateien im Ordner
For Each file In fs.GetFolder(folderPath).Files
' Durchsucht das Dictionary nach übereinstimmenden Dateinamen
For Each searchText In dict.Keys
If LCase(Left(file.Name, Len(searchText))) = LCase(searchText) Then
' Löscht die Datei
'On Error Resume Next ' Falls Datei gerade verwendet wird, überspringen
fs.DeleteFile file.Path
'On Error GoTo 0 ' Fehlerbehandlung zurücksetzen
Debug.Print "Datei gelöscht: " & file.Path ' Gibt den gelöschten Dateinamen im Direktfenster aus
End If
Next searchText
Next file
Next folderPath


' Wiederherstellung der ursprünglichen Einstellungen
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True

MsgBox "Dateien wurden geprüft und gelöscht, falls zutreffend.", vbInformation
End Sub





Anzeige
Dim letzteZeileRechnungAJ as Long, hilft aber auch nicht owT
22.01.2025 20:36:11
Christian
AW: Dim letzteZeileRechnungAJ as Long, hilft aber auch nicht owT
22.01.2025 20:41:37
Kuwer
Hallo Christian,

und nun füge in die erste Zeile des Moduls
Option Explicit
ein und versuche es nochmals.

Gruß, Uwe
Rechtschreibung lässt grüßen
22.01.2025 21:26:53
Christian
vielen Dank
Anzeige
und deshalb ...
22.01.2025 22:17:18
Uduuh
Hallo,
... solltest du immer Option Explicit im Kopf jedes Moduls haben oder noch besser die Variablendeklaration erzwingen.
Im VBE: Extras-Optionen-Editor, Haken bei Variablendeklaration erforderlich setzen.

Gruß aus'm Pott
Udo
AW: und deshalb ...
22.01.2025 22:39:43
Christian
bin gerade dabei 6 Makros zu einem zu machen, weil ich sie mit ein paar Zwischenschritten, die man auch vom Makro machen lassen kann sowieso immer nacheinander ausführe. habe ich direkt in das Gesamtmakro eingefügt...

danke für den Tipp
Anzeige
aber mal noch eine allgemeine Frage
22.01.2025 22:42:36
Christian
wenn ich einmalig, ich sag einfach mal 100 Zeilen in einem Makro überspringen will, gibt es da noch eine einfachere Möglichkeit als vor 100 Zeilen ein ' zu setzen und danach wieder zu entfernen?
AW: mit Sprungmarken
22.01.2025 22:54:28
Kuwer
Hallo Christian,

mit Sprungmarken z.B.:

GoTo Sprungmarke1

MsgBox "Hallöchen"
Sprungmarke1:

Gruß, Uwe
Anzeige
AW: mit Sprungmarken
22.01.2025 23:03:38
Christian
Hallo Udo

danke für den Tipp,

hatte da in der Zwischenzeit noch theoretisch eine andere Idee, konnte noch nicht testen weil immer noch das Makro läuft.

Aber müsste es nicht auch mit

If False Then
...
End if

gehen? da False per Definition immer Falsch ist und damit die Bedingung nie erfüllt sein kann?
Wäre jetzt mein ungetesteter Vorschlag gewesen

Chrisian
Anzeige
AW: oder ganzen Block ...
22.01.2025 23:06:21
Kuwer
... auf einmal auskommentieren. Also die Zeilen markieren und dann mit dem entsprechenden Button:

Userbild

Gruß, Uwe
finde ich nicht, siehe Bild
22.01.2025 23:10:02
Christian
Userbild
Anzeige
AW: finde ich nicht, siehe Bild
22.01.2025 23:21:17
Kuwer
Hallo Christian,

mache einen Rechtsklick auf die Menüleiste und hake "Bearbeiten" an.

Userbild

Gruß, Uwe
Uwe nicht Udo, sorry owT
22.01.2025 23:04:29
Christian
AW: Warum wird Schleife nur einmal durchlaufen
22.01.2025 20:40:30
Uduuh
Hallo,
lezteZeile,??
Option Explicit im Modulkopf hilft!

Gruß aus m Pott
Udo
Anzeige
AW: Warum wird Schleife nur einmal durchlaufen
22.01.2025 23:14:58
emkaes
Hallo,

wenn du mal so locker 100 Zeilen im Code überspringen willst, dann hört sich das für mich so an, als dass du einen unstrukturierten Spaghetti-Code bereits hast oder entwickeln willst.
Lass besser die Finger davon. Falls nicht, google nach goto und sprungmarke

Mein Vorschlag ist ein anderer:
schreibe dir mit Bleistift und Papier die einzelnen Arbeitsschritte auf, die dein Makro machen soll
Beispiel: es sollen 2 Tabellen verglichen werden, jeweils die Spalten A. Das Ergebnis soll sein, Welche Daten sind nur in der 2. Tabelle
Arbeitsschritte: Daten einlesen Tabelle1 Spalte A ***** Daten einlesen Tabelle2 Spalte A ******** Daten miteinander Vergleichen ****** Daten Ausgeben

wie zu sehen ist, sind es 4 Arbeitsschritte, aber lediglich 3 Programmabschnitte werden benötigt, da Daten Einlesen doppelt vorkommt und sich der Vorgang lediglich darin unterscheidet, von WO die Daten eingelesen werden müsen.

Soche "Prozedurschritte" lagert man dann in Funktionen oder Sub's aus. Das macht den Code insgesamt kürzer, übersichtlicher und leichter zu warten und anzupassen, wenn sich Veränderungen ergeben.

Wenn du die einzelnen Arbeitsschritte hast, überlege dir, mit welchen Methoden du am besten arbeiten solltest. Um im Beispiel zu bleiben:
Daten einlesen immer wenn möglich in ein Array, da das "Arbeiten mit Schleifen über Zeilen und Spalten" viel Rechnerzeit verbraucht, Arrays im RAM aber ratzifatzi bearbeitet werden können.

Wie vergleicht man Daten: viele Möglichkeiten, meine bevorzugte: ein Array in ein Dictionary einlesen und das andere Array auf das Dictionary ansetzten ( Methode Exists ).

Wenn du dir dann noch Gedanken über eine sinnvolle Ablaufsteuerung machst, dann bist du schon fast am Ziel, denn dann brauchst du lediglich noch den Code zu entwickeln.

Have Fun


Anzeige
AW: Warum wird Schleife nur einmal durchlaufen
22.01.2025 23:31:10
Christian
Hallo,

nein der Grund dafür ist ein anderer.
Ich kann nicht 2mal dieselben Dateien löschen, weil sie beim zweiten Versuch bereits gelöscht sind.
Es sind auch einige Schritte notwendig um zu Bestimmen, welche Dateien gelöscht werden. 100 Zeilen waren natürlich etwas übertrieben.

Aber danke für die Tipps, werde ich mir natürlich trotzdem zu Herzen nehmen.
In einem Punkt hast du aber recht, ich versuche hier sehr vieles zu Automatisieren, was immer die gleichen Abläufe sind. Allein das 6. Makro hat in Word eingefügt schon 12 Seiten. Aber solange es funktioniert....

Es sind allein nur deshalb 6 Makros, weil dazwischen auch Schritte außerhalb von Excel stattfinden.

Gruß
Christian

Anzeige

Forumthreads zu verwandten Themen

Anzeige