Занятие 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.