Курсовая работа «Туристическое агенство» (MSAccess+Delphi) (Часть 3)

Здравствуйте уважаемые коллеги!

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

И начнем мы с формы 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_idDisplayLabel = Код поездки, DisplayWidth = 5.
client_idVisible = False.
last_nameDisplayLabel = Фамилия, DisplayWidth = 20.
first_nameDisplayLabel = Имя, DisplayWidth = 20.
second_nameDisplayLabel = Отчество, DisplayWidth = 20.
route_idVisible = False.

countryDisplayLabel = Страна, DisplayWidth = 20.
transit_costDisplayLabel = Стоимость переезда.
day_stay_costDisplayLabel = Стоимость 1го дня пребывания.
start_dateDisplayLabel = Дата отъезда.
stay_countDisplayLabel = Кол-во дней пребывания.
total_costDisplayLabel = Общая стоимость.

Функция 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
Желаю успехов при сдаче! :) И до будущих встреч!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *