Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Visual2.doc
Скачиваний:
5
Добавлен:
07.03.2016
Размер:
3.31 Mб
Скачать

Void cado6Dlg::OnZapis_Update2()

{

if(pRecordset->GetState()==0)return;

if (!pRecordset->GetRecordCount ())

{

MessageBox("Пустая таблица!!!","Увага!!!",

MB_ICONINFORMATION);

return;

}

_variant_t a;

long i;

time_t time1;

struct tm *tm1;

COleDateTime mytime(2000,1,1,0,0,0);

try

{

FieldPtr field;

for(i=0;i<fields->GetCount ();i++)

{

field = fields->GetItem ((_variant_t)i);

switch(i)

{

case 0:

time(&time1); // time 2 у секунд із 1970 р.

tm1 = localtime(&time1);

a= (long)tm1->tm_sec;

break;

case 1:

a = 20L;

break;

case 2:

a = "Привет";

break;

case 3:

a = mytime;

break;

case 4:

a = 100L;

break;

}

field->Value = a;

}

pRecordset->Update();

}

catch(_com_error &ce)

{

Doc->ErrMessage(ce);

}

}

У даній функції кожному полю за допомогою властивості Value привласнюється відповідне значення типу _variant_t. Після цього необхідно зберегти зміни поточного запису БД за допомогою методу Update(). Тут представлена робота з датою класичними засобами (структура tm), а також з використанням класу COleDateTime.

При роботі з експериментальною таблицею otl_tab часто буває потрібно сформувати її заново. У цьому зв'язку в прикладі ADO6 представлена функція OnFormir_BD() по кнопці <Формирование БД>, у якій відбувається формування таблиці заданими порціями даних. Кожна порція даних повинна бути кратна 100 записам.

Текст даної функції наведений нижче.

// Формування бази із заданими порціями записів

Void cado6Dlg::OnFormir_bd()

{

if(pRecordset->GetState()==0)return;

CString str;

m_editquery.GetWindowText (str);

long per_dob = atol(str.GetBuffer(1));

if( per_dob < 100 || per_dob > 1000000 ||

(per_dob/100. - per_dob/100) > 0.0001)

{

if (MessageBox

("Введите кол-во записей (кратных 100) для одной дополняемой порции", "Ошибка, Повторите Ввод",MB_OKCANCEL) == IDOK)

{

m_editquery.SetFocus();

GetDlgItem(IDC_STATIC3)->

SetWindowText("Введите число кратное 100");

}

else GetDlgItem(IDC_STATIC3)->SetWindowText("");

return;

}

// Видалення записів

try

{

pConn->BeginTrans();

pConn->Execute((_bstr_t)"DELETE FROM otl_tab",0,

adCmdText);

pConn->CommitTrans();

}

catch (_com_error &ce)

{

pConn->RollbackTrans();

// Прив'язка об'єкта Recordset до Datagrid

m_datagrid1.SetRefDataSource(pRecordset);

Doc->ErrMessage(ce);

return;

}

try

{

pRecordset->Requery (-1);//перечитати набір

SAFEARRAY * ar_f;

SAFEARRAY * ar_v;

_variant_t fields,values;

values.vt = VT_ARRAY|VT_VARIANT;

fields.vt = VT_ARRAY|VT_VARIANT;

// Початкова ініціалізація покажчиків

values.parray = 0;

fields.parray = 0;

long i,j,per;

SAFEARRAYBOUND rgsabound;

rgsabound.lLbound = 0;

rgsabound.cElements = 5;

ar_f = SafeArrayCreate(VT_VARIANT, 1, &rgsabound);

ar_v = SafeArrayCreate(VT_VARIANT, 1, &rgsabound);

// Відв’язування об'єкта Recordset від Datagrid

m_datagrid1.SetRefDataSource(0);

// Додавання записів заданими порціями

long povt = -1;

long kol_zapis = 0;

CString mes;

while(1)

{

povt++;

if(kol_zapis > 999000)break;

if(povt)

{

mes.Format("Будете добавлять еще %d записей\nв базе - %d записей", per_dob,pRecordset->GetRecordCount ());

if (MessageBox(mes, Внимание!!!",MB_YESNO) == IDNO)break;

}

for(j = 1+povt*per_dob;j<=per_dob*(1+povt);j++)

{

kol_zapis++;

for(i = 0; i < 5; i++)

SafeArrayPutElement(ar_f, &i, &(_variant_t)i);

i = 0;

per = pRecordset->GetRecordCount();

SafeArrayPutElement(ar_v, &i, &(_variant_t)per);

i++;

SafeArrayPutElement(ar_v, &i, &(_variant_t)j);

i++;

SafeArrayPutElement(ar_v, &i, &(_variant_t)"aaaa");

i++; // Дата

COleDateTime mytime(2000,1,1,0,0,0);

SafeArrayPutElement(ar_v, &i, &(_variant_t)mytime);

i++; // Логіка

per = 0;

SafeArrayPutElement(ar_v, &i, &(_variant_t)per);

fields.parray = ar_f;

values.parray = ar_v;

pRecordset->AddNew(fields,values);

}

}

GetDlgItem(IDC_STATIC3)->SetWindowText("");

}//end try

catch (_com_error &ce)

{

Doc->ErrMessage(ce);

}

// Прив'язка об'єкта Recordset до Datagrid

m_datagrid1.SetRefDataSource(pRecordset);

}

Спочатку в змінну per_dob типу long записується значення рядка, введене в текстове поле m_editquery. У цьому випадку для перетворення рядка в число використовується функція atol(). Входом у цю функцію є char*. Щоб зі змінної класу CString одержати вказівку на char, доцільно скористатися функцією GetBuffer(), входом у яку є мінімальна кількість символів. Якщо довжина рядка більше чим це число, то буде виведений буфер під довжину рядка, інакше він буде виведений під задану величину. Якщо повернута функцією GetBuffer() вказівка на char використовується для внесення змін у текстовий рядок, то перед тим як звертатися до будь-яких інших функцій даного класу, необхідно викликати функцію ReleaseBuffer().

У тому випадку, якщо кількість записів у порції менше 100 або більше 1000000, або введене число порції записів не кратне 100, – виведеться відповідне повідомлення про помилку та буде здійснений вихід з функції.

На наступному етапі видаляються всі записи таблиці otl_tab, використовуючи SQL-запит на видалення. Потім створюються динамічні масиви ar_f, ar_v типу VARIANT, у які будуть записуватися відповідно індекси й значення полів знову доданого запису, а також робиться відв’язування об'єкта Recordset від елемента керування Datagrid. Відразу оголошуються змінні fields та values типу _variant_t, у які будуть передані вказівки на масиви SAFEARRAY типу VARIANT.

Увага!!! При роботі із класом _variant_t при передачі вказівки на масив SAFEARRAY існує наступна особливість: після присвоєння типу масиву vt (у нашому випадку, масив варіантів – VT_ARRAY|VT_VARIANT) необхідно ініціалізувати початкові вказівки на масив нульовими значеннями. Інакше при достроковому виході з функції, якщо дані вказівки не будуть проініціалізовані, – програма спробує звільнити відповідні вказівки, у яких перебуває "бруд", і буде виведене повідомлення про помилку.

Після цього здійснюється додавання записів заданими порціями. Із цією метою введена змінна povt, що відповідає за кількість порцій даних. У вічному циклі while(1) вона постійно накопичується. До циклу їй привласнюється значення -1. Потім вона накопичується й приймає значення 0. У циклі while() розташований цикл for() за допомогою якого додаються записи однієї порції. Він виглядає наступним чином:

for(j = 1+povt*per_dob;j<=per_dob*(1+povt);j++)

{

// тіло циклу

}

У даному циклі змінна per_dob – це кількість записів у заданій порції. Так, спочатку змінна povt дорівнює нулю, тобто буде записана перша порція даних (від 1 до per_dob), потім, коли буде записуватися друга порція даних – змінна povt дорівнює 1 (від 1+per_dob до 2*per_dob) і т.д. При кожній новій порції даних, починаючи з другої, на екран буде виводитися повідомлення про виведення нової порції записів, де користувачеві надається можливість або додати чергову порцію записів, або відмовитися. При відмові буде здійснений вихід з вічного циклу while(1). Крім того, якщо кількість записів перевищить 999000, також буде здійснений вихід з вічного циклу. Всі записи в даній функції додаються за допомогою методу AddNew() з параметрами. Наприкінці виконання функції здійснюється прив'язка об'єкта Recordset до елемента керування Datagrid.

З допомогою кнопки <Значение полей> (функція відгуку OnValues_Fields()) виводяться значення полів поточного запису, а також здійснюються арифметичні операції над полями таблиці otl_tab.

Текст даної функції відгуку наведений нижче.

// кнопка <Значение полей>

// Виведення значень полів і розрахункові операції

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]