Опубликован: 07.05.2010 | Уровень: специалист | Доступ: свободно
Лекция 6:

Поля (TField)

< Лекция 5 || Лекция 6 || Лекция 7 >
Аннотация: На этой лекции вы познакомитесь с объектами-полями и классом TField. Научитесь создавать и использовать в наборах данных подстановочные и вычисляемые поля , изучите наиболее важные свойства, методы и события класса TField.

Каждая база данных состоит из таблиц, каждая таблица - из записей. Каждая запись в свою очередь представляет собой набор полей. Поле набора данных - это экземпляр достаточно мощного класса TField, о котором мы и поговорим на этой лекции.

Изучение свойств полей будем проводить на примере приложения из прошлой лекции.

Подстановочные (Lookup) поля

Подстановочное поле Lookup изначально в набор данных не входит, его нужно создавать самостоятельно. Такое поле отличается от обычного тем, что показывает данные из другого набора данных. Для использования такого поля два набора данных обязательно должны иметь релятивную связь. На прошлой лекции мы применяли компонент DBLookupComboBox, который является аналогом подстановочного поля, но который нельзя показать в сетке DBGrid. При создании подстановочного поля также необходимо указать набор данных, откуда поле будет просматривать значения, ключевые поля для релятивной связи и поле со значениями, которые нужно подставлять.

Открываем проект из "Таблицы Paradox в ADO" , открываем окно модуля данных. Дважды щелкаем по компоненту FoodT, чтобы открыть редактор полей. В этом редакторе у нас уже присутствуют пять полей, имеющихся в таблице, добавим шестое, подстановочное. Для этого щелкните правой кнопкой по редактору полей и выберите команду New Field (Новое поле):

Создание подстановочного (Lookup) поля

Рис. 6.1. Создание подстановочного (Lookup) поля

В разделе Field type (Тип поля) вы можете выбрать один из трех вариантов. Нас сейчас интересует тип Lookup. Заполните необходимые поля значениями, как на рисунке 6.1 и нажмите кнопку "ОК". Новое подстановочное поле будет добавлено в набор данных. В списке полей его можно переместить мышью на другое место, установите его сразу под FName. Перейдите на окно главной формы и убедитесь, что новое поле появилось. Однако оно пока еще не содержит данных - данные будут доступны только во время прогона программы. Сохраните проект, скомпилируйте и посмотрите, как работает программа. Как мы видим, теперь на главной форме два поля, которые ни к чему показывать пользователю - FKey с номерами записей, и FType - с номерами типов блюд, которые нам уже не нужны, поскольку мы показываем сами типы. Уберем их, точнее, сделаем невидимыми. Снова откройте редактор полей набора данных FoodT. Установите свойство Visible этих полей в False.

Вычисляемые (Calculated) поля

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

В нашем примере мы создадим вычисляемое поле для показа стоимости блюда в долларах США. Для этого в модуле данных создадим глобальную переменную dollar:

var
  fDM: TfDM;
  dollar: Currency = 30.36;

Вы можете указать текущий курс доллара к рублю, он так быстро меняется, что едва ли будет таким, как в моем примере. Итак, дважды щелкаем по набору данных FoodT, чтобы открыть редактор полей. Щелкаем правой кнопкой по этому редактору и выбираем команду " New field ". В поле " Name " впишите название нового поля FDCena. В поле " Component " автоматически отобразится имя нового объекта-поля " FoodTFDCena ", по которому в дальнейшем мы сможем к нему обращаться. Это имя составное - имя набора данных плюс имя нового поля, без всяких пробелов и разделителей.

В поле " Type " выберите тип Float, так как у нас могут быть копейки, вернее, центы. Затем убедитесь, что переключатель установлен на " Calculated " и нажмите "ОК". В редакторе полей появилось новое поле. Чтобы мы не получили сумму с кучей цифр после запятой, выделите в редакторе полей поле FDCena, и в его свойстве DisplayFormat укажите маску "#.## $US" (разумеется, без кавычек). К слову сказать, при создании вычисляемого поля мы могли бы выбрать тип Currency (денежный), но тогда к цифре добавлялось бы "р.", если ваша Windows имеет российские настройки.

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

