005 — Разработка приложения «Магазин» (курсовая работа)




Проектирование приложения «Магазин»

(курсовая работа с нуля)

В данной статье описывается пошаговый процесс разработки полноценного законченного приложения «Магазин» учета поступившего и реализованного товара.

Пройдя пошаговую инструкцию, Вы научитесь создавать приложения подобного типа которые для хранения данных используют базу данных Microsoft Access.

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


Содержание


Условие задачи

Разработать приложение, которое осуществляет учет реализации товаров в магазине.

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

База данных должна быть разработана в системе Microsoft Access.

Программную систему разработать в системе Embarcadero Delphi 2010.

 

Выполнение

1. Создание приложения по шаблону VCL Form Application

Пример создания приложения по шаблону VCL Form Application подробно описывается здесь.

К содержанию.

2. Создание базы данных в MS Access

Создаем базу данных в MS Access. Задаем имя базы данных «01_02_00_005_auto_ru.mdb«.

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

К содержанию.

3. Сохранение проекта.

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

Например, можно создать отдельную папку:

E:\Programs\Program_01_02_00_005r

и в ней сохранить весь проект.
Имя главного модуля (формы) задаем «Main.pas«.

К содержанию.

 

4. Создание главного меню.

Выносим на форму компонент TMainMenu из палитры компонент Standard (рис. 1).

Формируется объект (переменная) с именем MainMenu1.

01_02_00_005_01_

Рис. 1. Главная форма приложения с компонентом MainMenu1

Вызываем режим формирования меню (рис. 2).
Это осуществляется двумя способами:
– двойной клик «мышкой» на компоненте MainMenu1;
– вызов команды «Menu Designer…» из контекстного меню.

01_02_00_005_02_

Рис. 2. Команда выбора окна создания меню

В результате вызова «Menu Designer…» открывается окно формирования меню (рис. 3).

01_02_00_005_03_

Рис. 3. Окно для создания меню

В ячейки меню вводим названия элементов меню. Можно создавать сложную структуру с выпадающих меню. В нашем случае создаем меню как показано на рисунке 4.

01_02_00_005_04r

Рис. 4. Главное меню приложения

Меню «Курс валют…» содержит команду «Изменить…«.

Меню «Группа» главного меню содержит команды (рис. 5):
– «Добавить…» – добавление новой группы в базу данных;
– «Редактировать…» – редактирование данных выделенной группы в базе данных;
– «Удалить» – удаление группы из базы данных.

01_02_00_005_05r

Рис. 5. Команды меню «Группа»

Меню «Товар«, «Поступления» и «Реализация» главного меню содержат такие же команды (рис. 6):
– «Добавить…» – добавление нового товара, поступления или реализации;
– «Редактировать…» – редактирование нового товара, поступления или реализации;
– «Удалить» – удаление товара, поступления или реализации.

01_02_00_005_06r

Рис. 6. Команды меню «Товар«, «Поступление«, «Реализация«

В программе используется два отчета, описание которых будет дано ниже. Поэтому меню «Отчеты» имеет следующий вид (рис. 7):

01_02_00_005_07r

Рис. 7. Команды меню «Отчет»

После закрытия «Menu Designer…» форма программы будет иметь вид, как показано на рисунке 8.

01_02_00_005_08r

Рис. 8. Главная форма приложения с созданным меню команд

К содержанию.

 

5. Задаем название приложения.

Для этого выделим форму Form1 и выделим в Object Inspector в свойстве Caption название «Магазин«.

Для удобного вывода главной формы приложения дополнительно настраиваем такие свойства:
– опцию biMaximize свойства BorderIcons устанавливаем в значение false;
– свойство Position=poScreenCenter (центрирование окна приложения).
Можно протестировать приложение и запустить его на выполнение. Окно приложения будет иметь вид как показано на рисунке 9.

01_02_00_005_09r

Рис. 9. Приложение в режиме выполнения

К содержанию.


6. Организация работы с базой данных.

6.1. Компоненты для работы с базой данных.

Для связи приложения с базой данных вначале используем следующие компоненты:
TDataSource (вкладка Data Access);
TADOConnection (вкладка dbGo);
TADOQuery (вкладка dbGo).

После вынесения этих компонент на форму будет создано три объекта (переменные) с именами DataSource1, ADOConnection1, ADOQuery1.

После изменений в размерах формы окно приложения в режиме проектирование будет иметь вид, как показано на рисунке 10.

01_02_00_005_10r

Рис. 10. Главная форма приложения с компонентами для работы
с базой данных

Компоненты из палитры dbGo предназначены для работы с базами данных по технологии ADO, которая хорошо используется для базы данных Microsoft Access.
Вместо компонента TADOQuery можно использовать компонент TADOTable. Можно совмещать эти два компонента. В нашем приложении чтение и изменение в базе данных будем осуществлять путем формирования отчетов на языке SQL, поэтому, в этом случае лучше подходит компонент TADOQuery, в котором эти отчеты удобно задавать. Также данный компонент хорошо подходит в случае сортировки данных в базе данных по некоторому полю.

Для визуализации данных из таблиц используется компонент TDBGrid из палитры Data Controls. Он отображает данные в некоторой области базы данных. Сначала отобразим данные в таблице Groups. После вынесения этого компонента на форму, вид окна проектирования будет иметь приблизительно следующий вид (рис. 11).

01_02_00_005_11r

Рис. 11. Добавление компонента типа TDBGrid на форму

К содержанию.

 

6.2. Подключение программы к базе данных.

Следующим шагом есть подключение программы к базе данных «01_02_00_005_auto_ru.mdb«.

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

Не забываем установить свойство LoginPrompt компонента ADOConnection1 в значение false. Это необходимо, чтобы избежать постоянного ввода имени пользователя и пароля для доступа к базе данных.

К содержанию.

6.3. Настройка связей между ADO компонентами.

В первую очередь подключаем таблицу Groups. Этой таблице соответствуют компоненты ADOQuery1, DataSource1 и DBGrid1. Компонент ADOConnection1 есть общим для всех других компонент, которые еще будут использованы в приложении. ADOConnection1 используется для непосредственной связи с базой данных.

Связываем компоненты ADOConnection1, DataSource1, ADOQuery1 и DBGrid1 между собой по такой схеме (рис. 12).

01_02_00_005_12r

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

Компонент DBGrid1 предназначен для отображения данных в некоторой таблице базы данных. В нашем случае это таблица Groups.

Связь компонента ADOConnection1 с базой данных уже установлена.

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

Свойство Connection компонента ADOQuery1 устанавливаем в значение ADOConnection1, выбирая его из выпадающего меню (в списке меню будет только один этот компонент).

Точно так же свойство DataSet компонента DataSource1 устанавливаем в значение ADOQuery1. Следующим шагом настраиваем свойство DataSource компонента DBGrid1 в значение DataSource1 путем выбора его из выпадающего списка.

К содержанию.

 

6.4. Формирование SQL-запроса.

Как было сказано раньше, в приложении работа с базой данных будет осуществляться путем использования запросов на языке SQL. Запросы на языке SQL в приложении формируются в компоненте ADOQuery1 с помощью одноименного свойства под названием SQL (рис. 13).

01_02_00_005_13_

Рис. 13. Свойство SQL компонента ADOQuery1

Путем выбора мышкой кнопки «» вблизи названия свойства открывается окно редактора, в котором необходимо задать код команды на языке SQL (рис. 14).

01_02_00_005_14_

Рис. 14. Редактор команд SQL компонента ADOQuery1

Рядок вида

SELECT * FROM [Group]

выводит значения всех полей таблицы Group базы данных. Эта таблица соответствует данным о группах товаров. Название таблицы Group нужно взять в квадратные скобки.

К содержанию.

 

6.5. Активация ADOQuery1.

Следующим шагом устанавливаем значение свойства Active компонента ADOQuery1 в значение true. Как только изменяется это свойство в значение true, автоматически в DBGrid1 отображаются все записи всех полей таблицы Group (рис. 15).

01_02_00_005_15r

Рис. 15. Установка свойства Active в значение true

К содержанию.

 

7. Настройка отображения данных.

Главным компонентом, отображающим данные в базе данных в виде таблицы есть компонент типа TDBGrid. Система Embarcadero Delphi 2010 дает в распоряжение программиста также и другие компоненты для отображения данных.

В нашем приложении для отображения таблицы Group используется компонент DBGrid1. Осуществим его настройку.
Таблица Group состоит из трех полей: ID_Group, Name и Code. Значимыми в таблице есть поля Name и Code. Поле ID_Group можно скрыть.

Это делается двумя способами.

 

7.1. Скрытие поля ID_Group с помощью SQL-запроса.

Язык SQL позволяет выводить данные определенных полей в таблице базы данных. В нашем случае SQL-запрос в компоненте ADOQuery1 (свойство SQL) будет иметь вид:

SELECT [Name], [Code] FROM [Group]

Этот запрос означает, что нужно вывести значения всех записей полей Name и Code.

После установки свойства SQL и активизации компонента ADOQuery1 (свойство Active компонента станет равным «false» после изменений SQL-запроса) поле ID_Group исчезнет.

К содержанию.

 

7.2. Скрытие поля ID_Group с помощью редактора полей.

Редактор полей (Columns Editor) вызывается в контекстном меню (правый клик «мышкой) компонента DBGrid1 (рис. 16).

01_02_00_005_16r

Рис. 16. Вызов редактора полей из контекстного меню компонента DBGrid1

