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

VBA Skript läuft fehlerfrei, funktioniert aber nur teilweise

Forumthread: VBA Skript läuft fehlerfrei, funktioniert aber nur teilweise

VBA Skript läuft fehlerfrei, funktioniert aber nur teilweise
17.04.2025 12:16:28
tempestas
Hallo zusammen,

ich möchte zwei Datensätze zusammenführen.
Die Datensätze befinden sich in einem Workbook in jeweils einem Sheet.
Die Datensätze enthalten die Verkaufsmengen von Produkten einer bestimmten Klasse pro Verkäufer pro Monat. Die Produkte haben noch dazu verschiedene Packungsgrößen - all das wird separat aufgeführt.
- Datensatz_1 enthält die Daten von Mai 2022 bis Mai 2024
- Datensatz_2 enthält die Daten von Februar 2023 bis Februar 2025.

Ich möchte nun aus Datensatz_2 die Verkaufsmengen von Juni 2024 bis Februar 2025 in Datensatz_1 ergänzen.
Herausforderung: es ist inzwischen ein Produkt mit mehreren Packungsgrößen hinzugekommen (ein Produkt, das wiederum von vielen Verkäufern abgesetzt wird) und bei einigen Produkten anderen können pro Verkäufer noch Packungsgrößen hinzugekommen sein, die er vorher nicht hatte.

Ich hab mir einen unique identifier mit Hilfe der VERKETTEN-Formel gebastelt: "Verkäufer Produkt Packungsgröße". Befindet sich in Spalte "E".
Ich möchte die Spalten mit den gewünschten Daten aus Datensatz_2 (Spalten Y bis AG) in Datensatz_1 (Spalten AH bis AP) hinzufügen und dann die komplette Zeile, die kopiert wurde, in Datensatz_1 löschen.

Sub MergeData()


Dim i As Long
Dim j As Long
Dim rng1 As Range
Dim rng2 As Range
Dim strSuch As String
Dim sheetSource As Worksheet 'Datensatz_2
Dim sheetDest As Worksheet 'Datensatz_1

Set sheetSource = Workbooks("daten_merge_work_20250415_test.xlsm").Worksheets("Daten_0223_bis_0225_test")
Set sheetDest = Workbooks("daten_merge_work_20250415_test.xlsm").Worksheets("Daten_0522_bis_0524_test")

Set rng1 = sheetSource.Range("E:E") 'Spalte mit dem Identifier
Set rng2 = sheetDest.Range("E:E") 'Spalte mit dem Identifier
sheetSource.Range("Y" & 1 & ":AG" & 1).Copy Destination:=sheetDest.Range("AH" & 1 & ":AP" & 1)
For i = 2 To sheetSource.Cells(Rows.count, 1).End(xlUp).Row
'strSuch = rng1(i).Value
For j = 2 To sheetDest.Cells(Rows.count, 1).End(xlUp).Row
' If rng2(j).Value = strSuch Then
If rng2(j).Value = rng1(i).Value Then
sheetSource.Range("Y" & i & ":AG" & i).Copy Destination:=sheetDest.Range("AH" & j & ":AP" & j)
sheetDest.Range("AH" & j & ":AP" & j).Font.Color = RGB(255, 0, 0)
sheetSource.Rows(i).Delete
End If
Next j
Next i
End Sub


Das Skript läuft fehlerfrei, allerdings werden leider nicht alle Daten, die kopiert werden müssen, auch wirklich in Datensatz_1 kopiert. Es bleiben zuviele übrig, als dass ich das per Hand korrigieren könnte.
Ich hab in Spalte E schon nur die Werte einkopiert (also: erst den unique identifier mit der VERKETTEN-Funktion erstellt und dann kopiert und als Wert eingefügt, aber auch das hilft nicht).

Was kann ich an dem Skript verbessern, dass wirklich alle Zeilen korrekt erkannt und die Daten in Datensatz_1 übertragen werden?

Vielen Dank vorab für die Hilfe!

tempestas
Anzeige

6
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: VBA Skript läuft fehlerfrei, funktioniert aber nur teilweise
17.04.2025 12:30:34
daniel
Hi
wenn man in einer Schleife Zeilen löscht oder hinzufügt, sollte die Schleife immer rückwärts laufen, dh
For i = sheetSource.Cells(Rows.count, 1).End(xlUp).Row To 2 Step -1

dann wirkt sich das Löschen oder Einfügen nur auf den Zellbereich aus, der schon bearbeitet wurde und nicht auf den, der noch bearbeitet werden muss.

ansonsten hast du folgendes Problem:

wenn der Schleifenzähler auf 3 steht und du löschst die Zeile 3, dann rutschen ja alle nachfolgenden Zeilen nach, dh die alte Zeile 4 wird zur neuen Zeile 3, die alte Zeile 5 wird zur neuen Zeile 4 usw.
Dein Schleifenzähler springt aber im nächsten Umlauf um 1 hoch, wird also von 3 zu 4.
Damit wird als nächstes die neue Zeile 4 bearbeitet, welches aber die alte Zeile 5 ist.
die alte Zeile 4 ist jetzt die neue Zeile 3, und wird so übersprungen.
dh. bei einer vorwärtslaufenden Schleife wird nach dem Löschen einer Zeile die Folgezeile übersprungen und nicht bearbeitet.
Das Rückwärtslaufenlassen der Schleife ist hier die einfachste Lösung, das Problem zu lösen.

