ich würde mich über Hilfe und Ideen freuen, für folgendes Problem:
Jede Woche bekomme ich eine neue Excel Tabelle mit gleichen Spaltenaufbau und unterschiedlichen Inhalten.
Die Aufgabe ist es, zwei Sheets zu vergleichen und wenn sich für bestimmte Ereignisse die Daten geändert haben, diese in einem dritten Sheet wiederzugeben und die alten Daten neben die neuen zu setzen. Hierfür habe ich eine Exceldatei vorbereitet (siehe Anhang).
Mein Ziel ist es, dies mittels Makro zu tun und per Knopfdruck das erste Sheet auszufüllen. Problem bei der Sache ist, dass sich die Zeilen ändern können! Das bedeutet, dass man für jedes bestimmte Ereignis (Name) die jeweiligen Daten heraussuchen muss.
Somit sollte die einzige konstante der Name sein...
Doch was passiert, wenn sich der Name ändert (teile des Namens) oder neue hinzukommen?
anbei deine Datei mit Makro zurück. Ich nehme an das die Lösung so richtig sein wird. Rückmeldung waere nett. In Zeile D9 steht "Start Ende", hat mich anfangs von der Logik verwirrt. Ich nehme an es muss "Start veraltet" heissen.
Die Zellen in "Änderungen zur Vorwoche" müssen noch auf Datum formatiert werden. Ich kopiere nur die Werte, ohne Formate. Sollte der Löschbereich in der Const Anweisung "B10;K58" nicht ausreichen bitte von Hand abaendern.
mfg Gast 123
Folgende(r) 1 Nutzer sagt Danke an Gast 123 für diesen Beitrag:1 Nutzer sagt Danke an Gast 123 für diesen Beitrag 28 • Exceljunge
Vielen Dank für deine Hilfe! Funktioniert soweit super...
jedoch habe ich eine Frage: Er gibt ALLE Daten in der Zieltabelle aus, nicht nur diese, bei der sich das Datum geändert hat.. Ist es möglich nur die auszugeben, die sich im Datum beispielsweise "Ende" unterscheiden?
So habe jetzt nochmal ein wenig rumgespielt und einige Fragen :)
Sub Tabellen_vergliechen() Dim Tb1 As Object, Tb2 As Object, Tb3 As Object Dim AC As Object, rFind As Object, asw As String Dim lz2 As Long, lz3 As Long, lz As Long, z As Long Set Tb1 = Worksheets("Änderungen zur Vorwoche") Set Tb2 = Worksheets("Strukturplan Aktuell") Set Tb3 = Worksheets("Strukturplan Veraltet") lz = Cells.Rows.Count 'LastZell suchen lz2 = Tb2.Cells(lz, 2).End(xlUp).Row lz3 = Tb3.Cells(lz, 2).End(xlUp).Row z = 10 '1. Zeile in Änderungen B10
'alte Tabelle löschen 'Tb3.Range(ClrBer).ClearContents Das habe ich nicht ganz verstanden und rausgenommen, müsste doch eigl Tb1.Range.....ClearContents heißen oder? Da sonst die Tabelle gelöscht wird, die ich ja eigentlich vergleichen wollte mit der neuen.
For Each AC In Tb2.Range("B4:B" & lz2) asw = "Nein" 'Auswerten Ja/Nein (Empty) Set rFind = Tb3.Range("B4:B" & lz).Find(What:=AC, After:=Range("B4"), LookIn:=xlFormulas, _ LookAt:=xlWhole, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False) If rFind Is Nothing Then Cells(AC.Row, 3) = "No": GoTo weiter Den Block verstehe ich leider nicht ganz, bin noch ein Excel Anfänger..muss ich mich noch etwas tiefgründiger mit befassen. 'wenn Name gefunden Datum vergleichen (über ElseÝf) 'bei -gleichem- Datum "tue nichts", ElseÝf ausführen ' If rFind.Offset(0, 3) <> AC.Offset(0, 3) Then asw = "" 'Start Habe ich erstmal rausgenommen, weil ich nun doch nur Ende (Veraltet) und Ende (aktuell) miteinander vergleiche
If rFind.Offset(0, 4) <> AC.Offset(0, 4) Then asw = "" 'Ende
zu deinen Fragen vorab einige Antworten, den Rest muss ich mir im Makro ansehen. Zur 1. Frage: das Löschen bezieiht sich auf den farblich markierten Bereich in der Tabelle "Änderungen zur Vorwoche". Weil ich nicht wusste ob sich der Bereich in der Länge verändern kann habe ich diesen Bereich oben als Const deklariert. Dort kannst du ihn von Hand ändern. Bei Programmierern ist die Methode Adressen so festzulegen gebräuchlich. Dann braucht man nicht im Makro suchen, sondern ändert es oben
Ich bin davon ausgegangen das der Vergleich nur in den Tabellen "Aktuell" und "Veraltet" durchgeführt werden soll, und diie alte Liste "Änderungen zur Vorwoche" somit immer gelöscht werden muss. Ist das falsch ???
If rFind Is Nothing heisst konkret, es wurden keine Daten gefunden, und Goto weiter heisst, überspringe den Makroteil! Die gesamte Auswertung wird damit übersprungen. Das Gegenstück heisst. "If Not rFind Is Nothing", wobei man sich als Neuling an den Begriff "Not rFind is Nothing" als "Wahr", ein Wert wurde gefunden, erst gewöhnen muss.
Ich verweise dich auf den Anfang der For Next Schleife und den 1. Befehlt asw = "Nein",das heist, keine Auswertung! Diese Variable wird gelöscht, wenn Auswertung erfolgen soll. Wenn du diese Löschungen annullierst kann ich nicht genau sagen was das Makro dann macht. Ob es noch korrekt ablaeuft?? Muss ich mir in Ruhe ansehen.
Unter Strich ist es aber nicht schlecht mal damit zu spielen. Mein Tipp: dazu bitt die Daten aus der Original Datei in mein Beispiel kopieren und dann experimentieren. Gefährlich bei Makros ist das falsche Befehle Daten löschen können. Ich arbeite trotz 20 Jahre programmieren beim Entwickeln nie in einer Original Datei. Ich habe mir schon zuviele selbst zerschossen. Dann arbeitet man beim Entwickeln immer in einer Test Datei.
Solltest du dir als VBA Neuling konsequent angewöhnen!
anbei das geänderte Makro, jetzt müsste es laufen. Ich entschuldige mich, es war ein dummer Flüchtigkeitsfehler drin, den ich nicht bemerkt habe weil im Beispiel nur 9 Zeilen mit Daten ausgefüllt sind. Ich wollte logischerweise die alten Daten in Tabelle "Änderungen zur Vorwoche" löschen, was sicher auch korrekt ist. Schreibt man im Makro aber für Tabelle 1 den Befehl: Tb3.Range().ClearContents, dann löscht man in Tabelle 3 und nicht in Tabelle1. Im Beispiel standen in Tabelle3 ab Zeile 10 -keine- Daten, deshalb ist mir der Fehler nicht aufgefallen. Und Excel fährt sturheil den Code so ab wie er ist!!
Die Auswertung habe ich vorsichtshalber mit vier Variablen für DAtum geändert. Jetzt sollte es perfekt laufen.
mfg Gast 123
Code:
Option Explicit '21.10.2016 Gast 123 Clever Forum '3 Start E5, 4 Ende F6, 7-Start I9, 8-Ende J10 (Offset)
Dim Start As Date, Ende As Date 'neu eingefügt statt asw Variable Dim BStart As Date, BEnde As Date 'Vergleich geaendert 24.10.2016
Const ClrBer = "B10:K58" 'Löschbereich in Tabelle "Änderungen"
Sub Tabellen_vergliechen() Dim Tb1 As Object, Tb2 As Object, Tb3 As Object Dim AC As Object, rFind As Object, z As Long Dim lz2 As Long, lz3 As Long, lz As Long Set Tb1 = Worksheets("Änderungen zur Vorwoche") Set Tb2 = Worksheets("Strukturplan Aktuell") Set Tb3 = Worksheets("Strukturplan Veraltet") lz = Cells.Rows.Count 'LastZell suchen lz2 = Tb2.Cells(lz, 2).End(xlUp).Row lz3 = Tb3.Cells(lz, 2).End(xlUp).Row z = 10 '1. Zeile in Änderungen B10
For Each AC In Tb2.Range("B4:B" & lz2) Set rFind = Tb3.Range("B4:B" & lz).Find(What:=AC, After:=Range("B4"), LookIn:=xlFormulas, _ LookAt:=xlWhole, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
'falls gewünscht Fehlermeldung in Spalte C wenn Name nicht gefunden wird 'If rFind Is Nothing Then Cells(AC.Row, "C") = "No" 'Name nicht gefunden! If rFind Is Nothing Then GoTo weiter
'alle Datum Variable laden Start = AC.Offset(0, 3) Ende = AC.Offset(0, 4) BStart = rFind.Offset(0, 3) BEnde = rFind.Offset(0, 4)
'wenn Name gefunden Datum vergleichen (über Elseİf) 'bei -ungleichem- Datum aktive Zeile auflisten If BStart <> Start Or BEnde <> Ende Then Tb1.Cells(z, 2) = AC.Offset(0, -1) 'ZNr Tb1.Cells(z, 3) = AC.Offset(0, 0) 'Name
Tb1.Cells(z, 8) = AC.Offset(0, 3) 'Start Tb1.Cells(z, 9) = AC.Offset(0, 4) 'Ende Tb1.Cells(z, 10) = AC.Offset(0, 7) 'Ba-Start Tb1.Cells(z, 11) = AC.Offset(0, 7) 'Ba-Ende z = z + 1 'next Zeile End If weiter: Next AC End Sub
Läuft alles perfekt durch, vielen Dank für deine Hilfe!
Ist allerdings alles etwas kniffliger, als ich dachte...
Die Tabellen, die ich Vergleiche, haben jeweils 1000 Einträge - es ist ein Art Ordnerstrukturplan mit mehreren Hierarchieebenen. Problem hier ist, dass Namen doppelt belegt werden und das Makro den ersten gefundenen Namen in der alten Tabelle nimmt und das dazugehörige Datum... zusätzlich ändert sich die ZNr. wenn jemand eine neue Datei im Ordner erstellt.. also ist diese auch nicht konstant.
Was vielleicht helfen könnte, wäre ein Befehl, der Namen ausschließt, die öfter als 2mal vorkommen - geht das ? Weil diese sind teilweise nicht relevant. Zusätzlich sind nur Daten wichtig, bei denen kein Start Datum existiert. Also wollte ich die If Bedingung etwas umschreiben.. daran arbeite ich grade etwas und fuchse mich dadurch!
Was bedeutet Option Explicit? :D
Code:
Option Explicit '21.10.2016 Gast 123 Clever Forum '3 Start E5, 4 Ende F6, 7-Start I9, 8-Ende J10 (Offset)
Dim Start As Date, Ende As Date 'neu eingefügt statt asw Variable Dim BStart As Date, BEnde As Date 'Vergleich geaendert 24.10.2016
Const ClrBer = "B10:K58" 'Löschbereich in Tabelle "Änderungen"
zu deiner Frage Option Explicit, kann man drauf verzichten, sollte man aber nicht. Es legt nur fest ob alle Variablen vorher mit Dim festgelegt sein müssen. Deaktiviere ihn mal durch ein Hochkomme, so: 'Option und schreibe ins Makro eine neue Variable mit dem Namen Test = Range(xx).Value, gefolgt von MsgBox Test, dahinter Exit Sub. Jetzt stoppt das Makro und zeigt dir den Wert Test an. Benutze ich zur Fehlersuche! Dann aktiviere Option wieder, der meckert sofort das diese neue Variable nicht mit Dim deklariert wurde. Option hilft dir keine Variable Deklaration zu vergessen und zeigt Schreibfehler an.
Die If Bedingung kannst du so aendern: If Start = Empty And BEnde <> Ende Then Welcher Start ist gemeint, Start oder Basis Start? Oder müssen beide Start auf Null sein, dann so: If BStart = Empty And Start = Empty And BEnde <> Ende
Die andere Sache mit den doppelten Namen hatte ich nicht gerechnet, das muss ich mir in Ruhe anschauen und aendern. Kann es auch doppelte Namen unter dem gleichen Datum geben? Soll die ZNr mit übernommen werden, wenn ja aus welcher Tabelle?? Ich nehme an aktive Daten??