Останній приклад: робота з базами даних в CBuilder

Без сумніву, ви тепер захочете використовувати в своїх додатках MFC всі ті розвинені можливості роботи з базами даних, які можуть надати обєкти VCL В останньому прикладі взаємодії MFC і VCL ми подивимося, як перетворити попередній приклад в додаток-записну книжку, що використовує базу даних для зберігання інформації, введеної користувачем

На рис 124 показана нова форма, яку нам треба додати в DLL При цьому для роботи з новою DLL нам не доведеться нічого змінювати в додатку Visual C + +, створеному в попередньому прикладі, оскільки інтерфейс залишиться незмінним

Рис 124 Форма вибору записів

Якщо ви досить давно працюєте в Visual C + +, то швидше за все припустіть, що для роботи з базами даних через обєкти VCL спочатку треба провести якусь їх ініціалізацію На щастя, ви будете не праві VCL використовує статичні бібліотеки, яким ніяка ініціалізація не потрібна, а компоненти VCL самі знають, коли треба відкрити, закрити або ініціалізувати машину баз даних Коротше кажучи, все це відбувається, так сказати, за лаштунками і не вимагає вашого втручання

У даному прикладі ми надамо користувачеві можливість шукати та переглядати значення в базі даних Користувач зможе ввести деяке значення (в тому числі використовує

символи і * для пошуку множини значень), а потім вибрати потрібну адресу зі списку знайдених адрес

Вам доведеться внести зміни до форми, що відображає інформацію про людину та його адресу Тепер на цій формі треба розмістити ще одну кнопку – Пошук, яка використовуватиметься для пошуку введених значень Для цієї кнопки треба додати обробник події (натискання на кнопку), в який слід внести наступні рядки:

void __fastcall TForm1::Button2Click(TObject *Sender)

{

AnsiString strSearch = &quot" AnsiString s = Edit1-&gtText

/ / Перевіряємо кожне поле введення

if ( Edit1-&gtTextLength() )

{

strSearch += &quotLASTNAME = " strSearch += Edit1-&gtText strSearch += &quot’"

}

if ( Edit2-&gtTextLength() )

{

if ( strSearchLength() = 0 ) strSearch += &quot AND "

strSearch += &quotFIRSTNAME = " strSearch += Edit2-&gtText strSearch += &quot’"

}

if ( Edit3-&gtTextLength() )

{

if ( strSearchLength() = 0 ) strSearch += &quot AND "

strSearch += &quotADDRESS_1 = "

strSearch += Edit3-&gtText strSearch += &quot’"

}

if ( Edit4-&gtTextLength() )

{

if ( strSearchLength() = 0 ) strSearch += &quot AND "

strSearch += &quotADDRESS_2 = "

strSearch += Edit4-&gtText strSearch += &quot’"

}

if ( Edit5-&gtTextLength() )

{

if ( strSearchLength() = 0 ) strSearch += &quot AND " strSearch += &quotCITY = " strSearch += Edit5-&gtText strSearch += &quot’"

}

if ( Edit6-&gtTextLength() )

{

if ( strSearchLength() = 0 ) strSearch += &quot AND " strSearch += &quotSTATE = " strSearch += Edit6-&gtText strSearch += &quot’"

}

if ( Edit7-&gtTextLength() )

{

if ( strSearchLength() = 0 ) strSearch += &quot AND " strSearch += &quotZIP_CODE = " strSearch += Edit7-&gtText strSearch += &quot’"

}

TForm2 *pForm = new TForm2(NULL) pForm-&gtSetSearchString(strSearch) pForm-&gtShowModal()

/ / Копіюємо значення з бази даних

Edit1-&gtText = pForm-&gtTable1-&gtFieldValues[&quotLASTNAME&quot] Edit2-&gtText = pForm-&gtTable1-&gtFieldValues[&quotFIRSTNAME&quot] Edit3-&gtText = pForm-&gtTable1-&gtFieldValues[&quotADDRESS_1&quot] Edit4-&gtText = pForm-&gtTable1-&gtFieldValues[&quotADDRESS_2&quot] Edit5-&gtText = pForm-&gtTable1-&gtFieldValues[&quotCITY&quot]

Edit6-&gtText = pForm-&gtTable1-&gtFieldValues[&quotSTATE&quot] Edit7-&gtText  = pForm-&gtTable1-&gtFieldValues[&quotZIP_CODE&quot] delete pForm

}

