ப07 (Разработка баз данных в Delphi)
Описание файла
Документ из архива "Разработка баз данных в Delphi", который расположен в категории "". Всё это находится в предмете "информатика" из , которые можно найти в файловом архиве . Не смотря на прямую связь этого архива с , его также можно найти и в других разделах. Архив можно найти в разделе "рефераты, доклады и презентации", в предмете "информатика, программирование" в общих файлах.
Онлайн просмотр документа "ப07"
Текст из документа "ப07"
Создание баз данных в Delphi
Урок 7: Редактор DataSet, Вычисляемые поля
Содержание Урока 7:
Содержание Урока 7: 1
Обзор 2
Редактор DataSet 2
Вычисляемые Поля 5
Управление TDBGrid во время выполнения 9
Обзор
В этой статье вы узнаете о Редакторе DataSet и о способах управления компонентом TDBGrid во время выполнения программы. Здесь же будут рассмотрены вычисляемые поля - весьма ценная особенность Редактора DataSet.
Примеры, которые вы увидите в этой статье, продемонстрируют основные способы, которыми пользуются большинство программистов для показа таблиц БД пользователям. Для понимания большей части материала требуется общее знание среды и языка Delphi.
Редактор DataSet
Редактор DataSet может быть вызван с помощью объектов TTable или TQuery. Чтобы начать работать с ним, положите объект TQuery на форму, установите псевдоним DBDEMOS, введите SQL запрос "select * from customer" и активизируйте его (установив св-во Active в True).
Откройте комбобокс “Object Selector” вверху Инспектора Объектов - в настоящее время там имеется два компонента: TForm и TQuery.
Нажмите правую кнопку мыши на объекте TQuery и в контекстном меню выберите пункт “Fields Editor”. Нажмите кнопку Add - появиться диалог Add Fields, как показано на рис.1
Рис.1: Диалог Add Fields Редактора DataSet.
По-умолчанию, все поля в диалоге выбраны. Нажмите на кнопку OK, чтобы выбрать все поля, и закройте редактор. Снова загляните в “Object Selector”, теперь здесь появилось несколько новых объектов, (см. рис.2)
Рис.2: Object Selector показывает в списке все объекты созданные в Редакторе DataSet. Вы можете также найти этот список в определении класса TForm1.
Эти новые объекты будут использоваться для визуального представления таблицы CUSTOMER пользователю.
Вот полный список объектов, которые только что созданы:
Query1CustNo: TFloatField;
Query1Company: TStringField;
Query1Addr1: TStringField;
Query1Addr2: TStringField;
Query1City: TStringField;
Query1State: TStringField;
Query1Zip: TStringField;
Query1Country: TStringField;
Query1Phone: TStringField;
Query1FAX: TStringField;
Query1TaxRate: TFloatField;
Query1Contact: TStringField;
Query1LastInvoiceDate: TDateTimeField;
Я вырезал и вставил этот список из определения класса TForm1, которое можно найти в окне Редактора исходного текста. Происхождение имен показанных здесь, должно быть достаточно очевидно. Часть "Query1" берется по-умолчанию от имени объекта TQuery, а вторая половина от имени поля в таблице Customer. Если бы мы сейчас переименовали объект Query1 в Customer, то получили бы такие имена:
CustomerCustNo
CustomerCompany
Это соглашение может быть очень полезно, когда Вы работаете с несколькими таблицами, и сразу хотите знать, на поле какой таблицы ссылается данная переменная.
Любой объект, созданный в редакторе DataSet является наследником класса TField. Точный тип потомка зависит от типа данных в конкретном поле. Например, поле CustNo имеет тип TFloatField, а поле Query1City имеет тип TStringField. Это два типа полей, которые Вы будете встречать наиболее часто. Другие типы включают тип TDateTimeField, который представлен полем Query1LastInvoiceDate, и TIntegerField, который не встречается в этой таблице.
Чтобы понять, что можно делать с потомками TField, откройте Browser, выключите просмотр полей Private и Protected, и просмотрите свойства и методы Public и Published соответствующих классов.
Наиболее важное свойство называется Value. Вы можете получить доступ к нему так:
procedure TForm1.Button1Click(Sender: TObject);
var
d: Double;
S: string;
begin
d := Query1CustNo.Value;
S := Query1Company.Value;
d:=d+1;
S := 'Zoo';
Query1CustNo.Value := d;
Query1Company.Value := S;
end;
В коде, показанном здесь, сначала присваиваются значения переменным d и S. Следующие две строки изменяют эти значения, а последний две присваивают новые значения объектам. Не имеет большого смысла писать код, подобный этому, в программе, но этот код служит лишь для того, чтобы продемонстрировать синтаксис, используемый с потомками TField.
Свойство Value всегда соответствует типу поля, к которому оно относится. Например у TStringFields - string, TCurrencyFields - double. Однако, если вы отображаете поле типа TCurrencyField с помощью компонент, “чувствительных к данным” (data-aware: TDBEdit, TDBGrid etc.), то оно будет представлена строкой типа: "$5.00".
Это могло бы заставить вас думать, что у Delphi внезапно отключился строгий контроль типов. Ведь TCurrencyField.Value объявлена как Double, и если Вы пробуете присвоить ему строку, Вы получите ошибку “type mismatch” (несоответствие типа). Вышеупомянутый пример демонстрирует на самом деле свойства объектов визуализации данных, а не ослабление проверки типов. (Однако, есть возможность получить значение поля уже преобразованное к другому типу. Для этого у TField и его потомков имеется набор методов типа AsString или AsFloat. Конечно, преобразование происходит только тогда, когда имеет смысл.)
Если нужно получить имена полей в текущем DataSet, то для этого используется свойство FieldName одним из двух способов, показанных ниже:
S := Query1.Fields[0].FieldName;
S := Query1CustNo.FieldName;
Если вы хотите получить имя объекта, связанного с полем, то вы должны использовать свойство Name:
S := Query1.Fields[0].Name;
S := Query1CustNo.Name;
Для таблицы CUSTOMER, первый пример вернет строку "CustNo", а любая из строк второго примера строку "Query1CustNo".
Вычисляемые Поля
Создание вычисляемых полей - одно из наиболее ценных свойств Редактора DataSet. Вы можете использовать эти поля для различных целей, но два случая выделяются особо:
-
выполнение вычислений по двум или более полям в DataSet, и отображение результата вычислений в третьем поле.
-
имитация соединения двух таблиц с возможностью редактировать результат соединения.
Программа CALC_SUM.DPR из примеров к данному уроку иллюстрирует первый случай использования вычисляемых полей.
Эта программа связывает три таблицы в отношении один ко многим. В частности, ORDERS и ITEMS связаны по полю OrderNo, а ITEMS и PARTS связаны по полю PartNo. (В таблице ORDERS хранятся все заказы; в таблице ITEMS - предметы, указанные в заказах; PARTS - справочник предметов). В программе можно перемещаться по таблице ORDERS и видеть связанный с текущим заказом список включенных в него предметов. Программа CALC_SUM достаточно сложная, но хорошо иллюстрирует мощность вычисляемых полей.
Последовательность создания проекта CALC_SUM:
-
Создайте новый проект (File|New Project) и удалите из него форму (в Менеджере Проекта View|Project Manager)
-
Выберите эксперта форм БД из меню Help.
-
На первом экране, выберите "Create a master/detail form" и "Create a form using TQuery Objects".
-
Нажмите кнопку Next и выберите таблицу ORDERS.DB из псевдонима БД DBDEMOS.
-
Нажмите Next и выберите поля OrderNo, CustNo, SaleDate, ShipDate и ItemsTotal из таблицы ORDERS.DB.
-
Нажмите Next и выберите "Horizontal" из расстановки компонентов dbEdit на форме.
-
Нажмите Next и выберите таблицу ITEMS.DB.
-
В двух следующих экранах выберите все поля из таблицы и поместите их в grid.
-
Нажмите Next и выберите поле OrderNo из Master и Detail ListBoxes, и Нажмите кнопку Add.
-
Нажмите Next и сгенерируйте форму.
Требуется много слов для того, чтобы описать процесс показанный выше, но, фактически, выполнение команд в Эксперте форм БД легко и интуитивно.
Выделите первый из двух объектов TQuery и установят свойство Active в True. Для Query2 в свойстве SQL напишите текст запроса:
select * from Items I, Parts P
where (I.OrderNo =:OrderNo) and
(I.PartNo=P.PartNo)
Активизируйте объект Query2 (Active установите в True) и вызовите редактор DataSet (Fields Editor) для него. Вызовите диалог Add Fields и добавьте поля OrderNo, PartNo, Qty и ListPrice.
Нажмите Define и ведите слово Total в поле FieldName. Установите Field Type в CurrencyField. Проверьте что Calculated CheckBox отмечен. Нажмите Ok и закройте редактор DataSet.
Простой процесс описанный в предыдущем абзаце, показывает как создать вычисляемое поле. Если посмотреть в DBGrid, то можно видеть, что там теперь есть еще одно пустое поле. Для того, чтобы поместить значение в это поле, откройте в Инспекторе Объектов страницу событий для объекта Query2 и сделайте двойной щелчок на OnCalcFields. Заполните созданный метод так:
procedure TForm2.Query2CalcFields(DataSet: TDataSet);
begin
Query2NewTotalInvoice.Value := 23.0;
end;
После запуска программы поле Total будет содержит строку $23.00.
Это показывает, насколько просто создать вычисляемое поле, которое показывает правильно сформатированные данные. На самом деле это поле должно показывать нечто другое - произведение полей Qty (количество) и ListPrice (цена). Для этого вышеприведенный код для события OnCalcFields нужно изменить следующим образом:
procedure TForm1.Query2CalcFields(DataSet: TDataset);
begin
Query2Total.Value:=Query2Qty.Value*Query2ListPrice.Value;
end;
Если теперь запустить программу, то поле Total будет содержать требуемое значение.
В обработчике события OnCalcFields можно выполнять и более сложные вычисления (это будет показано позже), однако следует помнить, что это вызывает соответствующее замедление скорости работы программы.
Теперь давайте добавим вычисляемое поле для первой таблицы (Query1, ORDERS), которое будет отображать сумму значений из поля Total второй таблицы (Query2) для данного заказа. Вызовите редактор DataSet для объекта Query1 и добавьте вычисляемое поле NewItemsTotal типа CurrencyField. В обработчике события OnCalcFields для Query1 нужно подсчитать сумму и присвоить ее полю NewItemsTotal:
procedure TForm1.Query1CalcFields(DataSet: TDataset);
var
R : Double;
begin
R:=0;
with Query2 do begin
DisableControls;
Close;
Open;
repeat
R:=R+Query2Total.Value;
Next;
until EOF;
First;
EnableControls;
end;
Query1NewItemsTotal.Value:=R;
end;
В данном примере сумма подсчитывается с помощью простого перебора записей, это не самый оптимальный вариант - можно, например, для подсчета суммы использовать дополнительный объект типа TQuery. Метод DisableControls вызывается для того, чтобы отменить перерисовку DBGrid при сканировании таблицы. Запрос Query2 переоткрывается для уверенности в том, что его текущий набор записей соответствует текущему заказу.
Поместите на форму еще один элемент DBEdit и привяжите его к Query1, полю NewItemsTotal. Запустите программу, ее примерный вид показан на рис.3
Рис.3: Программа CALC_SUM
Как видно из программы, наличие поля ItemsTotal в таблице ORDERS для данного примера необязательно и его можно было бы удалить (однако, оно необходимо в других случаях).
Управление TDBGrid во время выполнения
Объект DBGrid может быть полностью реконфигурирован во время выполнения программы. Вы можете прятать и показывать колонки, изменять порядок показа колонок и их ширину.
Вы можете использовать свойство Options объекта DBGrid, чтобы изменить ее представление. Свойство Options может принимать следующие возможные значения:
dgEditing | Установлен по-умолчанию в true, позволяет пользователю редактировать grid. Вы можете также установить свойство ReadOnly grid в True или False. |
dgAlwaysShowEditor | Всегда показывать редактор. |
dgTitles | Показывать названия колонок. |
dgIndicator | Показывать небольшие иконки слева. |
dgColumnResize | Может ли пользователь менять размер колонки. |
dgColLines | Показывать линии между колонками. |
dgRowLines | Показывать линии между строками. |
dgTabs | Может ли пользователь использовать tab и shift-tab для переключения между колонками. |
dgRowSelect | Выделять всю запись целиком. |
dgAlwaysShowSelection | Всегда показывать выбранные записи. |
dgConfirmDelete | Подтверждать удаление. |
dgCancelOnExit | Отмена изменений при выходе из DBGrid. |
dgMultiSelect | Одновременно может быть выделена больше чем одна запись. |
Как объявлено в этой структуре: