Рефераты. Создание приложения ODBC

BOOL CPrimView::OnMove(UINT nIDMoveCommand)

{

// TODO: Add your specialized code here and/or call the base class

           

// Проверяем, в каком режиме — добавления или перемещения -

// мы находимся

if(m_bAdd)  {


// «Выходим из режима добавления»

m_bAdd=false;


UpdateData();


if  (m_pSet->CanUpdate() )

m_pSet->Update() ;

m_pSet->Requery();

UpdateData(FALSE);

return TRUE;

            }

            else

// Переходим к следующей записи в результирующем наборе

return CRecordView::OnMove(nIDMoveCommand);

}



Рассмотрим логику работы функции OnMove. Если мы попали в нее после ввода новой записи (установлен флаг m_bAdd), то переписываем введенные значения в базу данных. В противном случае просто переходим к следующей записи. Нас, естественно, интересует режим добавления. Прежде всего необходимо прочитать данные из элементов управления формы. Обратите внимание, что переменные класса CDBView определены так, что мы это делаем непосредственно в результирующий набор, используя функции обмена полями данных, например, для поля IDC_PROD.


DDX_FieldText(pDX, IDC_PROD, m_pSet->m_ProductName, m_pSet);


Если никакой ошибки не произошло, то перечитаем информацию из базы данных, чтобы работать с самым последним набором. Теперь осталось только обновить элементы управления в форме. Помните, в функции OnRecordAppend мы перед входом в режим добавления переместились на первую запись результирующего набора. Поэтому необходимо вызвать функцию UpdateData(FALSE), чтобы отобразить ее в элементах управления формы. И, наконец, не забываем сбросить флаг m_bAdd, чтобы избежать ошибок.


Вернемся к табл.1, где представлены поля таблицы jobs. Видим, что у столбца job_id установлен тип данных IDENTITY. Это означает, что система управления базами данных сама позаботится о присвоении значения этому столбцу. Чтобы решить эту проблему достаточно поменять переменную, с которой связан элемент управления IDC_EDIT4 (например, на m_job_Nom типа long), и тем самым переложить задачу на СУБД.

Кроме этого, в код требуется также добавить одну строку, чтобы можно было видеть информацию об идентификаторе job_id.





void CPrimView::DoDataExchange(CDataExchange* pDX)

{// Для отображения значений поля job_id таблицы

 // необходимо выполнить присваивание 

m_job_Nom= m_pSet->m_job_id ;

// Осуществляем обмен данными с элементами управления в форме


            CRecordView::DoDataExchange(pDX);

            //{{AFX_DATA_MAP(CPrim_1View)

            DDX_FieldText(pDX, IDC_EDIT3, m_pSet->m_min_lvl, m_pSet);

            DDX_FieldText(pDX, IDC_EDIT2, m_pSet->m_max_lvl, m_pSet);

            DDX_FieldText(pDX, IDC_EDIT1, m_pSet->m_job_desc, m_pSet);

            DDX_Text(pDX, IDC_EDIT4, m_job_Nom);

            //}}AFX_DATA_MAP


           

}




Уберем значение идентификатора с экрана на время вставки новой записи. Для этого немного модифицируем код в двух функциях OnRecordAppend и On Move, как

показано ниже.


void CPrimView::OnRecordAppend()

{

            // TODO: Add your command handler code here

            // Сначала проверяем, не была ли открыта база данных 

// в режиме только для чтения. Если это так, 

//то выводим предупреждение и выходим из функции 

 

if(m_pSet->CanAppend() == 0)

MessageBox("Можно только просматривать записи", 

"Ошибка добавления записи", 

 MB_OK | MB_ICONWARNING); 

else 

{


// Скрываем элементы управления на время ввода новой записи

GetDlgItem(IDC_EDIT4)->ShowWindow(SW_HIDE);


// Устанавливаем фокус на поле ввода названия

GetDlgItem(IDC_EDIT1)->SetFocus();


// Перемещаемся на первую запись

m_pSet->MoveFirst();


// Создаем пустую запись,

//в которую пользователь будет вводить значения


m_pSet->AddNew();

// Устанавливаем флаг перехода в режим добавления записи

 m_bAdd = TRUE; 


// Обновляем поля формы

UpdateData(FALSE);}

           

}




BOOL CPrimView::OnMove(UINT nIDMoveCommand)

{

// TODO: Add your specialized code here and/or call the base class

           

// Проверяем, в каком режиме — добавления или перемещения -

// мы находимся

if(m_bAdd)  {


// «Выходим из режима добавления»

m_bAdd=false;


// После завершения ввода снова отображаем элементы управления


GetDlgItem(IDC_EDIT4)->ShowWindow(SW_SHOW);


UpdateData();


if  (m_pSet->CanUpdate() )

m_pSet->Update() ;

m_pSet->Requery();

UpdateData(FALSE);

return TRUE;

            }

            else

// Переходим к следующей записи в результирующем наборе

return CRecordView::OnMove(nIDMoveCommand);

}



