Hallo
Ich suche eine elegante Lösung um gescannte Produkte in einem Warenkorb Produktespezifisch zu zählen. Derzeit wird mir pro Scann ein separater Eintrag erstellt, auch wenn das gleiche Produkt mehrfach vorkommt. Das soll sich änder, indem mehrfach vorkommende Produkte nur einmal erscheinen aber entsprechend hochgezählt werden.
Der Warenkorb ist eine ListView / Menge / X / Produkt / Preis / etc. Die Preisberechnung ist hier nicht zu berücksichtigen.
Der Scann vergleicht den Barcode mit der Datenbank / Menge / Artikel_Name / Artikel_Nummer / Barcode / etc. und fügt das Produkt bei einem Treffer in dem Warenkorb ein.
Ich habe das wie unten ersichtlich mit einem Timer versucht um den Artikelnamen jederzeit vergleichen zu können. Das Ganze funktioniert aber nur mit einem Produkt und will nicht mehr, wenn mehrere Produkte gescannt werden. Oder es Zählt über alle Produkt gleichermassen. Das ganze muss wahrscheinlich über zwei ineinendergelegte Schlaufen realisiert werden, nur stehe ich da gerade etwas auf dem Schlauch. Vielleicht hat das schon mal jemand gemacht und kennt eine bessere Lösung? Vielen Dank!
int C = 1;
string ItemName;
private void axOPOSScanner1_DataEvent(object sender, AxOposScanner_CCO._IOPOSScannerEvents_DataEventEvent e)
{
TimerScanner.Start();
SqlConnection cn = new SqlConnection(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Path\Artikel.mdf;Integrated Security=True");
try
{
cn.Open();
if (axOPOSScanner1.ScanDataLabel.Length >= 13) //EAN 13
{
string SearchQuerry = "SELECT * FROM Artikel WHERE Barcode = '" + axOPOSScanner1.ScanDataLabel.Substring(0, 13);
SqlCommand com = new SqlCommand(SearchQuerry, cn);
SqlDataReader sqlReader = com.ExecuteReader();
while (sqlReader.Read())
{
ListViewItem item = new ListViewItem("" + C ); //produktcount);
item.SubItems.Add("X");
item.SubItems.Add(sqlReader.GetValue(1).ToString()); //Artikel
item.SubItems.Add(sqlReader.GetValue(5).ToString());
item.SubItems.Add(sqlReader.GetValue(3).ToString()); //Barcode
item.SubItems.Add(sqlReader.GetValue(4).ToString());
float num1 = float.Parse(string.Format("{0:0.00}", sqlReader.GetValue(4).ToString()));
float num2 = float.Parse(string.Format("{0:0.00}", sqlReader.GetValue(5).ToString()));
item.SubItems.Add("" + num2 / (100 + num1) * num1);
//listWarenkorbMain.Items.Add(item);
if (C == 1)
{
listWarenkorbMain.Items.Add(item);
}
if (ItemName != sqlReader.GetValue(1).ToString())
{
C = C + 1;
}
}
sqlReader.Close();
com.Dispose();
cn.Close();
}
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
}
private void TimerScanner_Tick(object sender, EventArgs e)
{
for (int i = 0; i <= listWarenkorbMain.Items.Count - 1; i++)
{
ItemName = listWarenkorbMain.Items[i].SubItems[2].Text;
}
TimerScanner.Stop();
}
Die Daten selber haben nichts im Control zu suchen.
[Artikel] Drei-Schichten-Architektur
Auch solltest du niemals das StringGefrickel mit Sql Strings machen
[Artikelserie] SQL: Parameter von Befehlen
Wenn du beides beachtest, hast Du die Daten in einer Liste, die du leicht durchlaufen kannst.
@FZelle
Danke für den Hinweis, macht Sinn! Hast Du vielleicht ein kleines Beispiel?
Beispiele sind in den Artikeln, musst sie nur lesen; bezweifle in Anbetracht der Zeit zwischen Post von FZelle und Deine, dass Du das getan hast.
Ansonsten beachte bitte [Hinweis] Wie poste ich richtig?, dass das Forum natürlich Dir kein fertigen Code liefert.
Umsetzen musst es schon selbst.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Teilweise gelesen, ist als Anfänger noch etwas Neuland, daher die dummen Fragen unter C# Grundlagen! Aber das hilft mir auf jeden Fall weiter, Danke.
Gerade als Anfänger muss man eben viel lesen, haben wir alle hier durch gemacht, um Software schreiben zu können.
Du suchst ja hilfe, dann les halt auch das durch, was die Helfer Dir geben. Wenn Du nur die Lösung suchst, ohne das verstehen zu wollen, dann musst jemanden dafür beauftragen - ist ja auch legitim.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Wie kommst du eigentlich auf die Idee mit dem Timer?
Rein logisch: Du musst doch vor dem Einfügen lediglich testen ob in deiner Liste der Eintrag schon vorhanden ist (wie z.B. in TimerScanner_Tick) und falls ja, die Spalte "Anzahl" des ListView-Items um eins erhöhen.
Trotzdem unbedingt FZelles Links berücksichtigen.
Einfacher ist es sowas erstmal als Konsolenanwendung richtig objektorientiert zu basteln.
Was mir noch auffällt und dir sicherlich hilft.
Nenne den Zähler nicht C, sondern so dass du weißt was er tut. Dann brauchst du hinter die Verwendung der Variable nicht schreiben was sie ist.
Ja, ich weiß man denkt sich gerne mal "das weiß ich dann später schon noch", wenn man als Anfänger sein erstes Programm macht. Ist aber garantiert nicht so 🙂
item.SubItems.Add(sqlReader.GetValue(1).ToString()); //Artikel
Das funktioniert solange der Wert 1 auch tatsächlich der Artikel ist.
Wenn du in die Tabelle einen Wert einfügst und sich die Spalten verschieben, ist dein komplettes Programm im Eimer und du suchst und fluchst.
Greife per Spaltenname auf den Wert zu. Dann kannst du auch hier wieder auf den Kommentar verzichten.
(Mit dem SqlReader bin ich spontan nicht so fit dass ich Methodennamen kenne. Ich weiß dass es mit einer Table und den einzelnen Rows funktioniert.)
float num2 = float.Parse(string.Format("{0:0.00}", sqlReader.GetValue(5).ToString()));
Allgemein wäre ich mit ToString bei solchen Dingen vorsichtig. Es verleitet einen das oft zu verwenden weil es einem aus allem schnell einen String macht. Nutze lieber den Datentyp der tatsächlich drin steckt. In deinem Fall steht hoffentlich ein float in der Datenbank? Warum also den in einen String wandeln und den String dann wieder zurück in float parsen? Lies den Wert doch gleich als float aus.
Dass string.Format einen String als 0.00 float formatiert kann ich mir übrigens nicht vorstellen. Funktioniert das bisher tatsächlich?
Das Ganze funktioniert aber nur mit einem Produkt und will nicht mehr, wenn mehrere Produkte gescannt werden.
Könnte das daran liegen dass du nur dann etwas zu listWarenkorbMain hinzufügst wenn C == 1 ist?
noch etwas Neuland
Zwecks Orientierung:
...im Endeffekt sind das aber "nur" Empfehlungen und man kann das Zielprogramm nach eigenen Vorstellungen konstruieren.
Goalkicker.com // DNC Magazine for .NET Developers // .NET Blogs zum Folgen
Software is like cathedrals: first we build them, then we pray 😉