Оглавление:

EAL-Industri4.0-RFID Dataopsamling для базы данных: 10 шагов (с изображениями)
EAL-Industri4.0-RFID Dataopsamling для базы данных: 10 шагов (с изображениями)

Видео: EAL-Industri4.0-RFID Dataopsamling для базы данных: 10 шагов (с изображениями)

Видео: EAL-Industri4.0-RFID Dataopsamling для базы данных: 10 шагов (с изображениями)
Видео: Industrie 4.0 : comment développer ses compétences ? 2024, Июль
Anonim
EAL-Industri4.0-RFID Dataopsamling Til База данных
EAL-Industri4.0-RFID Dataopsamling Til База данных

Dette projekt omhandler запускает vægtdata, регистрируя идентификатор vha. RFID, задержка данных в базе данных MySQL vha. node-RED, само видение и поведение опсамедляемых данных в программе C #, созданной в приложении Windows Form. Vi forestiller os følgende:

Vi har en produktionslinje som производителя leepostej i 200g foliebakker. Все средства идентификации после установки меток и меток RFID в пластиковом / этикеточном материалах, отдельные идентификаторы и уникальные идентификаторы (UID = уникальный идентификатор, например, 32-битный код, 8 шестнадцатеричных символов) для стандартной идентификации после проверки положения рычага. Da færdigvægten af hver enkelt bakke leepostej kan svinge (afhængig af råvarer, fordampning i ovn mm), og da kunderne hver har et specific krav færdigvægten, bruges UID tagget til at knytte hördigvgten, bruges UID tagget til at knytte hrevarer, enposte enposte, enposte enposte enposte, laklover enposik Leerpostejer til én specificik kunde. Kunderne er supermarkedskæder:

1. Ирма. Vgten på Irmas luksus leepostej skal holde sig inden for +/- 5%, altså минимум 190 г и максимум 210 г.

2. Бругсен. Vgten på Brugsens lerpostej skal holde sig inden for +/- 10%, altså минимум 180 г или максимум 220 г.

3. Алди. Предложение по Aldis со скидкой составляет +/- 15%, а также минимум 170 г и максимум 230 г.

Der er således følgende sorteringer:

Range0: вне диапазона

Диапазон1: минимум 190 г / максимум 210 г

Range2: минимум 180 г / максимум 220 г

Range3: минимум 170 г / максимум 230 г

Шаг 1. Использование данных Af для Vægt Samt, регистрирующего UID Af

Opsamling Af Data для Vægt Samt, регистрирующего UID Af
Opsamling Af Data для Vægt Samt, регистрирующего UID Af

Чтобы обработать данные для vægt, самостоятельно регистрируйте RFID-метки и их использование в Arduino MEGA2560 и считывающем / записывающем устройстве RFID-RC522. Просмотрите данные для моделирования и просмотра данных для использования с аналоговым устройством на Arduinoen.

Følgende opstilling er anvendt:

1 ст горшок 25к линейрт. Yder-benene er tilsluttet hhv. GND og + 5V, промежуточный кабель AN0

RFID-RC522 поддерживает порт SPI для Arduino с использованием следующих типов:

SDA -> контакт 53

SCK -> pin52

MOSI -> pin51

MISO-> pin50

IRQ -> NC

GND -> GND

RST -> pin5

3,3 В -> 3,3 В

De opsamlede data, для hhv. UID и отправляет один серийный порт и комма-отдельный текстовый поток видео на узел - красный адрес для последующего представления на панели управления и задержки в базе данных.

Шаг 2: Arduino-программа

Я запрограммировал Arduino для библиотеки SPI.h и MFRC522.h, чтобы получить доступ к RFID-идентификаторам. Я начал программно инициализировать переменную. Der laves en instans af MFRC522. Я устанавливаю блоки инициализации серийных файлов, порт SPI и MFRC522. Derefter сканирует RFID-метки. Для ikke at sende det samme UID afsted flere gange efter hinanden, er der lavet en stump kode som tjekker for dette. При сканировании сети и тега UID загружается собственный идентификатор пользователя с определенным идентификатором UID. Hvis array nyUID er forskellig fra oldUID er der story om et nyt UID som can send på den serielle port. Hvis nyUID или oldUID erens, er der story om samme UID tag или UID'et skal ignoreres. Hvis der er story om et nyt UID, отправляет 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. Данные отправляются в комма-отдельном текстстренге. Некоторые из этих систем имеют oldUID = nyUID, используются и другие коды RFID-меток. Эти функции программируются с помощью двух выборочных массивов. Функционал, возвращающий истинный hvis-массив, должен быть, или ложный hvis-массив, который должен быть создан.

#включают

#include // Эта программа сканирует RFID-карты с помощью платы считывания / записи RDIF-RC522. // Считывается UID, считывается аналоговый вывод. Аналоговое значение 0-1023 масштабируется до 150-250. // UID и аналоговое значение отправляются в виде текста, разделенного запятыми, на последовательный порт с использованием 9600, N, 8, 1. // Были приняты меры для отправки каждого UID только один раз подряд, // новый UID должен быть присутствует до того, как тот же UID может быть отправлен снова. // Эта функция реализована в коде путем сравнения массивов: oldUID nyUID в функции array_cmp (oldUID , nyUID )

constexpr uint8_t RST_PIN = 5;

constexpr uint8_t SS_PIN = 53; int sensorPin = A0; int Value = 0; Строка StringValue = «0000»; byte oldUID [4] = {}; byte nyUID [4] = {};

MFRC522 mfrc522 (SS_PIN, RST_PIN); // Создаем экземпляр MFRC522.

установка void ()