После внесения этих изменений скомпилируйте и запустите приложение.


После нажатия кнопки New Record и ввода информации о новой должности основное окно будет иметь вид представленный на рис. 16.



Рис. 16. Так теперь выглядит основное окно приложения в режиме ввода новой записи в базу данных


Итак, теперь мы умеем обновлять и добавлять записи в базу данных. Следующим шагом является удаление записей.

 

 

4.     Удаление записей из таблицы.

Как обычно, начнем с того, что добавим в наше приложение кнопку на панели инструментов, нажатие на которую позволит перейти в режим удаления. Создайте функцию OnRecordDelete, воспользовавшись стандартной описанной ранее.


void CPrimView::OnRecordDelete()




Правила хорошего тона требуют, чтобы перед удалением пользователю был задан вопрос, хорошо ли он подумал и не случайно ли нажал кнопку удаления. Если запись действительно надо удалить, то смело нажимайте кнопку ОК, после чего будет вызвана функция Delete класса CRecordset, которая проведет корректное удаление записи из базы данных. Чтобы обновить набор, с которым мы работаем, необходимо вызвать функцию Requery, иначе мы будем продолжать работать с записью, которой в базе данных уже нет. Этот шаг был бы не нужен, если бы мы работали с динамическим набором  — как вы помните, в этом случае результирующий набор обновляется одновременно с обновлением базы данных. Новыми при удалении являются следующие два действия — проверка на выход за начало и конец записей. Действительно, если мы переместились (вызов функции MoveNext) за последнюю запись (проверка if (m_pSet->isEOF ())), то непонятно, на что в этом случае будет указывать указатель. Поэтому его нужно установить на последнюю запись результирующего набора (вызов m_pSet->MoveLast ()). Аналогичные действия необходимо предпринять для проверки на выход за "левую границу", т. е. за первую запись (вызов if (m_pSet->isBOF())). Эта ситуация возникает тогда, когда из таблицы удаляется последняя строка и требуется очистить поля единственной пустой строки (ВЫЗОВ m_pSet->SetFieldNull (NULL) ).

Как и в случае обновления и добавления новой записи, здесь также всю основную работу делает библиотека MFC, а точнее, ее класс CRecordset.


 

5.     Сортировка записей.

Для демонстрации этой возможности создадим специальные элементы меню, внешний вид которых представлен на рис 17. Используем для организации сортировки два критерия: по идентификатору должности, по названию. Для создания элементов меню откройте окно Resource ViewMenu и дважды щелкните левой кнопкой мыши на идентификаторе ресурса IDR_MAINFRAIM. В строке заголовков меню введите текст &Sort (Сортировка) и добавьте подпункты - &ID_JOB и &JOB_NAME (с именами S_JOB_ID и S_JOB_DESC, а также соответствующими подсказками типа Sort by job_id\nJOB_ID sort).



Рис. 17. Окно свойств элементов меню



После того, как элементы меню созданы и им присвоены соответствующие идентификаторы, необходимо создать обработчик соответствующих команд (воспользуйтесь ClassWizard аналогично построению функций для кнопок).












//Сортировка


void CPrimView::OnSortJobId()

{

            OnSort("job_id");

           

}




void CPrimView::OnSortJobDesc()

{

            OnSort("job_desc");

}



Добавьте  в класс  CPrimView функцию OnSort, непосредственно осуществляющую сортировку по записям.



//Сортировка по записи



Рис. 18


void CPrimView::OnSort(CString szText)

{


m_pSet->Close ();

 m_pSet->m_strSort=szText;

 m_pSet->Open();

 UpdateData(FALSE);

}



 

6.     Поиск информации в базе данных.

Необходимо потратить некоторое время на модификацию меню и/или панели инструментов, прежде чем переходить непосредственно к поиску.  Добавим кнопку. Для того чтобы запросить у пользователя, что именно требуется найти, необходимо создать небольшое диалоговое окно. В окне Resource View щелкните правой кнопкой мыши на папке Dialog и выберите из контекстного меню Insert Dialog.




Рис. 19. Свойства блока диалога


Наберите IDD_DLG_FIND в поле ID. Далее следует дать этому диалоговому окну более содержательный заголовок. Наберите "Поиск информации в базе данных" в поле ввода Caption (Заголовок), а затем нажмите кнопку Close, расположенную в правом верхнем углу окна, чтобы завершить, ввод изменений. 

Теперь нам необходимо добавить один элемент управления Static Text и связанный с ним элемент управления Edit Box, чтобы завершить создание блока диалога. Последняя часть работы для этого диалогового окна — установить свойства элемента управления Edit Box. Щелкните правой кнопкой мыши на этом  элементе управления и выберите Properties из контекстного меню. Измените свойство ID в диалоговом окне Edit  Properties (Свойства текстового поля) на IDC_RECORD_FIND. Нажмите кнопку Close. Теперь при нажатой клавише <Ctrl> дважды щелкните на элементе управления Edit Box. При этом вы увидите блок диалога Adding a Class (Добавить класс). Причина появления этого блока диалога заключается в том, что каждый диалог в вашей программе должен быть с чем-то связан. Так же, как окно About, имеющееся в любом приложении, каждое диалоговое окно должно иметь свой собственный класс. Нажмите кнопку ОК, чтобы создать новый класс для этого диалогового окна. Visual C++ отобразит диалоговое окно New Class, в котором нужно набрать имя класса в поле Name. Вы можете использовать любое имя класса, какое хотите. Например, выберем CFindJob. Нажмите кнопку ОК, чтобы завершить создание нового класса, после чего еще раз нажмите ОК, чтобы закрыть диалоговое окно MFC ClassWizard. Затем при нажатой клавише <Ctrl> еще раз дважды щелкните на элементе управления Edit Box, появится диалоговое окно Add Member Variable, которое вы и ожидали увидеть. Наберите m_Job в поле Member variable name. Убедитесь, что поле Category содержит Value, а поле Variable TypeCString. Нажмите кнопку ОК, чтобы добавить компонентную переменную.



Осталось создать оболочку и саму функцию OnRecordFind() (просмотрите  примечания ниже по тексту):


void CPrimView::OnRecordFind()


{CDBVariant varBookmark;


// Создаем экземпляр диалогового окна

CFindJob dlgFind;


// Нашли соответствующую запись?

BOOL bFound = FALSE;


// Расположение закладки CDBVariant.varBookmark; 

 // Отображаем диалоговое окно и определяем,

 // какую кнопку пользователю нажимать для выхода 



if (dlgFind.DoModal () ==IDOK)  {



//Сохраняем текущую позицию, если закладки поддерживаются


            if(m_pSet->CanBookmark()) 


m_pSet->GetBookmark(varBookmark);



  // Идем к началу

m_pSet->MoveFirst(); }


 while (!m_pSet->IsEOF() ^ bFound) 

 


             // Проверяем, равны ли значения


if(m_pSet->m_job_desc.CompareNoCase(dlgFind.m_Job)==0)

bFound = TRUE;

 


 else


  // Переходим к следующей

m_pSet->MoveNext();

 }

 if (bFound)

{


//Отображаем данные о новой записи

  UpdateData(FALSE); 

 } else

             

MB_ICONERROR) ;

}

 

 

 

Примечание:

Однако, прежде чем компилировать и выполнять наше приложение, необходимо внести еще одно дополнение.В начале листинга файла <PrimView.cpp> расположены директивы #include. Чтобы можно было работать с диалоговым окном FindJob, необходимо включить в модуль его заголовочный файл. Добавьте новую директиву #include, аналогичную  показанной здесь:


// Для поддержки блока диалога FindJob,

 //в начало файла PrimView.CPP необходимо

 // самостоятельно включить строку


 #include "FindJob.h"


Теперь, когда есть все фрагменты, скомпилируйте и выполните программу.












Рис. 20.

Первое, на что следует обратить внимание в этом коде — мы запоминаем текущую позицию в базе данных, используя для этого закладки. Они работают практически так же, как закладки, которые мы используем для книги, чтобы отметить место, где читаем. Поэтому, используя функцию CanBookmark(), необходимо, прежде всего, убедиться в том, что система управления базами данных поддерживает закладки. Если это так, то можно применять функцию GetBookmark(), чтобы отметить текущую позицию, и функцию SetBookmark (), чтобы восстанавливать ее.

Обратите внимание, что предложенная процедура поиска очень проста. Если мы обнаружили запись, которую затребовал пользователь, мы устанавливаем булевскую переменную на значение "истина", в противном случае идем к следующей записи. Этот процесс продолжается до тех пор, пока мы либо не найдем первую запись, соответствующую пользовательскому критерию, либо не закончим запрос. Если вы устанавливаете аналогичную процедуру поиска, убедитесь, что проверяете оба момента. Если требуемая запись не будет обнаружена, программа выведет сообщение об ошибке. Она также старается возвратить пользователя к предыдущей записи, если система управления базами данных поддерживает закладки. В противном случае программа возвращает пользователя к первой записи в запросе. Крайне важно установить указатель на какую-нибудь запись, так как в противном случае система управления базами данных, вероятно, перейдет к обработке исключения, сообщая, что запись потеряна.





ЗАДАНИЕ:  Используя классы MFC, рассмотреть принципы программирования клиентских приложений через интерфейс ODBC. Самостоятельно создать приложение для БД EDUCATION, реализующее функции просмотра, редактирования, удаления и добавления записей, а также поиска студента по его  фамилии.



Страницы: 1, 2, 3



2012 © Все права защищены
При использовании материалов активная ссылка на источник обязательна.