AW: Wieder mal Tabellen vergleichen
20.11.2016 09:50:19
fcs
Hallo Peter,
ich hab auch mal versucht, das Makro von Ur-Opa nachzuvollziehen.
1. Er hat vergessen, die Hilfsspalte für die Formeln links von Spalte A in beiden Blättern einzufügen
2. Durch den 1. Fehler passt dann auch die Suche nach dem eindeutigen Code nicht, da Werte in den falschen Spalten verglichen werden.
3. Beim Einfügen von neuen Datensätzen von Neu nach Master ist er dann noch bei den Variablen durcheinander gekommen, so dass beim Kopieren eine schon vorhandene Zeile überschrieben werden soll, was zur Fehlermeldung führt.
Ich hab seinen Code angepasst plus das Färben der neuen Datensätze eingefügt, so dass er jetzt funktioniert.
ich hab dann auch noch eine Lösung ohne Hilfsspalten gebastelt. Hier wird dann im Makro mit Arrays gearbeitet in denen die Codes in Master und Neu verarbeitet werden.
LG
Franz
korrigierte Lösung von Ur-Opa
Sub Abgleich()
Dim rngMst As Range, _
rngNeu As Range
Dim rngCMst As Range, _
rngCNeu As Range
Dim varPMst As Variant, _
varPNeu As Variant
Set rngMst = ThisWorkbook.Worksheets("Master").Cells(1, 1).CurrentRegion
Set rngNeu = ThisWorkbook.Worksheets("Neu").Cells(1, 1).CurrentRegion
If rngMst.Rows.Count
Lösung ohne Hilfsspalten
'Code in einem allgemeinen Modul
Sub Update_Master()
Dim wksMaster As Worksheet, wksNeu As Worksheet
Dim arrNeu, arrCode, sCode As String, arrMaster
Dim Zeile_N As Long, Zeile_M As Long
Dim varZeile As Variant
Set wksNeu = ActiveWorkbook.Worksheets("Neu")
Set wksMaster = ActiveWorkbook.Worksheets("Master")
'Array mit Codes aus Daten in Spalten A bis C von Blatt "Neu" erstellen
arrCode = fncArrCode(wksNeu, Array(1, 2, 3))
With wksMaster
'Codea "Master" in Array einlesen
arrMaster = fncArrCode(wksMaster, Array(1, 2, 3))
'Codes im Master in Neu suchen
For Zeile_M = 2 To UBound(arrMaster)
sCode = arrMaster(Zeile_M)
varZeile = Application.Match(sCode, arrCode, 0)
If IsNumeric(varZeile) Then
'Code in Master ist in Neu vorhanden
wksNeu.Range(wksNeu.Cells(varZeile, 4), wksNeu.Cells(varZeile, 14)).Copy _
Destination:=.Cells(Zeile_M, 4)
Else
'Code in Master ist in Neu nicht vorhanden - durchstreichen
With .Range(.Cells(Zeile_M, 1), .Cells(Zeile_M, 14))
.Font.Strikethrough = True
End With
End If
Next
'Neue Codes mit Masterdaten vergleichen
For Zeile_N = 2 To UBound(arrCode)
sCode = arrCode(Zeile_N)
varZeile = Application.Match(sCode, arrMaster, 0)
If IsNumeric(varZeile) Then
'Zeile ist schon vorhanden - wurde aktualisiert
Else
'Einfüge-Zeile ermittel (Master-Liste muss aufsteigend sortiert sein!!!)
varZeile = Application.Match(sCode, arrMaster, 1)
If IsError(varZeile) Then varZeile = 1 'neuer Eintrag vor 1. Zeile
wksNeu.Range(wksNeu.Cells(Zeile_N, 1), wksNeu.Cells(Zeile_N, 14)).Copy
'kopierte Zellen einfügen
.Range(.Cells(varZeile + 1, 1), .Cells(varZeile + 1, 14)).Insert _
shift:=xlShiftDown
'eingefügte zeile grün färben
With .Range(.Cells(varZeile + 1, 1), .Cells(varZeile + 1, 14))
.Interior.Color = RGB(red:=0, green:=255, blue:=0)
End With
'Codes-Master neu berechnen
arrMaster = fncArrCode(wksMaster, Array(1, 2, 3))
End If
Next
End With
Erase arrMaster, arrCode
End Sub
Private Function fncArrCode(wks As Worksheet, arrSpalten, Optional sTrenn$ = "|", _
Optional Zeile1& = 1) As Variant
'Schlüsselwerte aus mehreren Spalten in einem 1-spaltigen Array zusammenfassen
Dim arrErgebnis() As String
Dim Spalte As Integer
Dim arrData
Dim Zeile_L As Long, Zeile As Long
With wks
'letzte Zeile mit Daten in den Spalten ermitteln
For Spalte = LBound(arrSpalten) To UBound(arrSpalten)
Zeile = .Cells(.Rows.Count, arrSpalten(Spalte)).End(xlUp).Row
If Zeile >= Zeile_L Then Zeile_L = Zeile
Next
'Daten in Tabelle in Array einlesen
arrData = .Range(.Cells(Zeile1, 1), .Cells(Zeile_L, arrSpalten(UBound(arrSpalten))))
ReDim arrErgebnis(Zeile1 To Zeile_L)
'Codes in Array schreiben mit Trennzeichen
For Zeile = Zeile1 To Zeile_L
arrErgebnis(Zeile) = arrData(Zeile, arrSpalten(LBound(arrSpalten)))
For Spalte = LBound(arrSpalten) + 1 To UBound(arrSpalten)
arrErgebnis(Zeile) = _
arrErgebnis(Zeile) & sTrenn & arrData(Zeile, arrSpalten(Spalte))
Next
Next Zeile
End With
fncArrCode = arrErgebnis
Erase arrErgebnis
End Function