Gruß Daniel
Anzeige
AW: VBA Skript läuft fehlerfrei, funktioniert aber nur teilweise
17.04.2025 16:58:08
Oppawinni
Hallo
ich hab das jetzt nicht im Detail angeschaut, aber wenn das Löschen der Zeilen nicht unbedingt sofort erfolgen muss,
kannst du auch die entsprechenden Zeilen in einer Union erfassen und erst nach Abschluss des Kopierens löschen.
Also etwa so (ungetestet):



Sub MergeData()

Dim i As Long
Dim j As Long
Dim rng1 As Range
Dim rng2 As Range
Dim unionRng As Range
Dim strSuch As String
Dim sheetSource As Worksheet 'Datensatz_2
Dim sheetDest As Worksheet 'Datensatz_1

Set sheetSource = Workbooks("daten_merge_work_20250415_test.xlsm").Worksheets("Daten_0223_bis_0225_test")
Set sheetDest = Workbooks("daten_merge_work_20250415_test.xlsm").Worksheets("Daten_0522_bis_0524_test")

Set rng1 = sheetSource.Range("E:E") 'Spalte mit dem Identifier
Set rng2 = sheetDest.Range("E:E") 'Spalte mit dem Identifier
sheetSource.Range("Y" & 1 & ":AG" & 1).Copy Destination:=sheetDest.Range("AH" & 1 & ":AP" & 1)
For i = 2 To sheetSource.Cells(Rows.Count, 1).End(xlUp).Row
'strSuch = rng1(i).Value
For j = 2 To sheetDest.Cells(Rows.Count, 1).End(xlUp).Row
' If rng2(j).Value = strSuch Then
If rng2(j).Value = rng1(i).Value Then
sheetSource.Range("Y" & i & ":AG" & i).Copy Destination:=sheetDest.Range("AH" & j & ":AP" & j)
sheetDest.Range("AH" & j & ":AP" & j).Font.Color = RGB(255, 0, 0)
If unionRng Is Nothing Then
Set unionRng = rng1(i)
Else
Set unionRng = Union(unionRng, rng1(i))
End If
End If
Next j
Next i

If Not unionRng Is Nothing Then
unionRng.EntireRow.Delete
End If

End Sub


/Winni
Anzeige
AW: VBA Skript läuft fehlerfrei, funktioniert aber nur teilweise
17.04.2025 13:01:32
tempestas
Vielen herzlichen Dank, Daniel, für Deine superschnelle Antwort!
So ein dämlicher Fehler von mir, dass ich da nicht dran gedacht hab, dass das Löschen der Zeile den Zähler beeinflusst!
Den Code Schnipsel, wie man die Schleife von unten loslaufen lässt, kannte ich noch nicht. Wieder was gelernt! Dankeschön!

Viele Grüße
Carola
Anzeige
AW: VBA Skript läuft fehlerfrei, funktioniert aber nur teilweise
17.04.2025 14:53:51
tempestas
Hi Daniel,

jetzt fällt mir noch eine Alternative zu dem Rückwärtslaufenlassen der Schleife: den Zähler um ein zurücksetzen. Also so hier:



For i = 2 To sheetSource.Cells(Rows.count, 1).End(xlUp).Row
For j = 2 To sheetDest.Cells(Rows.count, 1).End(xlUp).Row
If rng2(j).Value = rng1(i).Value Then
sheetSource.Range("Y" & i & ":AG" & i).Copy Destination:=sheetDest.Range("AH" & j & ":AP" & j)
sheetDest.Range("AH" & j & ":AP" & j).Font.Color = RGB(255, 0, 0)
sheetSource.Rows(i).Delete
i = i - 1
End If
Next j
Next i


Hab es noch nicht getestet, aber es müsste funktionieren, oder?

Viele Grüße
Carola
Anzeige
AW: VBA Skript läuft fehlerfrei, funktioniert aber nur teilweise
17.04.2025 15:38:57
Daniel
Hi
Ja, kann man machen, ist aber kein schöner Programmierstil, in der For-Schleife den Schleifenzähler zu manipulieren.

Konsequenterweise müsstest du auch den Endwert dann um 1 vermindern, damit die Schleife dann am Ende nicht nutzlos über leere Zellen läuft, oder, falls sich unter der Tabelle noch weitere Daten befinden würden, diese fälschlicherweise bearbeiten.
Aber in einer For-Schleife ist der Endwert nicht nachträglich änderbar.
Mit einer Do-Schleife könnte man das machen, ist aber aufwendiger, weil man dann die ganzen Schleifenoperationen (Hochzählen, auf Ende prüfen) selber programmieren muss.

Deswegen ist die rückwärtslaufende For-Schleife der einfachere Weg.

Gruß Daniel
Anzeige
AW: VBA Skript läuft fehlerfrei, funktioniert aber nur teilweise
17.04.2025 16:48:09
tempestas
Vielen Dank für die Erklärung!
Das leuchtet mir ein.

Viele Grüße
Carola

Forumthreads zu verwandten Themen

Anzeige
Anzeige
Anzeige