{Serial.begin (9600); // Инициируем последовательную связь SPI.begin (); // Запускаем шину SPI mfrc522. PCD_Init (); // Запускаем MFRC522}

пустой цикл ()

{// Ищем новые карточки if (! Mfrc522. PICC_IsNewCardPresent ()) {return; } // Выбираем одну из карточек if (! Mfrc522. PICC_ReadCardSerial ()) {return; } // загружаем nyUID с тегом UID для (byte i = 0; i <mfrc522.uid.size; i ++) {nyUID = mfrc522.uid.uidByte ; } // if oldUID nyUID if (! array_cmp (oldUID, nyUID)) {// отправляем тег UID на последовательный порт для (byte i = 0; i 1000) {Value = 1000; } Значение = (Значение / 10) + 150; // отправляем масштабированное аналоговое значение Serial.print (Value); // отправляем новую строку Serial.println (); // устанавливаем oldUID = nyUID для (byte z = 0; z <4; z ++) oldUID [z] = nyUID [z]; } // ждем задержку в 1 секунду (1000); }

// сравниваем 2 массива…

логический array_cmp (байт a , байт b ) {bool test = true; // проверяем идентичность каждого элемента. если только один - нет, вернуть false for (byte n = 0; n <4; n ++) {if (a [n]! = b [n]) test = false; // если байт не равен, test = false} if (test == true) return true; иначе вернет ложь; }

Шаг 3: Node-RED, база данных Lagring Af Data I

Node-RED, база данных Lagring Af Data I
Node-RED, база данных Lagring Af Data I
Node-RED, база данных Lagring Af Data I
Node-RED, база данных Lagring Af Data I

Følgende flow er lavet i node-RED:

COM4 - это серийная версия для модификации данных, хранящихся в плате Arduino. Функциональные возможности "Разделить и получить значение" или "Разделить и получить UID" разделитель текстовых сообщений имеет и возвращает значения UID. Посмотрите на панель инструментов и график в масштабе. UID fremvises и et текстфельт. Funktionen test_sound, озвученный со звуком "Вне диапазона", виден ниже 170 г и выше 230 г, DVS в диапазоне 0.

Разделить и получить значение:

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

temp = {полезная нагрузка: (вывод [1])}; возвратная температура;

Разделить и получить UID:

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

temp = {полезная нагрузка: вывод [0]}; возвратная температура;

test_sound:

var number = parseInt (msg.payload);

if (число> 230 || число <170) {newMsg = {payload: "Out of range"}; вернуть newMsg; } еще {newMsg = {полезная нагрузка: ""}; вернуть newMsg; }

Функции Разделить строку "," указатель и метку времени, UID и данные в базе данных patedb.patelog.

var output = msg.payload.split (","); // разбиваем msg.payload по запятой в массив

UIDTag = выход [0]; // первая часть в первую позицию [0] ValueTag = output [1]; // вторая часть во вторую позицию [1]

var m = {

тема: "INSERT INTO patedb.patelog (timestamp, UID, weight) VALUES ('" + new Date (). toISOString () + "', '" + UIDTag + "', '" + ValueTag + "');" }; return m;

Patelog er en База данных MySQL для некоторых заданных параметров:

Хост: localhost

Порт: 3306

Пользователь: root

База данных: patedb

Шаг 4: Дизайн базы данных

База данных-дизайн
База данных-дизайн

Databasen patedb indeholder 4 табеллер

Patelog er dataopsamlingstabellen, tilskrives data af node-RED og C # programmet

ordertable er en tabel som indeholder data om de genemførte ordrer, tilskrives данные из программы C #

таблица клиентов er et kunderegister

rangetable er en tabel som indeholder grænseværdierne for de i C # programmet benyttede range.

Шаг 5: Patelog

Patelog
Patelog

Табеллен Patelog indeholder folgende 6 kolonner:

PateID (int) er первичный ключ и автоматическая установка.

Отметка времени, UID и переменная типа varchar (med forskellig max længde)

rangeNr er af typen tinyint (поддерживает программы на C #)

orderID er af typen int (идентификатор заказа указан в программе C #)

Узел-КРАСНЫЙ, если вы хотите узнать больше о столбце rangeNr og orderID. rangeNr og orderID tillader NULL værdier, det bruges i C # программируется, пока обнаруживается, что rækker som skal tilskrives værdier for rangeNr og orderID

Шаг 6: таблица заказов

Таблица заказов
Таблица заказов

таблица ордеров на 5 колоннер:

orderID (int) er det aktuelle ordrenummer

orderQuant (mediumint) er ordens pålydende antal

QuantProduced (mediumint) er antal der rent faktisk er producted på ordren. (Tælles af C # programmet)

comment (tinytext) er en eventuel kommentar til ordren.

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

Шаг 7: Таблица клиентов

Таблица клиентов
Таблица клиентов

клиенттаблица держателя 6 колоннер:

customerID (int) er первичный ключ og auto inc.

имя, адрес, телефон, электронная почта (varchar) med forskellig max længde

rangeNr (целое)

Шаг 8: доступность

Rangetable
Rangetable

раздвижной андерхолдер 3 колоннера:

rangeNr (int) er первичный ключ og auto inc.

rangeMin (целое)

rangeMax (число)

Шаг 9: программа на C #

Программа C #
Программа C #

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

Kundenummer, ordrenummer, ordreantal og en eventuel kommentar indtastes i C # programmet (i praksis overføres det digitalt fra virksomhedens ordresystem. Produktionen starttes nu ved tryk på 'start'- knappen. Når en lelepostejer færdigproduceret de montegproduceret) på et transportbånd) Самоходный идентификатор UID или текущее сообщение отправляет серию на узел-RED, если пользователь видит данные на панели управления и т.д. tidspunkt ikke tilskrives værdier til rangeNr og orderID vil de have vrdien NULL.

Med et timerinterval undersøger C # programmet 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 det aktuelle orderID. Når en ordre er productret, afsluttes ordren ved tryk på”стоп” - кнаппен. Når ordren afsluttes, tilføjes en række til patedb.ordertable med de aktuelle ordredata. Если вы хотите, чтобы данные были доступны, вы можете использовать данные в таблицах фремвисов и попробовать их в группе. Обновите DataGridview. Таблица заказов может содержать карты, а также может быть заказана для индивидуального идентификатора пользователя или для индивидуального заказа.

using System; using System. Collections. Generic; using System. ComponentModel; using System. Data; с помощью System. Drawing; using System. Linq; using System. Text; using System. Threading. Tasks; using System. Windows. Forms; using MySql. Data. MySqlClient;

пространство имен show_data_from_database

{общедоступный частичный класс Form1: форма {MySqlConnection connection = new MySqlConnection ("datasource = localhost; username = root; password = ''"); int RowNumber = 0; // Переменная для хранения значения PateID int RangeNumber = 0; // Переменная для хранения номера диапазона int weight = 0; // Переменная для хранения веса int OrderNr = 0; // Переменная для хранения OrderNR int QuantProduced = 0; // Переменная для хранения произведенного количества int NumberOfRows = 0; // количество строк с нулями.. bool ProdRunning = false; // Переменная, указывающая, были ли активированы кнопки запуска и остановки int limits = new int [6]; // инициализируем массив int CustomerID; // Переменная для хранения идентификатора клиента public Form1 () {InitializeComponent (); load_table (); // вызов load_table}

void load_table ()

{MySqlCommand command = new MySqlCommand ("ВЫБРАТЬ * ИЗ patedb.patelog ORDER BY timestamp DESC;", соединение); попробуйте {MySqlDataAdapter adapter = new MySqlDataAdapter (); адаптер. SelectCommand = команда; DataTable dbdataset = новый DataTable (); адаптер. Fill (dbdataset); BindingSource bsource = новый BindingSource (); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; SetRowOrder (); адаптер. Update (dbdataset); } catch (Exception ex) {MessageBox. Show (ex. Message); }}

private void SetRowOrder ()

{dataGridView1. Columns ["PateID"]. DisplayIndex = 0; // Ее имя для колонки ndres dataGridView1. Columns ["timestamp"]. DisplayIndex = 1; // Ее имя для колонки ndres dataGridView1. Columns ["UID"]. DisplayIndex = 2; // Ее значение для колонки ndres dataGridView1. Columns ["weight"]. DisplayIndex = 3; // Ее имя для колонки ndres dataGridView1. Columns ["rangeNr"]. DisplayIndex = 4; // Ее имя для колонки ndres dataGridView1. Columns ["orderID"]. DisplayIndex = 5; // Ее kan rækkefølgen af kolonner ændres}

private void GetData_Click (object sender, EventArgs e) // Читает таблицу базы данных и заказы по метке времени

{load_table (); }

private void btnRefreshUID_Click (отправитель объекта, EventArgs e) //

{строка timeStr = "ВЫБРАТЬ * ИЗ patedb.patelog ЗАКАЗАТЬ ПО UID;"; Команда MySqlCommand = новая MySqlCommand (timeStr, соединение); попробуйте {MySqlDataAdapter adapter = new MySqlDataAdapter (); адаптер. SelectCommand = команда; DataTable dbdataset = новый DataTable (); адаптер. Fill (dbdataset); BindingSource bsource = новый BindingSource (); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; SetRowOrder (); адаптер. Update (dbdataset); } catch (Exception ex) {MessageBox. Show (ex. Message); }}

private void btnRefreshValue_Click (отправитель объекта, EventArgs e)

{string weightSort = "ВЫБРАТЬ * ИЗ patedb.patelog ORDER BY CAST (вес КАК ПОДПИСАННОЕ ЦЕЛОЕ);"; Команда MySqlCommand = новая MySqlCommand (weightSort, соединение); попробуйте {MySqlDataAdapter adapter = new MySqlDataAdapter (); адаптер. SelectCommand = команда; Таблица данных dbdataset = новая таблица данных (); адаптер. Fill (dbdataset); BindingSource bsource = новый BindingSource (); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; SetRowOrder (); адаптер. Update (dbdataset); } catch (Exception ex) {MessageBox. Show (ex. Message); }}

private void ChkNullBtn_Click (отправитель объекта, EventArgs e)

{если (ProdRunning) {CheckTableForNull (); load_table (); }}

частная недействительность CheckTableForNull ()

{// Проверяем / устанавливаем timerinterval минимум 100 мс int i; int. TryParse (textTimer1. Text, out i); если (я <100) {timer1. Stop (); я = 100; timer1. Interval = i; MessageBox. Show ("Минимальное значение 100 мс"); timer1. Start (); } else {timer1. Interval = i; } textTimer1. Text = timer1. Interval. ToString (); // Проверяем, доступны ли в таблице какие-либо строки с нулевым значением, возвращает количество строк в переменной: NumberOfRows string weightStr = ""; string chkNull = "ВЫБРАТЬ СЧЕТЧИК (*) ИЗ patedb.patelog, ГДЕ rangeNR ЕСТЬ NULL ORDER BY PATEID LIMIT 1;"; Команда MySqlCommand = новая MySqlCommand (chkNull, соединение); попробуйте {connection. Open (); NumberOfRows = Convert. ToInt32 (command. ExecuteScalar ()); connection. Close (); } catch (Exception ex) {MessageBox. Show (ex. Message); } finally {if (NumberOfRows! = 0) {try {// Выбирает наименьший номер PateID, где rangeNr равен NULL string readID = "ВЫБРАТЬ PATEID ИЗ patedb.patelog WHERE rangeNR IS NULL ORDER BY PATEID ASC LIMIT 1;"; MySqlCommand cmdID = new MySqlCommand (readID, соединение); {connection. Open (); RowNumber = (int) cmdID. ExecuteScalar (); // целое !! connection. Close (); } listPateID. Text = RowNumber. ToString (); // считываем выбранный номер PateID // Выбираем вес из выбранного номера строки string row = RowNumber. ToString (); string readweight = "ВЫБЕРИТЕ вес ИЗ patedb.patelog WHERE pateID =" + row; MySqlCommand cmdweight = new MySqlCommand (вес чтения, соединение); {connection. Open (); weightStr = (строка) cmdweight. ExecuteScalar (); //Нить !! connection. Close (); } вес = int. Parse (weightStr); // конвертируем в int txtWeight. Text = weight. ToString (); // печать int RangeNumber = 0; if (вес> = пределы [0] && вес = пределы [2] && вес = пределы [4] && вес <= пределы [5]) {RangeNumber = 3; }} txtRange. Text = RangeNumber. ToString (); UpdateLog (); } catch (Exception ex) {MessageBox. Show (ex. Message); } QuantProduced = QuantProduced + 1; }}} private void btnStart_Click (отправитель объекта, EventArgs e) {if (ProdRunning == false) {int valtest; попробуйте {CustomerID = int. Parse (txtCustomerNr. Text); // считываем идентификатор клиента} catch {MessageBox. Show ("Введите производственные данные и нажмите кнопку" Пуск "."); }

строка test = "ВЫБРАТЬ СЧЕТЧИК (*) ИЗ patedb.customertable WHERE customerID =" + CustomerID;

MySqlCommand cmdtestcustomer = new MySqlCommand (тест, соединение); {connection. Open (); valtest = Convert. ToInt32 (cmdtestcustomer. ExecuteScalar ()); // возвращает 0, если клиент не существует соединения. Close (); } if (valtest == 1) // если заказчик существует в базе данных - запускаем производство {try {OrderNr = int. Parse (txtOrderNumber. Text); ProdRunning = true; timer1. Start (); textTimer1. Text = timer1. Interval. ToString (); ReadLimits (); } catch (Exception ex) {MessageBox. Show («Введите производственные данные и нажмите кнопку« Пуск ».»); }} else MessageBox. Show («Клиент отсутствует в базе данных, попробуйте еще раз»); } // ReadLimits (); }

частная недействительность ReadLimits ()

{// Считывает пределы из диапазона от 1 до 3 int counter = 0; for (int rangeNr = 1; rangeNr <4; rangeNr ++) {string readmin = "ВЫБРАТЬ rangeMin ИЗ patedb.rangetable WHERE rangeNr =" + rangeNr; MySqlCommand cmdmin = new MySqlCommand (readmin, соединение); {connection. Open (); пределы [счетчик] = (число) cmdmin. ExecuteScalar (); счетчик = счетчик + 1; connection. Close (); } // MessageBox. Show (counter. ToString ()); string readmax = "ВЫБРАТЬ rangeMax ИЗ patedb.rangetable WHERE rangeNr =" + rangeNr; MySqlCommand cmdmax = new MySqlCommand (readmax, соединение); {connection. Open (); пределы [счетчик] = (число) cmdmax. ExecuteScalar (); счетчик = счетчик + 1; connection. Close (); }} // конец цикла}

частный недействительный UpdateLog ()

{// ОБНОВЛЕНИЕ rangeNR и строки идентификатора заказа Range = RangeNumber. ToString (); строка Order = OrderNr. ToString (); string update = "ОБНОВЛЕНИЕ patedb.patelog SET rangeNr =" + Range + ',' + "orderID =" + OrderNr + "WHERE pateID =" + RowNumber; MySqlCommand updatecmd = new MySqlCommand (обновление, подключение); попробуйте {connection. Open (); updatecmd. ExecuteNonQuery (); connection. Close (); } catch (Exception ex) {MessageBox. Show (ex. Message); }}

private void btnStop_Click (отправитель объекта, EventArgs e)

{если (ProdRunning == true) {timer1. Stop (); ProdRunning = false; UpdateOrderTable (); } else {MessageBox. Show («Производство еще не начато. Введите данные и нажмите кнопку« Пуск »»); }}

приватная недействительная 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 (вставка, соединение); попробуйте {connection. Open (); insertcmd. ExecuteNonQuery (); connection. Close (); QuantProduced = 0; } catch (Exception ex) {MessageBox. Show (ex. Message); }}

private void timer1_Tick (отправитель объекта, EventArgs e)

{CheckTableForNull (); load_table (); }

private void btnShowOrderTable_Click (отправитель объекта, EventArgs e)

{if (ProdRunning == false) {MySqlCommand command = new MySqlCommand ("ВЫБРАТЬ * ИЗ patedb.ordertable ORDER BY orderID DESC;", соединение); попробуйте {MySqlDataAdapter adapter = new MySqlDataAdapter (); адаптер. SelectCommand = команда; Таблица данных dbdataset = новая таблица данных (); адаптер. Fill (dbdataset); BindingSource bsource = новый BindingSource (); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; адаптер. Update (dbdataset); } catch (Exception ex) {MessageBox. Show (ex. Message); }} else {MessageBox. Show ("Нажмите стоп, чтобы просмотреть таблицу заказов"); }}

private void btnShowOrderDetails_Click (отправитель объекта, EventArgs e)

{if (ProdRunning == false) {string test = ("ВЫБРАТЬ patedb.ordertable.orderID, orderQuant, QuantProduced, comment, customerID ИЗ patedb.ordertable ВНУТРЕННЕЕ СОЕДИНЕНИЕ patedb.patelog НА patedb.patelog.orderID = patedb.ordertable.orderID ГДЕ patedb.patelog. UID = '"+ txtShowOrderDetails. Text +"' "); MySqlCommand command = new MySqlCommand (тест, соединение); попробуйте {connection. Open (); Адаптер MySqlDataAdapter = новый MySqlDataAdapter (); адаптер. SelectCommand = команда; Таблица данных dbdataset = новая таблица данных (); адаптер. Fill (dbdataset); BindingSource bsource = новый BindingSource (); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; адаптер. Update (dbdataset); } catch (Exception ex) {MessageBox. Show (ex. Message); } connection. Close (); } else {MessageBox. Show ("Нажмите стоп, чтобы просмотреть детали заказа"); }}

private void btnShowCustomerDetails_Click (отправитель объекта, 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 ГДЕ patedb.ordertable.orderID = '"+ txtShowCustomerDetails. Text +"' "); MySqlCommand command = new MySqlCommand (тест, соединение); попробуйте {MySqlDataAdapter adapter = new MySqlDataAdapter (); адаптер. SelectCommand = команда; Таблица данных dbdataset = новая таблица данных (); адаптер. Fill (dbdataset); BindingSource bsource = новый BindingSource (); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; адаптер. Update (dbdataset); } catch (Exception ex) {MessageBox. Show (ex. Message); }} else {MessageBox. Show ("Нажмите" Стоп, чтобы узнать подробности о клиенте "); }}}

}

Рекомендуемые: