| |
VB.NET - Ein- und UmsteigerTabelle Spalteninhalt vergleichen | | | Autor: Vegas85 | Datum: 06.10.15 23:00 |
| Hallo
Habe ein kleines Problem wobei ich nicht weiter komme.
Ich vergleiche zwei Spalten miteinander die schreibweise ist die gleiche soweit funzt mein Code sehr gut.
Nun möchte ich aber die Spalten so vergleichen das nur die Nummern in der Spalte verglichen werden.
z.b
SP_2
hallo 123456
blabla 180546
SP_13
test 123456
lalalalala 180546
Der Text davor soll irgnoiert werden und nur die Zahlen dahinter verglichen werden.
Momentan habe ich folgenden Code, Danke noch an User Manfred X
'Datarelation
Dim dr As New DataRelation("Artikel", ds.Tables(0).Columns("SP_2"), _
ds.Tables(1).Columns("SP_13"), False)
ds.Relations.Add(dr)
'Spalten in Ausgabedatei erstellen
dtout = New cDataTableCSV
dtout.Columns.Add("SP_0") : dtout.Columns.Add("SP_1")
dtout.Columns.Add("SP_2")
dtout.Rows.Add({"Action", "ItemID", "EndCode"})
Try
'Schleife über csv1-Zeilen (=Parent)
For Each prow As DataRow In ds.Tables(0).Rows
'Suchkriterium in csv1
If DirectCast(prow("SP_10"), String) = "out of stock" Then
'per Relation zugeordnete Childrow in csv2
For Each crow As DataRow In prow.GetChildRows(dr)
'Ausgabedatensatz aufbauen
Dim orow As DataRow = dtout.NewRow
orow("SP_0") = "End"
orow("SP_1") = crow("SP_0")
orow("SP_2") = "NotAvailable"
dtout.Rows.Add(orow)
Next crow
End If
Next prow | |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Manfred X | Datum: 07.10.15 06:31 |
| Hallo!
Damit das Thema für die Mitlesenden verständlich wird,
zunächst der Link auf den Beispielcode, der der Anfrage zugrunde liegt.
Zum Lesen des Inhalts der CSV-Dateien wird dabei die Klasse cDataTableCSV verwendet.
Wenn eine Datarelation verwendet werden soll, die sich auf Teil-Strings innerhalb
eines Spalten-Inhalts bezieht, ist eine neue Spalte in der Tabelle zu erstellen,
in die dieser Teil-String zeilenweise eingetragen wird.
Die Klasse "cDataTableCSV" enthält die Methode "AddColumn", die eine zusätzliche
leere Spalte in der Tabelle anfügt.
In Deinem Fall könnte eine Routine deshalb etwa so aussehen:
(Zeilen mit nicht-numerischem Teilstring am Content-Ende werden mit dem
Sonderwert DBNull belegt und beim autom. Aufbau der Relation deshalb ignoriert!)
Private Function CreateNumberColumn(ByVal dt As cDataTableCSV, _
ByVal ColumnEndswithNumber As String) As String
Dim ColumnWithNumber As String = ""
If Not dt.Columns.Contains(ColumnEndswithNumber) Then
Throw New ArgumentException _
("Die Spalte " & ColumnEndswithNumber & _
" ist nicht in der Tabelle vorhanden")
End If
dt.AddColumn() 'Spalte in Tabelle anfügen
'Name der neuen Spalte abfragen
ColumnWithNumber = dt.Columns(dt.Columns.Count - 1).ColumnName
'Hilfsvariable
Dim field As String, parts() As String, numberpart As String
Dim number As Integer
For Each row As DataRow In dt.Rows
field = row(ColumnEndswithNumber).ToString() 'Feldinhalt abfragen
parts = field.Split(" "c) 'Feldinhalt am Trennzeichen aufspalten
numberpart = parts(parts.Length - 1) 'Letzter Abschnitt (=Nummer)
'Prüfen, ob der letzte Teilstring als Integer darstellbar ist
If Integer.TryParse(numberpart, number) Then
'Nummer in der neuen Spalte als Zeichenfolge eintragen
row(ColumnWithNumber) = number.ToString
Else
'keine Ziffernfolge im letzten Teilstring !!!
row(ColumnWithNumber) = DBNull.Value
End If
Next row
'Name der neuen Spalte zurückgeben
Return ColumnWithNumber
End Function Anwendung der Routine (Spalten-Bezeichner sind anzupassen).
(Der Typ der Tabellen im Dataset muß beim Methodenaufruf gecastet (DirectCast)
werden, weil das Dataset Instanzen der Datatable-Klasse enthält, die Methode
aber als Parameter Instanzen der davon abgeleiteten Klasse "cDataTableCSV"
benötigt.)
'Die beiden CSV-Dateien laden
ds.Tables.Add(LoadCSV("C:\daten\csv1.csv"))
ds.Tables.Add(LoadCSV("C:\daten\csv2.csv"))
If Not ds.Tables.Count = 2 Then
MessageBox.Show("Eine Datei konnte nicht gelesen werden")
Exit Sub
End If
'Neue Spalten erstellen und Zeilen mit dem Teilstring (=Nummer) füllen
Dim columnwithnumber1 As String = _
CreateNumberColumn(DirectCast(ds.Tables(0), cDataTableCSV), "SP_13")
Dim columnwithnumber2 As String = _
CreateNumberColumn(DirectCast(ds.Tables(1), cDataTableCSV), "SP_2")
'Datarelation für die neuen Spalten anpassen
Dim dr As New DataRelation _
("Artikel", ds.Tables(0).Columns(columnwithnumber1), _
ds.Tables(1).Columns(columnwithnumber2))
ds.Relations.Add(dr) Du mußt diese Abläufe noch einmal sorgfältig durchdenken.
Eine "Datarelation" bezieht sich stets auf die Korrespondenz des gesamten Inhalts
der angegebenen Spalten-Paarung. Die "Datarelation" und die zugrundeliegenden
Daten müssen deshalb angepaßt werden, nicht der Code zum Erstellen der Zeilen
in der Datatable, die für die Ausgabe der kombinierten Daten gefüllt wird !!
(In der Praxis beziehen sich DataRelations auf Spalten, die Schlüssel-Werte
enthalten).
| |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Vegas85 | Datum: 07.10.15 08:53 |
| Danke schön
Hatte im ersten moment nicht so ganz funktioniert hatte wieder dieses False mit rein nehmen müssen.
Habe nun auch CSV1 angepasst in der CSV1 habe ich jetzt nur noch die Nummern in der Spalte2 und in der CSV2 steht es jetzt so in der Spalte13 z.b Faller Stadtmetzgerei Dold Spur H0 - Art.Nr. 130451
So funzt er prima.
Habe mich die Tage da etwas durchgeschlagen damit aber ich merke nun da war ich total auf dem Holzweg
Beitrag wurde zuletzt am 07.10.15 um 08:55:53 editiert. | |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Manfred X | Datum: 07.10.15 09:34 |
| Wenn die Datarelation den CreateConstraint-Parameter als "false" benötigt,
bedeutet das gewöhnlich ....
- in der Schlüsselspalte der zweiten Datei sind Nummern enthalten, die
es in der Schlüsselspalte der ersten Datei nicht gibt
(=Liste der Stammdaten in der ersten Datei ist unvollständig oder Datenfehler)
und/oder
- in der Schlüsselspalte der ersten Datei kommen Nummern mehrfach vor
(=keine eindeutige Zuordnung der Tabellenzeilen möglich)
| |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Sony85 | Datum: 07.10.15 10:13 |
| Wenn ich das False weg lasse bekomme ich bei ds.Relations.Add(dr) eine fehlermeldung.
Vermute mal das es an dem liegt:
- in der Schlüsselspalte der zweiten Datei sind Nummern enthalten, die
es in der Schlüsselspalte der ersten Datei nicht gibt
(=Liste der Stammdaten in der ersten Datei ist unvollständig oder Datenfehler)
Denn in der CSV2 sind Daten vorhanden die etwas anders geschrieben sind.
z.b Hallo 123456 Welt
Die werden wohl dann nicht erkannt und deswegen diese fehlermeldung ?
Beitrag wurde zuletzt am 07.10.15 um 10:16:10 editiert. | |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Manfred X | Datum: 07.10.15 10:37 |
| Hallo
Die Fehlermeldung beim Erstellen (=Einfügen in Dataset / Add) der DataRelation
sollte näheren Aufschluß geben.
Die Routine die ich vorgeschlagen habe, verwendet den letzten (numerischen) Abschnitt
in der Blanc-separierten Zeichenfolge für die Ermittlung der Schlüsselnummer.
An welcher Position beim Inhalt Deiner CSV-Spalte der geeignete Schlüsselabschnitt steht,
kann ich nicht beurteilen.
Ist es STETS der zweite Abschnitt, kannst Du den Array-Index 1 (statt Length-1) von Parts
benutzen.
Besitzen die Zeichenfolgen in der Spalte keinen "homogenen" Aufbau (=uneinheitlich), mußt Du
eventuell die gesamte Zeichenfolge in einer Schleife durchlaufen und gezielt nach den numerischen Werten (=Ziffernfolge) suchen (z.B. IsDigit-Methode der Char-Struktur - Forensuchmaschine).
| |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Sony85 | Datum: 07.10.15 11:16 |
| Wenn ich z.b Faller Stadtmetzgerei Dold Spur H0 - Art.Nr. 130451 es so habe dann funzt es sehr gut.
Aber es ist eigentlich alles uneinheitlich. | |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Manfred X | Datum: 07.10.15 12:02 |
| Völlig uneinheitliche Spalteninhalte erfordern Handarbeit.
Hier eine Routine, die die erste Ziffernfolge ermittelt und zurückgibt, die in
einer Zeichenfolge zu finden ist.
Dabei kann (optional) der null-basierte Startindex der Suche und die Länge des zu
durchsuchenden Abschnitts der Zeichenfolge angegeben werden.
Läßt sich dort keine Ziffer(nfolge) finden, wird ein leerer String zurückgegeben.
Private Function FindFirstNumber(ByVal text As String, _
Optional ByVal startindex As Integer = 0, _
Optional ByVal length As Integer = -1, _
Optional ByRef positionbehind As Integer = -1) As String
positionbehind = -1
If String.IsNullOrEmpty(text) Then Return ""
If startindex < 0 Or startindex >= text.Length Then Return ""
Dim lastindex As Integer
If length < 0 Then
lastindex = text.Length - 1
Else
lastindex = Math.Min(text.Length - 1, startindex + length - 1)
End If
Dim num As New System.Text.StringBuilder
For i As Integer = startindex To lastindex
If Char.IsDigit(text(i)) Then
num.Append(text(i))
ElseIf num.Length > 0 Then
If i < text.Length - 1 Then positionbehind = i
Exit For
End If
Next i
Return num.ToString
End Function Dieser Routine kann man den Inhalt der Variable "Field" (siehe oben) übergeben.
numberpart = FindFirstNumber(field)
Wenn allerdings mehrere Ziffernabschnitte (z.B. H0) vorkommen,
muß man den letzten Parameter auswerten (Rückgabe) und ab dieser
Position erneut suchen (StartIndex).
Beispiel:
Dim field As String = "asasdasd H0 weqwewqe 345 asdsd"
Dim startindex As Integer = 0, positionbehind As Integer = -1
Dim numberpart As String
Do
numberpart = FindFirstNumber(field, startindex, , positionbehind)
startindex = positionbehind
Loop While startindex > 0 And numberpart = "0" | |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Vegas85 | Datum: 07.10.15 22:44 |
| Hallo
Klappt soweit sehr gut.
Nur werden mir nun Daten angezeigt die nicht in der CSV1 vorkommen sondern nur in CSV2
Könnte das an den Ziffernabschnitten liegen ?
Hier mal ein kleiner auszug:
"Märklin 1.FC Märklin Jahreswagen 2011. Spur H0 - Art.Nr. 48611"
"Märklin Nahverkehrswagen-Set ""Silberlinge"". Spur 1 - Art.Nr. 58343"
"Fleischmann Schnellzugwagen 1./2. Klasse Spur N - Art.Nr. 8079"
"Märklin 2 x Diesellokomotive. MaK Typ DE 1002, HGK Spur H0 - Art.Nr. 37630"
"Roco 2-teiliges Set Reisezugwagen der CP Spur H0 - Art.Nr. 64036"
"Roco Schlafwagen T2S der DB Spur H0 - Art.Nr. 64751"
"Herpa Bauwagen 2-achs ""Max Wild"" - Art.Nr. 076357"
"Herpa VW UP! 2-türig ""Johanniter Rheinhessen"" - Art.Nr. 090438"
"Märklin 2er-Set Spundwandwagen Gbs 256 der DB gealtert Spur H0 - Art.Nr. 47312"
"Roco D-Zugwagen 2.Klasse DB Spur H0 - Art.Nr. 44740"
"Pola 2 Jaeger Spur G - Art.Nr. 331953"
"Fleischmann Mittelwagen, 2.Klasse der D AG Spur N - Art.Nr. 7463"
"Fleischmann ICE 2 Wagen 2. Klasse Spur N - Art.Nr. 7494"
"Märklin 2206 Gleis ger. 168,9 mm"
"Faller 180500 Straßen- und Geländebau-Spach"
"Faller 180538 Straßenlampen-Set"
"Faller 180575 Grillplatz"
"Faller 180577 Abenteuerspielplatz"
"Faller 180589 Holz-Sortiment" Habe mir das auch nochmal etwas genau angeschaut und dabei festgestellt das die Zahl die verglichen werden sollen
Meistens ganz am Ende wie z.b "Roco D-Zugwagen 2.Klasse DB Spur H0 - Art.Nr. 44740"
oder an zweiter stelle z.b "Faller 180575 Grillplatz" vorkommen. | |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Manfred X | Datum: 08.10.15 06:24 |
| Hallo
Wie schon mehrfach (!) erläutert:
Du mußt zunächst eine eindeutige Datensatz-Zuordnung anhand der Schlüsselspalten einrichten:
1. Sind alle Artikelnummern in den Stammdaten (csv1) eindeutig - auch bezüglich verschiedener Marken?
Eventuell müssen geeignete Anpassungen der Nummern in der Schlüsselspalte vorgenommen werden
2. Falls es Einträge in der "csv2" gibt, zu denen in den Stammdaten keine Entsprechung vorhanden ist,
muß für diese Datenzeilen eine der folgenden Optionen realisiert werden:
---- Ergänzen der Stammdaten zu diesen Artikel(nummer)n
---- Einführen einer Zeile "unbekannte Stammdaten" in csv1 mit Missing-Artikelnummer (z.B. 000000)
und Eintragung dieser Artikelnummer in der Schlüsselspalte von csv2 bei den entsprechenden Datensätzen
---- Verwalten dieser Datensätze in einer separaten Datei / Tabelle; Entfernen der Sätze aus csv2
Im Code der Routine zur Ermittlung der Artikelnummern innerhalb des Feldes
könnten "markenspezifische" Differenzierungen vorgenommen werden,
z.B. irgend so etwas ....
'bei Faller den zweiten Abschnitt als Art.Nr. verwenden
If field.startswith("Faller") then
numberpart = parts(1)
ElseIf row.Startswith(" .....")
............
End If Bei der Marke "Märklin" ist der Datensatz-Aufbau offenbar nicht einheitlich.
("Märklin 2206 Gleis ger. 168,9 mm")
Steht immer eine gültige Artikelnummer in diesen Datensätzen?
Vermutlich sind in manchen Fällen geeignete Ergänzungen erforderlich.
| |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Vegas85 | Datum: 08.10.15 08:35 |
| 1. Sind alle Artikelnummern in den Stammdaten (csv1) eindeutig - auch bezüglich verschiedener Marken?
Eventuell müssen geeignete Anpassungen der Nummern in der Schlüsselspalte vorgenommen werden
Ja denn bei jeder Marke sind die Artikelnummern anders aufgebaut und sind auch nicht Doppelt verhanden.
Faller sind immer 6 Stellig
Märklin 4-5 Stellig
Fleischmann 4 oder 6 Stellig
Roco 5 Stellig usw.
("Märklin 2206 Gleis ger. 168,9 mm")
Steht immer eine gültige Artikelnummer in diesen Datensätzen?
Ja in dem Fall ist das die 2206
Die Artikelnummern stehen immer direkt hinter dem Markenamen oder am ende nach Art.Nr. | |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Manfred X | Datum: 08.10.15 09:00 |
| Wenn diese beiden Bedingungen allgemein gelten, ist die
Ermittlung der Artikelnummer ziemlich einfach:
If Field.contains("Art.Nr.") then
numberpart = parts(parts.length-1) 'hinter Art.Nr. am Ende
Else
numberpart = parts(1) 'hinter Markennamen, der am Anfang steht
End If | |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Vegas85 | Datum: 08.10.15 09:20 |
| Fehler bei numberpart = parts(1)
Ein Ausnahmefehler des Typs "System.IndexOutOfRangeException" ist in CSV.exe aufgetreten.
Zusätzliche Informationen: Der Index war außerhalb des Arraybereichs. | |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Manfred X | Datum: 08.10.15 09:39 |
| Ich kenne natürlich Deinen Code nicht.
Diese Ausnahme würde z.B. bedeuten, daß sich die aktuelle Zeile nicht
in mehrere space-separierte Abschnitte einteilen läßt (per Field.split).
Eventuell enthält die Datei eine Leerzeile.
Das kannst Du durch die parts.length-Eigenschaft prüfen.
| |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Vegas85 | Datum: 08.10.15 10:35 |
| Habe es im moment so:
'Artikel löschen Teil ##################################################
'CSV1 Öffnen ##############################################################
Private Sub csv1_Click(sender As Object, e As EventArgs) Handles csv1.Click
Dim file_open_google As New OpenFileDialog
file_open_google.Filter = "csv-dateien|*.csv"
file_open_google.AddExtension = True
ds.Reset()
If file_open_google.ShowDialog = DialogResult.OK Then
ds.Tables.Add(LoadCSV(file_open_google.FileName))
End If
End Sub
Private Function CreateNumberColumn(ByVal dt As cDataTableCSV,
ByVal ColumnEndswithNumber As String) As String
Dim ColumnWithNumber As String = ""
If Not dt.Columns.Contains(ColumnEndswithNumber) Then
Throw New ArgumentException("Die Spalte " & ColumnEndswithNumber & _
" ist nicht in der Tabelle vorhanden")
End If
dt.AddColumn() 'Spalte in Tabelle anfügen
'Name der neuen Spalte abfragen
ColumnWithNumber = dt.Columns(dt.Columns.Count - 1).ColumnName
'Hilfsvariable
Dim field As String, parts() As String, numberpart As String
Dim number As Integer
For Each row As DataRow In dt.Rows
field = row(ColumnEndswithNumber).ToString() 'Feldinhalt abfragen
parts = field.Split(" "c) 'Feldinhalt am Trennzeichen aufspalten
'numberpart = parts(parts.Length - 1) 'Letzter Abschnitt (=Nummer)
'numberpart = FindFirstNumber(field)
If field.Contains("Art.Nr.") Then
numberpart = parts(parts.Length - 1) 'hinter Art.Nr. am Ende
Else
numberpart = parts(1) 'hinter Markennamen, der am Anfang steht
End If
'Prüfen, ob der letzte Teilstring als Integer darstellbar ist
If Integer.TryParse(numberpart, number) Then
'Nummer in der neuen Spalte als Zeichenfolge eintragen
row(ColumnWithNumber) = number.ToString
Else
'keine Ziffernfolge im letzten Teilstring !!!
row(ColumnWithNumber) = DBNull.Value
End If
Next row
'Name der neuen Spalte zurückgeben
Return ColumnWithNumber
End Function
Private Function FindFirstNumber(ByVal text As String,
Optional ByVal startindex As Integer = 0,
Optional ByVal length As Integer = -1,
Optional ByRef positionbehind As Integer = -1) As String
positionbehind = -1
If String.IsNullOrEmpty(text) Then Return ""
If startindex < 0 Or startindex >= text.Length Then Return ""
Dim lastindex As Integer
If length < 0 Then
lastindex = text.Length - 1
Else
lastindex = Math.Min(text.Length - 1, startindex + length - 1)
End If
Dim num As New System.Text.StringBuilder
For i As Integer = startindex To lastindex
If Char.IsDigit(text(i)) Then
num.Append(text(i))
ElseIf num.Length > 0 Then
If i < text.Length - 1 Then positionbehind = i
Exit For
End If
Next i
Return num.ToString
End Function | |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Vegas85 | Datum: 08.10.15 10:36 |
| 'CSV2 Öffnen ##############################################################
Private Sub csv2_Click(sender As Object, e As EventArgs) Handles csv2.Click
Dim file_open_ebay As New OpenFileDialog
file_open_ebay.Filter = "csv-dateien|*.csv"
file_open_ebay.AddExtension = True
If file_open_ebay.ShowDialog = DialogResult.OK Then
'CSV-Files lesen
ds.Tables.Add(LoadCSV(file_open_ebay.FileName))
If Not ds.Tables.Count = 2 Then
MessageBox.Show("Eine Datei konnte nicht gelesen werden")
Exit Sub
End If
'Datarelation
'Dim dr As New DataRelation("Artikel", ds.Tables(0).Columns(
' "SP_2"), ds.Tables(1).Columns("SP_13"), False)
Dim field As String = "asasdasd H0 weqwewqe 345"
'bei Faller den zweiten Abschnitt als Art.Nr. verwenden
Dim startindex As Integer = 0, positionbehind As Integer = -1
Dim numberpart As String
Do
numberpart = FindFirstNumber(field, startindex, , _
positionbehind)
startindex = positionbehind
Loop While startindex > 0 And numberpart = "0"
'Neue Spalten erstellen und Zeilen mit dem Teilstring (=Nummer)
' füllen
Dim columnwithnumber1 As String = CreateNumberColumn(DirectCast( _
ds.Tables(0), cDataTableCSV), "SP_2")
Dim columnwithnumber2 As String = CreateNumberColumn(DirectCast( _
ds.Tables(1), cDataTableCSV), "SP_13")
'Datarelation
Dim dr As New DataRelation("Artikel", ds.Tables(0).Columns( _
columnwithnumber1), ds.Tables(1).Columns(columnwithnumber2), _
False)
ds.Relations.Add(dr)
'Spalten in Ausgabedatei erstellen
dtout = New cDataTableCSV
dtout.Columns.Add("SP_0") : dtout.Columns.Add("SP_1")
dtout.Columns.Add("SP_2") : dtout.Columns.Add("SP_3")
dtout.Columns.Add("SP_4")
dtout.Rows.Add({"Action", "ItemID", "EndCode"})
Try
'Schleife über csv1-Zeilen (=Parent)
For Each prow As DataRow In ds.Tables(0).Rows
'Suchkriterium in csv1 nur Artikel die als Stückzahl 0
' haben.
If DirectCast(prow("SP_4"), String) = "0" Then
'per Relation zugeordnete Childrow in csv2
For Each crow As DataRow In prow.GetChildRows(dr)
'Ausgabedatensatz aufbauen
Dim orow As DataRow = dtout.NewRow
orow("SP_0") = "End"
orow("SP_1") = crow("SP_0")
orow("SP_2") = "NotAvailable"
orow("SP_3") = crow("SP_13") 'Titel
orow("SP_4") = prow("SP_4") 'Anzahl der Artikel
dtout.Rows.Add(orow)
Next crow
End If
Next prow
Catch ex As Exception
MessageBox.Show("Abbruch - Fehler: " & ex.Message)
Exit Sub
End Try
DataGridView3.DataSource = dtout
DataGridView3.Columns(0).Width = 383
DataGridView3.Columns(1).Width = 383
DataGridView3.Columns(2).Width = 383
DataGridView3.Columns(3).Width = 383
DataGridView3.Columns(4).Width = 383
End If
End Sub
'Speichern Funktion
' ##############################################################
Private Sub csv_safe_Click(sender As Object, e As EventArgs) Handles _
csv_safe.Click
ProgressBar2.Value = 0
Label10.Text = "0 %"
SaveFileDialog2.Filter = "Artikel (*.csv)|*.csv"
If SaveFileDialog2.ShowDialog() = DialogResult.OK Then
Timer3.Start()
End If
End Sub
Private Sub Timer3_Tick(sender As Object, e As EventArgs) Handles _
Timer3.Tick
ProgressBar2.Increment(1)
If ProgressBar2.Value = 100 Then
Timer3.Stop()
If Not dtout.SaveFile(SaveFileDialog2.FileName, ";"c) Then
MessageBox.Show("Fehler beim Schreiben der Datei")
Else
MessageBox.Show _
(dtout.Rows.Count.ToString & " Artikel sind zu löschen")
End If
Else
ProgressBar2.Value = ProgressBar2.Value + 1
End If
Label10.Text = ProgressBar2.Value & (" %")
End Sub Hier noch ein Bild von der Form:
Da ist bestimmt einiges noch zu verbessern | |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Manfred X | Datum: 08.10.15 11:37 |
| Nanu.
Was macht der Demo-Code, den ich Sony85 vorgeschlagen habe,
im vegas85-Code? An dieser sinnfreien Stelle.
Inwiefern ist es ein Problem, im Falle einer Ausnahme den Debugger
einzusetzen, und den Inhalt der Variablen Line, Field oder Parts zu untersuchen.
In einer Datei, deren Inhalt offenbar "bunt zusammengewürfelt" worden ist,
könnten statt dem Space-Zeichen auch irgendwelche Whitespace-Zeichen stehen,
z.B. Tabulator. Das würde die Split-Methode - in der programmierten Variante -
nicht erkennen.
Jede verwertbare Zeile benötigt in der Spalte, die die Artikelnummer enthält,
mindestens 3-4 space-separierte Teilabschnitte (Hersteller, Artikelnummer, weitere Angaben).
Es wäre vermutlich recht zweckmäßig, nach dem Erstellen des Parts-Array, eine einfache
zusätzliche Kontroll-Bedingung in den Code einzufügen:
If Parts.Length >= 3 Then
'Numparts extrahieren
'Spalte füllen
Else
'Meldung und die ungeeignete Datei-Zeile protokollieren oder
'oder sie als Messagebox zeigen
End If Welche Funktion diese Progressbar hat, .... ????
| |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Vegas85 | Datum: 08.10.15 17:01 |
| Weiß ich auch grade nicht so genau denn Sony85 ist ein alter Nickname von mir.
Wusste garnicht das ich mit dem Namen eingeloggt war. Komisch.
Sinnfreie Stelle ? kommt das da nicht hin ?
Prograssbar hat keine wirkliche funktion, die hab ich mit eingebaut damit es schöner aussieht beim speichern | |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Vegas85 | Datum: 09.10.15 08:43 |
| So habe es nun am laufen.
Habe zwar etwas gebraucht die Nacht über aber bin nun dahinter gekommen und es läuft so wie ich es haben wollte.
Dann noch eine bitte an einen Moderator falls einer mit liest. Ich bitte drum den User Sony85 zu löschen damit da keine missverständnissen mehr entstehen.
Warum ich aufeinmal mit diesem Acconut hier geschrieben hatte weiß ich nicht. Vermute mal das ich da am Pc noch eingeloggt war weil sonst schreibe ich vom Lappi aus nur in diesem moment war ich am PC. Wüsste auch nicht das ich überhaupt noch diesen Acconut habe.
Naja okay Manfred X ich danke dir für die Hilfe ohne dich hätte ich das nicht so schnell geschaft.
Habe nun fast mein kleines Programm fertig.
Mir würde nur noch eine sache fehlen.
Folgendes:
orow("SP_00") = row("SP_8") 'Wertangabe in Spalte 8 z.b 85,69
orow("SP_01") = "1,0" Wenn in SP_8 nun der Wert kleiner als 70 ist sollten alle Zeilen wo dies vor kommt nicht "1,0" bekomme sondern "0,0"
könnte z.b so aussehen.
SP_00 SP_01
569,25 1,0
254 1,0
58 0,0
698,27 1,0
33,33 0,0
70 1,0 Wäre sowas überhaupt möglich ?
Diese kleine Baustelle fehlt mir noch und wenn ich dies habe wäre ich fertig | |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Manfred X | Datum: 09.10.15 09:36 |
| Hallo!
'1.Schritt: den Wert in der Zelle als String lesen
Dim val As String = row("SP_8").ToString
'2.Schritt: eine Dezimalzahl-Variable erstellen
Dim dec As Decimal
'3.Schritt: Versuch, den String in die Dezimalvariable als Zahl einzutragen
If Decimal.TryParse(val, dec) Then
'4. Schritt: Bedingung prüfen = Ausprägung der Dezimalzahl
If dec => 70 Then
orow("SP_01") = "1,0" 'Zuweisung des gew. Wertes als String
Else
orow("SP_01") = "0,0"
End If
Else
'Bedingung: Der Zellinhalt ist nicht numerisch
orow("SP_1") = "" 'Leerstring oder Missing-Kennung zuweisen
End If Dieser Code setzt voraus, daß das Dezimalkomma in der Datei der aktuellen
Culture-Einstellung entspricht.
Eventuell kann man als Schritt noch einfügen 1a.) val = val.Replace("."c, ",")
Beitrag wurde zuletzt am 09.10.15 um 09:44:42 editiert. | |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Vegas85 | Datum: 09.10.15 18:55 |
| Danke klappt super.
Eine Frage noch bei dem Vergleich von Letzter Abschnitt (=Nummer) kann man das noch zusätzlich am Anfang machen mit der Marke?
Habe gesehen das es manche Artikelnummer doch doppelt gibt. Aber bei unterschiedlichen Marken.
Also einfach nur noch zusätzlich das erste Wort vergleichen | |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Vegas85 | Datum: 09.10.15 23:37 |
| Habe eine Lösung gefunden für das Problem, zwar nicht so elegant aber es läuft.
Ich mache es nun über eine textbox da trage ich den Markenname ein.
Die CSV1 ist auch nur mit der Marke gefüllt die ich zuvor in die textbox eingetragen habe.
Wenn ich keine Marke eintrage in die Textbox werden mir die Artikel anderen Marken angezeigt weil sie die gleiche Artikelnummer haben, obwohl sie nicht in der CSV1 vorkommen.
Das sollte ja eigentlich nicht sein.
Normal müsste dann aus CSV1 "SP_0" = Marke und "SP_1" = Nummer mit der "SP_13" aus CSV2 vergleichen werden. In "SP_13" steht ja "Marke lalalalala - Art.Nr. Nummer"
Okay ich danke dir sehr Manfred X für die echt tolle hilfe, hätte ich nie hinbekommen.
Habe ja nun mein Projekt soweit fertig bekommen.
Bis zu meinem nächsten Projekt heißt es aber erst mal für mich weiter die Bücher studieren | |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Vegas85 | Datum: 15.10.15 00:15 |
| Hallo,
Ich habe nun die letzten Tagen versucht es alleine raus zufinden.
Leider komme ich nicht darauf, könntest du mir noch einmal dabei helfen Manfred X ?
Möchte gerne zu der Nummer am Ende noch am Anfang die Marke vergleichen.
Momentan mache ich es so
If field.Contains(textbox1.text)
Then numberpart = parts(parts.Length - 1) 'hinter Art.Nr. am Ende
Else
numberpart = parts(0) 'Markennamen, der am Anfang steht
End If Wenn ich nun in die textbox die Marke eintrage dann wird auch nur die eingetragene Marke verglichen, das funktioniert soweit sehr gut.
Ist nur sehr umständlich wenn ich das bei 15 verschiedenen Marken machen muss.
Muss jedes mal dann von vorne beginnen.
Deswegen wäre es gut wenn ich es nur einmal machen müsste und die Marken automatisch zu den Nummern am Ende mit verglichen werden.
Lg
Vegas85 | |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Manfred X | Datum: 15.10.15 06:28 |
| Hallo!
Falls ich das richtig verstanden habe,
benötigst Du (für Eindeutigkeit) Werte in der ergänzten
Schlüsselspalte, die aus zwei Teilen zusamengesetzt sind:
Markenname-Artikelnummer
Der Markenname steht im ersten Abschnitt des Split-Array: parts(0)
Die Artikelnummer entweder im zweiten Abschnitt = parts(1) oder am
Ende = parts(parts.length-1)
Also etwa so:
row(columnwithnumber) = parts(0) & "-" & parts(1)
| |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Vegas85 | Datum: 15.10.15 08:33 |
| Danke
Leider funktioniert es so nicht.
In CSV2 bei "SP_13" steht ja "Markenname lalalalala - Art.Nr. Nummer"
Somit müsst aus CSV1 "SP_0" = Markenname und "SP_1" = Nummer mit der "SP_13" aus CSV2 vergleichen werden.
Das die Artikelnummer entweder im zweiten Abschnitt = parts(1)vorkommt habe ich nicht mehr.
Sie kommt nur noch am Ende vor. | |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Manfred X | Datum: 15.10.15 08:41 |
| Das sind wird doch alles längst durchgegangen !!!!!
Du mußt den Inhalt von SP_13 in Teile splitten split(" "c)
und dann die benötigten Teile (Markenname in parts(0),
Nummer in parts(parts.length-1) zu einem Schlüssel zusammenfügen
- siehe oben - und diesen Wert in die neue Schlüsselspalte der
Tabelle eintragen.
| |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Vegas85 | Datum: 15.10.15 22:07 |
| Das habe ich soweit verstanden das der Inhalt von SP_13 gesplitet wird.
Mit welchen Daten wird dann Markenname in parts(0) verglichen ?
Denn verglichen wird ja csv1 = SP_02 und csv2 = SP_13
Aber in csv1 = SP_02 stehen ja nur die Nummern und in SP_00 stehen die Marken.
Markenname in parts(0) müsste doch dann somit mit der csv1 = SP_00 verglichen werden.
Denn wenn ich zwar Markenname in parts(0) aus der SP_13 nehme woher nimmt er dann den vergleich das der Markename zur Nummer gehört ?
Oder versteh ich das nun komplett falsch ?
| |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Manfred X | Datum: 16.10.15 06:31 |
| Du verstehst leider nicht, worum es geht.
Lies noch mal diesen Beitrag:
http://www.vbarchiv.net/forum/id22_i98539t98538_tabelle-spalteninhalt-vergleichen.html
Der Inhalt der beiden csv-Dateien wird in Tabellen (Datatables) geladen.
Damit die Datensätze in diesen beiden TABELLEN aufeinander bezogen werden können,
wird jeweils eine ZUSÄTZLICHE Schlüsselspalte NEU erstellt.
Das erledigt die Routine "CreateNumberColumn".
Dieser Routine wird der Name einer Tabellenspalte übergeben, deren
Inhalt zu splitten ist und aus dem der Schlüsselwert erzeugt wird.
In dem obigen Beispiel wird nur die Artikelnummer als Schlüssel verwendet.
(In der Datarelation werden also NICHT die Spalten SP_13 und SP_2 verglichen.)
Danach hast Du festgestellt, daß aus der Artikelnummer kein eindeutiger Schlüssel
ensteht, sondern daß eine Kombination aus Markennname und Artikelnummer benötigt wird.
Soweit ich verstanden habe, steht in beiden Tabellen in der jeweils für den
Schlüsselaufbau relevanten Spalte (SP_2 bzw. SP_13) der Markenname am Anfang
und landet deshalb beim Splitten in parts(0).
Also muß die Routine irgendwie so angepaßt werden - im Detail abhängig vom aktuellen
Aufbau der Datensätze in den csv-Dateien ....
Private Function CreateNumberColumn(ByVal dt As cDataTableCSV, _
ByVal ColumnEndswithNumber As String) As String
Dim ColumnWithNumber As String = ""
If Not dt.Columns.Contains(ColumnEndswithNumber) Then
Throw New ArgumentException _
("Die Spalte " & ColumnEndswithNumber & _
" ist nicht in der Tabelle vorhanden")
End If
dt.AddColumn() 'Spalte in Tabelle anfügen
'Name der neuen Spalte abfragen
ColumnWithNumber = dt.Columns(dt.Columns.Count - 1).ColumnName
'Hilfsvariable
Dim field As String, parts() As String, numberpart As String
Dim number As Integer
For Each row As DataRow In dt.Rows
field = row(ColumnEndswithNumber).ToString() 'Feldinhalt abfragen
parts = field.Split(" "c) 'Feldinhalt am Trennzeichen aufspalten
'Annahme: Artikelnummer steht im letzten Abschnitt
numberpart = parts(parts.Length - 1) 'Letzter Abschnitt (=Nummer)
'Prüfen, ob der letzte Teilstring als Integer darstellbar ist
If Integer.TryParse(numberpart, number) Then
'Annahme: Markenname steht im ersten Abschnitt
'Markenname_ArtikelNummer in der neuen Spalte eintragen
row(ColumnWithNumber) = parts(0) & "_" & number.ToString
Else
'keine Ziffernfolge im letzten Teilstring !!!
row(ColumnWithNumber) = DBNull.Value
End If
Next row
'Name der neuen Spalte zurückgeben
Return ColumnWithNumber
End Function So lange Du nur den Code kopierst ohne dessen Bedeutung zu verstehen,
kannst Du die eventuell erforderlichen Detailanpassungen nicht vornehmen.
| |
Re: Tabelle Spalteninhalt vergleichen | | | Autor: Vegas85 | Datum: 21.09.16 21:15 |
| Hallo Manfred X,
Zuerst mal vielen Dank nochmal für die super Hilfe die du leistest.
Ich hätte da noch eine Frage zu dem Code wo du mir mal gegeben hast.
Ich nutzte im Moment diesen Code:
Private Function CreateNumberColumn(ByVal dt As cDataTableCSV, ByVal _
ColumnEndswithNumber As String) As String
Dim ColumnWithNumber As String = ""
If Not dt.Columns.Contains(ColumnEndswithNumber) Then
Throw New ArgumentException("Die Spalte " & ColumnEndswithNumber & _
" ist nicht in der Tabelle vorhanden")
End If
dt.AddColumn()
dt.AddColumn()
dt.AddColumn() 'Spalte in Tabelle anfügen
'Name der neuen Spalte abfragen
ColumnWithNumber = dt.Columns(dt.Columns.Count - 1).ColumnName
'Hilfsvariable
Dim field As String, parts() As String, numberpart As String
Dim number As Integer
For Each row As DataRow In dt.Rows
field = row(ColumnEndswithNumber).ToString() 'Feldinhalt abfragen
parts = field.Split(" "c) 'Feldinhalt am Trennzeichen aufspalten
'Annahme: Artikelnummer steht im letzten Abschnitt
numberpart = parts(parts.Length - 1) 'Letzter Abschnitt (=Nummer)
'Prüfen, ob der letzte Teilstring als Integer darstellbar ist
If Integer.TryParse(numberpart, number) Then
'Annahme: Markenname steht im ersten Abschnitt
'Markenname_ArtikelNummer in der neuen Spalte eintragen
row(ColumnWithNumber) = parts(0) & " " & number.ToString
row(ColumnWithNumber) = "hallo" 'Wird bei der ausgabe
' angezeigt in SP_3.
row(ColumnWithNumber) = parts(1) 'Wird bei der ausgabe nicht
' angezeigt in SP_3.
Else
'keine Ziffernfolge im letzten Teilstring !!!
row(ColumnWithNumber) = DBNull.Value
End If
Next row
'Name der neuen Spalte zurückgeben
Return ColumnWithNumber
dt.AddColumn() 'Spalte in Tabelle anfügen
'Name der neuen Spalte abfragen
ColumnWithNumber = dt.Columns(dt.Columns.Count - 1).ColumnName
End Function Da werden ja in einer Spalte der Markenname und die Nummer dazu eingetragen.
Nun würde ich gerne noch etwas in eine neue Spalte hinzufügen.
Habe es mal so versucht:
row(ColumnWithNumber) = "hallo" 'Wird bei der ausgabe angezeigt in SP_3.
row(ColumnWithNumber) = parts(1) 'Wird bei der ausgabe nicht angezeigt in SP_3.
Weil ich habe nun an erster Stelle ja den Markennamen und dazwischen kommt eine Zahl z.b 0,00 und dann komm der letzte Teil die ArtikelNummer.
Könntest du mir da eventuell behilflich sein?
Beitrag wurde zuletzt am 21.09.16 um 21:21:53 editiert. | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
vb@rchiv CD Vol.6 vb@rchiv Vol.6
Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
Online-Update-Funktion Entwickler-Vollversionen u.v.m.Jetzt zugreifen Tipp des Monats sevOutBar 4.0
Vertikale Menüleisten á la Outlook
Erstellen von Outlook ähnlichen Benutzer- interfaces - mit beliebig vielen Gruppen und Symboleinträgen. Moderner OfficeXP-Style mit Farbverläufen, Balloon-Tips, u.v.m. Weitere Infos
|