Занятие 3. Разработка форм «Товар» и «Покупатели».
Компоненты ZeosDBO размещаются на вкладке ZEOS Access и могут быть использованы в таких средах разработки:
- Delphi 5 - 7 and 9-11
- Lazarus (FreePascal)
- MSEide+MSEgui (FreePascal)
- C++ Builder 5 - 6
- Kylix 2 - 3
Компоненты позволяют разрабатывать клиентские приложения ( при установленных в ОС клиентских библиотеках ) для следующих СУБД:
- MySQL 3.20 - 5.0
- PostgreSQL 6.5 - 8.1
- Firebird 1.0 - 2.0
- Interbase 5.0 - 7.5
- Microsoft SQL Server 7, 2000
- Sybase ASE 12.0, 12.5
- Oracle 9i
- SQLite 2.8, 3.5
Рассмотрим назначение основных компонент:
TZConnection - отвечает за подключение к базе данных выбранной СУБД и управление транзакциями. Кроме того, в этом свойстве можно задать кодировку клиентско программы в виде:
ZConection.Properties.Add ('lc_ctype=win1251');
или
ZConnection.Properties.Add ('Codepage=cp1251');
TZReadOnlyQuery – позволяет выполнять запросы не возвращающие результат или запросы Select. При этом полученные данные не редактируемы ( read only ).
TZQuery и TZUpdateSQL чаще всего используются совместно и являются наиболее гибким средством выполнения запросов.
Основные свойства TZQuery:
SQL (TStrings) – строки, в которых задан оператор Select выборки данных;
UpdateObject – свойство, в котором указывают объект класса TZUpdateSQL, который отвечает за выполнения операторов Insert, Update, Delete и Refresh для данного запроса;
Params (TParams) – позволяет создавать SQL-запросы с параметрами, в частности создавать связи Master-Detailed между компонентам – наследниками класса TDataset (TZReadOnlyQuery, TZQuery и TZTable );
Connection – подключает компонент к TZConnection, после чего компонент может получать метаданные соответствующего серверного объекта ( название и типы столбцов таблиц, участвующих в запросе), посылать запросы и получать результаты от СУБД;
Active - позволяет включить или отключить компонент.
Основные свойства TZUpdateSQL:
InsertSQL, ModifySQL, DeleteSQL, RefreshSQL (TStrings) - свойства для хранения соответствующих SQL – операторов.
На практике используется UpdateSQL Editor, вызываемый из контекстного меню компонента TZUpdateSQL.
TZTable - позволяет обращаться к одной определенной таблице в базе данных. В использовании проще, чем TZQuery, что обеспечивает его частое использование на практике.
Основные свойства TZTable:
TableName – задает имя таблицы базы данных на сервере;
Filter – используется для фильтрации данных, запрашиваемых у сервера и содержит строку с условиями отбора данных в том виде, в каком она используется после ключевого слова WHERE в операторе SELECT;
Filtered – позволяет включить или отключить фильтрацию данных.
TZStoredProc – используется для вызова хранимых процедур, созданных на сервере. Если хранимая процедура возвращает в клиентское приложение много строк, то вызывают ее используя оператор SELECT, например:
SELECT * FROM MyProc1( :par1, ‘Текст’ )
В том случае, если хранимая процедура возвращает в клиентское приложение одну строку, то вызывают ее программным способом, используя ее входные и выходные параметры. Например:
with spSumByName do
begin
Close;
ParamByName ('Name').Value := 'DontKnowHow';
Open;
Label1.Caption:= ParamByName ('Result').AsString
end;
TZSQLProcessor – предназначен для выполнения скрипта из нескольких SQL - операторов, загружаемого методами LoadFromStream() или LoadFromFile().
TZSQLMonitor – позволяет обрабатывать и записывать события, поступающие с сервера. В текстовый файл на диске:
sqlMonitor.FileName := '.\MyAppLog.log';
sqlMonitor.Active := True;
sqlMonitor.AutoSave := True;
В компонент Мемо:
Procedure Tfrm_MyApp.sqlMonitorLogTrace (Sender: TObject;
Event: TZLoggingEvent);
Begin
If Trim (Event.Error) > '' Then
memMontor.Lines.Add (DateTimeToStr (Event.Timestamp) + ': ' +
Event.Message + #13#10 + ' Error: ' + Event.Error)
Else
memMontor.Lines.Add (DateTimeToStr (Event.Timestamp) + ': ' +
Event.Message);
End; // sqlMonitorLogTrace
TZSQLMetadata – позволяет получать метаданные об объектах базы данных ( таблицы, поля, просмотры и др. ) для использования в программе.
Отметим, что если компоненты TZConnection, TZReadOnlyQuery, TZQuery, TZUpdateSQL, TZTable опробованы лучше, то другие могут не работать должным образом для различных СУБД ( Приведенные данные взяты с сайта разработчика и справедливы для СУБД Firebird ).
ЗАДАНИЯ
1. Запустите Delphi и создайте новое приложение. Задайте свойству Name активной формы значение MainForm.
2. Добавьте в состав приложения модуль данных (File►New►DataModule), который предназначен для хранения невизуальных компонент разрабатываемого приложения. Его имя (Name)замените с DatataModule1 на DM.
3. Сохраните файлы проекта в отдельную папку. Для файла Unit1.pas задайте имя MainU.pas, Unit2.pas - DMU.pas, файл проекта Project1.dpr переименуйте в PrTorgovlia.dpr.
4. Чтобы начать работу с главными таблицами базы данных – «Накладная» и «Отпуск товара», Вам необходимо заполнить вспомогательные таблицы «Товар» и «Покупатель». Поэтому создайте дополнительную форму (File►New►Form), предназначенную для ввода товаров пользователем. Свойство BorderStyle этой формы установите равным bsSingle. Название формы измените на TovarForm, а заголовок – на «Сведения о товарах». Сохраните форму в общую папку проекта под именем TovarU.pas.
5. Переключитесь на работу с модулем данных и активизируйте его у (F12).
6. В палитре компонент Delphi найдите вкладку ZEOS Access и поместите в модуль данных компонент ZConnection и заполните свойства компонента данными:
DataBase = C:\Inetpub\ftproot\DB\Torgovl_FIOStudenta.fdb - - путевое имя файла БД на сервере. ( В других СУБД: MySql – имя базы данных, Oracle 11g R2 - SID базы данных – XE, а база данных определяется логином пользователя )
На рисунке 8 приведены заполненные свойства ZConnection:
7. Подключите базу данных –
( ZConnection.Connected=True).
8. Перенесите на модуль данных с вкладки ZEOS Access компонент TZTable и дайте ему имя TovarTbl. Чтобы подключить таблицу к существующей базе данных, задайте свойство Connection= ZConnection1. Так как в состав одной базы данных могут входить много таблиц (как в нашем случае), необходимо уточнить, какой таблице соответствует компонент Tovar. Поэтому откройте список поля TableName и выберите таблицу БД - Tovar.
9. Поместите в модуль данных экземпляр компонента DataSource ( они находятся на вкладке DataAccess ). Дайте имя компоненту DataSource DSTovar. В качестве свойства DataSet каждого компонента DataSource установите имя соответствующей таблицы TovarTbl.
10. Перейдите на форму TovarForm. С вкладки DataControls палитры компонент поместите компоненты DBGrid и DBNavigator. Со вкладки Additional добавьте на форму кнопку BitBtn. Свойство Kind кнопки установите в значение bkClose. Измените масштаб компонент и их расположение так, как показано на рисунке 10:
Рисунок 10. Форма TovarForm
11. Сохраните форму TovarU.pas.
12. Свяжите форму TovarForm c модулем данных. ( выполнив File►Use Unit►UDM )
13. Значение свойства DataSource для DBGrid и DBNavigator выберите из списка - DM.DSTovar. Активизируйте таблицу Tovar, задав свойству Active значение true. При этом вы увидите отображение в заголовках DBGrid названий столбцов, а в строках – данные строк таблицы товар.
Рисунок 11. Форма TovarForm в режиме разработки
Замечание: Обратите внимание, какие кнопки DBNavigator активны.
14. Нам нужно изменить заголовки столбцов таблицы, поместив в них названия на русском языке, а также задать формат вывода данных ( 2 знака после запятой ) для столбца Cena. Наиболее удобным методом является явное создание экземпляров полей таблицы Tovar и определение их свойств.
Сейчас определение класса TDM выглядит так:
Type
TDM = class(TDataModule)
ZConnection1: TZConnection;
Tovar: TZTable;
DSTovar: TDataSource;
Private
{ Private declarations }
Public
{ Public declarations }
end;
15. Переключитесь в режим формы, в Object TreeView, разверните список свойств Tovar, выделите Fields, вызовите контекстное меню и в нем выберите Add all fields ( как показано на рис. 12 )
Теперь определение класса TDM выглядит так:
Type
TDM = class(TDataModule)
ZConnection1: TZConnection;
Tovar: TZTable;
DSTovar: TDataSource;
TovarIDTOV: TIntegerField;
TovarTOVNAME: TStringField;
TovarEDIZM: TStringField;
TovarCENA: TFloatField;
TovarTOVGROUP: TStringField;
Private
{ Private declarations }
Public
{ Public declarations }
end;
16. Переключитесь в режим разработки, выделите в Object TreeView поле CENA и посмотрите на список свойств в Object Inspector ( см. рис. 13 ):
Обратите внимание: имя объекта, наследника класса TField формируется как Таблица поле (TovarCENA); значением свойства FieldName является имя столбца таблицы в базе данных и не должно изменяться; свойство DisplayLabel служит для отображения названия столбца в визуальных компонентах; свойство DisplayLabel позволяет задать количество символов ( ширину ), отображаемых в визуальных компонентах. Например, поле в таблице может содержать строку из 50 символов, а столбец в DBGrid должен быть шириной 20 символов. Тогда для отображения остальных символов в длинных строках нужно поместить курсор в ячейку таблицы и смещать его вправо.
Свойство DisplayFormat позволяет задавать строку формата, что используется чаще всего для типов дата, время, вещественное значение ( если вещественное значение представляет деньги, то можно использовать более простой способ – установить значение currency равным true ). Обратите также внимание на свойства ReadOnly и Visible. ReadOnly позволяеть разрешить/запретить редактирования набора данных, Visible - скрывает/ показывает поле в визуальных компонентах.
17. Изменим значение свойства DisplayLabel на “Цена”. Дадим свойству DisplayFormat значение “#.00”, а DisplayWidth – 10. Задайте свойства DisplayLabel и DisplayWidth для полей TOVNAME – “Название”,20; EDIZM – “ед.изм”, 10; TOVGROUP – “группа товара”, 20.
Теперь данные на форме TovarForm выглядят так:
Рисунок 14. Форма «Товар» после задания свойств полей
18. Поместите на главную форму приложения компонент MainMenu и создайте в нем два пункта меню – Файл и Справочники. В первом пункте создайте подпункт Выход, а во втором – подпункты Товары и Покупатели.
19. Свяжите форму MainForm c модулем данных и формой TovarForm (см. пункт 12 ).
20. Выберите в главном меню Delphi пункты: Project -> Options, в разделе Forms в поле выбора Auto-created forms перетащите мышкой модуль DataModul DM на первое место!!!
21. Создайте обработчик события OnCreate для главной формы с таким содержанием:
DM.Tovar.Active:=True;
22. Щелчок по пункту Выход должен закрывать приложение. Щелкните по пункту и в редакторе кода в программе обработчика события наберите Close;
23. Теперь щелкните по пункту меню Справочники►Товары. В тексте обработчика события наберите: FormTovar.ShowModal;
24. Запустите приложение, перейдите к окну формы TovarForm и проверьте возможность заполнения данными таблицы Tovar.
Рисунок 15. Ввод новых данных в таблицу Tovar
1. Добавьте в проект новую форму, задайте свойство Name – PokupForm, Caption – Покупатели. Сохраните файл под именем PokupFUnit. Свяжите форму PokupForm с модулем данных DM, а главную форму – с модулем формы PokupForm.
2. Поместите на форме 2 компонента DBGrid и 2 компонента DBNavigator так, как показано на рисунке.
Рисунок 15. Визуальные компоненты формы «Покупатели»
3. В модуле данных DM разместите два новых компонента ZTable, задайте свойства Name Pokupatel и Phone соответственно. Свойства TableName – POKUP и TEL.
4. Разместите в DM два новых компонента DataSource, дав им имена DSPokup и DSPhone, а свойство DataSet для них установите – Pokupatel и Phone.
5. Подключите компоненты DBGrid и DBNavigator к DSPokup и DSPhone, откомпилируйте, запустите приложение и введите на форме PokupForm данные о 2 покупателях и 2 телефона для первого покупателя так, как приведено на рисунке:
Рисунок 16. Добавление новых данных в окне «Покупатели»
Первое, на что Вы наверное обратили внимание – навигация по данным родительской таблицы POKUP и дочерней таблицы TEL совершенно независимы, хотя нам было бы удобнее работать в данной форме не со всеми телефонами в таблице TEL, а только с телефонами одного покупателя.
Запомните: Реализация связей родительская – дочерняя таблица на сервере означает только контроль за целостностью данных и никак не связана с выборкой данных, т.е. результатами операторов SELECT и DML.
В Delphi и C++Builder эта проблема решается путем организации связи между компонентами – наследниками класса TDataset ( TTable, TQuery ) с помощью связывания Master – Detail. Как Вы поняли, компонент TDataSource осуществляет передачу данных от TTable к визуальным компонентам, но кроме этого используется в реализации связывания Master – Detail
Сейчас мы установим связь Master – Detail между компонентами TZTable родительской таблицы POKUP и дочерней таблицы TEL
6. В свойстве MasterSource дочерней таблицы Phone раскройте список и выберите TDataSource DSPokup, подключенный к родительской таблице. В выпадающем списке свойства MasterFields выберите среди всех полей таблицы POKUP поле первичного ключа - IDPOKUP, а для свойства LinkedFields выберите поле внешнего ключа таблицы TEL - POKUPID.
7. Запустите программу, откройте окно PokupForm и выполните навигацию по записям таблицы POKUP. Теперь в DBGrid, связанном с таблицей Phone отображаются только записи, относящиеся к текущей записи таблицы Pokupatel.
Рисунок 17. Добавление новой записи в таблицу Phone
после создания связывания Master – Detail
На рис. 17 показано добавление новой записи в дочернюю таблицу. Обратите внимание, что значение поля внешнего ключа в таблице Phone добавляется автоматически. Следовательно это поле можно скрыть от пользователя, установив значение свойства Visible поля POKUPID равным false.
В следующих занятиях мы увидим, как реализовать связь Master – Detail для компонент TZQuery.