В результате откроется окно «Editing DBGrid1.Columns» (рис. 17).

01_02_00_005_17_

Рис. 17. Окно редактора полей компонента DBGrid1

Выбираем команду «Add All Fields» из контекстного меню или из панели инструментов (рис. 18).

01_02_00_005_18_

Рис. 18. Добавление всех полей для отображения в компоненте DBGrid1

В окне появляются все поля таблицы Group (рис. 19).

01_02_00_005_19_

Рис. 19. Поля таблицы Group в редакторе полей компонента DBGrid1

Для того, чтобы скрыть поле ID_Group в компоненте DBGrid1 нужно выбрать команду «Delete» из контекстного меню этого поля (рис. 20). Сразу же поле ID_Group в таблице DBGrid1 исчезнет. После этого закрываем редактор полей.

01_02_00_005_20_

Рис. 20. Удаление поля ID_Group

Данный способ дает нам доступ к полям таблицы как к объектам. В нашем случае поле Name в редакторе есть объектом с именем DBGrid1.Columns[0] типа TColumn (отображается в Object Inspector). Это означает, что Delphi дает возможность редактировать некоторые параметры этого поля, например, ширину, центрирование заголовка и т.д. Поэтому этот способ нам подходит лучше.

Если использовать только SQL-запросы для отображения данных, то, например, такую операцию как центрирование заголовка нужно будет выполнять программно.

К содержанию.

 

7.3. Настройка параметров полей.

Осуществим настройку поля Name компонента DBGrid1.

Для этого откроем редактор полей и выделим поле Name. В результате в Object Inspector активизируется объект DBGrid1.Columns[0].

Настроим ширину поля (свойство Width), например в значение 150.

Осуществим настройку в названии в поле Name (рис. 21), для этого раскроем (знак «+») свойство Title и установим:
– значение свойства Alignment в taCenter;
– значение свойства Caption в «Группа«.

01_02_00_005_21r

Рис. 21. Настройка параметров поля Name таблицы Group в DBGrid1

Точно так же настраиваем параметры поля Code соответствующими значениями.

После выполненных действий окно приложения в режиме проектирования будет иметь вид, как показано на рисунке 22.

01_02_00_005_22r

Рис. 22. Окно главной формы приложения после настройки полей

К содержанию.

 

7.4. Установление опции «только для чтения» в компоненте DBGrid1.

В нашем приложении компонент DBGrid1 предназначен для отображения данных в таблице Group. Меню приложения «Группа» содержит три команды, которые обеспечивают все необходимые операции с таблицей «Group«. Это команды «Добавить…«, «Редактировать…» и «Удалить«. Поэтому, логично будет установить компонент DBGrid1 в режим только для чтения чтобы случайно не изменять значения ячеек.

Для этого нужно выделить компонент DBGrid1 и установить в Object Inspector опцию ReadOnly в значение true.

После тестового запуска приложения на выполнение, есть возможность передвигаться по полям таблицы Group, но нет возможности случайно изменять значения ячеек.

К содержанию.

 

8. Создание таблицы Tovar.

После успешного создания таблицы Group переходим к созданию таблицы Tovar.

Таблица Tovar в базе данных имеет следующие поля:
ID_Tovar – уникальный идентификатор записи для одного товара;
ID_Group – уникальный идентификатор записи группы, к которой принадлежит товар;
Name – название товара;
Code – код товара;
Text – описание товара (необязательное поле);
N_Post – число поступлений данного товара, выраженное в штуках;
Suma_Post – сумма, выраженная в денежных единицах, поступлений данного товара;
N_Real – количество реализаций данного товара, выраженное в штуках;
Suma_Real – сумма, выраженная в денежных единицах, реализаций данного товара;
Ostatok – остаток данного товара на складе (в штуках).

К содержанию.

 

8.1. Компоненты для работы с таблицей Tovar.

В таблице Tovar есть несколько полей, которые будут вычисляться в процессе работы приложения.

Поля, для которых должны проводиться вычисления, могут быть сформированы с помощью соответствующего SQL-запроса (компонент типа TADOQuery) или с помощью программного вычисления с использованием компонента типа TADOTable.

В нашем случае второй способ подходит лучше, поскольку, в этом случае, Delphi создает соответствующие объекты, которыми удобно оперировать. Поэтому для доступа к таблице Tovar будем использовать компонент типа TADOTable вместо TADOQuery (как было описано в п. 7) из палитры компонент DBGo.

Для отображения таблицы Tovar выносим на главную форму приложения еще три компонента с именами ADOTable1, DataSource2 и DBGrid2. Компонент DBGrid2 предназначен для непосредственного отображения таблицы Tovar.

К содержанию.

 

8.2. Связывание компонент между собой и с базой данных.

Осуществим связывание этих компонент с базой данных так как в п. 6.3. В компоненте ADOTable1 свойство Connection устанавливаем в значение ADOConnection1. В компоненте DataSource2 свойство Dataset устанавливаем равным ADOTable1. В компоненте DBGrid2 свойство DataSource устанавливаем в значение DataSource2.

Отдельно задаем таблицу, с которой соединяется компонент ADOTable1. В компоненте ADOQuery1 такого свойства нет и быть не может, поскольку ADOQuery1 есть запросом к базе данных, а не физической таблицей.

Для задания таблицы Tovar в компоненте ADOTable1 необходимо свойство TableName установить в значение «Tovar» (выбрать из выпадающего списка).

Взаимодействие компонент с базой данных изображено на рисунке 23.

01_02_00_005_23r

Рис. 23. Взаимодействие компонент с базой данных

К содержанию.

 

8.3. Настройка ADOTable1.

После активации (свойство Active устанавливается в true) ADOTable1 форма приложения будет иметь следующий вид (рис. 24).

01_02_00_005_24r

Рис. 24. Вид главного окна приложения после добавления таблицы Tovar

К содержанию.

 

8.4. Создание полей в ADOTable1.

Для удобства оперирования полями ADOTable1 рекомендуется сформировать их в приложении в редакторе полей «Fields Editor…» из контекстного меню, которое открывается при нажатии правой кнопкой «мыши» на компоненте ADOTable1 (рис. 25).

01_02_00_005_25_

Рис. 25. Вызов редактора полей компонента ADOTable1

В результате откроется окно Form1.ADOTable1 редактора полей, изображенное на рисунке 26.

01_02_00_005_26_

Рис. 26. Редактор полей компонента ADOTable1

Добавляем поля правым кликом «мыши». Откроется контекстное меню. Выбираем команду «Add all fields» (рис. 27).

01_02_00_005_27_

Рис. 27. Добавление всех полей для обработки в ADOTable1

Окно редактора полей примет вид как показано на рисунке 28.

01_02_00_005_28r

Рис. 28. Окно редактора полей ADOTable1

Добавляются все поля, которые есть в таблице «Tovar» базы данных «auto.mdb«.

Имеем 10 полей с именами ID_Tovar, ID_Group, Name, Code, Text, N_Post, Suma_Post, N_Real, Suma_Real, Ostatok. Для каждого поля Delphi создает компонент-объект с разного рода свойствами. Так, например, для поля ID_Tovar создается компонент ADOTable1ID_Tovar. Для поля ID_Group создается компонент ADOTable1ID_Group и т.д.

Поля N_Post, Suma_Post, N_Real, Suma_Real и Ostatok есть вычисляемыми полями. Это означает, что значения этих полей вычисляются по мере внесения данных в базу данных. Эти поля будут формироваться программно.

Виды полей таблицы Tovar приведены ниже.

01_02_00_005_table01r

Закрываем редактор полей ADOTable1.

К содержанию.

 

8.5. Создание отображения таблицы Tovar в DBGrid2.

Таблица Tovar будет отображаться в компоненте DBGrid2.
Нам не нужно отображать все поля из таблицы Tovar, которые есть в компоненте ADOTable1. Поля ID_Tovar и ID_Group предназначены для связи с внешними таблицами. Поэтому их можно спрятать на экране.

Для этого формируем отображение в компоненте DBGrid2.

Процесс создания полей дла отображения в DBGrid2 точно такой же как описано в п. 7.2.

Вызываем редактор полей «Editing DBGrid2.Columns» из контекстного меню “Columns Editor…” компонента DBGrid2. С помощью команд добавления (Add All Fields) и удаления (Delete) полей ID_Tovar и ID_Group получим следующее окно редактора полей (рис. 29).

01_02_00_005_29r

Рис. 29. Сформированные поля в редакторе полей компонента DBGrid2

Таким образом, таблица Tovar отображает только значимые поля (8 полей). Для каждого поля, которое отображено в окне создается компонент (объект). В этом компоненте можно более подробно сформировать отображение того или иного поля. Так, например, для поля «0-Name» система Delphi создаст объект DBGrid2.Columns[0]. Для поля «1-Code» система создаст объект DBGrid.Columns[1] и т.д.

К содержанию.

 

8.6. Модификация отображения таблицы Tovar в DBGrid2.

На данный момент таблица Tovar, отображающаяся в компоненте DBGrid2 имеет не очень корректный вид. Так, заглавия таблицы можно изменить на русский язык а также центрировать их. Также можно сделать центрирование данных в некоторых полях.

Преобразуем таблицу в следующий вид.

01_02_00_005_table02r

К содержанию.

 

8.6.1. Изменение порядка следования полей.

