Laden...

Warenkorb Produktecounter

Erstellt von Attentus vor 2 Jahren Letzter Beitrag vor 2 Jahren 464 Views
A
Attentus Themenstarter:in
3 Beiträge seit 2022
vor 2 Jahren
Warenkorb Produktecounter

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();
}

F
10.010 Beiträge seit 2004
vor 2 Jahren

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.

A
Attentus Themenstarter:in
3 Beiträge seit 2022
vor 2 Jahren

@FZelle

Danke für den Hinweis, macht Sinn! Hast Du vielleicht ein kleines Beispiel?

16.833 Beiträge seit 2008
vor 2 Jahren

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.

A
Attentus Themenstarter:in
3 Beiträge seit 2022
vor 2 Jahren

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.

16.833 Beiträge seit 2008
vor 2 Jahren

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.

309 Beiträge seit 2020
vor 2 Jahren

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.

C
2.121 Beiträge seit 2010
vor 2 Jahren

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?

M
368 Beiträge seit 2006
vor 2 Jahren

noch etwas Neuland

Zwecks Orientierung:

  • Code-Konventionen machen Sinn um sich überhaupt im (fremden) Quellcode zurechtzufinden
  • die Aufteilung in Schichten macht (effektiv) Sinn, wenn das Programm (häufig) geändert oder erweitert werden soll: dann hat man die Änderung/Erweiterung (im Idealfall) an einer (zentralen) Stelle
  • SQL-Parameter machen Sinn, wenn irgendein(e) Endnutzer(in) irgendwelche Daten in eine Ziel-Datenbank eintragen darf/soll/muss: damit können kritische Einträge (oder Befehle) verhindert werden
  • SW-Architektur: man fügt die die sich nicht (oder selten) ändernden Teile der Software zusammen, sich schnell(er) ändernde Teile werden ausgelagert

...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 😉