
- •6. Разработка приложений
- •7. Работа с базами данных
- •7.8. Добавление записей
- •7.9. Удаление записей
- •8. Работа с запросами sql
- •Visual query builder (vqb)
- •9. Отчеты
- •Procedure NewPage;
- •Procedure Preview;
- •Property Enabled: Boolean;
- •Property ForceNewPage: Boolean;
- •Property BeforePrint: tqrBeforePrintEvent;
- •Property Data : tqrSysData Type;
- •Property DataSet: tDataSet;
- •Property Bands : tqrSubDetailGroupBands;
- •Property HasHeader : Boolean; property HasFooter: Boolean;
7.8. Добавление записей
Для добавления записей в НД используются методы:
Insert - вставка пустой строки перед текущей;
AppendRecord([cписок значений]) - добавляет запись в конец таблицы.
В <списке значений> параметры перечислены в том же порядке, в каком они расположены в диалоге Конструктора набора данных Field Editor. Если в Конструкторе набора данных поля не определены, то параметры идут в порядке следования полей в таблице на диске.
Примечание. Если нужно передать нулевое значение, в параметре пишется ключевое слово nil.
Например, Table1.AppendRecord ([124, 'Россия', nil,'1.01.98']);
или
Table1.Insert;
Tablel.FieldByName('PersID').AsInteger := 124;
Tablel.FieldByName('Country').AsString :='Россия';
Tablel.FieldByName('Data').AsString:='l.01.98';
Table1.Post;
Метод Post производит сохранение изменения текущей записи.
Пример. Добавление записи методом AppendRecord.
1. Добавьте в форму TButton, 4 компонента TEdit;
2. Переименуйте кнопку в btnAdd;
3. В OnClick btnAdd введите:
Tablel.AppendRecord([Editl.Text,StrToInt(Edit2.Text),
S trToInt(Edit3.Text), Edit4.Text]);
7.9. Удаление записей
Для этих целей используется метод Delete.
Пример. Удаление записи.
Добавьте в форму кнопку TButton.
2. Переименуйте в btnDelete и Caption - «Удалить»;
3. Введите код:
if Application.MessageBox('удалить текущую запись', 'Предупреждение',
mb_OkCancel+MB_ICONQUESTION)=IDOK then
Table1.Delete;
Здесь мы использовали метод MessageBox объекта TApplication (приложение). Функция использует три параметра:
• Текст сообщения
• Заголовок диалога
• Тип кнопок + иконка
MessageBox возвращает код нажатой кнопки. В данном примере мы использовали кнопки ОК и Cancel (mb_OkCancel) и иконку вопрос.
7.10. Редактирование записи
Для того чтобы изменить значение какого-либо поля в программе необходимо:
• Перевести НД в режим редактирования (метод Edit);
• Произвести изменения;
• Сохранить изменения (метод Post).
Пример. Редактирование текущей записи.
Для редактирования текущей записи мы будим вводить значения в элементы TEdit формы, которые использовали для добавления записи.
1. Добавьте кнопку TButton
2. Переименуйте в btnSave;
3. Надпись на кнопке - «Сохранить»;
4. Введите код:
with Table1 do
begin
Edit;
FieldByName('Name').AsString:=Editl.Text; FieldByName('Size').AsInteger:=StrToInt(Edit2.Text); FieldByName('Weight').AsInteger:=StrToInt(Edit3.Text); FieldByName('Area')AsString:=EdM.Text;
Post;
end;
7.11. Фильтры
Установка фильтра
Для установки и настройки фильтра используются следующие свойства компонента ТТаblе или TQuery.
Filter: String - содержит условие которому должны удовлетворять записи
Filtered: Boolean - включает и выключает режим фильтрации.
Условие в свойстве Filter формируется по тому же принципу, что и для команды if.
Например, из таблицы Customer нас интересуют только клиенты проживающие в US
Table1.Filter: Country='US'
Теперь, если включить режим фильтрации (Filtered:=true) для перемещения по фильтрованному набору данных применяются стандартные методы навигации: First, Last, Next, Prior.
Перемещение по записям фильтра при отключенном режиме фильтрации данных
У компонентов ТТаblе и TQuery есть методы перемещения по записям удовлетворяющих условию свойства Filter без перехода в режим фильтрации (Filtered = False).
FindFirst, FindLast, FindNext, FindPrior - переход на первую, последнюю, следующую и предыдущую запись, удовлетворяющую условию фильтра.
7.12. Связь таблиц в систему master-detail
Реальные базы данных состоят более чем из одной таблицы. Причем эти таблицы связаны между собой. Самой распространенным типом связи является связь Один-ко-многим (Master-Detail). В этой системе одной записи таблице со стороны один (Master) соответствует несколько записей в таблице со стороны многие (Detail). Для реализации таких связей применяются свойство MasterSource.
Чтобы связать две таблицы в систему Master-Detail (Table1-Table2), необходимо связать свойство MasterSource со стороны Detail (Table2) с элементом TDataSource связанного с таблицей Master (Table1).
7.13. Комплексный пример приложения баз данных
Пример. Создание приложения Lineltem
В этом примере вы создадите приложение, процесс создания которого освещает следующие вопросы:
Программное выполнение запросов
Отображение данных из нескольких таблиц в одном элементе управления DBGrid
Настройка отображаемых полей в Конструкторе набора данных
Вычисление данных в полях во время выполнения приложения.
Рис. 7.7 показывает приложение Lineltem после завершения разработки.
Программа визуализирует окно Customer Invoice Form. Во время выполнения приложения вы сможете редактировать и перемещаться по записям трех таблиц базы данных DBDEMOS при помощи кнопок элементов управления DBEdit и DBNavigator, расположенного в верхней части формы. При перемещении через таблицу CUSTOMER.DB информация о покупателях, хранимая в таблице, будет появляться в элементах управления DBEdit в верхней части формы.
Если данные в элементах управления DBEdit изменяются, то и информация в двух таблицах внизу также обновится синхронно с изменениями в элементах управления DBEdit.
При выполнении приложения Lineltem таблица с подписью Заказ в середине формы содержит данные из таблицы ORDERS.DB базы данных. Эта таблица входит в состав учебной базы данных, поставляемой вместе с Delphi, и содержит сведения о заказах покупателей, имена которых хранятся в таблице CUSTOMER.DB.
Таблица с подписью Состав заказа, расположенная в нижней части формы, содержит данные из таблицы ITEMS. DB учебной базы данных. Эта таблица содержит информацию о составе заказов покупателей. Приложение Lineltem использует сведения из таблицы ITEMS.DB для отображения списка товаров для каждого покупателя.
Всякий раз, когда имя нового покупателя появляется в строке редактирования Имя, таблица Заказы отображает самую последнюю информацию о заказах этого покупателя. Сведения о заказах других покупателей при этом не показываются.
При каждом изменении данных в таблице Заказы изменяются и данные в таблице Состав заказа — здесь появляется список товаров для соответствующего заказа. Данные в эту таблицу поступают из таблицы базы данным ITEMS.DB, содержащей сведения о заказах покупателей.
Когда вы разберетесь, как все это работает, вы увидите, что программ Lineltem — настоящее приложение для базы данных. Она комбинирует данные из трех таблиц, используя механизм внешних соединений (операций для связывания данных из разных таблиц) и отображает их в реальном времени.
И это не все что может делать программа — в ней также вычисляются значения показываемые в одном из полей, которые отображаются в реальном времени.
В таблице Заказы в средней части формы поле Баланс является вычисляемым, оно вычитает значения поля Amount Paid из значений поля Items Total и показывает результат.
Поле Discount в таблице Состав заказа является форматируемым и предназначено для показа процентов. (Подробнее об этом вы узнаете в следующем разделе.)
Поэтапная разработка формы
Вначале создания проекта Lineltem выполните следующие действия:
При помощи операций, описываемых в прошлых примерах, перенесите на форму следующие компоненты:
Восемь TLabel
Пять TDBEdit
Один TDBNavigator
Два TDBGrid
Три ТТаblе
Три TDataSource.
Расположите компоненты так, как показано на рисунке 7.8
В левом верхнем углу формы выберите компонент ТТаblе (его имя должно быть Table1). Установите свойство DatabaseName в значение dbdemos и соедините компонент с таблицей CUSTOMER.DB, задав для свойства TableName имя customer.db. Затем установите свойство Active в True.
В левом верхнем углу формы выделите компонент TDataSource (его имя должно быть DataSourcel) и свяжите его с компонентом ТаЫе1, задав для свойства DataSet имя Table1
Свяжите компонент TDBNavigator в правом верхнем углу формы с компонентом TDataSource1 установив его свойство DataSource в DataSource1
Соедините пять компонентов TDBEdit с полями CustNo, Company, City, Addr1 и Country из набора данных Table1 путем задания для войств DataSource значений DataSourcel и для свойств DataField, имен соответствующих полей таблицы CUSTOMER.DB.
Выберите компонент ТТаblе слева в центре формы (его имя должно быть Table2). Для свойства DatabaseName задайте значение dbdemos. Затем для свойства TableName установите имя таблицы ORDERS.DB и переведите свойство Active в True.
В центральной части формы слева выделите компонент TDataSource (его имя должно быть DataSource2) и свяжите его с компонентом Таblе2.
Соедините компонент TDBGrid подписанный Заказы в центре формы с компонентом DataSource2, установив свойство DataSource компонента TDBGrid в DataSource2. После этого в таблице появится информация о заказах покупателей.
Выберите компонент ТТаblе слева в нижней части формы (его имя должно быть ТаblеЗ). Для его свойства DatabaseName задайте значение dbdemos. Затем для свойства TableName установите имя таблицы ITEMS.DB и переведите свойство Active в True.
Свяжите компонент TDataSource в левом нижнем углу формы (его имя должно быть DataSource3) с компонентом ТаЫеЗ
Свяжите компонент TDBGrid подписанный Состав заказа с компонентом DataSource3. Теперь на форме работают все компоненты отображения данных (см. рис. 7.9).
Сохраните проект Lineltem в его нынешнем состоянии и запустите приложение для проверки правильности выполненных действий.
Определение полей в Конструкторе набора данных
Для того чтобы заставить приложение Lineltem делать то, для чего оно предназначено, необходимо добавить в форму Customer Invoice Form несколько элементов управления и настроить их соответствующим образом. Для этой работы целесообразно использовать утилиту Конструктор набора данных. Во-первых, для удаления некоторых полей из таблицы Заказы и изменения положения оставшихся выполните следующие действия:
Дважды щелкните на компоненте ТТаblе в левой центральной части формы (его имя Таblе2). В результате откроется окно Конструктора набора данных.
В окне Конструктора набора данных щелкните правой кнопкой мыши и выберите команду New Field.
Откроется диалоговое окно New Field. Задайте поле по имени Balance типа CurrencyField, выбрав значение Currency в списке Туре и напечатав "Balance" в строке редактирования Name. Delphi автоматически задает все необходимые данные для представляющего новое поле компонента (см. рис. 7.10). (При желании имя компонента можно изменить, но дальше в этом пункте будет использоваться имя Table2Balance.)
Обратите внимание, что переключатель Calculated в середине диалогового окна помечен.
Для закрытия диалогового окна New Field щелкните на кнопке ОК. Когда снова появится окно Конструктора набора данных, обратите внимание, что в списке полей появится имя Balance.
Откройте диалоговое окно Add Fields командой Add Fields из всплывающего меню Конструктора набора данных (вызывается щелчком Правой кнопки мыши).
В списке Available Fields выделите следующие поля: OrdersNo, CnsNo, SaleDate, ShipDate, IternsTotal, AmountPaid и Balance (используйте комбинацию <Ctrl> + щелчок левой кнопкой мыши).
Для закрытия диалогового окна Available Fields щелкните на кнопке ОК. Выделенные в пункте 7 поля теперь появились в списке Конструктора набора данных.
Перемещая в списке Fields при помощи мыши нужные поля, расположите их так как показано на рис. 7.11.
Закройте окно Конструктора набора данных при помощи кнопки закрытия окна.
Слияние данных из двух таблиц
Теперь настало время для соединения таблицы ORDERS.DB и CUSTOMER.DB таким образом, чтобы их данные слились и отображались синхронно. Для этого необходимо выполнить следующие действия:
Для компонента Таblе2 в окне Object Inspector установите для свойства MasterSource значение DataSourcel и дважды щелкните на кнопке в строке редактирования свойства MasierFields. Delphi откроет диалоговое окно Field Link Designer (см. рис. 7.12). Эта утилита предназначена для связывания полей баз данных.
В окне Field Link Designer выберите строку By CustNo из списка Available Indexes. Обратите внимание, что имя поля CustNo появилось в списке Detail Fields.
Для соединения поля CustNo таблицы Customer с полем CustNo таблицы Orders выделите имя CustNo и в списке Detail Fields и в списке MasterFields, а затем щелкните на кнопке Add.
В списке Joined Fields появится следующее сообщение:
CustNo -> CustNo.
Это означает, что таблицы Orders и Customer теперь соединены таким образом, что содержимое таблицы Orders изменяется при выборе нового покупателя в таблице Customer. Теперь окно Field Link Designer соответствует рис. 7.12.
Для закрытия диалогового окна Field Link Designer щелкните на кнопке ОК.
Для связывания таблицы Items в нижней части формы Customer Invoice Form с таблицей Orders в средней части формы выберите компонент ТаblеЗ и установите его свойство MasterSource в DataSource2. Затем, используя пЗ, определите для свойства MasterFields компонента ТаblеЗ поле OrdertNo таблицы Orders (компонент Таblе2).
Сохраните проект.
Запустите приложение в его нынешнем виде.
Заметьте, что при просмотре имен покупателей при помощи элемента управления DBNavigator, информация в таблице Orders отражает заказы текущего покупателя. Теперь обратите внимание на маленькую стрелку слева от поля OrdersNo в таблице Заказы. Когда вы перемещаете эту стрелку вверх или вниз на одну или несколько позиций, таблица Состав заказа в нижней части формы изменяет отображаемые товары в соответствии с заказом покупателя, на который указывает стрелка в таблице Заказы.
Переформатирование полей таблиц
Отметим, что таблица Состав заказа (Items) на форме Customer Invoice Form имеет поле по имени Discount. Скидки (Discounts) обычно выражаются в процентах, но поле Discount не может отображать чисел со знаком %. Вы можете решить эту проблему простой настройкой формата визуализации поля Discount.
Для получения возможности отображать в этом поле числа с процентами, необходимо выполнить следующие действия:
Откройте Конструктор набора данных. Добавьте в список все поля. Для этого щелкните правой кнопкой мыши. Выберите пункт Add Fields и затем кнопку Ок. Выберите поле Discount.
Обратите внимание, что окно Object Inspector теперь отображает свойства компонента поля Discount. В этом окне наберите в строке редактирования свойства DisplayFormat "O.##%". Как только свойство DspiayFormat потеряет фокус, Delphi переформатирует данные в поле Discount в проценты.
Установите ТаbleЗ.Active в True.
При желании можно сохранить проект и запустить приложение.
Вычисление значений полей
В предыдущем пункте вы добавили в приложение Lineltems важную возможность — отображать поля, которые отсутствуют в таблицах баз данных, но могут быть вычислены динамически во время выполнения приложения. Здесь вы настроите поле Balance из таблицы Orders. После этого ваше приложение будет вычислять и отображать текущий баланс каждого покупателя в поле Balance во время своего выполнения.
Для придания вашему приложению возможности использовать вычисляемые поля, необходимо выполнить следующие действия:
Щелкните дважды на компоненте Таblе2 (компонент TTable в левой центральной части формы). Откроется окно Конструктора набора данных.
В окне Object Inspector перейдите на страницу Events.
Щелкните дважды на событии onCalcFields. В Редакторе кода появится процедура TForm1.Table2CalcFields.
В блоке begin. . .end процедуры наберите следующий код:
Table2Balance.Value := Table2ItemsTotal.Value - Table2AmouutPaid. Value;
Эта процедура будет вызываться при каждом изменении данных в таблице. Процедура задает значение поля Balance набора данных Таblе2 как разницу между полями ItemsTotal набора данных Table2 и AmountPaid набора данных Table2.
Связывание таблицы с компонентом TDBEdit
Приложение Lineltem почти готово, осталось добавить один важный элемент. На этом этапе разработки приложение обеспечивает любую информацию о товарах, заказанных различными покупателями. Кроме этого отображаются данные о заказах, платежеспособных покупателях, номерах партий товаров в каждом заказе.
К сожалению, форма не переводит номера партий товаров в каждом заказе в их описание, поэтому видя на форме Customer Invoice Form номер какой-либо партии, вы ничего не можете сказать о списке товаров в партии. Добавив имена партий товаров в форму, тем самым вы можете получить описание каждой партии из таблицы PARTS.DB и добавить его в форму Customer Invoice Form. Вы умеете комбинировать данные из разных таблиц и визуализировать их различными способами. Далее описывается простая методика, не требующая использования запросов SQL.
Используйте Конструктор набора данных для уменьшения ширины полей. Сделайте каждое поле размером в 5 или 6 символов для уменьшения общей ширины таблицы Состав заказа (Items).
Передвиньте уменьшенную таблицу Items влево и перенесите на освободившееся место четыре новых компонента: TLabel, TDBEdit, TTable и TDataSource. Установите подпись компонента TLabel — Описание заказа (Part Description).
Соедините новый компонент TTable (его имя Таblе4) с таблицей PARTS.DB и новый компонент TDataSource — с Таblе4.
Установите свойство DataSource нового компонента TDBEdit в значение DataSource4 и свойство DataField в значение Description.
Установите связь ТаЫе4 с ТаЫеЗ по полю PartNo (п.З стр.89).
Установите свойство Active компонента Таblе4 в True. В новом компоненте TDBEdit появятся данные (см. рис. 7.13).
Теперь приложение Lineltem готово. Запустите его и вы увидите форму так, как показано на рис. 7.14. Обратите внимание, что при просмотре данных изменяется и описание партий товара.