Здравствуйте уважаемые коллеги!
Третья и последняя часть статьи посвященной разработки программы по заданию «Туристическое агенство».
И начнем мы с формы fmTrip.
Кликаем 2 раза по кнопке bOk. Нас должно перекинуть в редактор кода, в котором добавились следующие строки:
procedure TfmTrip.bOkClick(Sender: TObject); begin end;
Между begin и end; добавим строку:
procedure TfmTrip.bOkClick(Sender: TObject); begin ModalResult := mrOk; end;
При нажатии на кнопку вернуть в качестве результата модального вызова mrOk.
Теперь кликаем 2 раза на кнопку bCancel и прописываем код:
procedure TfmTrip.bCancelClick(Sender: TObject); begin ModalResult := mrCancel; end;
При нажатии на кнопку вернуть в качестве результата модального вызова mrCancel.
Это весь код, который нужно написать для формы fmTrip.
Для форм fmClients и fmRoutes код не нужен, поэтому переходим сразу к форме fmMain
В первую очередь добавим формы fmClietns, fmRoutes и fmTrip в uses после implementation, чтобы мы могли их вызывать:
var fmMain: TfmMain; implementation uses Clients, Routes, Trip; {$R *.dfm}
Далее открываем список функций кликнув 2 раза на ActionListи прописываем код для каждой функции:
Кликаем 2 раза по aExit и в редакторе кода вставляем:
procedure TfmMain.aExitExecute(Sender: TObject); begin Close; end;
При вызове данной функции будет закрыта основная форма программы fmMain.
Функция aClients:
procedure TfmMain.aClientsExecute(Sender: TObject); begin fmClients.ShowModal; end;
Открыть справочник клиентов в модальном режиме, что означает: форма откроется поверх fmMain и пока не будет закрыта мы не сможем вернуться к fmMain.
Функция aRoutes:
procedure TfmMain.aRoutesExecute(Sender: TObject); begin fmRoutes.ShowModal; end;
Открыть справочник маршрутов в модальном режиме.
Функция aAddTrip:
procedure TfmMain.aAddTripExecute(Sender: TObject); begin tTrip.Append; if fmTrip.ShowModal = mrOk then begin tTrip.Post; aRefresh.Execute; end else tTrip.Cancel; end;
Разберем код более подробно:
tTrip.Append; — Процедура Append добавляет строку в конец таблицы tTrip
if fmTrip.ShowModal = mrOk then — Если форма редактирования поездки вернула результат mrOk (нажали кнопку «ОК»), то
tTrip.Post; — Сохраним введенные данные в базу.
aRefresh.Execute; — Вызовем функцию обновления, чтобы наша добавленная строка отобразилась в сводной таблице.
else — Иначе.
tTrip.Cancel; — Отменим ввод данных.
Функция aEditTrip:
procedure TfmMain.aAddTripExecute(Sender: TObject); begin tTrip.Edit; if fmTrip.ShowModal = mrOk then begin tTrip.Post; aRefresh.Execute; end else tTrip.Cancel; end;
Код очень похож на код кнопки добавления, за исключением того, что мы входим в режим редактирования текущей строки командой tTrip.Edit;.
Функция aDeleteTrip:
procedure TfmMain.aDeleteTripExecute(Sender: TObject); begin tTrip.Delete; aRefresh.Execute; end;
Вызываем метод Delete у таблицы tTrip, который удаляет строку.
И обновим данные вызвав функцию aRefresh.Execute;
Прежде чем мы перейдем к написанию кода функции aRefresh давайте добавим и настроим поля для запроса qTrips по аналогии с таблицами tClients, tRoutes, tTrip.
В свойстве SQL запроса нажимаем на три точки и в появившемся окне пишем запрос к БД:
SELECT * FROM view_trips
Далее кликаем 2 раза по qTrips и добавляем все поля из запроса. Настраиваем свойства:
trip_id — DisplayLabel = Код поездки, DisplayWidth = 5.
client_id — Visible = False.
last_name — DisplayLabel = Фамилия, DisplayWidth = 20.
first_name — DisplayLabel = Имя, DisplayWidth = 20.
second_name — DisplayLabel = Отчество, DisplayWidth = 20.
route_id — Visible = False.
country — DisplayLabel = Страна, DisplayWidth = 20.
transit_cost — DisplayLabel = Стоимость переезда.
day_stay_cost — DisplayLabel = Стоимость 1го дня пребывания.
start_date — DisplayLabel = Дата отъезда.
stay_count — DisplayLabel = Кол-во дней пребывания.
total_cost — DisplayLabel = Общая стоимость.
Функция aRefresh:
procedure TfmMain.aRefreshExecute(Sender: TObject); begin if qTrips.Active then qTrips.Close; qTrips.SQL.Clear; qTrips.SQL.Add('SELECT * FROM view_trips'); qTrips.SQL.Add('WHERE'); qTrips.SQL.Add('start_date >= ' + FormatDateTime('#d"/"m"/"yyyy#', dtpBegin.Date)); qTrips.SQL.Add('and start_date <= ' + FormatDateTime('#d"/"m"/"yyyy#', dtpEnd.Date)); qTrips.Open; end;
Разберем код:
if qTrips.Active then — если запрос был открыт, то
qTrips.Close; — закроем его прежде, чем вносить изменения
qTrips.SQL.Clear; — очистим предыдущий текст запроса
qTrips.SQL.Add(‘SELECT * FROM view_trips’); — добавим запрос
qTrips.SQL.Add(‘start_date >= ‘ + FormatDateTime(‘#d»/»m»/»yyyy#’, dtpBegin.Date)); — условия выборки данных:
поле start_date должно быть больше либо равно даты указанной в компоненте dtpBegin.
Функция FormatDateTime переводит тип TDateTime в строку, где первый параметр — формат перевода и второй — сама дата. Формат перевода состоит из:
# — обозначение начала и конца даты в Access
d — день числом от 1 до 31
m — месяц числом от 1 до 12
yyyy — 4 цифры года.
«/» — Поскольку знак деления в строке формата означает подстановку локального разделителя компонентов даты, которые могу меняться в зависимости от локальных настроек Windows, то мы обернули его кавычками, чтобы программа воспринимала его просто как символ.
qTrips.SQL.Add(‘and start_date <= ' + FormatDateTime('#d"/"m"/"yyyy#', dtpEnd.Date)); — уловие выборки данных:
поле start_date должно быть меньше либо равно даты указанной в компоненте dtpEnd.
qTrips.Open; — выполнить запрос.
Условия по дате мы добавили, но у нас еще должны быть условия по клиентам и маршрутам. Чтобы мы могли это реализовать для начала нам необходимо заполнить выпадающие списки из таблиц БД.
Напишем соответствующие процедуры, которые будут заполнять списки:
Добавляем описание процедур в разделе private:
private procedure LoadClientsList; procedure LoadRoutesList; public { Public declarations } end;
Теперь в разделе implementation добавим код процедуры:
procedure TfmMain.LoadClientsList; begin cbClients.Items.BeginUpdate; tClients.DisableControls; try cbClients.Items.Clear; cbClients.Items.Add('Все'); tClients.First; while not tClients.Eof do begin cbClients.Items.AddObject(tClients.FieldByName('last_name').AsString, TObject(tClients.FieldByName('client_id').AsInteger)); tClients.Next; end; finally tClients.EnableControls; cbClients.Items.EndUpdate; end; cbClients.ItemIndex := 0; end;
Теперь разберем код:
cbClients.Items.BeginUpdate; — Включаем режим обновления у списка для ускорения работы.
tClients.DisableControls; — Отключим все элементы управления привязанные к таблице для ускорения обновления.
cbClients.Items.Clear; — Очистим все элементы списка.
cbClients.Items.Add(‘Все’); — Добавим элемент, который будет отображать всех клиентов.
tClients.First; — Переходим на первую строку таблицы.
while not tClients.Eof do begin — Запускаем цикл, пока не будет достигнут конец таблицы.
cbClients.Items.AddObject(tClients.FieldByName(‘last_name’).AsString, — Добавляем элементы. Метод AddObject добавляет строку в список и привязывает к нему объект.
TObject(tClients.FieldByName(‘client_id’).AsInteger)); — в качестве объекта передадим код клиента, предварительно приведя его к типу TObject.
tClients.Next; — Переходим к следующей строке.
tClients.EnableControls; — Подключаем элементы.
cbClients.Items.EndUpdate; — Выключаем режим обновления у списка.
cbClients.ItemIndex := 0; — Устанавливаем выбранным первый элемент («Все»).
По аналогии напишем код процедуры для заполнения списка маршрутов:
procedure TfmMain.LoadRoutesList; begin cbRoutes.Items.BeginUpdate; tRoutes.DisableControls; try cbRoutes.Items.Clear; cbRoutes.Items.Add('Все'); tRoutes.First; while not tRoutes.Eof do begin cbRoutes.Items.AddObject(tRoutes.FieldByName('country').AsString, TObject(tRoutes.FieldByName('route_id').AsInteger)); tRoutes.Next; end; finally tRoutes.EnableControls; cbRoutes.Items.EndUpdate; end; cbRoutes.ItemIndex := 0; end;
Добавим вызов созданных процедур на событие формы onShow, которое происходит при запуске программы:
procedure TfmMain.FormShow(Sender: TObject); begin LoadClientsList; LoadRoutesList; aRefresh.Execute; end;
aRefresh.Execute; — обновим список поездок при запуске.
Так же необходимо добавить вызовы процедур обновления списков на функции вызова форм справочников:
для клиентов:
procedure TfmMain.aClientsExecute(Sender: TObject); begin fmClients.ShowModal; LoadClientsList; end;
и для маршрутов:
procedure TfmMain.aRoutesExecute(Sender: TObject); begin fmRoutes.ShowModal; LoadRoutesList; end;
Обновим процедуру запроса данных из БД:
procedure TfmMain.aRefreshExecute(Sender: TObject); begin if qTrips.Active then qTrips.Close; qTrips.SQL.Clear; qTrips.SQL.Add('SELECT * FROM view_trips'); qTrips.SQL.Add('WHERE'); qTrips.SQL.Add('start_date >= ' + FormatDateTime('#d"/"m"/"yyyy#', dtpBegin.Date)); qTrips.SQL.Add('and start_date <= ' + FormatDateTime('#d"/"m"/"yyyy#', dtpEnd.Date)); if cbClients.ItemIndex > 0 then qTrips.SQL.Add('and client_id = '+IntToStr(Integer(cbClients.Items.Objects[cbClients.ItemIndex]))); if cbRoutes.ItemIndex > 0 then qTrips.SQL.Add('and route_id = '+IntToStr(Integer(cbRoutes.Items.Objects[cbRoutes.ItemIndex]))); qTrips.Open; end;
if cbClients.ItemIndex > 0 then — Если выбран элемент с индексом больше 0 (нулевой — это «Все»), то
qTrips.SQL.Add(‘and client_id = ‘+IntToStr(Integer(cbClients.Items.Objects[cbClients.ItemIndex]))); — добавим условие по клиенту.
Для маршрутов условие добавляется аналогично.
Поскольку у нас вывод данных в экранную таблицу осуществляется через запрос, а редактирование данных через таблицу — нам необходимо сделать синхронизацию данных при редактировании и удалении:
в процедуру редактирования поездки добавляем код:
procedure TfmMain.aEditTripExecute(Sender: TObject); begin tTrip.Locate('trip_id', qTrips.FieldByName('trip_id').AsInteger, []); tTrip.Edit; if fmTrip.ShowModal = mrOk then begin tTrip.Post; aRefresh.Execute; end else tTrip.Cancel; end;
и в процедуру удаления:
procedure TfmMain.aDeleteTripExecute(Sender: TObject); begin tTrip.Locate('trip_id', qTrips.FieldByName('trip_id').AsInteger, []); tTrip.Delete; aRefresh.Execute; end;
Код написан, теперь проведем тестирование.
Начнем с заполнения справочников. Заполним справочник клиентов тестовыми данными:
Для тестирования пяти строчек вполне хватит. То же самое для справочника маршрутов:
Добавим 5 тестовых поездок:
Попробуем отредактировать страну для клиента 2 и удалить строку для клиента 5:
Проверим работу условий выбора. В качестве клиента выберем Клиент 3 и нажмем кнопку «Обновить»:
На этом написание программы можно закончить, так как все условия задания выполнены. Но если вы перенесете ваш проект, например, на флешку, то он перестанет работать, так как путь к БД прописан в свойстве соединения компонента TADOConnection и для его изменения мы должны менять код программы. С точки зрения разработки программы это не верно, поэтому добавим функцию, которая будет позволять указать путь к БД во время работы программы.
Добавим на главную форму компонент TOpenDialog. Назовем его OpenDialog и в свойстве Filter добавим следующие записи:
В ActionList добавляем новую функцию aOpenDB. Свойство Caption = «Открыть БД…». И на событие OnExecute добавляем код:
procedure TfmMain.aOpenDBExecute(Sender: TObject); begin if OpenDialog.Execute then begin ADOConnection.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;' +'User ID=Admin;' +'Data Source='+OpenDialog.FileName+';' +'Mode=Share Deny None;' +'Jet OLEDB:System database="";' +'Jet OLEDB:Registry Path="";' +'Jet OLEDB:Database Password="";' +'Jet OLEDB:Engine Type=5;' +'Jet OLEDB:Database Locking Mode=1;' +'Jet OLEDB:Global Partial Bulk Ops=2;' +'Jet OLEDB:Global Bulk Transactions=1;' +'Jet OLEDB:New Database Password="";' +'Jet OLEDB:Create System Database=False;' +'Jet OLEDB:Encrypt Database=False;' +'Jet OLEDB:Don''t Copy Locale on Compact=False;' +'Jet OLEDB:Compact Without Replica Repair=False;' +'Jet OLEDB:SFP=False;'; ADOConnection.Connected := True; end; end;
if OpenDialog.Execute then — Если в диалоге выбора файла нажали кнопку «Ок», то указываем свойство ConnectionString компонента TADOConnection.
‘Data Source=’+OpenDialog.FileName+’;’ — Указываем выбранный файл в качестве источника данных в строке подключения.
Перенесем процедуры обновления списков на события AfterConnect (после соединения) компонента ADOConnection.:
procedure TfmMain.ADOConnectionAfterConnect(Sender: TObject); begin tClients.Open; tRoutes.Open; tTrip.Open; LoadClientsList; LoadRoutesList; aRefresh.Execute; end;
Так же в эту процедуру добавляем открытие таблиц, с которыми мы будем работать: tClients.Open, tRoutes.Open и tTrip.Open.
Событие OnShow удаляем, так как оно нам больше не нужно.
Указываем Connected = False для компонента ADOConnection. И добавляем кнопку в главное меню в разделе «Программа» указав aOpenDB в свойстве Action.
Запускаем программу. Нажимаем Программа ► Открыть БД… и выбираем наш файл с базой данных. После открытия в таблицы должны появиться записи о поездках.
Исходники программы и БД можно скачать по ссылке: trabeldb.rar.
Если у вас есть вопросы, можете писать в комментариях или мне на почту: info@asd-soft.ru
Желаю успехов при сдаче! :) И до будущих встреч!