DisplayFormat - Определяет формат отображения числа.

DisplayEdit - Определяет формат числа при редактировании.

MaxValue - Определяет максимально возможное для поля число.

MinValue - Определяет минимально возможное число.

Свойства MaxValue и MinValue по умолчанию имеют значение 0, что указывает на отсутствие ограничений.

Однако, это еще полдела. Поле мы сделали, осталось сделать вычисления. Код необходимых вычислений прописывается в свойстве OnCalcFields набора данных. Закройте редактор полей и выделите НД FoodT. Сгенерируйте для него обработчик события OnCalcFields и в этом обработчике пропишите следующую строчку:

FoodTFDCena.Value := FoodTFCena.Value / dollar;

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

Сохраните проект, скомпилируйте и посмотрите, как работает программа. Если вы все сделали правильно, у вас получится подобная картина:

Подстановочное и вычисляемое поле в программе

Рис. 6.2. Подстановочное и вычисляемое поле в программе

Поле данных (Data)

Если вы помните, при создании нового поля мы имеем три переключателя Field type. Переключатель " Data " предназначен для создания поля данных - пустого поля, которое программист использует по своему усмотрению. Наполнение этого столбца можно прописать в обработчике события OnGetText полученного объекта-поля. На практике такие поля используют редко, чаще они применяются для программного создания таблиц, о чем мы поговорим на одной из следующих лекций.

Свойство DisplayValues

Свойство DisplayValues объекта-поля предназначено для отображения данных логического поля в нужном формате. Для примера изменим отображение данных поля FVeget. Откройте редактор полей компонента FoodT, выделите поле FVeget. В его свойстве DisplayValues укажите значение "Да;Нет". У логического поля вместо True и False здесь можно указать свою пару значений. Значение до точки с запятой считается истинным, значение после - ложным. Примеры:

Да;Нет
Муж;Жен
Yes;No
Y;N
Д;Н

и т.п. Указанные в свойстве значения пары "Истина;Ложь" будут отображаться в компонентах вывода данных, таких как DBGrid, DBEdit и т.п. Кроме того, эти же значения будут отображены, если вы будете получать значения этого поля с использованием свойства AsString, чтобы преобразовать значение в строковый тип.

Для облегчения пользователю ввода данных немного изменим проект. Откройте окно fEditor и удалите DBEdit, предназначенный для ввода логического значения в поле FVeget. Вместо него установите компонент DBComboBox. Дважды щелкните по свойству Items этого компонента и в открывшемся редакторе значений впишите две строки:

Да
Нет

В свойстве DataSource компонента выберите таблицу FoodT, а в свойстве DataField - поле FVeget. Сохраните проект, скомпилируйте и посмотрите, как он работает. Теперь пользователю не нужно вписывать значение - он может выбрать его из списка.

Для полей других типов свойство DisplayValues недоступно. Вместо него предлагается использовать свойство DispalyFormat, которое доступно только для числовых полей и полей типа TDataTime. При этом формат задается так же, как в функциях формата, например, FormatFloat() и FormatDateTime(), применение которых подробно рассматривалось на курсе "Введение в программирование на Delphi ". Например, для поля типа Дата формат:

dddd dd mmm yyyy

выведет дату в формате "Понедельник 04 Янв 2010"

Другие наиболее важные свойства класса TField

Aligment - Определяет выравнивание выводимого значения. Может иметь следующие значения:

  • taLeftJustufy - выравнивание по левому краю
  • taRightJustify - выравнивание по правому краю
  • taCenter - выравнивание по центру.

AsXXXX - Группа свойств этого типа преобразует значение поля к нужному типу. Вместо XXXX могут быть использованы:

  • BCD - двоично-десятичный тип.
  • Boolean - логический тип.
  • Currency - денежный тип.
  • DataTime - тип дата-время.
  • Float - вещественный тип.
  • Integer - целый тип.
  • String - строка.
  • Variant - variant.

Пример:

DBText1.Field.AsString := 'Santa Cruz Wharf';

Calculated - Содержит True, если значение поля вычисляется в обработчике OnCalcFields набора данных, и False в противном случае.

CanModify - Содержит True, если значение поля можно изменить, и False в противном случае.

Currency - Свойство доступно у вещественных полей. Если свойству при проектировании приложения присвоить True, то значения будут выходить в денежном формате.

DataSize - Содержит размер данных.

DataType - Содержит тип данных, определяемый перечислением TFieldType, например, ftString - строка, ftBoolean - логический тип, ftFloat - вещественный тип, и так далее. Класс TFieldType содержит достаточно большой список типов полей, более подробные данные вы можете посмотреть в справочной системе Delphi.

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

EditMask - Позволяет указать строку - маску для ввода данных.

FieldName - Имя поля.

Lookup - Содержит True, если поле подстановочное.

Origin - Содержит имя поля в физической таблице.

ReadOnly - Если содержит True, значение поля нельзя менять.

Required - Если содержит True, значение поля не может быть пустым.

Size - Если поле имеет запись переменной длины, свойство указывает текущий размер данных.

Value - Содержит значение поля.

Visible - Если содержит True (по умолчанию), поле отображается в таких компонентах, как DBGrid.

Наиболее важные методы класса TField

AssignValue() - Преобразует вариантное значение поля Value с помощью метода AsXXXX и помещает результат в переменную Value, переданную в метод как параметр.

Create() - Создает поле-объект и инициализирует его.

Destroy() - Уничтожает поле-объект.

Наиболее важные события класса TField

OnChange - возникает после изменения данных поля и их успешной записи.

OnGetText - в обработчике этого события можно подготовить текст для свойств DisplayText и Text.

OnSetText - возникает при записи данных из параметра Text в свойство Text.

OnValidate - возникает после изменения значения но до записи в буфер. Этот обработчик удобно использовать для проверки на правильность введенных данных.

Обращение к значению поля

К значению поля можно обратиться через свойства Value или AsXXXX, например:

Edit1.Text := FoodTFName.Value;
Edit1.Text := FoodTFName.AsString;

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

Если вы не вызывали редактор полей и не создавали для набора данных ни одного объекта-поля, то значение поля можно получить через свойство FieldByName, например:

FoodT.FieldByName('FName').AsString := Edit1.Text;

Кроме того, доступ к значению поля можно получить через свойства набора данных Fields или FieldValues:

FoodT.Fields[1].AsString := Edit1.Text;
FoodT.FieldValues['FName'] := Edit1.Text;

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

FoodT['FName'] := Edit1.Text;

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

Свойство FieldValues обладает еще одной особенностью: оно имеет вариантный тип и позволяет использование списка полей, таким образом, единственным оператором можно записать сразу несколько полей:

var
  v : Variant;
begin
  //создаем вариантный массив:
  v := VarArrayCreate([0, 2], varVariant);
  //читаем значения полей:
  v := FoodT['FName;FType;FCena'];
  Edit1.Text := v[0];
  Edit2.Text := v[1];
  Edit3.Text := v[2];
< Лекция 5 || Лекция 6 || Лекция 7 >
Евгений Медведев
Евгений Медведев

В лекции №2 вставляю модуль данных. При попытке заменить name на  fDM выдает ошибку: "The project already contains a form or module named fDM!". Что делать? 

Анна Зеленина
Анна Зеленина

При вводе типов успешно сохраняется только 1я строчка. При попытке ввести второй тип вылезает сообщение об ошибке "project mymenu.exe raised exception class EOleException with message 'Microsoft Драйвер ODBC Paradox В операции должен использоваться обновляемый запрос'.