Поменяем местами поля Name и Code. Для этого в редакторе “Editing DBGrid2.Columns” перетащим поле «1-Code» на самый верх. Окно редактора примет вид (рис. 30).

01_02_00_005_30r

Рис. 30. Изменение порядка следования полей в таблице Tovar

Теперь поле «0-Code» находится первым в списке полей и ему соответствует объект DBGrid2.Columns[0].

К содержанию.

 

8.6.2. Центрирование заголовков полей.

Процесс центрирования заглавий в DBGrid2 такой же, как и в DBGrid1, и описан в п. 7.3.

Для центрирования заглавия сначала надо выделить «0-Code» в окне «Editing DBGrid2.Columns«. Потом нужно перейти в Object Inspector и в нем раскрыть свойство Title (знак +). Установить свойство Alignment в значение taCenter, свойство Caption в значение «Код«. Можно, по желанию, навести цвета заглавия, параметры шрифта и другое.

Также формируем ширину каждого поля (свойство Width) таким образом, чтобы уместились все поля в видимой части окна компонента DBGrid2.

Подобным образом формируем все заглавия таблицы.

После внесенных изменений окно приложения в режиме проектирования будет иметь вид, как показано на рисунке 31.

01_02_00_005_31r

Рис. 31. Главная форма приложения после настройки таблицы Tovar

Для заполнения вычисляемых полей (N_Post, Suma_Post, N_Real, Suma_Real, Ostatok) в таблице Tovar (ADOTable1) нужно иметь доступ к двум другим таблицам из базы данных:
– таблице Postupl поступлений заданного товара;
– таблице Realiz реализаций каждого поступления для заданного товара.

Для этого нужно создать эти таблицы так, как описано в п. 8.

К содержанию.

 

9. Создание таблиц Postupl и Realiz.

9.1. Компоненты для доступа к таблицам Postupl и Realiz.

Процесс создания таблиц Postupl и Realiz такой же как и таблицы Tovar и описан в п. 8.

Для создания таблицы Postupl выносим на форму компоненты с такими именами: ADOTable2, DataSource3, DBGrid3. Связываем эти компоненты между собой (см. п.п. 6.3 и 8.2.) и базой данных через компонент ADOConnection1.

Свойство TableName компонента ADOTable2 устанавливаем в значение Postupl.

Для создания таблицы Realiz так же выносим компоненты с именами ADOTable3, DataSource4, DBGrid4. Связываем эти компоненты (см. п.п. 6.3 и 8.2) между собой и базой данных через компонент ADOConnection1.

Свойство TableName компонента ADOTable3 устанавливаем в значение Realiz.

Общая схема взаимодействия между компонентами приложения и базой данных имеет вид (рис. 32):

01_02_00_005_32r

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

Таблица Postupl в базе данных состоит из таких полей.

01_02_00_005_table03r

Таблица Realiz в базе данных состоит из таких полей.

01_02_00_005_table04r

Добавляем в таблицы ADOTable2 и ADOTable3 поля с помощью редактора Fields Editor… по примеру, который описан в п. 8.4.

После активации таблиц ADOTable2 и ADOTable3 (свойство Active=true) приложение в режиме проектирования будет иметь следующий вид (рис. 33).

01_02_00_005_33r

Рис. 33. Главная форма приложения после настройки ADOTable2 и ADOTable3

К содержанию.

 

9.2. Настройка отображения таблиц Postupl и Realiz в компонентах DBGrid3 та DBGrid4.

Для отображения таблица Postupl в приложении должна иметь приблизительно следующий вид.

01_02_00_005_table05r

Для отображения таблица Realiz должна иметь приблизительно следующий вид.

01_02_00_005_table06r

Процесс настройки отображения таблиц в компоненте DBGrid1 описан в п. 7. Таким же образом настраиваем поля компонент DBGrid3 и DBGrid4.

В компоненте DBGrid3 в редакторе DBGrid3.Columns (команда контекстного меню «Columns Editor…«) сначала добавляем все поля (команда «Add All Fields«) а потом удаляем поля (ID_Postupl и ID_Tovar).

Оконочательный вид окна редактора «Editing DBGrid3.Columns» (рис. 34).

01_02_00_005_34r

Рис. 34. Настройка полей компонента DBGrid3

Таким же образом в компоненте DBGrid4 в редакторе DBGrid4.Columns после добавления всех полей удаляем поля ID_Realiz, ID_Postupl. Окончательный вид окна редактора «Editing DBGrid4.Columns» (рис. 35).

01_02_00_005_35r

Рис. 35. Настройка полей компонента DBGrid4

С помощью Object Inspector настраиваем нужный нам вид таблиц, которые отображаются в компонентах DBGrid3 и DBGrid4 (см. п. 7.3). Вносим изменения в названия заглавий и выравнивания полей.

Корректируем размеры главной формы и компонент DBGrid3 и DBGrid4 так, чтобы все поля таблиц корректно отображались на экране (рис. 36).

01_02_00_005_36r

Рис. 36. Главная форма приложения после добавления и настройки таблиц Postupl и Realiz в компонентах ADOTable2, ADOTable3, DBGrid3, DBGrid4

К содержанию.

 

10. Создание подписей таблиц.

С помощью компонента TLabel из палитры компонент Standart устанавливаем подписи каждой таблицы. В нашем случае выносим на форму 4 компонента, которые имеют имена Label1, Label2, Label3, Label4. Свойство Caption каждого из этих компонент становится равным названию соответствующей таблицы.

Окно главной формы в режиме проектирования имеет следующий вид (рис. 37).

01_02_00_005_37r

Рис. 37. Главная форма приложения после добавления подписей

К содержанию.

 

11. Программное формирование значений вычисляемых полей.

На данный момент вычисляемые поля таблиц Tovar, Postupl и Realiz есть пустые. Они должны заполняться в процессе выполнения приложения.

Для заполнения данными таблицы Tovar создадим две процедуры:
Calc_Tovar_Row – заполняет одну строку таблицы Tovar;
Calc_Tovar – заполняет все строки (записи) таблицы Tovar.

Эти процедуры включим в раздел public (или private – не имеет значения) класса формы TForm1.

Аналогично создаем процедуры заполнения расчетных полей таблиц Postupl и Realiz:
Calc_Postupl_Row – заполняет одну строку таблицы Postupl;
Calc_Postupl – заполняет все строки таблицы Postupl
Calc_Realiz_Row – заполняет одну строку таблицы Realiz;
Calc_Realiz – заполняет все строки таблицы Realiz.

Фрагмент программного кода описания класса TForm1 следующий:

type
 TForm1 = class(TForm)
   ADOConnection1: TADOConnection;
   ADOTable1: TADOTable;
   ...
   private
     { Private declarations }
   public
     { Public declarations }
   procedure Calc_Tovar_Row(RecNo:word);
   procedure Calc_Postupl_Row(RecNo:word);
   procedure Calc_Realiz_Row(RecNo:word);
  procedure Calc_Realiz; // заполнение таблицы Realiz
  procedure Calc_Postupl; // заполнение таблицы Postupl
  procedure Calc_Tovar; // заполнение таблицы Tovar
   procedure Show_Tovar;
   procedure Show_Postupl;
   procedure Show_Realiz;
 end;

Листинги всех шести процедур вычисления расчетных полей дано ниже. Их нужно вписывать в раздел

implementation
 ...
end.

Листинг процедуры, которая заполняет одну строку таблицы Realiz.

procedure TForm1.Calc_Realiz_Row(RecNo:word);
begin
 ADOTable3.DisableControls;
 ADOTable3.RecNo := RecNo;
 ADOTable3.Edit;
 ADOTable3.Fields[5].AsFloat := ADOTable3.Fields[3].AsFloat *
 ADOTable3.Fields[4].AsInteger;
 ADOTable3.Post;
 ADOTable3.EnableControls;
end;

Объясним некоторые фрагменты кода.

Доступ к вычисляемому полю Suma_Real таблицы Realiz осуществляется через объект

ADOTable3.Fields[5].AsFloat

Число 5 обозначает порядковй номер поля в ADOTable3 (можно посмотреть через редактор полей «Fields Editor«). Окончание AsFloat значит, что тип поля есть число с плавающей точкой. Тип поля в компоненте ADOTable3 должен совпадать с типом поля таблицы Realiz в базе данных «auto.mdb«. В базе данных этот тип установлен как «двойное с плавающей точкой». Точно так же типы полей других таблиц между компонентами и соответствующими им таблицами должны совпадать.

Существуют и другие способы доступа к полям базы данных в таблицах в системе Delphi.

Листинг процедуры, заполняющей все строки таблицы Realiz следующий.

procedure TForm1.Calc_Realiz;
var
 i:integer;
begin
 ADOTable3.DisableControls;
 ADOTable3.First;
 for i := 1 to ADOTable3.RecordCount do
 begin
   Calc_Realiz_Row(ADOTable3.RecNo);
   ADOTable3.Next;
 end;
 ADOTable3.EnableControls;
end;

В начале и в конце процедуры вызываются два метода (процедуры) DisableControls и EnableControls компонента ADOTable3. Эти методы отвечают за подключение и отключение к наборам данных визуальных элементов управления (в нашем случае это компонент DBGrid4). Вызов метода DisableControls в начале позволяет существенно ускорить процесс перебора записей, так как освободит наше приложение от необходимости постоянного (с каждой сменой записи) перерисовывания содержимого элемента управления DBGrid4. В конце процедуры обязательно нужно вызвать EnableControls.

