Indholdsfortegnelse:

EAL-Industri4.0-RFID Dataopsamling Til Database: 10 trin (med billeder)
EAL-Industri4.0-RFID Dataopsamling Til Database: 10 trin (med billeder)

Video: EAL-Industri4.0-RFID Dataopsamling Til Database: 10 trin (med billeder)

Video: EAL-Industri4.0-RFID Dataopsamling Til Database: 10 trin (med billeder)
Video: Industry 4.0 Internet of Things, Technology Evolution & Big Data. How Technology Changes Our Lives 2024, Juli
Anonim
EAL-Industri4.0-RFID Dataopsamling Til Database
EAL-Industri4.0-RFID Dataopsamling Til Database

Dette projekt omhandler opsamling af vægtdata, registrering af identiteter vha. RFID, lagring af data i en MySQL database vha. node-RED, samt fremvisning og behandling af de opsamlede data i et C# program i form af en Windows Form Application. Vi forestiller os følgende:

Vi har en produktionslinje som producent leverpostej i 200g foliebakker. Alle færdigbagte 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 hexadecimale karakterer) til entydig identifikation af hver enkelt bakke leverpostej. Da færdigvægten af hver enkelt bakke leverpostej kan svinge (forhold af råvarer, fordampning i ovn mm), og da kunderne hver har et specifikt krav færdigvægten, bruges UID tagget til at knytte hver enkelt leverpostej til en specifik lagerlokation på lageret, hvor der kun kan lagres leverpostejer til én specifik kunde. Kunderne er supermarkedskæder:

1. Irma. Vægten på Irmas luksus leverpostej skal holde sig inden for +/- 5%, altså minimum 190g og maksimum 210g.

2. Brugsen. Vægten på Brugsens leverpostej skal holde sig inden for +/- 10%, altså minimum 180g og maksimum 220g.

3. Aldi. Vægten på Aldis discount leverpostej skal holde sig inden for +/- 15%, altså minimum 170g og maksimum 230g.

Der er således følgende sorteringer:

Range0: uden for rækkevidde

Område 1: minimum 190g/maksimum210g

Rækkevidde2: minimum 180g/maksimum220g

Område 3: minimum 170 g/maksimum 230 g

Trin 1: Opsamling af data til Vægt Samt Registrering Af UID

Opsamling Af Data for Vægt Samt Registrering Af UID
Opsamling Af Data for Vægt Samt Registrering Af UID

Til opsamling af data til vægt, samt registrering af RFID-tags er anvendt i Arduino MEGA2560 med en 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 og +5V, midterbenet er tilsluttet AN0

RFID-RC522 er tilsluttet Arduino boardets SPI port på følgende måde:

SDA -> pin 53

SCK -> pin52

MOSI -> pin51

MISO-> pin50

IRQ -> NC

GND -> GND

RST -> pin5

3,3V -> 3,3V

De opsamlede data, for hhv. UID og vægte, sender på den serielle port som en kommasepareret tekststreng videre til node-Red som står for den efterfølgende præsentation på et dashboard og lagring i en database.

Trin 2: Arduino-program

I Arduino programmet inkluderer de til biblioteker SPI.h og MFRC522.h for at kunne bruge RFID læseren. Jeg starter af programmet initialiseres de anvendte variabel. Der laves en instans af MFRC522. I Setup blokken initialiseres den serielle forbindelse, SPI porten og MFRC522. Derefter scannes efter RFID -tags. For ikke at sende det samme UID afsted flere gange efter hinanden, der er lavet en stump kode som tjekker for dette. Når der er scannet et UID tag, loades arary nyUID med det netop læste UID. Hvis array nyUID er forskellig fra oldUID er der tale om et nyt UID, der kan sendes på den serielle port. Hvis nyUID og oldUID er ens, er der tale om samme UID -tag og UID'et skal ignoreres. Hvis der er tale om et nyt UID, sender UID'et på den serielle port sammen med en læst værdi fra den serielle port. Den analoge værdi skaleres til området 150-250. Data sender 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.. Den sidste funktion i programmet er den funktion som sammenligner 2 arrays. Funktionen returnerer true hvis array'ne er ens, og false hvis array'ne er forskellige.

#omfatte

#include // Dette program scanner RFID-kort ved hjælp af RDIF-RC522 læser/skriverkort. // UID læses, en analog pin læses. Analog værdi 0-1023 skaleres til 150-250. // UID og analog værdi sendes som kommasepareret tekst på seriel port ved hjælp af 9600, N, 8, 1. // Der er sørget for kun at sende hver UID én gang i træk, // en ny UID skal være til stede, før det samme UID kan sendes igen. // Denne funktion implementeres i koden ved at sammenligne arrays: oldUID nyUID i funktion array_cmp (oldUID , nyUID )

constexpr uint8_t RST_PIN = 5;

constexpr uint8_t SS_PIN = 53; int sensorPin = A0; int Værdi = 0; String StringValue = "0000"; byte oldUID [4] = {}; byte nyUID [4] = {};

MFRC522 mfrc522 (SS_PIN, RST_PIN); // Opret MFRC522 -forekomst.

ugyldig opsætning ()

{Serial.begin (9600); // Start en seriel kommunikation SPI.begin (); // Start SPI -bus mfrc522. PCD_Init (); // Start MFRC522}

hulrum ()

{// Se efter nye kort, hvis (! Mfrc522. PICC_IsNewCardPresent ()) {return; } // Vælg et af kortene, hvis (! Mfrc522. PICC_ReadCardSerial ()) {return; } // indlæs nyUID med UID -tag for (byte i = 0; i <mfrc522.uid.size; i ++) {nyUID = mfrc522.uid.uidByte ; } // if oldUID nyUID if (! array_cmp (oldUID, nyUID)) {// send UID -tag på seriel port for (byte i = 0; i 1000) {Value = 1000; } Værdi = (Værdi / 10) + 150; // send skaleret analog værdi Serial.print (værdi); // send ny linje Serial.println (); // sæt oldUID = nyUID for (byte z = 0; z <4; z ++) oldUID [z] = nyUID [z]; } // vent 1 sek forsinkelse (1000); }

// sammenlign 2 arrays …

boolsk array_cmp (byte a , byte b ) {bool test = sand; // test hvert element for at være det samme. hvis bare en ikke er det, skal du returnere false for (byte n = 0; n <4; n ++) {if (a [n]! = b [n]) test = false; // hvis på byte ikke er lig, test = false} hvis (test == sand) returnerer sand; ellers returner falsk; }

Trin 3: Node-RED, Lagring Af Data I Database

Node-RED, Lagring Af Data I Database
Node-RED, Lagring Af Data I Database
Node-RED, Lagring Af Data I Database
Node-RED, Lagring Af Data I Database

Følgende flow er lavet i node-RØD:

COM4 er den serielle forbindelse, hvor data modtages fra Arduino boardet. Funktionerne "Split and Get value" og "Split and Get UID" splitter tekststrengen ved kommaet og returnere hhv vægten og UID. Vægten bruges til fremvisning på dashboardet i et linechart og en skala. UID fremvises i et tekstfelt. Funktionen test_sound advarer verbalt med sætningen "Out of range", hvis vægten er under 170g eller over 230g, dvs i område 0.

Opdel og få værdi:

var output = msg.payload.split (',');

temp = {nyttelast: (output [1])}; retur temp;

Opdel og få UID:

var output = msg.payload.split (",");

temp = {nyttelast: output [0]}; retur temp;

test_lyd:

var number = parseInt (msg.payload);

hvis (tal> 230 || nummer <170) {newMsg = {nyttelast: "Uden for område"}; returner newMsg; } ellers {newMsg = {nyttelast: ""}; returner newMsg; }

Funktioner Split string "," indsætter og tidsstempel, UID og vægten i en database patedb.patelog.

var output = msg.payload.split (","); // split msg.payload med komma i array

UIDTag = output [0]; // første del til første position [0] ValueTag = output [1]; // anden del til anden position [1]

var m = {

emne: "INSERT INTO patedb.patelog (tidsstempel, UID, vægt) VÆRDIER ('"+ny dato (). toISOString ()+"', '"+UIDTag+"', '"+ValueTag+"');" }; tilbagevenden m;

patelog er en MySQL -database, der kan bruges på følgende parametre:

Vært: localhost

Havn: 3306

Bruger: root

Database: patedb

Trin 4: Database-design

Database-design
Database-design

Databasen indeholder 4 tabeller

patelog er dataopsamlingstabellen, tilskrives data af node-RED og C# program

ordertable er en tabel, der indeholder data om de genemførte ordrer, tilskrives data af C# program

kundetilpasset er og kundeegister

rangetable er en tabel, der indeholder grænseværdierne til de i C# programmet benyttede intervaller.

Trin 5: Patelog

Patelog
Patelog

Tabellen indeholder følgende 6 kolonner:

pateID (int) er primær nøgle og inkrementeres automatisk.

Tidsstempel, UID og vægt er af typen varchar (med forskellig max længde)

rangeNr er af typen tinyint (beregnes og tilføjes af C# program)

orderID er af typen int (orderID tilføjes af C# program)

Node-RØD tilføjer ikke værdier til kolonnerne rangeNr og orderID. rangeNr og orderID tillader NULL værdier, det bruges i C# program til at detektere de rækker som skal tilskrives værdier for rangeNr og orderID

Trin 6: Ordertable

Ordretable
Ordretable

ordertable indeholder 5 kolonner:

orderID (int) er det aktuelle ordrenummer

orderQuant (mediumint) er ordens pålydende antal

quantProduced (mediumint) er antal der rent faktisk er produceret på ordren. (Tælles af C# program)

kommentar (lille tekst) er en eventuel kommentar til ordren.

customerID (int) er det aktuelle kundenummer på ordren.

Trin 7: Customertable

Tilpasset
Tilpasset

brugerdefineret indeholder 6 kolonner:

customerID (int) er primærnøgle og auto inc.

navn, adresse, telefon, e -mail (varchar) med forskellig max længde

områdeNr (int)

Trin 8: Rangetable

Rangetable
Rangetable

rangetable indeholder 3 kolonner:

rangeNr (int) er primærnøgle og auto inc.

rangeMin (int)

rangeMax (int)

Trin 9: C# -program

C# -program
C# -program

Når der produceres en ordre leverpostej, er proceduren følgende:

Kundenummer, ordrenummer, ordreantal og en eventuel kommentar indtastes i C# program (i praksis overføres det digitalt fra virksomhedens ordresystem. Produktionen starter nu ved tryk på 'start'- knappen. Når en leverpostej er færdigproduceret og låget er monteret, vil den af Arduinoen (på et transportbånd) Samhørende værdier af UID og den aktuelle vægt sendes serielt til node-RED, som viser de opsamlede data på dashboard 'og samtidig skrives tidsstempel, UID og vægt i en ny række i patedb.patelog-tabeller. tidspunkt ikke tilskrives værdier til rangeNr og orderID vil have værdien NULL.

Med et timerinterval undersøger C# program 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 og det tilføjes sammen med den aktuelle ordreID. Når en ordre er produceret, afsluttes ordren ved tryk på”stop”- knappen. Når ordren afsluttes, tilføjes en række til patedb.ordertable med de aktuelle ordredata. Når en ordre er afsluttet, kan jeg opsamle data i patelog tabellen fremvises ved at trykke på de forskellige knapper i gruppen Opdater DataGridview. ordertable kan også vises, og der kan søges ordredata på individueller UID'er eller kundedata på individuelle ordrer.

ved hjælp af System; ved hjælp af System. Collections. Generic; ved hjælp af System. ComponentModel; ved hjælp af System. Data; ved hjælp af System. Drawing; ved hjælp af System. Linq; ved hjælp af System. Text; ved hjælp af System. Threading. Tasks; ved hjælp af System. Windows. Forms; ved hjælp af MySql. Data. MySqlClient;

navneområde show_data_from_database

{offentlig delklasse Form1: Form {MySqlConnection connection = new MySqlConnection ("datasource = localhost; brugernavn = root; password = ''"); int RowNumber = 0; // Variabel til lagring af pateID -værdi int RangeNumber = 0; // Variabel til lagring af rangenumber int vægt = 0; // Variabel til lagring af vægten int OrderNr = 0; // Variabel til lagring af OrderNR int QuantProduced = 0; // Variabel til lagring af produceret mængde int NumberOfRows = 0; // antal rækker med nuller.. bool ProdRunning = false; // Variabel, der angiver, om start- og stopknapper er blevet aktiveret int limits = new int [6]; // initialiserer array int CustomerID; // Variabel til lagring af customerID public Form1 () {InitializeComponent (); load_table (); // opkald load_table}

ugyldig load_table ()

{MySqlCommand -kommando = ny MySqlCommand ("SELECT * FRA patedb.patelog ORDER BY tidsstempel DESC;", forbindelse); prøv {MySqlDataAdapter adapter = new MySqlDataAdapter (); adapter. SelectCommand = kommando; DataTable dbdataset = ny DataTable (); adapter. Fyld (dbdataset); BindingSource bsource = ny BindingSource (); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; SetRowOrder (); adapter. Update (dbdataset); } catch (Undtagelse ex) {MessageBox. Show (ex. Message); }}

private void SetRowOrder ()

{dataGridView1. Columns ["pateID"]. DisplayIndex = 0; // Her kan rækkefølgen af kolonner ændres dataGridView1. Columns ["tidsstempel"]. DisplayIndex = 1; // Her kan rækkefølgen af kolonner ændres dataGridView1. Columns ["UID"]. DisplayIndex = 2; // Her 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; // Her kan rækkefølgen af kolonner ændres dataGridView1. Columns ["orderID"]. DisplayIndex = 5; // Her kan rækkefølgen af kolonner ændres}

private void GetData_Click (objekt afsender, EventArgs e) // Læser databasetabel og ordrer efter tidsstempel

{load_table (); }

private void btnRefreshUID_Click (objekt afsender, EventArgs e) //

{string timeStr = "SELECT * FROM patedb.patelog ORDER BY UID;"; MySqlCommand -kommando = ny MySqlCommand (timeStr, forbindelse); prøv {MySqlDataAdapter adapter = new MySqlDataAdapter (); adapter. SelectCommand = kommando; DataTable dbdataset = ny DataTable (); adapter. Fyld (dbdataset); BindingSource bsource = ny BindingSource (); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; SetRowOrder (); adapter. Update (dbdataset); } catch (Undtagelse ex) {MessageBox. Show (ex. Message); }}

private void btnRefreshValue_Click (objekt afsender, EventArgs e)

{string weightSort = "SELECT * FROM patedb.patelog ORDER BY CAST (weight AS SIGNED INTEGER);"; MySqlCommand -kommando = ny MySqlCommand (weightSort, forbindelse); prøv {MySqlDataAdapter adapter = new MySqlDataAdapter (); adapter. SelectCommand = kommando; DataTable dbdataset = ny DataTable (); adapter. Fyld (dbdataset); BindingSource bsource = ny BindingSource (); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; SetRowOrder (); adapter. Update (dbdataset); } catch (Undtagelse ex) {MessageBox. Show (ex. Message); }}

private void ChkNullBtn_Click (objekt afsender, EventArgs e)

{if (ProdRunning) {CheckTableForNull (); load_table (); }}

privat tomrum CheckTableForNull ()

{// Kontroller/indstil timerinterval minimum 100 ms int i; int. TryParse (textTimer1. Text, ud i); hvis (i <100) {timer1. Stop (); i = 100; timer1. Interval = i; MessageBox. Show ("Mindste værdi i 100mS"); timer1. Start (); } ellers {timer1. Interval = i; } textTimer1. Text = timer1. Interval. ToString (); // Kontroller, om nogen rækker med nul er tilgængelige i tabellen, returnerer antallet af rækker i variablen: NumberOfRows streng weightStr = ""; string chkNull = "VÆLG TÆL (*) FRA patedb.patelog HVOR områdeNR ER NULL ORDER AF pateID LIMIT 1;"; MySqlCommand -kommando = ny MySqlCommand (chkNull, forbindelse); prøv {connection. Open (); NumberOfRows = Convert. ToInt32 (command. ExecuteScalar ()); forbindelse. Luk (); } catch (Undtagelse ex) {MessageBox. Show (ex. Message); } endelig {if (NumberOfRows! = 0) {try {// Vælger det laveste pateID -nummer, hvor rangeNr er NULL string readID = "SELECT pateID FROM patedb.patelog WHERE rangeNR IS NULL ORDER BY pateID ASC LIMIT 1;"; MySqlCommand cmdID = nyt MySqlCommand (readID, forbindelse); {connection. Open (); RowNumber = (int) cmdID. ExecuteScalar (); //heltal!! forbindelse. Luk (); } listPateID. Text = RowNumber. ToString (); // læs det valgte PateID -nummer ud // Vælger vægt fra den valgte rownumber -strengrække = RowNumber. ToString (); string readweight = "VÆLG vægt FRA patedb.patelog WHERE pateID =" + række; MySqlCommand cmdweight = ny MySqlCommand (læsevægt, forbindelse); {connection. Open (); weightStr = (streng) cmdweight. ExecuteScalar (); // streng !! forbindelse. Luk (); } vægt = int. Parse (weightStr); // konverter til int txtWeight. Text = weight. ToString (); // print int RangeNumber = 0; hvis (vægt> = grænser [0] && vægt = grænser [2] && vægt = grænser [4] && vægt <= grænser [5]) {RangeNumber = 3; }} txtRange. Text = RangeNumber. ToString (); UpdateLog (); } catch (Undtagelse ex) {MessageBox. Show (ex. Message); } QuantProduced = QuantProduced + 1; }}} private void btnStart_Click (objektafsender, EventArgs e) {if (ProdRunning == false) {int valtest; prøv {CustomerID = int. Parse (txtCustomerNr. Text); // læs customerID} catch {MessageBox. Show ("Indtast produktionsdata, og tryk på" start "-knappen."); }

string test = "SELECT COUNT (*) FRA patedb.customertable WHERE customerID ="+CustomerID;

MySqlCommand cmdtestcustomer = ny MySqlCommand (test, forbindelse); {connection. Open (); valtest = Convert. ToInt32 (cmdtestcustomer. ExecuteScalar ()); // returnerer 0, hvis kunden ikke eksisterer forbindelse. Luk (); } hvis (valtest == 1) // hvis kunden findes i databasen - start produktionen {prøv {OrderNr = int. Parse (txtOrderNumber. Text); ProdRunning = true; timer1. Start (); textTimer1. Text = timer1. Interval. ToString (); ReadLimits (); } catch (Undtagelse ex) {MessageBox. Show ("Indtast produktionsdata, og tryk på" start "-knappen."); }} else MessageBox. Show ("Kunden er ikke i databasen, prøv igen"); } // ReadLimits (); }

privat tomrum ReadLimits ()

{// Læser grænser fra rangetable, område 1 til 3 int tæller = 0; for (int rangeNr = 1; rangeNr <4; rangeNr ++) {string readmin = "SELECT rangeMin FROM patedb.rangetable WHERE rangeNr ="+rangeNr; MySqlCommand cmdmin = ny MySqlCommand (readmin, forbindelse); {connection. Open (); grænser [tæller] = (int) cmdmin. ExecuteScalar (); tæller = tæller + 1; forbindelse. Luk (); } // MessageBox. Show (counter. ToString ()); string readmax = "SELECT rangeMax FROM patedb.rangetable WHERE rangeNr =" + rangeNr; MySqlCommand cmdmax = ny MySqlCommand (readmax, forbindelse); {connection. Open (); grænser [tæller] = (int) cmdmax. ExecuteScalar (); tæller = tæller + 1; forbindelse. Luk (); }} // ende for sløjfe}

private 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 = ny MySqlCommand (opdatering, forbindelse); prøv {connection. Open (); updatecmd. ExecuteNonQuery (); forbindelse. Luk (); } catch (Undtagelse ex) {MessageBox. Show (ex. Message); }}

private void btnStop_Click (objekt afsender, EventArgs e)

{if (ProdRunning == true) {timer1. Stop (); ProdRunning = falsk; UpdateOrderTable (); } else {MessageBox. Show ("Ingen produktion er startet endnu. Indtast data, og tryk på" start "-knappen"); }}

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 = ny MySqlCommand (indsæt, forbindelse); prøv {connection. Open (); insertcmd. ExecuteNonQuery (); forbindelse. Luk (); QuantProduced = 0; } catch (Undtagelse ex) {MessageBox. Show (ex. Message); }}

private void timer1_Tick (objekt afsender, EventArgs e)

{CheckTableForNull (); load_table (); }

private void btnShowOrderTable_Click (objekt afsender, EventArgs e)

{hvis (ProdRunning == false) {MySqlCommand -kommando = ny MySqlCommand ("SELECT * FROM patedb.ordertable ORDER BY orderID DESC;", forbindelse); prøv {MySqlDataAdapter adapter = new MySqlDataAdapter (); adapter. SelectCommand = kommando; DataTable dbdataset = ny DataTable (); adapter. Fyld (dbdataset); BindingSource bsource = ny BindingSource (); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; adapter. Update (dbdataset); } catch (Undtagelse ex) {MessageBox. Show (ex. Message); }} else {MessageBox. Show ("Tryk på stop for at se orderTable"); }}

private void btnShowOrderDetails_Click (objekt afsender, 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 WHERE patedb.patelog. UID = '" + txtShowOrderDetails. Text +"' "); MySqlCommand -kommando = ny MySqlCommand (test, forbindelse); prøv {connection. Open (); MySqlDataAdapter adapter = ny MySqlDataAdapter (); adapter. SelectCommand = kommando; DataTable dbdataset = ny DataTable (); adapter. Fyld (dbdataset); BindingSource bsource = ny BindingSource (); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; adapter. Update (dbdataset); } catch (Undtagelse ex) {MessageBox. Show (ex. Message); } forbindelse. Luk (); } ellers {MessageBox. Show ("Tryk på stop for at se ordredetaljer"); }}

private void btnShowCustomerDetails_Click (objekt afsender, 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 -kommando = ny MySqlCommand (test, forbindelse); prøv {MySqlDataAdapter adapter = new MySqlDataAdapter (); adapter. SelectCommand = kommando; DataTable dbdataset = ny DataTable (); adapter. Fyld (dbdataset); BindingSource bsource = ny BindingSource (); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; adapter. Update (dbdataset); } catch (Undtagelse ex) {MessageBox. Show (ex. Message); }} else {MessageBox. Show ("Tryk på stop for at se kundeoplysninger"); }}}

}

Anbefalede: