Laden...

Vergleich von zwei Excel Spalten

Erstellt von Marccore vor 5 Jahren Letzter Beitrag vor 5 Jahren 3.695 Views
M
Marccore Themenstarter:in
9 Beiträge seit 2018
vor 5 Jahren
Vergleich von zwei Excel Spalten

Hallo Leute,
ich hoffe ihr könnt mir helfen.
Ich habe schon Ewigkeiten das Net und das Forum durchsucht und ein paar Sachen gefunden.
Leider bin ich nicht an mein Ziel gekommen.

Ich habe eine Excel Datei mit zwei Blättern.

Jetzt möchte ich Tabelle 1 Spalte 2 mit
Tabelle zwei Spalte 4 vergleichen.
Dabei will ich ermitteln welche Werte ich Zellen von Tabelle 2, schon in Tabelle 1 vorhanden sind.
Und wenn diese vorhanden sind will ich in entsprechender Zeile , in Spalte 20 ein X setzten.

Genau das habe ich schon mit VBA gemacht,
das ganze klappt auch ganz gut.

Nur leider sind es pro Tabelle 200.000 Datensätze und das dauert mit VBA 25h.

Grüße
Marco

W
872 Beiträge seit 2005
vor 5 Jahren

Ich persönlich benutze EPPlus für so etwas.
Man kann auch direkt das Office XML benutzen.
Bei 200.000 Spalten wirst Du vielleicht recht viel Speicher brauchen - aber das sollte sehr schnell sein.

M
Marccore Themenstarter:in
9 Beiträge seit 2018
vor 5 Jahren

Danke dir,
aber leider bin ich nicht so ein erfahrener C# Skripter und brauche etwas Hilfe.

2.207 Beiträge seit 2011
vor 5 Jahren

Hallo Marccore,

aber leider bin ich nicht so ein erfahrener C# Skripter und brauche etwas Hilfe.

Das ist gar kein Problem. Wir helfen dir gerne. Zeig doch mal was du schon auf die Beine gestellt hast und dann können wir dir helfen. Von 0 auf machen wir dir die Arbeit nicht. Hast du schon etwas Code?

Gruss

Coffeebean

M
Marccore Themenstarter:in
9 Beiträge seit 2018
vor 5 Jahren

Also leider nur in VBA,
da habe ich einfach mit der .Find Methode und eine For Schleife die Datenfelder Verglichen.
Das dauert ewig.

Ich bin gerade erst am Anfang und muss erstmal die Excel Tabellen irgendwie einlesen.

2.207 Beiträge seit 2011
vor 5 Jahren

Hallo Marccore,

für das Einlesen hast du ja schon Hinweise bekommen. Die einfach mal anschauen und dann bekommst du das schon hin. Die Links verweisen auf Github, da sind auch Samples für viele Applikationsarten dabei.

Hats du das schonmal probiert?

Gruss

Coffeebean

M
Marccore Themenstarter:in
9 Beiträge seit 2018
vor 5 Jahren

Also leider nur in VBA,
da habe ich einfach mit der .Find Methode und eine For Schleife die Datenfelder Verglichen..


''++++++++++++++++++++++++++++++++++++++++++++++++++++++++++        Deklartion
Dim Wks1 As Worksheet
Dim lngCounterColum As Long
Dim lngCounterRow_Clean As Long
Dim lngCounterRow_FileAll As Long
Dim CkeckBit As Boolean
Dim EndRow_Clean As Long
Dim EndColumn_Clean As Long
Dim EndRow_FileAll As Long
Dim EndColumn_FileAll As Long
Dim error As Integer
Dim OK As Integer
Dim Row As Long
Dim ColumnART As Long
Dim ColumnERP As Long
Dim Test1 As String
Dim Test2 As String
Dim FindString As String
Dim Rng As Range
Dim Cell As String
''++++++++++++++++++++++++++++++++++++++++++++++++++++++++++        Deklartion

Sub Search()


For Wks = 1 To Worksheets.Count
    If Worksheets(Wks).Name = "PDM_Daten" Then
    
            
        Set Wks_Clean = Sheets("PDM_Daten")
        Set Wks_FileAll = Sheets("fileAll00-0F")
        
        With Wks_Clean
        EndRow_Clean = .Cells(Rows.Count, 2).End(xlUp).Row                        '' Ermitteln letzte Zeile
        EndColumn_Clean = .Cells(2, Columns.Count).End(xlToLeft).Column           '' Ermittel letzte Spalte
        
        End With
        
        With Wks_FileAll
        EndRow_FileAll = .Cells(Rows.Count, 4).End(xlUp).Row                        '' Ermitteln letzte Zeile
        EndColumn_FileAll = .Cells(2, Columns.Count).End(xlToLeft).Column           '' Ermittel letzte Spalte
        
        End With


            For lngCounterRow_Clean = 1 To EndRow_Clean
            
        
                    FindString = Wks_Clean.Cells(lngCounterRow_Clean, 2).Value
                    
                    If Trim(FindString) <> "" Then
                        With Wks_FileAll.Range("D:D")
                            Set Rng = .Find(What:=FindString, _
                                            After:=.Cells(.Cells.Count), _
                                            LookIn:=xlValues, _
                                            LookAt:=xlWhole, _
                                            SearchOrder:=xlByRows, _
                                            SearchDirection:=xlNext, _
                                            MatchCase:=False)
                                                        
                            If Not Rng Is Nothing Then
                                Cell = Rng.Address
                                Cell = Right(Cell, Len(Cell) - 3)
                                Wks_FileAll.Cells(Cell, 20).Value = "X"
                                Wks_FileAll.Cells(2, 21).Value = lngCounterRow_Clean
                            ''Else
                                ''MsgBox "Nothing found"
                            End If
                        End With
                    End If
                 



                ''Next lngCounterRow_FileAll
    
            
            Next lngCounterRow_Clean
        
        
        
        
        
        
        Application.ScreenUpdating = False                                  '' Screen Update
           

        
End If
     

End Sub



Next Wks

Exit Sub


Sub MatchTab()
Dim Wks1 As Worksheet, Wks2 As Worksheet
Dim RangeMaster As Range, RangetoMatch As Range, Zelle As Range

'Tabellenname und Bereich anpassen
Set Wks1 = Sheets("fileAll00-0F")
Set RangeMaster = Wks1.Columns(4)
Set Wks2 = Sheets("PDM_Daten")
Set RangetoMatch = Wks2.Columns(2)

On Error GoTo errExit

For Each Zelle In RangeMaster.SpecialCells(xlCellTypeConstants)
    If Application.CountIf(RangetoMatch, Zelle) Then
    Zelle.Interior.Color = vbGreen
    Else
    Zelle.Interior.Color = vbRed
    End If
Next

errExit:
Set Wks1 = Nothing
Set RangeMaster = Nothing
Set Wks2 = Nothing
Set RangetoMatch = Nothing
End Sub

M
Marccore Themenstarter:in
9 Beiträge seit 2018
vor 5 Jahren

Hats du das schonmal probiert?

Also leider habe ich damit noch nichts gemacht. Ich wühle mich da gerade mal durch, aber leider verstehe ich das noch nicht wirklich.

Hinweis von Coffeebean vor 5 Jahren

Bitte keine Full-Quotes [Hinweis] Wie poste ich richtig?

2.207 Beiträge seit 2011
vor 5 Jahren

Hallo Marccore,

dann mach dich erstmal mit den Grundlagen [FAQ] Wie finde ich den Einstieg in C#? vertraut, bevor du sowas anfängst. Und dann kannst du sicher auch mit den Beispielen etwas mehr anfangen.

Gruss

Coffeebean

H
523 Beiträge seit 2008
vor 5 Jahren

Ich weiß, dass wir hier in einem c#-Forum sind 😄, aber ich würde das ganze ohne eine Zeile Code realisieren. Einfach mit den Formeln und bedingten Formatierungen die Excel mitliefert. WENN, SVERWEIS oder ZÄHLENWENN sollten für das Vorhaben vollkommen ausreichen.

1.029 Beiträge seit 2010
vor 5 Jahren

Hi,

Würde mich hypersurf anschließen.

Zum einen lässt sich sicher der VBA-Code optimieren - zum anderen dürften Formeln in der Tat genügen. Das ist für Endanwender in aller Regel komfortabler.

Abseits davon:
Mehr als 200.000 Einträge klingt in meinen Augen schon nach Missbrauch. Solche Datenmengen gehören eigentlich in eine ordentliche Datenbank...

LG

5.657 Beiträge seit 2006
vor 5 Jahren

Hi Marccore,

Jetzt möchte ich Tabelle 1 Spalte 2 mit
Tabelle zwei Spalte 4 vergleichen.
Dabei will ich ermitteln welche Werte ich Zellen von Tabelle 2, schon in Tabelle 1 vorhanden sind.
Und wenn diese vorhanden sind will ich in entsprechender Zeile , in Spalte 20 ein X setzten.

Es gibt auch in VBA einen Dictionary-Datentyp.

Anstatt jeden Wert bei jedem Durchlauf wieder per API aus dem Excel-Dokument zu lesen, solltest du im ersten Schritt die Werte in ein Dictionary ablegen, bzw. die Werte aus der zweiten Tabelle in eine Liste.

Dann kannst du im zweiten Schritt durch die Liste gehen und im Dictionary in O(1) überprüfen, ob der Wert schon vorhanden ist. Und nur in diesem Fall mußt du die Excel-API verwenden, um die Markierung zu setzen.

Somit machst du aus einer Laufzeit von O(n²) eine Laufzeit von O(n), und zusätzlich sparst du dir alle redundanten Abfragen über die Excel-API. Damit sollte der Algorithmus um einiges schneller laufen, als bisher.

Weeks of programming can save you hours of planning

M
Marccore Themenstarter:in
9 Beiträge seit 2018
vor 5 Jahren

Danke euch.
Nein das ist kein Missbrauch.
Die Daten kommen aus einem DMS System.
Und sollen in ein neues übertragen werden.
Dabei soll der ganze Datenmüll der sich über 10 Jahre gesammelt hat, gelöscht werden.
Und ich habe zwei CSV Dateien, die ich vergleichen soll.

So ich habe mal das ganze mit einem Dic. getestet und leider auch kein Erfolg gehabt.
Leider kann das Dic. nie zwei gleiche Werte aufnehmen, wovon ich wohl einige in der Datenmenge habe.

1.029 Beiträge seit 2010
vor 5 Jahren

Hi,

nun - wenn alle Daten aus einem DMS kommen - sind diese ja bereits in einer Datenbank, die sich ggf. mit Hilfe von SQL auswerten lässt. Selbst wenn dem nicht so ist - scheint der Export im CSV-Format sein, mit dem du in C# deutlich leichter (und schneller) zu Leibe rücken könntest... Beide Varianten würde ich in jedem Fall Excel vorziehen.

LG

L
136 Beiträge seit 2015
vor 5 Jahren

Hallo Marccore,

Versuch mal sowas, sollte es doch mit C# gelöst werden:



        public List<ModelCSV> ReadCSV(string path, string delimiter)
        {

            using (StreamReader reader = new StreamReader(path))
            {

                var arrCSV = from line in ReadFile(reader, delimiter)
                               where line[0].IndexOf("!") != 0   //Damit kann z.B. die erste Spalte mit den Headern gefiltert werden...
                               select new ModelCSV
                               {
                                   Column1 = line[0],
                                   Column2 = line[1],
                                   Column3 = line[2],
                                   Column4 = line[3]
                                };

                return arrCSV.ToList();
            }

        }

        private IEnumerable<string[]> ReadFile(StreamReader reader, string delimiter)
        {
            while (reader.EndOfStream == false)
            {
                yield return reader.ReadLine().Split(delimiter.ToCharArray());
            }
        }

Der Methode kannst Du dann den Pfad Deiner Datei und den delimiter (richtigerweise "Komma", habe aber auch schon "Semikolon"; etc. gesehen)

  1. Beiden CSV-Listen einlesen
  2. Die eine Liste in ein Dictionary packen mit Schlüsselwort von Liste...dabei dürfen diese nicht mehrmals enthalten sein
  3. Durch die Liste Iterieren und mit dem Dictionary vergleichen -> 3. Liste erstellen
  4. Ausgeben, wieder als CSV Serialisieren

Gruss Lhyn

5.657 Beiträge seit 2006
vor 5 Jahren

Leider kann das Dic. nie zwei gleiche Werte aufnehmen, wovon ich wohl einige in der Datenmenge habe.

Verstehe ich nicht. Laut deinen Anforderungen mußt du nicht wissen, wie oft ein Wert vorkommt, sondern nur, ob er vorkommt.

Wenn das aber so ist, kannst du die Anzahl der Vorkommen als Wert des Dictionarys speichern.

Weeks of programming can save you hours of planning