Autor |
Beitrag |
csharpfreak
Hält's aus hier
Beiträge: 13
|
Verfasst: Mo 21.10.13 14:47
Hallo, ich komme nicht darauf, wie ich von einer CSV die Werte von der ersten Spalte vergleiche, um Positionszahlen hinzufügen zu können.
Was ich nun versucht habe, war die CSV in eine DataTable einzulesen, und die Positionen mit einer for-Schleife rausfiltern zu können.
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| for (int i = 0; i< dt.Rows.Count ; i++) { if (dt.Rows[i].ItemArray[0] == dt.Rows[i++].ItemArray[0]) { iPos++; } else { iPos = 0; iPos++; } } |
Was ich mit dem Befehl machen wollte ist, wenn der Spaltenwert den gleichen Wert wie der nächste Spaltenwert, dann soll die Positionen weitergezählt werden (zb. 2 haben den Spaltenwert 1, die Positionszahlen wären dann 1 und 2).
Falls der nächste Spaltenwert nocht dem davorigen ähnelt, dann soll der Zähler auf 0 gesetzt werden, und die Position somit ab 1 neu hochzählen.
Wo ist mein Fehler und wie könnte ich es richtig machen
Moderiert von Th69: C#-Tags hinzugefügt
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 21.10.13 15:08
Du willst bestimmt nicht mit Rows[i++] vergleichen sondern eher mit Rows[i+1]. Sonst hättest du ja den Wert von i geändert und würdest innerhalb des If-Blocks auf eine andere Row zeigen als du vorher geprüft hast. Auch würde bei i++ erst i für den Index des Array verwendet und dann hochgezählt. Du vergleichst also im If im Moment die Row mit sich selbst. Es hätte also eh ++i sein müssen wenn du tatsächlich auch i verändern wolltest.
Auch sollte die Schleife bei count-1 aufhören sonst schaust du hinter das Array und es knallt.
|
|
csharpfreak 
Hält's aus hier
Beiträge: 13
|
Verfasst: Mo 21.10.13 15:17
Zuletzt bearbeitet von csharpfreak am Mo 21.10.13 15:47, insgesamt 1-mal bearbeitet
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 21.10.13 15:25
Lies nochmal denn letzten Satz meiner Antwort
Und wenn er schon bei Position 1 knallt ist da ja maximal 1 Row in deiner Datatable. Ein vergleich von 2 Rows macht natürlich auch nur Sinn wenn mindestens 2 Rows im Dataset sind.
|
|
csharpfreak 
Hält's aus hier
Beiträge: 13
|
Verfasst: Mo 21.10.13 15:26
Gibt es auch einen anderen Weg, als das mit der Datatable, um die Werte aus der ersten Spalten einer CSV pro Zeile zu vergleichen?
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 21.10.13 15:34
Ja. Aber ob das sinn macht?
Erklär mal kurz wofür du diese ~Positionsnummer ~ brauchst und was du im Anschluss damit machst.
Soll die z.B ins CSV zurückgeschrieben werden? Sind die Daten irgendwie sortiert? Du schaust ja scheinbar einfach auf Nachbarzeilen nur dann setzt du denn Zähler zurück. Macht es einen Unterschied ob 2 als gleich erachtete Zeilen im CSV direkt untereinander stehen oder nicht?
|
|
csharpfreak 
Hält's aus hier
Beiträge: 13
|
Verfasst: Mo 21.10.13 15:43
Ich habe z.B eine CSV die so aufgebaut ist
"1";"W1757675";1;"";16.10.13 10:51:33;"ORD"
"1";"4000710050";2;"";16.10.13 10:52:07;"ORD"
"2";"944201015 ";1;"";16.10.13 10:54:27;"ORD"
"3";"2608597729";4;"";17.10.13 14:57:12;"ORD"
"4";"69428";1;"";17.10.13 15:00:14;"ORD"
Die erste Spalte soll dann wie ne Id sein nach der sortiert wird. Die Positionsnr brauch ich, damit diese Daten später in Form einer Rechnung angezeigt werden. Dh. bei Id = 1 wären für die Artikel 1 die Positonsnr 1 und 2 da.
Bei Id = 2 soll es dann wieder ab 1 zählen.
Ach und die Daten werden dabei in eine MSSQL - Datenbank gecshrieben
|
|
Th69
      

Beiträge: 4798
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Mo 21.10.13 15:46
Hallo csharpfreak  ,
bitte formatiere deine Beiträge besser, d.h. benutze die C# oder Code-Tags. Für deinen ersten Beitrag habe ich das mal für dich schon übernommen.
Für diesen Beitrag haben gedankt: csharpfreak
|
|
csharpfreak 
Hält's aus hier
Beiträge: 13
|
Verfasst: Mo 21.10.13 16:02
Hast du da jetzt eine Idee?
|
|
baumina
      