Доступ к полям таблицы Postupl осуществляется через компонент ADOTable2.

Листинг процедуры Calc_Postupl_Row заполнения одной строки таблицы Postupl приведен ниже. Процедура Calc_Postupl_Row вызывается из процедури Calc_Postupl.

procedure TForm1.Calc_Postupl_Row(RecNo: Word);
var
 i:integer;
 id_post1, id_post2:integer;
 n_real:integer;
 suma_real:real;
begin
 ADOTable2.RecNo := RecNo;
 ADOTable2.Edit;
 // Сумма поступлений (закупки)
 ADOTable2.Fields[7].AsFloat :=
 ADOTable2.Fields[3].AsFloat * ADOTable2.Fields[6].AsInteger;
// рассчитываем количество и сумму реализаций для данного поступления
 n_real := 0;
 suma_real := 0;
 id_post1 := ADOTable2.Fields[0].AsInteger; // Postupl.ID_Postupl
 ADOTable3.First;
 for i:=1 to ADOTable3.RecordCount do
 begin
   id_post2 := ADOTable3.Fields[1].AsInteger; // Realiz.ID_Postupl
   if id_post1 = id_post2 then
   begin
     n_real := n_real + ADOTable3.Fields[4].AsInteger;
     suma_real := suma_real + ADOTable3.Fields[5].AsFloat;
   end;
   ADOTable3.Next;
 end;
 // число реализаций (сумма)
 ADOTable2.Fields[8].AsInteger := n_real;
 // сумма реализаций
 ADOTable2.Fields[9].AsFloat := suma_real;
 // остаток
 ADOTable2.Fields[10].AsInteger :=
 ADOTable2.Fields[6].AsInteger - ADOTable2.Fields[8].AsInteger;
 ADOTable2.Post;
end;

Листинг процедуры Calc_Postupl для заполнения полей таблицы Postupl следующий.

procedure TForm1.Calc_Postupl;
var
 i:integer;
begin
 ADOTable2.First;
 for i:=1 to ADOTable2.RecordCount do // перебор всех полей таблицы Postupl
 begin
   Calc_Postupl_Row(ADOTable2.RecNo);
   ADOTable2.Next;
 end;
end;

Доступ к полям таблицы Tovar осуществляется через компонент ADOTable1.

Программный код процедуры заполнения одной строки таблицы Tovar следующий.

procedure TForm1.Calc_Tovar_Row(RecNo:word);
var
 n_post:integer;
 suma_post:real;
 n_real:integer;
 suma_real:real;
 zal:integer;
 id_tovar1, id_tovar2:word;
 i:integer;
begin
 ADOTable1.DisableControls;
 ADOTable2.DisableControls;
 ADOTable1.RecNo := RecNo;
 ADOTable1.Edit;
 id_tovar1 := ADOTable1.Fields[0].AsInteger; // Tovar.ID_Tovar
 n_post := 0; // число поступлений
 suma_post := 0; // сумма всех поступлений
 n_real := 0; // число реализаций
 suma_real := 0; // сумма реализаций
 zal := 0; // остаток
 ADOTable2.First;
 for i:=1 to ADOTable2.RecordCount do
 begin
   // взяли код товара из таблицы Postupl
   id_tovar2 := ADOTable2.Fields[1].AsInteger; // Postupl.ID_Tovar
   if id_tovar1 = id_tovar2 then 
   begin
     n_post := n_post + ADOTable2.Fields[6].AsInteger;
     suma_post := suma_post + ADOTable2.Fields[7].AsFloat;
     n_real := n_real + ADOTable2.Fields[8].AsInteger;
     suma_real := suma_real + ADOTable2.Fields[9].AsFloat;
     zal := zal + ADOTable2.Fields[10].AsInteger;
   end;
   ADOTable2.Next;
 end;
 // заполняем расчетные поля таблицы Tovar
 ADOTable1.Fields[5].AsInteger := n_post;
 ADOTable1.Fields[6].AsFloat := suma_post;
 ADOTable1.Fields[7].AsInteger := n_real;
 ADOTable1.Fields[8].AsFloat := suma_real;
 ADOTable1.Fields[9].AsInteger := zal;
 ADOTable1.Post;
 ADOTable1.EnableControls;
 ADOTable2.EnableControls;
end;


В этом коде программно подсчитываются суммы поступлений, реализаций и остаток на складе. Процедура Calc_Tovar_Row вызывается из процедуры Calc_Tovar. Листинг процедуры Calc_Tovar вычисления всех строк (записей) таблицы Tovar приведен ниже.

procedure TForm1.Calc_Tovar;
var
 i:integer;
begin
 ADOTable1.First;
 // перебор всех полей таблицы Tovar
 for i := 1 to ADOTable1.RecordCount do 
 begin
   Calc_Tovar_Row(ADOTable1.RecNo);
   ADOTable1.Next;
 end;
end;

К содержанию.

 

12. Установка фильтра в таблицах.

Во время работы с приложением пользователь имеет возможность осуществлять передвижение по записям таблиц базы данных. При переходе на другую запись (смена активной группы) в таблице Group автоматически должно происходить перерисовывание записей таблицы Tovar которые относятся к активной группе. При изменении активной записи в таблице Tovar должны выводиться только те записи таблицы Postupl, которые соответствуют данному товару. То же самое можно сказать и о записях таблицы Postupl от которых зависит вид таблицы Realiz.

Напишем программный код обработчиков событий, которые реагируют на изменение группы в таблице Group, товара в таблице Tovar и поступлений в таблице Postupl. Для фильтрации нужных записей в компоненте ADOTable1 есть свойство Filter, которое подобно SQL-запросу. Например, для вывода записей таблицы Tovar, которые относятся к группе с идентификатором равным 3, нужно выполнить такие действия:
– в свойство Filter ввести строку «ID_Group = 3«;
– свойство Filtered установить в значение true.

Первым делом в классе формы TForm1 создаем три процедуры (см. п. 11):
Show_Tovar;
Show_Postupl;
Show_Realiz.

Листинг реализации этих процедур имеет вид.

// перерисовывание таблицы Tovar
 procedure TForm1.Show_Tovar;
 var
   id_group:word;
 begin
   id_group := ADOQuery1.Fields[0].AsInteger;
   ADOTable1.Filter := 'ID_Group = ' + IntToStr(id_group);
   ADOTable1.Filtered := true;
   ADOTable1.First;
   ADOTable1.Refresh;
 end;

// перерисовывание таблицы Postupl
procedure TForm1.Show_Postupl;
var
  id_tovar:integer;
begin
 id_tovar := ADOTable1.Fields[0].AsInteger;
 ADOTable2.Filter := 'ID_Tovar = ' + IntToStr(id_tovar);
 ADOTable2.Filtered := true;
 ADOTable2.First;
 ADOTable2.Refresh;
end;

// перерисовывание таблицы Realiz
procedure TForm1.Show_Realiz;
var
 id_postupl:integer;
begin
 id_postupl := ADOTable2.Fields[0].AsInteger;
 ADOTable3.Filter := 'ID_Postupl = ' + IntToStr(id_postupl);
 ADOTable3.Filtered := true;
 ADOTable3.First;
 ADOTable3.Refresh;
end;

В каждой из процедур выполняются следующие действия:

1. Определяется уникальный идентификатор главной таблицы id_… .
2. Заполняется свойство Filter таблицы с одновременным установлением опции Filtered в значение true.
3. Перемотка на первую запись таблицы (метод First).
4. Происходит перерисовывание изображения в компонентах отображения DBGrid (метод Refresh).

В обработчик события OnCellClick компонента DBGrid1 вписываем следующий код.

// Изменение активной группы
procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
 Show_Tovar;
 Show_Postupl;
 Show_Realiz;
end;

Точно такой же код вписываем в обработчик события OnKeyUp этого компонента.

Этот код устанавливает фильтр в компоненте ADOTable1, благодаря чему в таблице Tovar отображаются только те товары, которые относятся к группе, которая есть активной в компоненте DBGrid1.

Листинг процедуры обработки события OnCellClick компонента DBGrid2 описан ниже. Точно такой код вписываем и в обработчик события OnKeyUp этого компонента.

// Изменение товара - перерисовать таблицы Postupl, Realiz
procedure TForm1.DBGrid2CellClick(Column: TColumn);
begin
 Show_Postupl;
 Show_Realiz;
end;

Листинг процедуры обработки события OnCellClick компонента DBGrid3 описан ниже. Этот код вписываем в обработчик события OnKeyUp этого компонента.

// Изменение активного поступления - перерисовать таблицу Realiz
procedure TForm1.DBGrid3CellClick(Column: TColumn);
begin
  Show_Realiz;
end;

После запуска проекта на выполнение можно убедиться, что при выборе записей таблиц Tovar, Postupl и Realiz выводятся только нужные записи соответствующих зависимых таблиц.

К содержанию.

 

13. Настройка маски вывода в полях таблиц.

На данный момент форма приложения в режиме проектирования имеет вид (рис. 38).

01_02_00_005_38u

Рис. 38. Главная форма приложения

В некоторых полях таблиц Tovar, Postupl и Realiz там, где фигурируют денежные единицы целесообразно вводить значения с точностью 2 знака после запятой.

Устанавливаем точность вывода для таких полей таблицы Tovar (компонент ADOTable1):
– поле «Пост.«, которому соответствует поле Suma_Post таблицы;
– поле «Реал.«, которому соответствует поле Suma_Real таблицы.

Последовательность шагов для заполнения поля «Пост.» следующая.
– открываем редактор полей «Fields Editor…» (см. п. 8.3) компонента ADOTable1;
– выбираем мышкой поле Suma_Post;
– в Object Inspector устанавливаем свойство «Display Format» в значение «0.00«.

Автоматически в таблице Tovar все строки будут отображаться в удобном денежном виде.

Можно поэкспериментировать с полем «Display Format«, установив, например, значение «0.00 грн» или «0.00 руб«.

Таким же образом настраиваем и другие поля:
– поле Suma_Real компонента ADOTable1;
– поля Prise_Zak, Exchange, Price_Rek, Suma_Zak, Suma_Real компонента ADOTable2;
– поля Price_Real, Suma_Real компонента ADOTable3.

В результате выполненных действий поля всех таблиц, которые соответствуют денежным единицам, будут выводиться в более читабельном виде.

К содержанию.

 

14. Настройка защиты ячеек таблиц от случайного изменения.

При выделении полей таблиц есть вероятность случайного изменения значения выделенной ячейки.

С целью избежания этой ситуации осуществим такие шаги для компонента DBGrid1:
– выделить компонент DBGrid1;
– в Object Inspector свойство «ReadOnly» установить в значение true;
– раскрываем свойство Options (знак «+«) и в раскрытом списке устанавливаем опцию dgRowSelect в значение true.

Эти операции позволяют выделять целую строку в таблице и избегают случайной смене отдельных ячеек таблицы.
Точно такие же действия прорабатываем для компонент DBGrid2, DBGrid3, DBGrid4.

К содержанию.

 

15. Проектирование форм диалоговых окон.

На данный момент у нас есть возможность удобно просматривать данные таблиц базы данных auto.mdb, которая загружается в приложение автоматически.

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

К содержанию.

 

15.1. Проектирование и подключение формы «Курс валют».

Форма «Курс валют» вызывается командой «Изменить…» из меню «Курс валют» главного меню приложения.

После создания формы объект-переменная формы имеет имя Form2. Оставим это имя без изменений.

К содержанию.

15.1.1. Настройка компонент формы «Курс валют».

Последовательность шагов по созданию формы следующая.

1. Создать новую форму в приложении. Установить имя модуля (файла) формы «Form_Exchange«.

2. Подключить новую форму к приложению.

3. Настроить следующие свойства новой формы:
– свойство Caption = «Курс валют»;
– свойство BorderStyle = bsDialog (стиль как диалоговое окно);
– свойство Position = poScreenCenter (форма будет отображаться по центру экрана).

4. Вынести на форму компоненты (элементы управления) типа TLabel, TButton, TEdit и разместить их как указано на рисунке. Имеем компоненты с именами Label1, Button1, Button2, Edit1. Формируем размеры и положение компонент таким образом, чтобы форма имела привлекательный вид.

01_02_00_005_39r

Рис. 39. Окно формы «Курс валют»

Устанавливаем следующие свойства компонент.

В компоненте Button1 свойство Caption=»Подтвердить».
В компоненте Button2 свойство Caption=»Отменить».
В компоненте Edit1 свойство Text=» (пустая строка).

Устанавливаем порядок изменения активности элементов управления с помощью клавиши Tab путем вызова контекстного меню формы «Tab Order…«. Устанавливаем следующий порядок изменения:
Edit1;
Button1;
Button2.

К содержанию.

 

15.1.2. Реализация событий формы.

Обработчик события активизации формы Form2 имеет вид.

procedure TForm2.FormActivate(Sender: TObject);
begin
 Edit1.Text := '';
 Edit1.SetFocus;
end;

В обработчике события активизации формы очищается поле строки ввода и фокус управления передается компоненту Edit1.
Обработчики событий клика мышкой на кнопках «Подтвердить» и «Отменить» имеют следующий вид. Результат возврата из формы заносится во внешнюю переменную ModalResult.

procedure TForm2.Button1Click(Sender: TObject);
begin
 ModalResult := mrOk;
end;

procedure TForm2.Button2Click(Sender: TObject);
begin
 ModalResult := mrNo;
end;

К содержанию.

 

15.2. Проектирование формы добавления новой группы.

После создания, форму добавления новой группы сохраняем в модуле Form_Add_Group.pas. Объект-переменная данной формы имеет имя Form3.

Формируем форму по образцу, как показано на рисунке 40.

01_02_00_005_40r

Рис. 40. Окно добавления группы товаров

Для формы Form3 формируем свойства подобно тому, как описано в п. 15.1.1.

Устанавливаем следующий порядок изменения фокуса ввода для элементов управления с помощью клавиши Tab:
Edit1;
Edit2;
Button1;
Button2.

Программируем событие выбора команд «Подтвердить» и «Отменить» точно также, как описано в п. 15.1.2.

Листинг обработчика события активизации формы Form3 следующий.

Procedure Tform3.FormActivate(Sender: Tobject);
begin
 Edit1.Text := '';
 Edit2.Text := '';
 Edit1.SetFocus;
end;

К содержанию.

 

15.3. Проектирование формы изменения (редактирования) активной группы.

Окно формы вызывается после выбора команды «Редактировать…» в меню «Группа«.

Форма изменения активной группы имеет имя (по умолчанию) Form4. Компоненты, которые размещены на форме такие же как и в форме Form3. При сохранении модуля формы указываем имя «Form_Chg_Group.pas«.

Формируем свойства формы так же, как и в п. 15.1.1.

Программный код обработчиков событий такой же как и в Form3 за исключением того, что обработчик события активизации формы имеет вид.

Procedure Tform4.FormActivate(Sender: Tobject);
begin
 Edit1.SetFocus;
end;

Значения полей (Edit1, Edit2) о выделенной на данный момент группе будет устанавливаться в главной форме Form1 приложения, з которой эта форма будет вызываться (рис. 41).

01_02_00_005_41r

Рис. 41. Форма редактирования информации о группе

К содержанию.

 

15.4. Форма окна добавления товара.

Добавление нового товара в таблицу Tovar осуществляется командой «Добавить…» из меню «Товар«. Файл формы сохраняем под именем «Form_Add_Tovar.pas«. Объект-переменная формы имеет название Form5.

Процесс создания формы добавления товара подобен процессу создания формы добавления группы (Form3). Форма добавления нового товара имеет вид, как изображено на рис. 42.

01_02_00_005_42r

Рис. 42. Форма добавления нового товара

К содержанию.

 

15.5. Форма окна редактирования данных товара.

Форма окна редактирования данных товара сохраняется в приложении в модуле «Form_Chg_Tovar.pas«. Компонент формы имеет имя Form6.

Последовательность действий по созданию формы такая же как и при создании формы добавления нового товара (Form5). Форма редактирования информации о товаре изображена на рис. 43.

01_02_00_005_43r

Рис. 43. Редактирование данных о товаре

К содержанию.

 

15.6. Форма окна добавления нового поступления.

Модуль формы сохраняется в файле «Form_Add_Postupl.pas«.
Окно добавления нового поступления имеет вид (рис. 44).

01_02_00_005_44r

Рис. 44. Окно добавления нового поступления

Переменная-компонент, которая соответствует форме поступления имеет название Form7.

Поле «Дата поступления» – это есть компонент типа TDateTimePicker, который размещен на палитре Win32.

Обработчик события активизации формы несколько отличается от обработчиков событий предыдущих форм.

Procedure Tform7.FormActivate(Sender: Tobject);
begin
 DateTimePicker1.DateTime := Date;
 Edit1.Text := '';
 Edit3.Text := '';
 Edit4.Text := '';
 Edit1.SetFocus;
end;

В первой строке значению компонента DateTimePicker1.DateTime присваивается результат функции Date. Функция Date возвращает дану, которая на данный момент установлена в операционной системе.

Кроме функции Date в Delphi есть еще функция Time, возвращающая текущее время.

К содержанию.

 

15.7. Форма окна редактирования поступления.

Форма окна редактирования поступления в приложении имеет имя Form8 и сохраняется в файле «Form_Chg_Postupl.pas«. Окно редактирования поступления изображено на рисунке 45.

Обработчики событий, настройки формы и значения свойств компонент формы устанавливаем по предыдущим примерам.

01_02_00_005_45r

Рис. 45. Окно редактирования поступления

К содержанию.

 

15.8. Добавление новой реализации.

Компонент-переменная формы добавления новой реализации в приложении имеет имя Form9. Исходный код формы сохраняется в модуле «Form_Add_Realiz.pas«.

Окно добавления новой реализации изображено на рисунке 46.

01_02_00_005_46r

Рис. 46. Окно добавления новой реализации

Программный код процедуры события активизации формы следующий.

procedure TForm9.FormActivate(Sender: TObject);
begin
 DateTimePicker1.DateTime := Date;
 Edit2.Text := '';
 DateTimePicker1.SetFocus;
end;

В обработчике событий активизации формы изменяем только значения строки ввода Edit2.Text. Другие строки будут формироваться из главной формы приложения.

К содержанию.

 

15.9. Редактирование реализации.

Форма редактирования одной строки реализации изображена на рисунке 47. В результате создания формы сформирована переменная с именем Form10. Модуль формы имеет название «Form_Chg_Realiz.pas«.

01_02_00_005_47r

Рис. 47. Окно редактирования строки реализации

Листинг события активизации формы имеет вид.

Procedure Tform10.FormActivate(Sender: Tobject);
begin
 DateTimePicker1.DateTime := Date;
