Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Warenkorb Produktecounter
Attentus
myCSharp.de - Member



Dabei seit:
Beiträge: 3

Themenstarter:

Warenkorb Produktecounter

beantworten | zitieren | melden

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();
}
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 9.954

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
Attentus
myCSharp.de - Member



Dabei seit:
Beiträge: 3

Themenstarter:

beantworten | zitieren | melden

@FZelle

Danke für den Hinweis, macht Sinn! Hast Du vielleicht ein kleines Beispiel?
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15.490

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
Attentus
myCSharp.de - Member



Dabei seit:
Beiträge: 3

Themenstarter:

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15.490

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 297

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
chilic
myCSharp.de - Experte



Dabei seit:
Beiträge: 2.099

beantworten | zitieren | melden

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?
Zitat
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?
private Nachricht | Beiträge des Benutzers
M.L.
myCSharp.de - Member



Dabei seit:
Beiträge: 274

beantworten | zitieren | melden

Zitat von Attentus
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 ;-)
private Nachricht | Beiträge des Benutzers