Beiträge: 305
Erhaltene Danke: 61
Win 7
Delphi 10.2 Tokyo Enterprise
|
Verfasst: Mo 21.10.13 16:18
Ohne C# zu können würde ich folgende for-Schleife machen:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| LetzteID = 0
for-Schleife wenn LetzteID = AktuelleID dann PosNr = PosNr+1 sonst PosNr = 1 LetzeID = AktuelleID endewenn endefor |
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 21.10.13 16:56
Benutzt du die jetztige DataTable denn auch zum schreiben der Daten in den SQL Server? Dann ist es nicht verkehrt das an der DataTable zu machen.
|
|
csharpfreak 
Hält's aus hier
Beiträge: 13
|
Verfasst: Mo 21.10.13 17:10
Nein die datatable hab ich nur benutzt, damit ich irgendwie das erste Feld pro Zeile lesen kann, falls es eine bessere alternative gibt, wäre ich dafür dankbar ^^
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 21.10.13 17:16
Die bessere Alternative wäre es an der Datenmenge zu machen die du zum schreiben in den SQL Server benutzt.
|
|
csharpfreak 
Hält's aus hier
Beiträge: 13
|
Verfasst: Mo 21.10.13 21:42
wie meinst du das? weil was ich eigentlich nur wissen will ist, wie ich ich den ersten Wert jeder Zeile lesen kann und dann vergleichen kann.
Solange die Felder identisch sind, wird weiter hochgezählt, kommt ne andere Zahl, ist die erste Positionszahl = 1 und immer so weiter
Denn ich weiß die Parameter dafür nicht, mit der Datatable schien es vom Code irgendwie logisch zu passen
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 21.10.13 22:31
Ich dachte das hättest du schon. Denn du hast ja das csv in eine DataTable bekommen, wozu dann auch irgendwie ein parsen der einzelnen Spalten gehört. Oder nicht?
Versuchen wir es mal mit Code wie ich mir das vorstelle
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| string path = "DeinPfadZurCSVDatei";
DataTable destination = new DataTable(); DataRow lastRow = null;
foreach (var line in File.ReadAllLines(path)) { string[] fields = line.Split(';'); if (fields.Length > 0) { string firstColumnValue = fields[0];
DataRow newRow = destination.NewRow(); if ((lastRow != null) && (lastRow["FirstColumn"].ToString() == firstColumnValue)) newRow["PositionsNummer"] = ((long)newRow["PositionsNummer"]) + 1; else newRow["PositionsNummer"] = 1; lastRow = newRow; } } |
|
|
csharpfreak 
Hält's aus hier
Beiträge: 13
|
Verfasst: Di 22.10.13 09:12
Ich glaube du denkst zu kompliziert^^
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48:
| while ((inputLine = sr.ReadLine()) != null) {
string[] inputValues = inputLine.Split(';'); string id = inputValues[0];
for (int i = 0; i < inputValues.Length; i++) { inputValues[i] = inputValues[i].TrimStart(' ', '"'); inputValues[i] = inputValues[i].TrimEnd('"'); }
for (int i = 0; i < dt.Rows.Count - 1; i++) { if (dt.Rows[i][0] == dt.Rows[i+1][0]) { iPos++; } else { iPos = 0; iPos++; }
}
conn.Open();
SqlCommand cmd2 = conn.CreateCommand(); cmd2.CommandText = queryPos;
cmd2.Parameters.AddWithValue("@PosNr", iPos); cmd2.Parameters.AddWithValue("@EAN", inputValues[1]); cmd2.Parameters.AddWithValue("@Anzahl", inputValues[2]); cmd2.Parameters.AddWithValue("@Datum", UnixTimestamp); |
Die Datatable will ich gar nichz übertragen, ich übernehme nur speizifische Werte und übergebe diese dann nur.
Bisher krieg ich als Positionsnr nur die 1, auch wenn die ersten Felder den gleichen Wert hatten
|
|
baumina
      
Beiträge: 305
Erhaltene Danke: 61
Win 7
Delphi 10.2 Tokyo Enterprise
|
Verfasst: Di 22.10.13 09:16
So wie ich das sehe, liest du zeilenweise ein, erwartest aber schon zu wissen was in der nächsten Zeile stehen soll. Deswegen ist es sinnvoller mit der vorherigen Zeile zu vergleichen und nicht mit der darauffolgenden.
|
|
csharpfreak 
Hält's aus hier
Beiträge: 13
|
Verfasst: Di 22.10.13 09:22
Wie meinst du das? Wie würde das aussehen? dh. (dt.Rows[i-1]) ?
Das würde aber nicht funktionieren, weil es dann ja auch an der Position -1 prüfen würde
|
|
baumina
      
Beiträge: 305
Erhaltene Danke: 61
Win 7
Delphi 10.2 Tokyo Enterprise
|
Verfasst: Di 22.10.13 09:29
LastRow merken, so wie Ralf es vorgeschlagen hat. Oder LastID merken so wie ich es vorgeschlagen hatte.
|
|
csharpfreak 
Hält's aus hier
Beiträge: 13
|
Verfasst: Di 22.10.13 09:30
Geht das auch ohne Datatable?
|
|