end;

Таким образом, на данном этапе мы спроектировали 9 форм и запрограммировали их корректное поведение. Все формы будут открываться из главного модуля «Main.pas«.

К содержанию.

 

16. Подключение формы к главному модулю приложения.

Для того, чтобы иметь доступ из главного модуля приложения к модулям форм, созданных в п. 15, нужно осуществить соответствующее подключение оператором uses.

Переходим в модуль Main.pas (главная форма приложения). После слова implementation набираем строку подключения модулей форм.

Листинг фрагмента кода приложения имеет вид.

implementation
{$R *.dfm}
uses Form_Add_Group, Form_Add_Postupl, Form_Add_Realiz, Form_Add_Tovar,
 Form_Chg_Group, Form_Chg_Postupl, Form_Chg_Realiz, Form_Chg_Tovar,
 Form_Exchange;

После этого, к формам, которые были созданы в п. 15 можно иметь доступ по именам переменных (компонент). Так, например, к свойствам и методам формы добавления новой группы можно доступиться по имени Form3.

К содержанию.

 

17. Работа с группой.

В этом разделе напишем программный код, реализующий операции с группой товаров. В главном меню приложения предусмотрено три операции над группой товаров (меню «Группа«):
– «Добавить…»;
– «Редактировать…»;
– «Удалить».

К содержанию.

 

17.1. Добавление новой группы.

Доступ к полям формы, которая используется для добавления новой группы, осуществяется с помощью переменной Form3.

Для того, чтобы вызвать добавление новой группы в приложении, нужно запрограммировать обработчик события выбора команды «Добавить…» из меню «Группа«.

Сначала найдем (вызовем) объект-переменную, которая соответствует этой команде. Для этого вызовем «Menu Designer…» компонента MainMenu1 (см. п. 4) и выделим команду «Добавить…» из меню «Группа«, как показано на рисунке 48.

01_02_00_005_48r

Рис. 48. Команда «Добавить…» из меню «Группа»

В Object Inspector отобразится название элемента меню (объекта) типа TMenuItem. В нашем случае это объект с именем N4. Названия элементов меню (поле Name) могут отличаться в зависимости от порядка (последовательности) построения команд меню.

После этого в Object Inspector переходим во вкладку Events (события) и активируем событие OnClick (рис. 49).

Событие OnClick генерируется в случае, когда пользователь выбрал элемент меню с помощью «мышки», клавиатуры или комбинаций быстрого вызова.

01_02_00_005_49r

Рис. 49. Обработчик события OnClick команды «Добавить…» из меню «Группа«

Листинг обработчика события N4Click выбора команды добавления группы следующий.

// Выбор команды Группа -> "Добавить..."
procedure TForm1.N4Click(Sender: TObject);
begin
 //
 if Form3.ShowModal = mrOk then
 begin
  ADOQuery1.Close; // закрываем соединение с базой данных
// Формируем SQL-запрос для компонента ADOQuery1
 ADOQuery1.SQL.Clear; // очищаем строку предыдущего SQL-запроса
  ADOQuery1.SQL.Add('INSERT INTO [Group] '); // формируем новый запрос
  ADOQuery1.SQL.Add('([Name], [Code]) ');
  ADOQuery1.SQL.Add('VALUES ("' + Form3.Edit1.Text + '", ');
  ADOQuery1.SQL.Add('"' + Form3.Edit2.Text + '") ');
// выполняем новый запрос - группа добавляется в базу данных
  ADOQuery1.ExecSQL; 
 // восстанавливаем старый SQL-запрос
  ADOQuery1.SQL.Clear;
  ADOQuery1.SQL.Add('SELECT * FROM [Group]');
 ADOQuery1.Open; // открываем доступ к базе данных
  ADOQuery1.Last; // выделение добавленной группы
 end;
end;

Объясним некоторые моменты в приложении.

После вызова команды «Добавить…» открывается форма Form3 из модуля «Form_Add_Group.pas» с помощью вызова функции Form3.ShowModal. Если в окне формы добавления группы пользователь выбрал кнопку «Подтвердить«, то результатом возврата из формы будет константа mrOk. В нашем случае при выборе «Подтвердить» ход выполнения приложения переходит в область операторных скобок begin … end (с помощью оператора условного перехода if).

В операторных скобках формируется SQL-запрос к базе данных, который имеет вид:

INSERT INTO [Group]
 ([Name], [Code])
VALUES ("value1", "value2")

где значение value1 берется из строки ввода Form3.Edit1.Text, а значение value2 из строки Form3.Edit2.Text. Данный SQL-запрос добавляет строку в таблицу Group базы данных.

Поскольку таблица Group соединена с приложением с помощью компонента ADOQuery1 системы Delphi, то этот запрос формируем в одноименном свойстве ADOQuery1.SQL. Это свойство есть массивом строк типа TStrings.

Обязательным есть предыдущая очистка строки SQL-запроса. Добавление новых строк выполняется с помощью метода Add, который в качестве параметра принимает строку, которая добавляется.

Для выполнения SQL-запроса используется функция ExecSQL компонента ADOQuery1. После вызова функции новая группа с заданными параметрами будет добавлена к базе данных.

Поскольку с компонентом ADOQuery1 связан элемент управления отображения данных DBGrid1, то обязательным в данном коде есть восстановление старого SQL-запроса, который был до этого. Старый SQL-запрос просто выводил все записи таблицы Group и имел следующий вид:

SELECT *
FROM [Group]

Название таблицы Group в SQL-запросах нужно брать в квадратные скобки, потому что в языке SQL есть команда GROUP BY. Это делается с целью избежания неоднозначностей.

Протестируем работу системы. Запускаем проект на выполнение (клавиша F9). Вызываем команду «Добавить…» из меню «Группа«. Вносим данные, как указано на рисунке 50 (или другие данные).

01_02_00_005_50r

Рис. 50. Окно добавления новой группы в режиме выполнения

После подтверждения группа с заданными данными добавляется к базе данных (рис. 51).

01_02_00_005_51r

Рис. 51. Результат добавления новой группы

К содержанию.

 

17.2. Редактирование группы.

Редактирование данных о группе вызывается командой «Редактировать…» из меню «Группа».

При редактировании данных группы точно так же, как и при добавлении будем использовать SQL-запрос. Вид SQL-запроса следующий.

UPDATE [Group]
SET [Name] = value1, [Code] = value2
WHERE [Group].ID_Group = id_gr

где value1 – значение строки Form4.Edit1.Text, а value2 – значение строки Form4.Edit2.Text.

Исходный код обработки события выбора команды «Редактировать…» из меню «Группа» имеет вид.

// Группа -> Редактировать...
procedure TForm1.N5Click(Sender: TObject);
var
 id_gr:word;
 old_rec:word;
begin
 //
 Form4.Edit1.Text := ADOQuery1.Fields[1].AsString; // взяли название выделенной группы
 Form4.Edit2.Text := ADOQuery1.Fields[2].AsString; // код группы
 if Form4.ShowModal = mrOk then
 begin
   old_rec := ADOQuery1.RecNo;
   id_gr := ADOQuery1.Fields[0].AsInteger; // взяли код ID_Group
   ADOQuery1.Close;
   ADOQuery1.SQL.Clear;
   ADOQuery1.SQL.Add('UPDATE [Group] ');
   ADOQuery1.SQL.Add('SET [Name] = "' + Form4.Edit1.Text + '", ');
   ADOQuery1.SQL.Add('[Code] = "' + Form4.Edit2.Text + '" ');
   ADOQuery1.SQL.Add('WHERE [Group].ID_Group = ' + IntToStr(id_gr));
   ADOQuery1.ExecSQL;
   ADOQuery1.SQL.Clear;
   ADOQuery1.SQL.Add('SELECT * FROM [Group]');
   ADOQuery1.Open;
   ADOQuery1.RecNo := old_rec;
 end;
end;

Как видно из кода формируем SQL-запрос в компоненте ADOQuery1 и выполняем его. Переменная old_rec предназначена для запоминания номера позиции активной записи до выполнения запроса и его восстановления после выполнения запроса (для корректной работы).

К содержанию.

 

17.3. Удаление группы.

Удаление группы вызывается командой «Удалить» из меню «Группа«. SQL-запрос удаления активной строки (группы) имеет вид

DELETE FROM [Group] 
WHERE ID_Group = id_gr

где num_gr – уникальный идентификатор выделенной группы.

Листинг обработчика события удаления группы имеет следующий вид.

// Група -> Видалити
procedure TForm1.N6Click(Sender: TObject);
var
 id_gr:word;
begin
 //
 if MessageDlg('Вы действительно хотите удалить данную группу?',
 mtConfirmation,[mbYes,mbNo],0,mbYes)=mrYes then
 begin
  id_gr := ADOQuery1.Fields[0].AsInteger; // взяли код ID_Group
  ADOQuery1.Close;
  ADOQuery1.SQL.Clear;
  ADOQuery1.SQL.Add('DELETE FROM [Group]');
  ADOQuery1.SQL.Add('WHERE ID_Group = ' + IntToStr(id_gr));
  ADOQuery1.ExecSQL;
  ADOQuery1.SQL.Clear;
  ADOQuery1.SQL.Add('SELECT * FROM [Group]');
  ADOQuery1.Open;
 end;
end;

