- •О.С. Зеленський
- •Розділ 9. Структура створення додатків
- •9.1. Загальна структура додатків
- •9.2. Додатки без використання архітектури «Документ-вид»
- •9.2.1. Приклад додатку реєстрації wnd-класу вікна
- •9.2.2. Створення та видалення дочірніх вікон без використання архітектури «Документ-Вид»
- •9.2.3. Створення дочірніх вікон без використання архітектури «Документ-Вид» (переключення вікон з використанням функції ShowWindow)
- •9.3. Архітектура «Документ-Вид»
- •Idr_mainframe формат строкового ресурсу.
- •9.3.1. Приклад додатку з використанням архітектури «Документ-Вид»
- •9.3.2. Види у архітектурі «Документ-Вид»
- •9.3.3. Створення видів у архітектурі «Документ-Вид» (переключення видів з використанням функції ShowWindow)
- •9.3.4. Робота з документами та видами на прикладі додатку SingleTemplate
- •9.4. Додатки mdi, робота з шаблонами
- •9.4.1. Приклад додатку mdi з одним шаблоном
- •9.4.2. Приклад додатку mdi з декількома шаблонами
- •Контрольні питання
- •Розділ 10. Робота з базами даних з використанням об'єктів ado
- •10.1.1. Ініціалізація об'єктів com з використанням директиви #import
- •10.1.2. Підтримка класів сом
- •10.2. Об'єкт Connection
- •10.3. Об'єкт Command
- •10.4. Об'єкт Recordset
- •10.5. Об'єкт Field і колекція Fields
- •10.6. Об'єкт Error і колекція Errors
- •10.8. Коротка характеристика структури мови sql
- •10.9. Синтаксис оператора вибору Select
- •10.10. Приклад програмування об'єктів ado
- •10.11. Опис розробленого навчального пакету ado6 для роботи з базами даних access та MySql
- •Int tip_bd; // тип бд 1- ms access, 2- MySql, 3 - xml
- •Void Connect_Baza(cString str);
- •Void ErrMessage(_com_error &ce);
- •If(pConn.CreateInstance("adodb.Connection"))
- •If(pRecordset.CreateInstance("adodb.RecordSet"))
- •Void cAdo6Doc::ErrMessage(_com_error &ce)
- •Void cAdo6Doc::OnMsaccess()
- •Void cAdo6Doc::OnMysql()
- •Void cAdo6Doc::OnXmlRead()
- •Void cAdo6Doc::Connect_Baza(cString str)
- •Virtual void DoDataExchange(cDataExchange* pDx);
- •Void cAdo6Dlg::DoDataExchange(cDataExchange* pDx)
- •Void cAdo6Dlg::Struct_MySql()
- •Void cAdo6Dlg::OnSelchangeListBaza()
- •Void cAdo6Dlg::OnVibor_bd()
- •Void cAdo6Dlg::AccessOpen()
- •Void cAdo6Dlg::xmlOpen()
- •Void cAdo6Dlg::Structura_bd()
- •Void cAdo6Dlg::OnSelchangeListTab()
- •Void cAdo6Dlg::show(int kod, int kod_bd)
- •Void cAdo6Dlg::Recordset_Baza(cString str)
- •Void cAdo6Dlg::OnClose()
- •10.11.2. Формування списку бд (MySql), відкриття бази даних (ms access), відкриття xml-файлу, формування списку таблиць (MySql і ms access) та полів (MySql, ms access, xml)
- •Void cAdo6Dlg::OnSelchangeListTab()
- •1. Обрану таблицю необхідно брати в зворотні лапки "`", щоб виключити помилку в тому випадку, якщо в імені таблиці будуть зустрічатися пробіли.
- •10.11.3. Робота з sql-запитами
- •Void cAdo6Dlg::OnZapros_Select()
- •If (str_query.Mid(0,6).Compare("select"))
- •If(!baza.Left(3).Compare("otl") &&
- •Void cAdo6Dlg::Recordset_Baza(cString str)
- •Void cado6Dlg::OnZapros_Make()
- •Vr_zap.Format(" Запрос выполнен за %f сек ",conec - nach);
- •10.11.4. Видалення, сортування, пошук, фільтрація, оновлення набору записів
- •Void cado6Dlg::OnZapis_Delete()
- •Void cado6Dlg::OnCheck_Sort()
- •Void cado6Dlg::OnFind()
- •0L,adSearchForward,bb);
- •Void cado6Dlg::OnFilter()
- •Void cado6Dlg::OnVozvrat()
- •10.11.5. Переходи по записах
- •Void cado6Dlg::OnButtonFirst()
- •Void cado6Dlg::OnButtonLast()
- •Void cado6Dlg::OnButtonLeft()
- •Void cado6Dlg::OnButtonRight()
- •Void cado6Dlg::OnButtonRecno()
- •Void cado6Dlg::OnButtonPgup()
- •Void cado6Dlg::OnButtonPgdn()
- •Void cado6Dlg::OnButtonBookmark()
- •10.11.6. Запис даних до xml-файлу
- •Void cAdo6Dlg::OnButtonSave()
- •10.11.7. Кнопки, призначені тільки для роботи з otl_tab
- •Void cado6Dlg::OnZapis_Add1()
- •Void cado6Dlg::OnZapis_Add2()
- •Void cado6Dlg::OnZapis_Update1()
- •Void cado6Dlg::OnZapis_Update2()
- •Void cado6Dlg::OnFormir_bd()
- •Void cAdo6Dlg::OnValues_Fields()
- •10.12. Використання у якості джерела даних електронної таблиці Excel
- •Контрольні питання
- •Завдання
- •Розділ 11. Програмування для інтернет
- •11.1. Створення броузера
- •11.3. Використання протоколу http
- •If ((pInternetSession)
- •11.4. Використання протоколу ftp
- •Контрольні питання
- •Розділ 12. Створення елементів activex
- •12.1. Створення елементів ActiveX
- •Invalidate();
- •12.2. Тестування елемента ActiveX
- •12.4. Створення елемента ActiveX на базі стандартних елементів
- •12.5. Відображення елементів ActiveX
- •Контрольні питання
- •Розділ 13. Налагодження програм
- •Int data[5];
- •Invalidate();
- •13.3. Установка точки переривання
- •13.2. Покрокове виконання програми
- •13.4. Перевірка значень змінних під час виконання програми
- •Контрольні питання
- •Список літератури
- •Додатки
Void cAdo6Dlg::OnValues_Fields()
{
if(pRecordset->GetState()==0)return;
int kol_zap = pRecordset->GetRecordCount ();
if (!kol_zap)
{
MessageBox("Пустая таблица!!!","Внимание!!!",
MB_ICONINFORMATION);
return;
}
try
{
// ------------------ Виведення полів ---------------------
long i;
_bstr_t zn;
_variant_t pol,vr;
pol = (long)0;
CString str="";
char buf[100];
for(i=0;i<fields->GetCount();i++)
{
vr = fields->GetItem((_variant_t)i)->GetValue();
zn = "NULL";
if (vr.vt!= VT_NULL) zn = vr;
str+= zn;
str+=" ";
}
MessageBox(str);
// Кінець виведення полів
// Обчислювальні операції по першому поточному запису
int d1,d2;
pol = (long)0;
pRecordset->MoveFirst();
vr = fields->GetItem(pol)->GetValue();
d1 = 0;
if (vr.vt!= VT_NULL) d1 = vr.iVal ;
pol = (long)1;
vr = fields->GetItem(pol)->GetValue();
zn = "0";
if (vr.vt!= VT_NULL) zn = vr ;
d2 = d1 + atoi(zn);
sprintf(buf,"Сумма первых двух полей = %d",d2);
MessageBox(buf);
// Обчислення середнього арифметичного - Варіант 1
m_datagrid1.SetRefDataSource(0);// Відв’язка від datagrid
double sum = 0;
int kol = 0;
for(i = 0; i < kol_zap;i++)
{
vr = fields->GetItem(pol)->GetValue();
if (vr.vt!= VT_NULL){kol++;sum+= vr.iVal ;}
pRecordset->MoveNext();
}
if(kol)sprintf(buf," Среднее арифметическое = %f %d ",
sum/kol, kol);
else sprintf(buf,"Данные по полю kod не заполнены");
MessageBox(buf);
// --------------------------------------------------------
// Обчислення середнього арифметичного - Варіант 2
// --------------------------------------------------------
sum = 0;
kol = 0;
pRecordset->MoveFirst();
while(!pRecordset->ADO_EOF)
{
vr = fields->GetItem(pol)->GetValue();
if (vr.vt!= VT_NULL){kol++;sum+= vr.iVal ;}
pRecordset->MoveNext();
}
if(kol)sprintf(buf," Среднее арифметическое = %f %d ",
sum/kol, kol);
else sprintf(buf,"Данные по полю kod не заполнены");
pRecordset->MoveFirst();
// Прив'язка до datagrid
m_datagrid1.SetRefDataSource(pRecordset);
MessageBox(buf);
// ---------------------------------------------------
// РОБОТА З DATE
//---------------------------------------------------
// ПЕРЕТВОРЕННЯ з рядка ASCII в UNICODE і навпаки
// -------------------------------------------------
char pp[] ="ABCD"; // 1 байт на символ
_bstr_t ww = pp;
BSTR tt = ww.copy(); // 2 байти на символ
char* hh = (char*)tt; // псується рядок
LPSTR j = (char*)ww; // рядок стискується - символ 1 байт
sprintf(buf," -і %c -і %c -і %c -і %c",
hh[0],hh[2],hh[4],hh[6]);
MessageBox(buf);
// ----------------------------------------------------
}
catch(_com_error &ce)
{
Doc->ErrMessage(ce);
}
}
Спочатку у функції відгуку, у змінну str типу CString записуються дані всіх полів поточного запису за допомогою змінної zn класу _bstr_t, що привласнюється значення відповідного поля, що має тип _variant_t.
Увага!!! Варто звернути увагу на контроль порожніх значень полів у наборі Recordset. Так, при зчитуванні даних з полів таблиці БД, необхідно здійснити перевірку типу даних змінної варіант (_variant_t.) на VT_NULL. І тільки в тому випадку, якщо значення типу _variant_t (параметр vt) не дорівнює VT_NULL, можна робити з полем різні операції, інакше поле має порожнє значення, і можуть виникати помилки, наприклад, при виконанні розрахункових операцій із числовими даними.
На другому етапі складаються значення двох цілих полів, відповідно id та kod. Значення поля id повертається через змінну ival, що входить в об'єднану структуру VARIANT, а значення поля kod приводиться до змінного класу _bstr_t, для одержання цілого значення якої використовується функція atoi().
На наступному етапі обчислюється середнє арифметичне значення поля id. У цьому випадку використовуються два варіанти проходу по набору Recordset. У першому випадку у якості межі використовується кількість записів (метод GetRecordCount()), у другому – контролюється змінна кінця набору записів ADO_EOF. На початку цього етапу здійснюється відв’язка об'єкта Recordset від Datagrid, а наприкінці – прив'язка. Причому, при підрахунку середнього арифметичного порожні записи в таблиці ігноруються. У цьому зв'язку розраховується сума й кількість для тих записів, які не мають нульове значення по полю id (параметр vt відмінний від VT_NULL).
В даному фрагменті становить особливий інтерес перетворення рядка в кодування Unicode і назад. При використанні кодування Unicode рядкові змінні складаються з 16-розрядних символів (2 байти). Для стандартного кодування Windows вони складаються з 8-розрядних символів.
Приведемо фрагмент тексту програми перекладу в кодування Unicode і назад:
.........................................................................................................
char pp[] ="ABCD"; // 1 байт на символ
_bstr_t ww = pp;
BSTR tt = ww.copy(); // 2 байти на символ
char* hh = (char*)tt; // псується рядок
LPSTR j = (char*)ww; // рядок стискується - символ 1 байт
.........................................................................................................
Слід зазначити, що класи COM-об'єктів, такі як _variant_t, _bstr_t працюють із кодуванням Unicode. Для перетворення звичайного рядка типу (char*) до 16-розрядного кодування, необхідно створити об'єкт класу _bstr_t і привласнити його вихідному рядку. У даному фрагменті об'єкту ww типу _bstr_t привласнюється рядок "ABCD". Якщо привести це рядок до (char*) – він стиснеться, і буде мати місце 8-розрядне кодування (це зроблено за рахунок перевантаження операторів класу _bstr_t). Якщо ж використати об'єкт tt стандартної структури BSTR (метод copy() класу _bstr_t), то при приведенні його до (char*) рядок буде займати 2 байти (16-розрядне кодування Unicode). За допомогою реалізації даного механізму можна встановити кодування, що цікавить користувача, – стандартне або Unicode.