Наведений код досить обємний, але абсолютно нескладний Ми перевіряємо кожне поле редагування форми на предмет того, ввів туди користувач якесь значення чи ні Якщо так, то ми робимо додавання в рядок пошуку, яка буде передана базі даних для використання в якості фільтра Тобто ми формуємо рядок виду:

FIELD=Value AND FIELD=Value

де FIELD – Одне з полів нашої бази даних, а Value – Рядок, введена користувачем, що представляє собою значення для даного поля, за яким користувач хоче здійснити пошук Коротше кажучи, ми створюємо форму QBE (Query By Example, запит за прикладом), яка додасть ці можливості в додаток Visual C + + В принципі, можна створювати запити QBE і в Visual C + +, але це малоприємне заняття Воно являє собою або створення запитів SQL часу виконання з наступним отриманням з них необхідних полів, або написання абсолютно жахливих параметричних запитів А в CBuilder ми створили все, що нам було потрібно, за допомогою декількох простих рядків коду, представляють собою зіставлення імен полів і введених значень

Тепер, коли рядок для пошуку створена, треба відфільтрувати базу даних і показати користувачеві всі записи, що задовольняють введеним ним обмеженням Якраз для цього ми й використовуємо нову форму (Form2) На цій формі міститься вікно списку, в якому будуть відображатися відфільтровані записи, з яких користувач і робитиме остаточний вибір

Форма вибору записів містить два елементи – вікно списку (list box) і кнопку OK Список міститиме записи, з яких користувач буде здійснювати вибір За натисканні кнопки OK форма буде закриватися, повідомляючи зухвалій формі, що запис з бази даних була благополучно вибрана

Перше, що треба зробити в цій формі, – забезпечити завантаження списку записів Ми не можемо зробити це безпосередньо при створенні форми, так як на момент її створення рядок пошуку ще не буде визначена Зате ми можемо визначити метод, який викликає форма (Form1) може використовувати для завдання рядка пошуку Давайте подивимося на код цього методу:

void TForm2::SetSearchString(AnsiString strSearch)

{

Table1-&gtFilter = strSearch Table1-&gtFiltered = true

/ / Вантажимо елементи в список

Table1-&gtFirst()

while ( Table1-&gtEof )

{

AnsiString s = Table1-&gtFieldValues[&quotLASTNAME&quot] s += &quot,"

s += Table1-&gtFieldValues[&quotFIRSTNAME&quot]

ListBox1-&gtItems-&gtAdd( s ) Table1-&gtNext()

}

}

У цьому коді таблиця бази даних фільтрується (як фільтр використовується рядок пошуку, певна нами в обробнику для кнопки Пошук у формі Form1), а потім у циклі якась інформація з кожного запису поміщається в список В даному випадку в список завантажується рядок виду ПРІЗВИЩЕ, ІМЯ (поля таблиці LASTNAME, FIRSTNAME), але при бажанні ви, звичайно, можете завантажувати в нього й іншу інформацію Можливо, було б навіть зручніше відображати не список, а сітку, що містить всі дані, але для нашого прикладу вистачить і цього Зверніть увагу на те, що нам немає необхідності очищати список перед завантаженням у нього даних, оскільки для кожного нового пошуку форма створюється заново, а потім знищується

Останнє, що нам треба обробити, – це ситуацію, коли користувач вибирає якийсь запис зі списку і натискає кнопку OK Все, що нам треба при цьому зробити, – це встановити покажчик в базі даних (Не плутайте з покажчиками-адресами змінних, до яких ви звикли в C, – в базах даних цей термін позначає зовсім інше) на обраний запис На даний момент таблиця все ще «видна» викликає формі (це обєкт, визначений як

__published), Так що ми без праці можемо прочитати з неї необхідну інформацію Ось як виглядає код, що обробляє натискання кнопки OK:

void __fastcall TForm2::Button1Click(TObject *Sender)

{

if ( ListBox1-&gtItemIndex == -1 ) return

/ / Переміщаємо покажчик до потрібної записи

Table1-&gtFirst()

for ( int i=0 i&ltListBox1-&gtItemIndex ++i )

Table1-&gtNext() Close()

}

Код цей гранично прямолінійний і прозорий Спочатку ми перевіряємо, чи дійсно користувач вибрав якесь значення у списку Якщо ні, функція повертає управління Якщо ж яка-небудь запис була обрана, ми переміщаємо покажчик в таблиці бази даних на цей запис – для цього ми просто переміщаємося по записах таблиці до тих пір, поки не доберемося до потрібного запису Після цього ми закриваємо форму при посередництві методу Close класу TForm

Відразу після закриття цієї форми функція ShowModal поверне управління зухвалій формі Тут хочеться відзначити, що замість використання методу Close можна було б просто привласнити властивості ModalResult другої форми значення, відмінне від 0, при цьому форма б точно так же закрилася і передала це значення в зухвалу форму

Повернувшись в зухвалу форму, ми читаємо дані з таблиці і заносимо їх у відповідні поля редагування Це дозволить користувачеві відредагувати їх перед тим, як форма буде закрита і вони будуть передані в зухвалу програму Visual C + + Останнє, що повинен забезпечити код форми Form1, – це видалити обєкт Form2, Оскільки саме в цьому коді виділялася під нього память Якщо цього не зробити, відбудеться витік оперативної памяті (витік ресурсів), оскільки цей обєкт вже ніколи не буде видалений з памяті після завершення роботи програми Витік ресурсів може привести до збою операційної системи, так що давайте самі видаляти за собою все, що створювали

Тепер мені хотілося б зупинитися на деяких моментах, повязаних з нашим невеликим додатком По-перше, як ми побачили, ініціалізація бази даних здійснюється безпосередньо всередині компонентів, працюють з базою Раджу вам перенести цей підхід на всі свої компоненти Якщо ви маючи на увазі ете, що щось вже встановлено (визначено, ініціалізувати і тп), але це мо же бути не так, встановлюйте це у своїх компонентах самі Не чекайте, що кінцевий користувач сам встановить за вас які-небудь глобальні змінні або викличе глобальні функції, адже якщо він цього все ж не зробить, вся ваша система, що базується на ваших компонентах, не працюватиме так, як ви (і кінцевий користувач) очікуєте У компонентах всі необхідні для їх роботи речі повинні визначатися всередині них – не треба нічого залишати на користувача

Далі хотілося б відзначити, що форми можна створювати не тільки в обгорткового функції вашої DLL, а й в інших формах При цьому треба твердо памятати, що память, яку ви споживаєте, належить зухвалому додатком, і не забувати звільняти її Під обєкт, переданий в обгортковий функцію DLL (у нас це TAddress), Функціями DLL память не виділяється, так що про це повинні подбати ви самі

І останнє, про що хочеться сказати з приводу нашого застосування, – якщо під час виконання відбудеться помилка, система обробки виняткових ситуацій CBuilder автоматично перехопить її, навіть якщо вами не визначений спеціальний обробник для цієї ситуації Це може бути дуже важливо для програміста, який розробляє програми Ви як і раніше можете використовувати в своєму коді блоки try .. catch і навіть сміливо розраховувати на те, що виняткові ситуації, не оброблені вами, обробить що лежить в основі вашого коду VCL Якщо виняткова ситуація сталася в DLL, то, як правило, можна вважати, що метод всетаки буде виконаний до кінця Це відноситься, природно, тільки до тих винятковим ситуацій, які не є фатальними ці тут же припинять виконання функції Постарайтеся обробити в своєму коді якомога більше виняткових ситуацій, щоб можливо менша їх кількість проходило повз вашу увагу і збивало роботу вашої програми

На цьому наш приклад завершений Відзначте, що ми не внесли ніяких змін ні в обгортковий функцію DLL, ні в що викликає додаток MFC в порівнянні з попереднім прикладом Всі зміни укладені всередині однієї з форм DLL, так що більше нікому знати про них не треба Згадайте – адже нам навіть не довелося генерувати нову бібліотеку імпорту для нашої DLL Правда, здорово

Джерело: Теллес М – Borland C + + Builder Бібліотека програміста – 1998

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*