В выше предложенном листинге для подтверждения запроса об удалении строки текущей группы используется метод MessageDlg, который представляет собой обычное диалоговое окно подтверждения, которое изображено на рисунке 52. Метод MessageDlg имеет ряд собственных параметров, которые позволяют манипулировать видом окна и количеством кнопок в окне.

Можно пойти и другим путем, создав собственную форму запроса на удаление.

01_02_00_005_52r

Рис. 52. Окно, которое открывается при вызове метода MessageDlg

К содержанию.

 

18. Команды меню «Товар«.

В меню «Товар» содержится три команды:
– добавление товара (команда «Добавить…«);
– редактирование текущего товара (команда «Редактировать…«);
– удаление товару (команда «Удалить«).

С товарами в приложении связана таблица Tovar базы данных. Для доступа к записям таблицы Tovar в базе данных используется компонент ADOTable1. Поэтому все операции по добавлению, редактированию или удалению данных будут выполняться в компоненте ADOTable1. Автоматически все изменения будут отображаться в компоненте DBGrid2, связанном с ADOTable1.

К содержанию.

 

18.1. Добавление товара.

Добавление нового товара осуществляется командой «Добавить» из меню «Товар«. В результате вызова команды должно открыться окно добавления товара, которое было сформировано в п. 15.4.

Обработчик события добавления товара имеет следующий вид.

// Товар -> Добавить...
procedure TForm1.N8Click(Sender: TObject);
var
 id_group:word;
begin
 // добавление нового товара
 if Form5.ShowModal=mrOk then
 begin
  // взяли ID_Group из таблицы Group
  id_group := ADOQuery1.Fields[0].AsInteger;
  ADOTable1.Append;
  ADOTable1.Fields[1].AsInteger := id_group;
  ADOTable1.Fields[2].AsString := Form5.Edit1.Text;
  ADOTable1.Fields[3].AsString := Form5.Edit2.Text;
  ADOTable1.Fields[4].AsString := Form5.Edit3.Text;
  ADOTable1.Post;
  Show_Tovar;
 end;
end;

Доступ к полям таблицы Tovar компонента ADOTable1 осуществляется через массив-свойство Fields. Нумерация элементов массива Fields начинается с 0.

Элемент массива ADOTable1.Fields[0] – это уникальный идентификатор строки товара ID_Tovar, который имеет тип «Счетчик«. Этот элемент массива не изменяется в базе данных (формируется автоматически, каждый раз увеличиваясь на 1).

Элемент массива ADOTable1.Fields[1] есть идентификатором группы, к которой принадлежит данный товар. Он заполняется со значения идентификатора группы ID_Group компонента ADOQuery1, который связан с таблицей Group.

Элементы массива ADOTable1.Fields[2], ADOTable1.Fields[3], ADOTable1.Fields[4] есть данными о товаре который добавляется (название, код и описание товара).

При заполнении значений полей важно придерживаться совместимости типов. Если поле ADOTable2.Fields[2] (название товара) есть строкой символов, то в приложении необходимо прямо указывать его тип:

ADOTable1.Fields[2].AsInteger

Для добавления новой строки в компоненте ADOTable1 есть метод Append. После заполнения значений каждого поля строки (за исключением поля строки с индексом 0) внесенные данные фиксируются с помощью метода ADOTable1.Post.

К содержанию.

 

18.2. Редактирование товара.

Редактирование данных о товаре осуществляется командой «Редактировать…» из меню «Товар«. Листинг обработчика события вызова команды «Редактировать…» имеет вид.

// Товар -> Редактировать
procedure TForm1.N9Click(Sender: TObject);
begin
 // есть ли запииси в таблице товаров
 if ADOTable1.RecordCount<=0 then exit;
 
 // перед вызовом заполняем поля формы Form6
 Form6.Edit1.Text := ADOTable1.Fields[2].AsString;
 Form6.Edit2.Text := ADOTable1.Fields[3].AsString;
 Form6.Edit3.Text := ADOTable1.Fields[4].AsString;
 if Form6.ShowModal=mrOk then
 begin
   ADOTable1.Edit; // перевод таблицы в режим редактирования
   ADOTable1.Fields[2].AsString := Form6.Edit1.Text;
   ADOTable1.Fields[3].AsString := Form6.Edit2.Text;
   ADOTable1.Fields[4].AsString := Form6.Edit3.Text;
   ADOTable1.Post;
 end;
end;

Форма редактирования в приложении имеет имя Form6.

Перед вызовом формы Form6 данные о выделенном (активном) товаре получаются из полей ADOTable1.Fields. Эти данные копируются в поля формы Form6.Edit1.Text (название товара), Form6.Edit2.Text (код товара), Form6.Edit3.Text (описание товара). На момент вызова команды поля ADOTable1.Fields (таблица Tovar) содержат значения выделенной в DBGrid2 записи.

После вызова формы и выбора пользователем подтверждения все внесенные изменения заносятся в таблицу базы данных через ADOTable1.Fields. Перевод таблицы в режим редактирования осуществляется методом ADOTable1.Edit. Фиксирование данных в таблице базы данных осуществляется методом ADOTable1.Post.

К содержанию.

 

18.3. Удаление товара.

Удаление товара из данной группы осуществляется командой «Удалить» из меню «Товар«.

Листинг обработчика события удаления товара имеет такой вид.

// Товар -> Удалить
procedure TForm1.N10Click(Sender: TObject);
begin
 if ADOTable1.RecordCount<=0 then exit;
 if MessageDlg('Вы действительно хотите удалить данную группу?',
 mtConfirmation,[mbYes,mbNo],0,mbYes)=mrYes then
 ADOTable1.Delete;
end;

Для удаления товара вызывается метод ADOTable1.Delete.

К содержанию.

 

19. Команды меню «Поступления«.

В меню «Поступления» содержится три команды:
– добавление нового поступления (команда «Добавить…«);
– редактирование текущего поступления (команда «Редактировать…«);
– удаление поступления (команда «Удалить«).

С поступлениями товаров в приложении связана таблица Postupl базы данных. Для доступа к записям таблицы Postupl в базе данных используется компонент ADOTable2. Через этот компонент будут выполнятся все операции с таблицей Postupl. Автоматически все изменения будут отображаться в компоненте DBGrid3, который связан с ADOTable2 (см. схему в п.9.1).

К содержанию.

 

19.1. Добавление нового поступления.

Окно, которое вызывается при добавление нового поступления, было сформировано в п. 15.6. Форма, которая соответствует окну добавления нового поступления, имеет имя Form8.

Обработчик события добавления нового поступления в приложении имеет следующий вид.

// Поступление -> Добавить...
procedure TForm1.N12Click(Sender: TObject);
var
 id_tovar:integer;
begin
 // заполнили поле текущего курса денежной единицы
 Form8.Edit2.Text :=
 FloatToStrF(ADOTable2.FieldByName('Exchange').AsFloat, ffFixed, 8, 2);
 if Form8.ShowModal = mrOk then
 begin
   id_tovar := ADOTable1.Fields[0].AsInteger;
   ADOTable2.Append;
   ADOTable2.Fields[1].AsInteger := id_tovar;
   ADOTable2.Fields[2].AsDateTime := Form8.DateTimePicker1.DateTime;
   ADOTable2.Fields[3].AsFloat := StrToFloat(Form8.Edit1.Text);
   ADOTable2.Fields[4].AsFloat := StrToFloat(Form8.Edit2.Text);
   ADOTable2.Fields[5].AsFloat := StrToFloat(Form8.Edit3.Text);
   ADOTable2.Fields[6].AsInteger := StrToInt(Form8.Edit4.Text);
   ADOTable2.Post;
   Calc_Postupl_Row(ADOTable2.RecNo); // пересчет строки поступления
   Calc_Tovar_Row(ADOTable1.RecNo); // пересчет строки товара
 end;
end;

К содержанию.

 

19.2. Редактирование поступления.

Окно редактирования поступления было описано в п. 15.7. Доступ к форме редактирования выделенного поступления осуществляется через имя Form9.

Листинг обработчика события редактирования поступления имеет вид.

// редактирование поступления
procedure TForm1.N13Click(Sender: TObject);
var
 old_rec:word;
begin
 // если поступлений нет, то выход
 if ADOTable2.RecordCount<=0 then exit;
 Form9.DateTimePicker1.Date := ADOTable2.FieldByName('Date').AsDateTime;
 Form9.Edit1.Text := FloatToStr(ADOTable2.FieldByName('Prise_zak').AsFloat);
 Form9.Edit2.Text := FloatToStr(ADOTable2.FieldByName('Exchange').AsFloat);
 Form9.Edit3.Text := FloatToStr(ADOTable2.FieldByName('Price_rek').AsFloat);
 Form9.Edit4.Text := FloatToStr(ADOTable2.FieldByName('Count').AsFloat);
 if Form9.ShowModal = mrOk then
 begin
   old_rec := ADOTable2.RecNo; // запомнили номер
   ADOTable2.Edit;
   ADOTable2.FieldByName('Date').AsDateTime := Form9.DateTimePicker1.Date;
   ADOTable2.FieldByName('Prise_zak').AsFloat := StrToFloat(Form9.Edit1.Text);
   ADOTable2.FieldByName('Exchange').AsFloat := StrToFloat(Form9.Edit2.Text);
   ADOTable2.FieldByName('Price_rek').AsFloat := StrToFloat(Form9.Edit3.Text);
   ADOTable2.FieldByName('Count').AsInteger := StrToInt(Form9.Edit4.Text);
   ADOTable2.Post;
   Calc_Postupl_Row(ADOTable2.RecNo);
   Calc_Tovar_Row(ADOTable1.RecNo);
   ADOTable2.RecNo:=old_rec;
 end;
