Inhaltsverzeichnis:
- Schritt 1: Opsamling von Af-Daten für die Registrierung von Af UID von Vægt Samt
- Schritt 2: Arduino-Programm
- Schritt 3: Node-RED, Lagring Af Data I Database
- Schritt 4: Datenbank-Design
- Schritt 5: Patelog
- Schritt 6: Bestelltabelle
- Schritt 7: Kundentabelle
- Schritt 8: Rangetable
- Schritt 9: C#-Programm
Video: EAL-Industri4.0-RFID Dataopsamling Til-Datenbank - Gunook
2024 Autor: John Day | [email protected]. Zuletzt bearbeitet: 2024-01-30 07:21
Dette projekt omhandler opsamling af vægtdata, registrering af identiteter vha. RFID, Datenspeicherung in der MySQL-Datenbank vha. node-RED, samt fremvisning und behandling von opsamlede-Daten und C#-Programmen in Form einer Windows Form-Anwendung. Vi Förster os følgende:
Vi har en produktionslinje som Produzent Leverpostej i 200g Foliebakker. Alle Frdigbagte Leverpostejer udstyres efter afkøling med et RFID tag i plasticlåget/labelen, som indeholder et unikt ID (UID = Unique Identifier, er en 32 bits kode, 8 hexadezimale karakterer) zur eindeutigen Identifizierung af hke enkeltjak. Da færdigvægten af hver enkelt bakke Leverpostej kan svinge (afhængig af råvarer, fordampning i ovn mm) Hebelpostejer til én specifik kunde. Kunderne er supermarkedskæder:
1. Irma. Vægten på Irmas Luksus Leverpostej skal holde sig inden für +/- 5%, altså minimum 190g og max. 210g.
2. Brüggen. Vægten på Brugsens Leverpostej skal holde sig inden für +/- 10%, altså minimum 180g og maksimum 220g.
3. Aldi. Vægten på Aldis Discount Leverpostej skal holde sig inden für +/- 15%, altså minimum 170g og maksimum 230g.
Der er således følgende sorteringer:
Range0: außerhalb der Reichweite
Bereich1: Minimum 190g/Maximum210g
Bereich2: mindestens 180 g/maximal 220 g
Bereich3: Minimum 170g/Maximum230g
Schritt 1: Opsamling von Af-Daten für die Registrierung von Af UID von Vægt Samt
Tilt opsamling von Daten für vægt, samt Registrierung von RFID-Tags und Arduino MEGA2560 und RFID-RC522 Reader/Writer. Da vi ikke har nogen vægt, simulerer vi data for vægten med et potmeter tilsluttet en analog indgang på Arduinoen.
Følgende opstilling er anvendt:
1 stk Potmeter 25k lineært. Yder-benene er tilsluttet hhv. GND und +5V, Mittelwert oder tilsluttet AN0
RFID-RC522 er tilsluttet Arduino-Boardets SPI-Port auf der følgenden Seite:
SDA -> Pin 53
SCK -> pin52
MOSI ->pin51
MISO->pin50
IRQ ->NC
GND -> GND
RST -> pin5
3.3V -> 3.3V
De opsamlede Daten, für hhv. UID und vægten, sendes på den seriellen Port som en komma-separeret tekststreng videre to node-Red som står for the efterfølgende præsentation på et Dashboard og laring i en database.
Schritt 2: Arduino-Programm
Ich habe Arduino programt inklusive biblioteker SPI.h og MFRC522.h für kunne bruge RFID löseren. Ich starte af programt initialiseres de anvendte Variable. Der laves en instants von MFRC522. I Setup blokken initialiseres den seriellen forbindelse, SPI porten og MFRC522. Derefter scannt nach RFID-Tags. Für ikke at sende det samme UID afsted flere gange efter hinanden, er der lavet en stump kode som tjekker for dette. Når der er scannet et UID tag, lädt Arary nyUID mit det netop læste UID. Hvis array nyUID er forskellig fra oldUID er the tale om et nyt UID som kan sendes på the serial port. Hvis nyUID und oldUID sind ens, er ist die Geschichte von dem gleichen UID-Tag und UID'et skal Ignoreres. Hvis der er tale om et nyt UID, sendes UID'et på den seriellen Port sammen med en læst værdi fra den seriellen Port. Den analogen værdi skaleres til området 150-250. Daten sendet som en komma-separeret tekststreng. Som det sidste sættes oldUID = nyUID, således at koden klart til at læse et nyt RFID-Tag. Funktionen returnerer true hvis array'ne er ens, og false hvis array'ne er forskellige.
#enthalten
#include // Dieses Programm scannt RFID-Karten mit der RDIF-RC522-Lese-/Schreibplatine. // UID wird gelesen, ein analoger Pin wird gelesen. Analogwert 0-1023 wird auf 150-250 skaliert. // UID und Analogwert werden als kommagetrennter Text auf der seriellen Schnittstelle mit 9600, N, 8, 1 gesendet. // Es wurde darauf geachtet, jede UID nur einmal hintereinander zu senden, // eine neue UID muss vorhanden sein, bevor dieselbe UID erneut gesendet werden kann. // Diese Funktion wird im Code durch Vergleichen von Arrays implementiert: oldUIDnyUID in function array_cmp(oldUID, nyUID)
constexpr uint8_t RST_PIN = 5;
constexpr uint8_t SS_PIN = 53; int sensorPin = A0; int-Wert = 0; String StringValue = "0000"; Byte oldUID[4] = {}; Byte-nyUID[4] = {};
MFRC522 mfrc522 (SS_PIN, RST_PIN); // MFRC522-Instanz erstellen.
Void-Setup ()
{ Serial.begin (9600); // Initiieren einer seriellen Kommunikation SPI.begin(); // SPI-Bus initiieren mfrc522. PCD_Init(); // MFRC522 einleiten }
Leere Schleife ()
{ // Nach neuen Karten suchen if (! mfrc522. PICC_IsNewCardPresent()) { return; } // Eine der Karten auswählen if (! mfrc522. PICC_ReadCardSerial()) { return; } // nyUID mit UID-Tag laden für (Byte i = 0; i < mfrc522.uid.size; i++) { nyUID = mfrc522.uid.uidByte; } // if oldUIDnyUID if (!array_cmp(oldUID, nyUID)) { // UID-Tag an serielle Schnittstelle senden für (Byte i = 0; i 1000) { Value = 1000; } Wert = (Wert / 10) + 150; // skalierten Analogwert senden Serial.print (Wert); // Zeilenumbruch Serial.println () senden; // setze oldUID = nyUID für (Byte z = 0; z < 4; z++) oldUID[z] = nyUID[z]; } // 1 Sek. warten Verzögerung (1000); }
// 2 Arrays vergleichen…
boolean array_cmp(byte a, byte b) { bool test = true; // Jedes Element auf das gleiche prüfen. wenn nur einer nicht ist, gebe false zurück for (byte n = 0; n < 4; n++) { if (a[n] != b[n]) test = false; // wenn ein Byte nicht gleich ist, test = false } if (test == true) return true; sonst false zurückgeben; }
Schritt 3: Node-RED, Lagring Af Data I Database
Følgende Blume er lavet i node-ROT:
COM4 ist den seriellen Forbindelse hvor Datenmodtagen für Arduino Boardet. Funktionen "Split and Get value" und "Split and Get UID" Splitter teksstrengen kommaet og returnere hhv vægten og UID. Vægten bruges til fremvisning på Dashboardet i et linechart og en scale. UID fremvises i et tekstfelt. Funktionen test_sound advarer verbalt med sætningen "Out of range", hvis vægten er unter 170g oder über 230g, dvs i range 0.
Wert teilen und abrufen:
var-Ausgabe = msg.payload.split(', ');
temp = {Nutzlast:(Ausgabe[1])}; Rücklauftemperatur;
Teilen und UID abrufen:
var-Ausgabe = msg.payload.split(", ");
temp = {Nutzlast:Ausgabe[0]}; Rücklauftemperatur;
test_sound:
Var-Nummer = parseInt(msg.payload);
if (number >230 || number<170) { newMsg = {payload:"Out of range"}; neue Nachricht zurückgeben; } else { newMsg = {Nutzlast:""}; neue Nachricht zurückgeben; }
Funktionen Split string ", " indsætter et timestamp, UID und vægten in der Datenbank patedb.patelog.
var-Ausgabe = msg.payload.split(", "); // msg.payload durch Komma in Array aufteilen
UIDTag = Ausgabe[0]; //erster Teil an erster Stelle [0] ValueTag = output[1]; //zweiter Teil an zweiter Stelle [1]
varm = {
Thema: "INSERT INTO patedb.patelog (timestamp, UID, weight) VALUES('"+new Date().toISOString()+"', '"+ UIDTag +"', '"+ValueTag+"');" }; zurück m;
Patelog er en MySQL-Datenbank forbindelse som er sat op med følgende Parameter:
Gastgeber: localhost
Hafen: 3306
Benutzer: root
Datenbank: patedb
Schritt 4: Datenbank-Design
Databasen patedb indeholder 4 Tabellen
Patelog er dataopsamlingstabellen, tilskrives data af node-RED und C# programt
ordertable er en tabel som indeholder data om de genemførte ordrer, tilskrives data af C# programt
Kundentabelle er und Kundenregister
rangetable er en tabel som indeholder grænseværdierne für de i C# programt benyttede Ranges.
Schritt 5: Patelog
Tabellen Patelog Indeholder folgende 6 Kolonner:
pateID (int) ist ein Primärschlüssel und ein inkrementeres Automatisk.
Timestamp, UID & vægt er af typen varchar (med forskellig max længde)
rangeNr er af typen tinyint (beregnes og tilføjes af C# programt)
orderID er af typen int (orderID tilføjes af C# programt)
Node-RED tilføjer ikke værdier til kolonnerne rangeNr og orderID. rangeNr og orderID Tillader NULL værdier, det bruges i C# programt til at detektere de rækker som skal tilskrives værdier for rangeNr og orderID
Schritt 6: Bestelltabelle
Bestelltabelle indeholder 5 kolonner:
orderID (int) er det aktuelle Bestellnummer
orderQuant (mediumint) er ordens pålydende antal
quantProduced (mediumint) er antal der rent faktisk er Produceret på ordren. (Tlles von C#-Programmiert)
comment (tinytext) er en eventuel kommentar til ordren.
customerID (int) er det aktuelle Kundennummer på ordren.
Schritt 7: Kundentabelle
Kundentabelle indeholder 6 Kolonner:
customerID (int) er Primärschlüssel og auto inc.
Name, Adresse, Telefon, E-Mail (varchar) med forskellig max længde
BereichNr (int)
Schritt 8: Rangetable
Rangetable Indeholder 3 Kolonner:
rangeNr (int) er Primärschlüssel og auto inc.
BereichMin (int)
BereichMax (int)
Schritt 9: C#-Programm
Når der Produzenten en ordre Leverpostej, er Verfahren følgende:
Kundenummer, ordrenummer, ordreantal og en eventuel kommentar indtastes i C# programt (i praksis overføres det digitalt fra virksomhedens ordresystem. Produktionen startes nu ved tryk på 'start'- knappen. på et transportbånd) Samhørende værdier af UID og den aktuellen vægt sendes serielt til node-RED, som viser de opsamlede data på Dashboard 'et tidspunkt ikke Tilskrives værdier til rangeNr og orderID vil de have værdien NULL.
Med et timeinterval undersøger C# programt patedb.patelogtabellen for nye tilkomne rækker med NULL værdier i rangeNr kolonnen. Når der er detekteret en række med NULL værdi, beregnes rangeNr und det Tilføjes med med det aktuelle orderID. Når en ordre er productionet, afsluttes ordren ved tryk på”stop”- knappen. Når ordren afsluttes, tilføjes en række til patedb.ordertable mit aktuellen ordredata. Når en ordre er afsluttet, can kan de opsamlede data and patelog tabellen fremvises ved at trykke på de forskellige knapper i gruppen Update DataGridview. bestelltabelle kan også schraubstöcke, og der kan søges ordredata på individueller UID'er eller kundendata på order.
using System; using System. Collections. Generic; Verwenden von System. ComponentModel; Verwenden von System. Data; Verwenden von System. Drawing; Verwenden von System. Linq; Verwenden von System. Text; Verwenden von System. Threading. Tasks; Verwenden von System. Windows. Forms; Verwenden von MySql. Data. MySqlClient;
Namespace show_data_from_database
{ öffentliche Teilklasse Form1: Form { MySqlConnection-Verbindung = new MySqlConnection("datasource=localhost; username=root; password=''"); int Zeilennummer = 0; // Variable zum Speichern des PateID-Werts int RangeNumber = 0; //Variable zum Speichern der Bereichsnummer int weight =0; // Variable zum Speichern des Gewichts int OrderNr = 0; // Variable zum Speichern von OrderNR int QuantProduced = 0; //Variable zum Speichern der produzierten Menge int NumberOfRows = 0; //Anzahl der Zeilen mit Nullen.. bool ProdRunning = false; //Variable, die angibt, ob Start- und Stop-Buttons aktiviert wurden int limits = new int[6];// Array initialisieren int CustomerID; // Variable zum Speichern der Kunden-ID public Form1() { InitializeComponent(); load_table(); // load_table aufrufen }
void load_table()
{ MySqlCommand command = new MySqlCommand("SELECT * FROM patedb.patelog ORDER BY Zeitstempel DESC;", Verbindung); try { MySqlDataAdapter-Adapter = new MySqlDataAdapter(); adapter. SelectCommand = Befehl; DataTable dbdataset = new DataTable(); adapter. Fill(dbdataset); BindingSource bsource = new BindingSource(); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; SetRowOrder(); adapter. Update(dbdataset); } catch (Ausnahme ex) { MessageBox. Show (ex. Message); } }
privat void SetRowOrder()
{ dataGridView1. Columns["pateID"]. DisplayIndex = 0; // Ihr kan rækkefølgen af kolonner ndres dataGridView1. Columns["timestamp"]. DisplayIndex = 1; // Ihr kan rækkefølgen af kolonner ndres dataGridView1. Columns["UID"]. DisplayIndex = 2; // Ihr kan rækkefølgen af kolonner ndres dataGridView1. Columns["weight"]. DisplayIndex = 3; // Her kan rækkefølgen af kolonner ndres dataGridView1. Columns["rangeNr"]. DisplayIndex = 4; // Ihr kan rækkefølgen af kolonner ndres dataGridView1. Columns["orderID"]. DisplayIndex = 5; // Ihr kan rækkefølgen af kolonner ændres }
private void GetData_Click(object sender, EventArgs e) // Liest Datenbanktabelle und Bestellungen nach Zeitstempel
{ Ladetabelle(); }
private void btnRefreshUID_Click(object sender, EventArgs e) //
{ string timeStr = "SELECT * FROM patedb.patelog ORDER BY UID;"; MySqlCommand-Befehl = new MySqlCommand(timeStr, Verbindung); try { MySqlDataAdapter-Adapter = new MySqlDataAdapter(); adapter. SelectCommand = Befehl; DataTable dbdataset = new DataTable(); adapter. Fill(dbdataset); BindingSource bsource = new BindingSource(); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; SetRowOrder(); adapter. Update(dbdataset); } catch (Ausnahme ex) { MessageBox. Show (ex. Message); } }
private void btnRefreshValue_Click(Objektsender, EventArgs e)
{ string weightSort = "SELECT * FROM patedb.patelog ORDER BY CAST(weight AS SIGNED INTEGER);"; MySqlCommand-Befehl = new MySqlCommand(weightSort, connection); try { MySqlDataAdapter-Adapter = new MySqlDataAdapter(); adapter. SelectCommand = Befehl; DataTable dbdataset = new DataTable(); adapter. Fill(dbdataset); BindingSource bsource = new BindingSource(); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; SetRowOrder(); adapter. Update(dbdataset); } catch (Ausnahme ex) { MessageBox. Show (ex. Message); } }
private void ChkNullBtn_Click(Objektsender, EventArgs e)
{ if (ProdRunning) { CheckTableForNull(); load_table(); } }
privat void CheckTableForNull()
{ // Timerinterval prüfen/einstellen mindestens 100 ms int i; int. TryParse(textTimer1. Text, out i); wenn (i <100) {timer1. Stop(); ich = 100; Timer1. Intervall = i; MessageBox. Show("Mindestwert i 100mS"); Timer1. Start(); aufrechtzuerhalten. Sonst { Timer1. Interval = i; } textTimer1. Text = timer1. Interval. ToString(); //Überprüfen, ob Zeilen mit Null in der Tabelle verfügbar sind, gibt die Anzahl der Zeilen in der Variablen zurück:NumberOfRows string weightStr = ""; string chkNull = "SELECT COUNT(*) FROM patedb.patelog WHERE rangeNR IS NULL ORDER BY pateID LIMIT 1;"; MySqlCommand-Befehl = new MySqlCommand(chkNull, Verbindung); try { Verbindung. Open(); NumberOfRows = Convert. ToInt32(command. ExecuteScalar()); Verbindung. Schließen(); } catch (Ausnahme ex) { MessageBox. Show (ex. Message); } finally { if (NumberOfRows != 0) { try { //Wählt die niedrigste PateID-Nummer aus, wobei rangeNr NULL ist string readID = "SELECT pateID FROM patedb.patelog, WO rangeNR NULL IST ORDER BY pateID ASC LIMIT 1;"; MySqlCommand cmdID = new MySqlCommand(readID, Verbindung); { Verbindung. Open(); Zeilennummer = (int)cmdID. ExecuteScalar(); //ganze Zahl!! Verbindung. Schließen(); } listPateID. Text = RowNumber. ToString(); // Ausgewählte PateID-Nummer auslesen // Gewicht aus ausgewählter Zeilennummer auswählen string row = RowNumber. ToString(); string readweight = "SELECT weight FROM patedb.patelog WHERE pateID=" + row; MySqlCommand cmdweight = new MySqlCommand(readweight, connection); { Verbindung. Open(); weightStr = (string)cmdweight. ExecuteScalar(); //String !! Verbindung. Schließen(); } Gewicht = int. Parse(weightStr); // in int konvertieren txtWeight. Text = weight. ToString(); // drucke int RangeNumber = 0; if (Gewicht>= Grenzen[0] && Gewicht = Grenzen[2] && Gewicht = Grenzen[4] && Gewicht <= Grenzen[5]) { RangeNumber = 3; } } txtRange. Text = RangeNumber. ToString(); UpdateLog(); } catch (Ausnahme ex) { MessageBox. Show (ex. Message); } Quant produziert = Quant produziert + 1; } } } private void btnStart_Click (Objektsender, EventArgs e) { if (ProdRunning == false) { int valtest; try { CustomerID = int. Parse(txtCustomerNr. Text); //Kunden-ID lesen} catch { MessageBox. Show("Geben Sie die Produktionsdaten ein und drücken Sie die Schaltfläche 'Start'."); }
string test = "SELECT COUNT(*) FROM patedb.customertable WHERE customerID ="+CustomerID;
MySqlCommand cmdtestcustomer = new MySqlCommand(test, connection); { Verbindung. Open(); valtest = Convert. ToInt32(cmdtestcustomer. ExecuteScalar()); // gibt 0 zurück, wenn Kunde nicht existiert connection. Close(); } if (valtest==1) // wenn Kunde in Datenbank vorhanden - Produktion starten { try { OrderNr = int. Parse(txtOrderNumber. Text); ProdRunning = true; Timer1. Start(); textTimer1. Text = timer1. Interval. ToString(); ReadLimits(); } catch (Exception ex) { MessageBox. Show("Geben Sie die Produktionsdaten ein und drücken Sie die Schaltfläche 'Start'."); } } else MessageBox. Show("Kunde nicht in der Datenbank, versuchen Sie es erneut"); } //ReadLimits(); }
privat void ReadLimits()
{ // Liest Grenzen aus Rangetable, Bereich 1 bis 3 int counter = 0; for (int rangeNr = 1; rangeNr < 4; rangeNr++) { string readmin = "SELECT rangeMin FROM patedb.rangetable WHERE rangeNr=" + rangeNr; MySqlCommand cmdmin = new MySqlCommand(readmin, Verbindung); { Verbindung. Open(); limit[counter] = (int)cmdmin. ExecuteScalar(); Zähler = Zähler + 1; Verbindung. Schließen(); } // MessageBox. Show(counter. ToString()); string readmax = "SELECT rangeMax FROM patedb.rangetable WHERE rangeNr=" + rangeNr; MySqlCommand cmdmax = new MySqlCommand(readmax, Verbindung); { Verbindung. Open(); limit[counter] = (int)cmdmax. ExecuteScalar(); Zähler = Zähler + 1; Verbindung. Schließen(); } } // Ende für Schleife }
privat void UpdateLog()
{ // UPDATE rangeNR & orderID string Range = RangeNumber. ToString(); string Order = OrderNr. ToString(); string update = "UPDATE patedb.patelog SET rangeNr= "+Range+', ' + "orderID= "+OrderNr+" WHERE pateID="+RowNumber; MySqlCommand updatecmd = new MySqlCommand(Update, Verbindung); try { Verbindung. Open(); updatecmd. ExecuteNonQuery(); Verbindung. Schließen(); } catch (Ausnahme ex) { MessageBox. Show (ex. Message); } }
private void btnStop_Click(Objektsender, EventArgs e)
{ if (ProdRunning == true) { timer1. Stop(); ProdRunning = false; UpdateOrderTable(); } else { MessageBox. Show("Noch keine Produktion gestartet. Geben Sie Daten ein und drücken Sie die Schaltfläche 'Start'"); } }
private void UpdateOrderTable()
{ string insert = "INSERT INTO patedb.ordertable (orderID, orderQuant, quantProduced, comment, customerID) VALUES ('" + this.txtOrderNumber. Text + "', '" + this.txtOrderQuant. Text + "', '"+ QuantProduced. ToString()+"', '"+this.txtComment. Text+"', '"+this.txtCustomerNr. Text+"');"; MySqlCommand insertcmd = new MySqlCommand(insert, connection); try { Verbindung. Open(); insertcmd. ExecuteNonQuery(); Verbindung. Schließen(); Quant produziert = 0; } catch (Ausnahme ex) { MessageBox. Show (ex. Message); } }
private void timer1_Tick(Objektsender, EventArgs e)
{ CheckTableForNull(); load_table(); }
private void btnShowOrderTable_Click(Objektsender, EventArgs e)
{ if (ProdRunning == false) { MySqlCommand command = new MySqlCommand("SELECT * FROM patedb.ordertable ORDER BY orderID DESC;", Verbindung); try { MySqlDataAdapter-Adapter = new MySqlDataAdapter(); adapter. SelectCommand = Befehl; DataTable dbdataset = new DataTable(); adapter. Fill(dbdataset); BindingSource bsource = new BindingSource(); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; adapter. Update(dbdataset); } catch (Ausnahme ex) { MessageBox. Show (ex. Message); } } else { MessageBox. Show("Drücken Sie auf Stop, um die OrderTable anzuzeigen"); } }
private void btnShowOrderDetails_Click(Objektsender, EventArgs e)
{ if (ProdRunning == false) { string test = ("SELECT patedb.ordertable.orderID, orderQuant, quantProduced, comment, customerID FROM patedb.ordertable INNER JOIN patedb.patelog ON patedb.patelog.orderID= patedb.ordertable.orderID WO patedb.patelog. UID = '" + txtShowOrderDetails. Text + "'"); MySqlCommand-Befehl = new MySqlCommand (Test, Verbindung); try { Verbindung. Open(); MySqlDataAdapter-Adapter = new MySqlDataAdapter(); adapter. SelectCommand = Befehl; DataTable dbdataset = new DataTable(); adapter. Fill(dbdataset); BindingSource bsource = new BindingSource(); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; adapter. Update(dbdataset); } catch (Ausnahme ex) { MessageBox. Show (ex. Message); } Verbindung. Schließen(); } else { MessageBox. Show("Stopp drücken, um Bestelldetails anzuzeigen"); } }
private void btnShowCustomerDetails_Click(Objektsender, EventArgs e)
{ if (ProdRunning == false) { string test = ("SELECT patedb.customertable.customerID, name, address, phone, email, rangeNr FROM patedb.customertable INNER JOIN patedb.ordertable ON patedb.ordertable.customerID= patedb.customertable. customerID WHERE patedb.ordertable.orderID = '" + txtShowCustomerDetails. Text + "'"); MySqlCommand-Befehl = new MySqlCommand (Test, Verbindung); try { MySqlDataAdapter-Adapter = new MySqlDataAdapter(); adapter. SelectCommand = Befehl; DataTable dbdataset = new DataTable(); adapter. Fill(dbdataset); BindingSource bsource = new BindingSource(); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; adapter. Update(dbdataset); } catch (Ausnahme ex) { MessageBox. Show (ex. Message); } } else { MessageBox. Show("Stopp drücken, um Kundendetails anzuzeigen"); } } }
}