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
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.
Danke dir,
aber leider bin ich nicht so ein erfahrener C# Skripter und brauche etwas Hilfe.
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
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
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.
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
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
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
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.
Bitte keine Full-Quotes [Hinweis] Wie poste ich richtig?
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
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
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.
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
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
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.
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
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)
Gruss Lhyn
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