end;

Дополнительная переменная old_rec предназначена для запоминания старой позиции во время редактирования.. Значение порядкового номера выделенной строки (записи) базы данных получается из свойства ADOTable2.RecNo.

В этой процедуре доступ к полям базы данных осуществляется с помощью вызова метода FieldByName компонента ADOTable2. Параметром входа в процедуру FieldByName есть строка названия поля, в которое вносится информация. Например, для доступа к полю «Exchange» таблицы Postupl, которое имеет вещественный тип данных (данные с плавающей точкой), нужно указать следующую строку:

ADOTable2.FieldByName('Exchange').AsFloat

Это есть еще один способ доступа к выделенной строке (записи) заданного поля базы данных. В предыдущих процедурах мы использовали доступ путем вызова свойства ADOTable2.Fields[i], где i – порядковый номер поля. Отсчет номеров полей начинается с 0.

К содержанию.

 

19.3. Удаление поступления.

Программный код обработчика события удаления поступления имеет вид.

// Поступление -> Удалить
procedure TForm1.N14Click(Sender: TObject);
begin
 if ADOTable2.RecordCount<=0 then exit;
 if MessageDlg('Вы действительно хотите удалить данное поступление?',
 mtConfirmation,[mbYes,mbNo],0,mbYes)=mrYes then
 begin
 ADOTable2.Delete;
 Calc_Tovar_Row(ADOTable1.RecNo); // пересчет строки товара
 end;
end;

К содержанию.

 

20. Установление курса валют.

В условии задачи стоит требование учета плавающего курса валюты при проведении реализации товара. Для обеспечения этого в приложении внесены дополнительные команды, а в таблицах базы данных введены специальные поля.

20.1. Изменение текущего курса.

Для установления курса валют нужно вызвать команду «Изменить…» из меню «Курс валют«.

Форма окна задания текущего курса главной валюты была спроектирована в п. 15.1. В приложении доступ к форме окна осуществляется через объект-переменную с именем Form2.

Обработчик события, который обеспечивает вывод формы Form2 имеет вид.

// Курс валют -> Изменить...
procedure TForm1.N2Click(Sender: TObject);
var
 old_value:real;
begin
 //
 old_value := StrToFloat(Form2.Edit1.Text);
 if Form2.ShowModal = mrNo then
 Form2.Edit1.Text := FloatToStrF(old_value, ffFixed, 8, 2);
end;

Изменение значения курса денежной единицы возможна, если в окне Form2 пользователь ее подтвердит. В другом случае вернется предыдущее значение. В программном коде предыдущее значение курса денежной единицы предварительно запоминается в переменной old_value.

К содержанию.

 

20.2. Изменение активизации главной формы.

Сделаем так, чтобы при первом запуске приложения (перед началом работы) пользователь вводил текущий курс денежной единицы, с которым будут проводиться финансовые операции с товарами.

Для этого в событие активизации главной формы OnActivate поместим соответствующие фрагменты кода. После внесенных изменений обработчик события активизации формы Form1 имеет вид.

procedure TForm1.FormActivate(Sender: TObject);
begin
 // задаем текущий курс валют
 if Form2.ShowModal=mrNo then
   Form2.Edit1.Text := '1'
 else
 if Form2.Edit1.Text = '' then
   Form2.Edit1.Text := '1';
 // Заполняем расчетные поля таблиц
 Calc_Realiz;
 Calc_Postupl;
 Calc_Tovar;
 // отображение всех таблиц
 Show_Tovar;
 Show_Postupl;
 Show_Realiz;
end;

К содержанию.

 

21. Команды меню «Реализация».

Меню «Реализация» содержит команды, которые относятся к реализации товара:
– «Добавить…» – добавляет новую реализацию (продажу) товара;
– «Редактировать…» – изменяет данные раньше внесенной реализации;
– «Удалить» – удаляет строку реализации, внесенную раньше.

Реализация товаров в базе данных отображается в таблице Realiz. Таблица Realiz базы данных связана с приложением с помощью компонента ADOTable3. Таким образом, корректируя значения записей компонента ADOTable3 можно вносить изменения в таблицу Realiz базы данных.

К содержанию.

21.1. Добавление новой реализации.

Добавление новой реализации вызывается командой «Добавить…» из меню «Реализация«. Форма соответствующего окна была спроектирована в п. 15.8.

Обработчик события добавления новой реализации имеет вид.

// Реализация -> Добавить...
procedure TForm1.N16Click(Sender: TObject);
var
 id_postupl:word;
 price:real;
 ex1, ex2:real;
 price_rek:real;
begin
 // рассчитываем цену реализации
 ex1 := StrToFloat(Form2.Edit1.Text); // текущий курс
 ex2 := ADOTable2.FieldByName('Exchange').AsFloat; // курс поступления
 price_rek := ADOTable2.FieldByName('Price_rek').AsFloat; // цена рекомендованная
 price := ex1/ex2*price_rek; // цена реализации
 // заполняем поля - подсказки
 Form7.Edit1.Text := FloatToStrF(price,ffFixed,8,2); // цена реализации
 Form7.Edit3.Text := Form2.Edit1.Text; // текущий курс
 Form7.Edit4.Text := FloatToStrF(ex2, ffFixed, 8, 2); // курс поступления
 if Form7.ShowModal = mrOk then
 begin
   id_postupl := ADOTable2.Fields[0].AsInteger;
   ADOTable3.Append;
   ADOTable3.Fields[1].AsInteger := id_postupl;
   ADOTable3.Fields[2].AsDateTime := Form7.DateTimePicker1.DateTime;
   ADOTable3.Fields[3].AsFloat := StrToFloat(Form7.Edit1.Text);
   ADOTable3.Fields[4].AsInteger := StrToInt(Form7.Edit2.Text);
   ADOTable3.Fields[5].AsFloat := ADOTable3.Fields[3].AsFloat *
   ADOTable3.Fields[4].AsInteger;
 ADOTable3.Post;
   Calc_Postupl_Row(ADOTable2.RecNo);
   Calc_Tovar_Row(ADOTable1.RecNo);
 end;
end;

К содержанию.

 

21.2. Редактирование реализации.

Редактирование строки реализации вызывается командой «Редактировать…» из меню «Реализация«. Форма окна, которое откроется для редактирования данных реализации товара, имеет имя Form10 (см. п. 15.9). Программный код обработчика события редактирования одной строки реализации следующий.

// Реализация - "Редактировать..."
procedure TForm1.N17Click(Sender: TObject);
var
 id_postupl:word;
 price:real;
 ex:real;
 price_rek:real;
begin
 if ADOTable3.RecordCount<=0 then exit;
 // рассчитываем цену реализации
 ex := ADOTable2.FieldByName('Exchange').AsFloat; // курс поступления
 // заполняем поля - подсказки
 Form10.DateTimePicker1.DateTime := ADOTable3.FieldByName('Date').AsDateTime;
 // цена реализации
 Form10.Edit1.Text :=
 FloatToStrF(ADOTable3.FieldByName('Price_Real').AsFloat, ffFixed, 8, 2);
 // количество
 Form10.Edit2.Text :=
 IntToStr(ADOTable3.FieldByName('Count').AsInteger);
 Form10.Edit3.Text := Form2.Edit1.Text; // текущий курс
 Form10.Edit4.Text := FloatToStrF(ex, ffFixed, 8, 2); // курс поступления
 if Form10.ShowModal=mrOk then
 begin
   id_postupl := ADOTable2.Fields[0].AsInteger;
   ADOTable3.Edit;
   ADOTable3.Fields[1].AsInteger := id_postupl;
   ADOTable3.Fields[2].AsDateTime := Form10.DateTimePicker1.DateTime;
   ADOTable3.Fields[3].AsFloat := StrToFloat(Form10.Edit1.Text);
   ADOTable3.Fields[4].AsInteger := StrToInt(Form10.Edit2.Text);
   ADOTable3.Fields[5].AsFloat := ADOTable3.Fields[3].AsFloat *
   ADOTable3.Fields[4].AsInteger;
   ADOTable3.Post;
   Calc_Postupl_Row(ADOTable2.RecNo);
   Calc_Tovar_Row(ADOTable1.RecNo);
 end;
end;

К содержанию.

 

21.3. Удаление строки реализации.

Листинг обработчика события, которое вызывается командой «Удалить» меню «Реализация«.

// Реализация -> Удалить
procedure TForm1.N18Click(Sender: TObject);
var
 p,t:word;
begin
 //
 if ADOTable3.RecordCount<=0 then exit;
 if MessageDlg('Вы действительно хотите удалить данную реализацию?',
 mtConfirmation,[mbYes,mbNo],0,mbYes)=mrYes then
 begin
 ADOTable3.Delete;
 ADOTable3.First;
 p:=ADOTable2.RecNo;
 t:=ADOTable1.RecNo;
 Calc_Postupl_Row(ADOTable2.RecNo);
 Calc_Tovar_Row(ADOTable1.RecNo);
 ADOTable1.RecNo := t;
 ADOTable2.RecNo := p;
 end;
end;

К содержанию.

 

22. Команда «Выход«.

Обработчик события команды «Выход» имеет следующий вид.

// Выход
procedure TForm1.N20Click(Sender: TObject);
begin
 Close;
end;


Начало


Похожие темы: