Russian Belarusian English German Japanese Ukrainian

BDE

BDE (от англ. Borland Database Engine - «движок баз данных Borland») - 32-битный движок баз данных под Microsoft Windows для доступа к базам данных.
BDE - механизм управления базами данных разных форматов таких как: Paradox, MS Access, dBase и так далее.
BDE представляет собой совокупность динамических библиотек и драйверов, обеспечивающих доступ к данным. Процессор BDE должен устанавливаться на всех компьютерах, на которых выполняются приложения С++ Builder, осуществляющие работу с БД. Приложение через BDE передает запрос к базе данных, а обратно получает требуемые данные.

DBGrid - представление записей в табличном виде с помощью сетки

Для вывода записей набора данных в табличном виде удобно использовать сетку, представленную компонентом DBGrid. Внешний вид сетки соответствует внутренней структуре таблицы БД и набора данных, при этом строке сетки соответствует запись, а столбцу поле. С помощью сетки пользователь управляет набором данных, поля которого в ней отображаются. Для навигации по записям и их просмотра используются полосы прокрутки и клавиши перемещения курсора. Для перехода в режим редактирования поля достаточно установить на него курсор и нажать любую алфавитно-цифровую клавишу. Переход в режим вставки новой записи выполняется нажатием клавиши <Insert>, после чего можно заполнять поля. Вставка записи происходит в том месте, где находится указатель текущей записи. Изменения, сделанные при редактировании или добавлении записи, подтверждаются нажатием клавиши <Enter>, или переходом к другой записи, или отменяются нажатием клавиши <Esc>. Для удаления записи следует нажать комбинацию клавиш <Ctrl>+<Delete>.
 
Характеристики сетки
Сетка DBGrid отображает все записи, имеющиеся в наборе данных, т.е. числом строк в ней управлять нельзя.
 
Основным свойством сетки DBGrid является свойство Columns типа TDBGridColumns, которое представляет собой массив (коллекцию) объектов Column типа TColumn, описывающих отдельные столбцы сетки.
Свойство SelectedIndex типа int задает номер текущего столбца в массиве columns, а свойство SelectedField указывает на объект типа TField, которому соответствует текущий столбец сетки.
Свойство Fieldcount типа int, доступное во время выполнения программы, содержит число видимых столбцов сетки, а свойство Fields [int FieldIndex] типа TField позволяет получить доступ к отдельным столбцам. Индекс определяет номер столбца в массиве столбцов и принимает значения в интервале 0..Fieidcount - 1.
Свойства Color и FixedColor типа TColor задают цвет сетки и ее фиксированных элементов соответственно. По умолчанию свойство color имеет значение clWindow (цвет фона Windows), а свойство FixedColor - значение clBtnFace (цвет кнопки).
Свойство TitleFont типа TFont определяет шрифт, используемый для вывода заголовков столбцов.
Доступ к параметрам сетки (например, для настройки) возможен через свойство Options типа TGridOptions. Это свойство представляет собой множество и принимает комбинации следующих значений:
  • dgEditing (пользователь может редактировать данные в ячейках)
  • dgAlwaysShowEditor (сетка постоянно находится в режиме редактирования)
  • dgTities (отображаются заголовки столбцов)
  • dgIndicator (для текущей записи в начале строки выводится указатель)
  • dgColumnResize (пользователь может с помощью мыши изменять размер столбцов и перемещать их)
  • dgColLines (между столбцами выводятся разделительные вертикальные линии)
  • dgRowLines (между строками выводятся разделительные горизонтальные линии)
  • dgTabs (для перемещения по сетке можно использовать клавиши <Таb> и <Shift>+<Tab>)
  • dgRowSelect (пользователь может выделить целую строку); при установке этого значения игнорируются значения dgEditing и dgAlwaysShowEditor
  • dgAlwaysShowSelection (ячейка остается выделенной, даже если сетка теряет фокус)
  • dgConfirmDelete (при удалении строки выдается запрос на подтверждение операции)
  • dgCancelOnExit (добавленные к сетке пустые строки (записи) при потере сеткой фокуса не сохраняются в наборе данных)
  • dgMultiSelect (в сетке можно одновременно выделить несколько строк)
По умолчанию свойство Options содержит комбинацию значений [dgEditing, dgTitles, dgIndicator, dgColumnResize, dgColLines, dgRowLines, dgTabs, dgConfirmDelete, dgCancelOnExit].
 
При щелчке на ячейке с данными генерируется событие OnCellClick, а щелчок на заголовке столбца вызывает событие OnTitleClick. Оба события имеют тип TDBGridClickEvent, описываемый так:
typedef void __fastcall (__closure *TDBGridClickEvent)(TColumn* Column);
Параметр column представляет собой столбец, на котором был произведен щелчок. При перемещении фокуса между столбцами сетки инициируются события OnColEnter и OnColExit типа TNotifyEvent, первое из которых возникает при получении столбцом фокуса, а второе при его потере.
 
Если свойство Options содержит значение dgColumnResize, то пользователь может с помощью мыши перемещать столбцы сетки. При таком перемещении генерируется событие OnColumnMoved типа TMovedEvent, описываемого как:
typedef void __fastcall (__closure *TMovedEvent)(System::TObject* Sender, int FromIndex, int ToIndex);
Параметры FromIndex и ToIndex указывают индексы в массиве столбцов сетки, соответствующие предыдущему и новому положению перемещенного столбца соответственно.
 
Сетка DBGrid способна автоматически отображать в своих ячейках информацию, но при необходимости программист может выполнить и собственное отображение сетки. Это может понадобиться в случае, когда желательно выделить ячейку или столбец с помощью цвета или шрифта, а также вывести в ячейке, кроме текстовой, графическую информацию, например, рисунок. Для программной реализации отображения сетки используется обработчик события OnDrawColumnCell типа TDrawColumnCellEvent, которое возникает при прорисовке любой ячейки. Тип события OnDrawColumnCell описан так:
typedef void __fastcall (__closure *TDrawColumnCellEvent) (System::TObject* Sender, const Types::TRect &Rect, int DataCol, TColumn* Column, Grids::TGridDrawState State);
Здесь параметр Rect содержит координаты ограничивающего ячейку прямоугольника, параметр DataCol определяет номер прорисовываемого столбца в массиве столбцов сетки, а параметр column является объектом прорисовываемого столбца. Параметр state задает состояние ячейки и принимает комбинации следующих значений:
  • gdSelected (ячейка находится в выбранном диапазоне)
  • gdFocused (ячейка имеет фокус ввода)
  • gdFixed (ячейка находится в фиксированном диапазоне)
Порядок вызова события onDrawColumnCell зависит от значения свойства DefaultDrawing типа bool. Если свойство имеет значение true (по умолчанию), то перед генерацией события onDrawColumnCell в ячейке отображается фон и выводится информация. Затем вокруг выбранной ячейки рисуется прямоугольник выбора. Если свойство DefaultDrawing имеет значение false, то сразу вызывается событие onDrawColumnCell, в обработчике которого следует разместить операции по прорисовке области сетки.
Пример программной прорисовки сетки:
// Свойство DefaultDrawing должно иметь значение true
void __fastcall TForm1::DBGrid1DrawColumnCell(TObject *Sender, const TRect &Rect, int DataCol, TColumn *Column, TGridDrawState State)
{
s = Table1->FieldByName(Column->FieldName)->AsString;
if (Column->FieldName == "Area") {
DBGrid1->Canvas->Brush->Color = clYellow;
DBGrid1->Canvas->Font->Color = clRed;
DBGrid1->Canvas->Font->Style = TFontStyles() << fsBold << fsItalic;
DBGrid1->Canvas->FillRect(Rect);
DBGrid1->Canvas->TextOut(Rect.Left+2, Rect.Top , s);
}
}
Здесь для столбца сетки, который соответствует полю Area (Площадь) набора данных, устанавливается желтый цвет фона, а данные с помощью строковой переменной s выводятся красным цветом и полужирным курсивом. При прорисовке ячеек используется свойство Canvas элемента DBGrid1, а также параметр Rect.

Добавление записей

Добавлять записи можно только к модифицируемому набору данных, в противном случае будет сгенерировано исключение. Для добавления записи нужно выполнить следующие действия.
  1. Перевести набор данных в режим вставки.
  2. Задать значения полей новой записи.
  3. Подтвердить сделанные изменения или отказаться от них, после чего набор данных снова переходит в режим просмотра.
Для добавления записей используются методы Insert, InsertRecord, Append и AppendRecord.
 
Метод Insert переводит набор данных в режим вставки и добавляет к нему новую пустую запись. Новая запись вставляется перед записью, на которой находится указатель текущей записи. При необходимости перед вызовом метода Insert нужно выполнить перемещение текущего указателя в требуемую позицию набора данных.
 
После перевода набора данных в режим вставки дальнейшие действия по заданию (изменению) значений полей, подтверждению или отмене сделанных изменений не отличаются от аналогичных действий при редактировании записи. При этом для задания или изменения значений полей используются инструкции присваивания и метод SetFields, а для подтверждения или отмены изменений методы Post и Cancel. Некоторые поля новой записи могут остаться пустыми, если до подтверждения им не были присвоены значения.
При переходе в режим вставки к набору данных добавляется пустая запись, значения полей которой не заданы. Если запись добавляется к подчиненному набору данных, связанному с главным набором связью «главный-подчиненный», то индексные поля автоматически получают корректные значения, и программист может не заботиться об их заполнении.
Рассмотрим следующий пример:
Table1->Insert() ;
Table1->FieldByName("Name")->AsString = Edit1->Text;
Table1->Post();
Здесь в новой записи задаются значение поля наименования (Name), остальные поля остаются пустыми. В этом и последующих примерах предполагается, что набор данных не связан с главным набором данных, и полям не были автоматически присвоены значения как индексным полям.
 
Метод InsertRecord объединяет функциональность методов Insert и SetFields, выполняя те же действия, что и их последовательный вызов. Метод имеет объявление:
void __fastcall InsertRecord(const System::TvarRec * values, const int vaiues_size);
вставляет в позицию указателя текущей записи новую, задавая значения всех или части ее полей. Например:
Table1->InsertRecord (ARRAYOFCONST(("Country", "Capital", NULL, NULL,22222)));
Здесь вставляется запись и затем, как и в примере с методом SetFields, в первое, второе и пятое поля вставленной записи набора данных Table1 заносятся страна, столица и численность населения соответственно. Третье и четвертое поля этой записи принимают значение 0.
 
Методы Append и AppendRecord отличаются от методов Insert и InsertRecord тем, что вставляют запись в конец набора данных, а не в позицию указателя текущей записи. Пользователь управляет набором данных, в том числе вставкой записи, с помощью элементов управления формы. Для компонента DBGrid новая запись добавляется к набору данных при нажатии клавиши <Insert> или при переходе на последнюю запись. Если в форме находится компонент DBNavigator, то новая запись добавляется при нажатии кнопки InsertRecord.
 
При добавлении новой записи любым методом возникают события BeforeInsert и AfterInsert типа TDataSetNotifyEvent, а также событие OnNewRecord типа TDataSetNotifyEvent. В обработчиках событий BeforeInsert и OnNewRecord можно выполнить действия, связанные с проверкой набранных пользователем данных или с заполнением (инициализацией) части полей новой записи. Вот пример соответствующей процедуры:
void __fastcall TForm1::Table1NewRecord(TDataSet *DataSet)
{
Table1->FieldByName("Name")->AsString = Edit1->Text;
Table1->FieldByName("Capital")->AsString = Edit2->Text;
Table1->FieldByName("Area")->AsInteger = StrToInt(Edit3->Text);
}
При утверждении или отмене изменений, связанных с добавлением новой записи, также генерируются события BeforePost и AfterPost или BeforeCancel и AfterCancel.

Домены

Домен представляет собой именованное описание столбца. После определения домена его имя можно использовать при описании других столбцов. Домен удобен в случаях, когда несколько столбцов, в том числе принадлежащих различным таблицам, имеют одинаковое описание. Если провести сравнение с языком программирования, например С++, то аналогом домена является тип данных. Таким образом, домен можно рассматривать как шаблон описания столбца.
 
Перед использованием домена его нужно создать с помощью оператора:
CREATE DOMAIN <Имя домена>
[AS] <Описание домена>
Имя созданного домена затем можно включать в описания столбцов:
<Имя столбца> <Имя домена>
Описание домена не отличается от ранее рассмотренного описания столбца и может включать различные ограничения, применимые к столбцу. Однако в отличие от ограничений для столбца, имя домена нельзя использовать в выражениях для ограничений: вместо имени домена в них используется слово VALUE.
 
Пример использования доменов:
CREATE DOMAIN D_Position AS VARCHAR(20) NOT NULL;
CREATE DOMAIN D_Price AS FLOAT CHECK(VALUE > 0);
CREATE TABLE Position
(Code INTEGER NOT NULL PRIMARY KEY
Position D_Position,
Note VARCHAR(50));
CREATE TABLE Personnel
(Code INTEGER NOT NULL PRIMARY KEY,
Name VARCHAR(30),
Position D_Position,
Salary FLOAT,
BirthDay DATE);
Домен D_Position представляет собой/описание строкового столбца длиной не более 20 символов, который не может быть пустым. Этот домен использован при описании столбцов Position Таблиц Position и Personnel. Второй домен D_Price представляет собой числовой столбец, значение которого должно быть положительным. Это ограничение задано конструкцией CHECK (VALUE > 0). Для приводимых таблиц домен D_Price не нужен, а создан с целью последующего использования.

Доступ к полям

Каждое поле набора данных представляет собой отдельный столбец, для работы с которым в С++ Builder служат объект Field типа TFieid и объекты производных от него типов, например, TIntegerField, TFloatField или TStringFieid. Для доступа к этим объектам и, соответственно, к полям записей у набора данных есть специальные методы и свойства, доступные при выполнении приложения.
 
Свойство Fieldcount типа int указывает количество полей набора данных. Это свойство доступно только для чтения. Количество полей набора данных может отличаться от физического числа полей таблицы БД, поскольку в набор данных не обязательно включаются все поля таблицы. Состав полей формируется при разработке приложения с помощью Редактора полей набора данных и Редактора столбцов сетки DBGrid. Кроме того, возможно динамическое изменение состава полей во время выполнения приложения. Для компонента Query состав полей набора данных зависит также от SQL-запроса.
 
Значение свойства property
TFields* Fields = {read=FFields};
представляет собой поле (столбец) набора данных. К отдельному полю можно обратиться, указав его номер index в массиве Fields; номера полей находятся в пределах от нуля до Fieldcount - 1. Номер объекта поля в массиве полей определяет свойство index типа int. В отличие от Редакторов полей и столбцов, применяемых на этапе разработки приложения, свойство index можно использовать для определения и изменения порядка полей набора данных во время выполнения приложения.
 
Для примера рассмотрим чтение полей текущей записи:
void __fastcall TForm1::Button5Click(TObject *Sender)
{
for(int i = 0; i < Table1->FieldCount; i++) ListBox1->Items->Add(Table1->Fields->Fields[i]->AsString);
}
Здесь содержимое каждого поля текущей записи интерпретируется как строковое значение и добавляется к списку ListBox1.
 
Номер поля в наборе данных не является заранее фиксированным и известным числом и зависит от порядка полей в таблице БД. от текущего состав полей набора данных, а также от значений свойств некоторых визуальных компонентов, связанных с этим набором, например сетки DBGrid. Так, при изменении порядка расположения столбцов в компоненте DBGrid соответственно изменяется порядок следования полей набора данных. В связи с этим обращение к какому-либо полю по его номеру в массиве полей может вызвать обращение совсем к другому полю. Поэтому для доступа к полям чаще используются методы FindField и FieldByName.
 
Функция
TField* __fastcall FindField(const AnsiString FieldName);
возвращает для набора данных поле, имя которого указывает параметр FieldName. В отличие от номера в массиве полей, имя поля более статично и изменяется реже. Кроме того, имя поля несет большую смысловую нагрузку, чем номер. Если заданное параметром FieldName поле не найдено, то метод FindField возвращает значение NULL. На практике чаще используется метод FieldByName, который отличается от метода FindField тем, что если заданное поле не найдено, то генерируется исключение.
Имя поля, определяемое параметром FieldName, является именем физического поля таблицы БД, заданным при создании таблицы, а не именем (свойством Name) объекта Field, которое создано для этого поля.
Для набора данных Query имя FieldName физического поля можно переопределить в тексте SQL-запроса.
 
Свойство Fields и методы FindField и FieldByName наиболее часто используются для доступа к значению поля текущей записи совместно с такими свойствами объекта Field, как AsString, Aslnteger, AsFloat или AsBooiean, которые позволяют обращаться к значению поля как к строковому, целочисленному, вещественному или логическому значению соответственно.
 
Так, в коде:
void __fastcall TForm1::Button5Click(T0bject *Sender)
{
Label1->Caption = Table1->FieldByName("Name")->AsString;
int x = Table1->FieldByName("Size")->AsInteger;
Edit4->Text=IntToStr(x);
}
строковое значение поля Name отображается в надписи Label1, а переменной х присваивается целочисленное значение поля size и оно помещается в Редактор Edit4. Если же поле size содержит значение, которое нельзя интерпретировать как целое число, то генерируется исключение.
 
В рассмотренных примерах выполнялось чтение содержимого полей текущей записи. Аналогичным образом можно присваивать произвольному полю текущей записи новое значение, при этом набор данных должен находиться в режиме редактирования или вставки.
 
Например, с помощью следующих инструкций:
void __fastcall TForm1::Button5Click(TObject *Sender)
{
// Перевод набора данных в режим редактирования
Table1->Edit(); // Изменение значений полей
Table1->FieldByName("Name")->AsString = Edit1->Text;
Table1->FieldByName("Size")->AsInteger = 5;
// Сохранение изменений
Table1->Post();
}
выполняется присвоение новых значений полям Name и size текущей записи после того, как набор данных Table1 переведен в режим редактирования. Произведенные изменения сохраняются, а набор данных переводится в режим просмотра.

Задание индексов

Задание индекса сводится к определению:
  • состава полей;
  • параметров;
  • имени.
Эти элементы устанавливаются или изменяются при выполнении операций создания, изменения и удаления индекса. Напомним, что для таблиц Paradox индекс называют не просто индексом, а вторичным индексом. Для выполнения операций, связанных с заданием индексов, необходимо выбрать пункт Secondary Indexes (Вторичные индексы) списка Table properties (Свойства таблицы), при этом под списком появляются кнопки Define (Определить) и Modify (Изменить), список индексов и кнопка Erase (Удалить). В списке индексов выводятся имена созданных индексов - индекс indName.
 
Создание нового индекса начинается с нажатия кнопки Define, которая всегда доступна. Она открывает окно Define Secondary Index (Задание вторичного индекса), в котором задаются состав полей и параметры индекса.
 
В списке Fields окна выводятся имена всех полей таблицы, включая и те, которые нельзя включать в состав индекса, например, графическое поле или поле комментария. В списке Indexed fields (Индексные поля) содержатся поля, которые включаются в состав создаваемого индекса. Перемещение полей между списками выполняется выделением нужного поля (полей) и нажатием расположенных между этими списками кнопок с изображением горизонтальных стрелок. Имена полей, которые нельзя включать в состав индекса, выделяются в левом списке серым цветом. Поле не может быть повторно включено в состав индекса, если оно уже выбрано и находится в правом списке.
При работе с записями индексные поля обрабатываются в порядке следования этих полей в составе индекса. Это нужно учитывать при указании порядка полей в индексе.
Изменить порядок следования полей в индексе можно с помощью кнопок с изображением вертикальных стрелок, имеющих общее название Change order (Изменить порядок). Для перемещения поля (полей) необходимо его (их) выделить и нажать нужную кнопку.
 
Флажки, расположенные в нижней части окна задания индекса, позволяют указать следующие параметры индекса:
  • Unique - индекс требует для составляющих его полей уникальных значений;
  • Maintained - задается автоматическое обслуживание индекса;
  • Case sensitive - для полей строкового типа учитывается регистр символов;
  • Descending - сортировка выполняется в порядке убывания значений.
Так как у таблиц dBase нет ключей, для них использование параметра Unique является единственной возможностью обеспечить уникальность записей на физическом уровне (уровне организации таблицы), не прибегая к программированию.
 
После задания состава индексных полей и нажатия кнопки ОК появляется окно Save Index As, в котором нужно указать имя индекса. Для удобства обращения к индексу в его имя можно включить имена полей, указав какой-нибудь префикс, например ind. Нежелательно образовывать имя индекса только из имен полей, т.к. для таблиц Paradox подобная система именования используется при автоматическом образовании имен для обозначения ссылочной целостности между таблицами. После повторного нажатия кнопки ОК сформированный индекс добавляется к таблице, и его имя появляется в списке индексов.
 
Созданный индекс можно изменить, определив новый состав полей, параметров и имени индекса. Изменение индекса практически не отличается от его создания. После выделения индекса в списке и нажатия кнопки Modify снова открывается окно задания индекса. При нажатии кнопки ОК появляется окно сохранения индекса, содержащее имя изменяемого индекса, которое можно исправить или оставить прежним.
 
Для удаления индекса его нужно выделить в списке индексов и нажать кнопку Erase. В результате индекс удаляется без предупреждающих сообщений.
 
Кнопки Modify и Erase доступны, только если индекс выбран в списке.

Задание ограничений на значения полей

Задание ограничений на значения полей заключается в указании для полей:
  • требования обязательного ввода значения;
  • минимального значения;
  • максимального значения;
  • значения по умолчанию;
  • маски ввода.
Установленные ограничения задаются на физическом уровне (уровне таблицы) и действуют для любых программ, выполняющих операции с таблицей: как для программ типа Database Desktop, так и для приложений, создаваемых в С++ Builder. Дополнительно к этим ограничениям или вместо них в приложении можно задать программные ограничения.
 
Для выполнения операций, связанных с заданием ограничений на значения полей, нужно выбрать пункт Validity Checks (Проверка значений) комбинированного списка Table properties, при этом ниже списка появляются флажок Required Field (Обязательное поле), поля редактирования Minimum Value, Maximum Value, Default Value, Picture (Маска ввода) и кнопка Assist (Помощь). Флажок и поля редактирования отображают установки для поля таблицы, которое выбрано в списке (курсор находится в строке этого поля).
 
Требование обязательного ввода значения означает, что поле не может быть пустым (иметь значение Null). Это требование действует при добавлении к таблице новой записи. До того как изменения в таблице будут подтверждены, поле должно получить какое-либо непустое значение, в противном случае генерируется ошибка. Ошибка может возникнуть также при редактировании записи, когда будет удалено старое значение поля и не присвоено новое.
 
Данное требование удобно использовать для так называемых обязательных полей таблиц, например, для поля фамилии в таблице сотрудников организации.
Обязательность ввода значения не действует на автоинкрементное поле, которое и без того является обязательным и автоматически заполняемым.
Для указания обязательности ввода значения в поле необходимо установить флажок Required Field, который по умолчанию снят.
 
Для полей некоторых типов, в первую очередь числовых, денежных, строковых и даты, иногда удобно задавать диапазон возможных значений, а также значение по умолчанию. Диапазон определяется минимальным и максимальным возможными значениями, которые вводятся в полях редактирования Minimum Value и Maximum Value. После их задания выход значения поля за указанные границы не допускается при вводе и редактировании любым способом.
 
Значение поля по умолчанию указывается в поле Default Value. Это значение устанавливается при добавлении новой записи, если при этом для поля не указано какое-либо значение.
Задание диапазона и значений по умолчанию возможно не для всех полей, например, они не определяются для графического поля и поля комментария. Для этих полей соответствующее поле ввода в диалоговом окне определения структуры таблицы блокируется.
В поле ввода Picture можно задать маску (шаблон) для ввода значения поля. Ввод по маске поддерживается, например, для таких типов полей, как числовой или строковый. Его удобно использовать для ввода информации определенных форматов, например, телефонных номеров или почтовых индексов.
 
Для маски используются следующие символы:
  • # (цифра);
  • ? (любая буква; регистр не учитывается);
  • & (любая буква; преобразуется к верхнему регистру);
  • ~ (любая буква; преобразуется к нижнему регистру);
  • @ (любой символ);
  • ! (любой символ; преобразуется к верхнему регистру);
  • ; (за этим символом следует буква);
  • * (число повторов следующего символа);
  • [abc] или {а,b,с} (любой из приведенных символов а, b или с; во втором случае значения перечисляются через запятую без пробелов).
Маску можно ввести в поле ввода Picture вручную или использовать для этого диалоговое окно Picture Assistance (Помощник представления), вызываемое нажатием кнопки Assist.
 
Указанное окно помогает ввести, выбрать или откорректировать маску, а также проверить ее функционирование. Список Sample pictures содержит образцы масок, которые выбираются нажатием кнопки Use. Выбранная маска помещается в поле ввода Picture и доступна для изменения. Для модификации списка образцов масок служат кнопки Add to List и Delete from List: первая добавляет к списку маску, содержащуюся в поле ввода Picture, а вторая удаляет из списка Sample pictures выбранную маску.
 
Проверка синтаксиса маски выполняется по нажатию кнопки Verify Syntax, результат проверки выводится в информационной панели. Кнопка Restore Original (Вернуть исходную) служит для восстановления начального (т.е. до начала редактирования) значения маски.
 
функционирование маски можно проверить, введя в поле ввода Sample value значение поля таблицы. По нажатию кнопки Test Value выполняется проверка введенного значения, результат проверки выводится в информационной панели.

Задание паролей

Пароль позволяет задать права доступа пользователей (приложений) к таблице. Если для таблицы установлен пароль, то он будет автоматически запрашиваться при каждой попытке открытия таблицы.
Пароль действует на физическом уровне и его действие распространяется на все программы, выполняющие доступ к таблице: как на программы типа Database Desktop, так и на создаваемые приложения С++ Builder.
Для выполнения операций, связанных с заданием пароля, нужно выбрать строку Password Security в комбинированном списке Table properties окна определения структуры таблицы. При этом под списком становятся доступными кнопки Define и Modify. Нажатие кнопки Define открывает окно Password Security, в котором задается главный пароль.
 
Главный пароль таблицы вводится дважды в полях Master password (Главный пароль) и Verify master password (Подтвердить главный пароль). При нажатии кнопки ОК значения сверяются, и при их совпадении пароль принимается. Когда пароль определен, кнопка Define блокируется и становится доступной кнопка Modify изменения пароля. Ее нажатие снова вызывает окно задания пароля, в котором появляются кнопки Change и Delete, а поля ввода заблокированы.
 
При нажатии кнопки Delete главный пароль удаляется, после чего его можно ввести заново. Если в качестве значения главного пароля указана пустая строка, то пароль для таблицы не задан. Нажатием кнопки Change поля ввода разблокируются, и значение пароля можно изменить (это нужно сделать в обоих полях). При этом название кнопки Change изменяется на Revert (Возврат), и ее повторное нажатие возвращает значение пароля, которое было до редактирования.
 
Рассмотренный нами главный пароль предоставляет пользователю полные права доступа к таблице, включая изменение записей и структуры таблицы, в том числе смену пароля. Кроме главного пароля, можно задать для таблицы дополнительные пароли, устанавливающие пользователю ограниченные права доступа к таблице. Для задания дополнительных паролей нажатием кнопки Auxffiaiy Passwords открывается одноименное окно.
 
В списке Passwords выводятся действующие дополнительные пароли. Группа переключателей Table rights определяет для пароля права доступа к таблице в целом. Они могут быть следующими:
  • All - полные права, включая изменение записей и структуры таблицы;
  • Insert & delete - разрешены вставка и удаление, а также редактирование записей, запрещено изменение структуры таблицы;
  • Data entry - разрешены редактирование и вставка записей, запрещены изменение структуры таблицы и удаление записей;
  • Update - разрешены только просмотр (чтение) записей и редактирование неключевых полей;
  • ReadOnly - разрешен только просмотр (чтение) записей.
Права доступа к таблице действуют на все ее поля, кроме того, для каждого поля можно установить отдельные права доступа, не зависящие от прав доступа к другим полям. Права доступа к полям выводятся слева от имени поля в списке Fields rights и могут иметь следующие значения:
  • All (чтение и изменение значения поля);
  • ReadOnly (только чтение значения поля);
  • None (доступ к полю запрещен).
Смена права доступа к полю выполняется выбором поля в списке и нажатием кнопки Fields Rights, при котором право циклически устанавливается очередным значением списка (All, ReadOnly и None). Создание пароля начинается нажатием кнопки New, после чего его имя указывается в поле Current password (Текущий пароль) и устанавливаются права доступа к таблице и ее полям. Нажатие кнопки Add заносит пароль в список дополнительных паролей.
 
Нажатие кнопки Change переводит выбранный в списке пароль в режим редактирования, при этом появляются кнопки Accept (Подтвердить) и Revert (Возврат), а также разблокируется кнопка Delete. В процессе редактирования пароль можно изменить, удалить или оставить без изменений. После смены пароля и прав доступа внесенные изменения утверждаются нажатием кнопки Accept. Для выхода из режима редактирования и возврата к прежним установкам пароля необходимо нажать кнопку Revert. Удаляется пароль нажатием кнопки Delete.
При выполнении приложения, использующего механизм доступа BDE, можно добавлять и удалять пароли с помощью методов компонента Session.
Метод void __fastcall AddPassword(const AnsiString Password); добавляет новый пароль, заданный параметром Password.
Метод void __fastcall RemovePassword(const AnsiString Password); удаляет указанный пароль.
Метод void __fastcall RemoveAllPasswords(void); удаляет все пароли. Например, добавление пароля задается следующим образом: Session->AddPassword("Word_secret");.

Задание ссылочной целостности

Понятие ссылочной целостности относится к связанным таблицам и проявляется в следующих вариантах взаимодействия таблиц:
  • запрещается изменять поле связи или удалять запись главной таблицы, если для нее имеются записи в подчиненной таблице;
  • при удалении записи в главной таблице автоматически удаляются соответствующие ей записи в подчиненной таблице (каскадное удаление).
Для выполнения операций, связанных с заданием ссылочной целостности, необходимо выбрать пункт Referential Integrity комбинированного списка Table properties. При этом, как и в случае задания индексов, появляются кнопки Define, Modify, Erase и список, в котором выводятся имена созданных условий ссылочной целостности.
 
Условие ссылочной целостности задается для подчиненной таблицы и определяется следующими элементами:
  • полями связи подчиненной таблицы;
  • именем главной таблицы;
  • полями связи главной таблицы;
  • параметрами.
 
Разработчик может создать, изменить или удалить условие ссылочной целостности. Для задания условия ссылочной целостности нужно нажать кнопку Define, после чего появляется окно Referential Integrity.
 
Поле связи следует выбрать в списке Fields и нажатием кнопки со стрелкой вправо перевести его в список Child fields (Дочерние поля). Если полей связи несколько, то эти действия выполняются для каждого из них. Кнопка со стрелкой влево удаляет выбранное поле из списка дочерних полей.
Задание рабочего каталога программы Database Desktop выполняется с помощью команды FileXWorking Directory (Файл\Рабочий каталог).
Главная таблица указывается в списке Table, имена таблиц выбираются в рабочем каталоге программы Database Desktop (каталог, определенный как Working Directory). После выбора таблицы и нажатия кнопки со стрелкой влево (рядом со списком таблиц) в поле Parent's key автоматически заносятся ключевые поля главной таблицы.
 
Главная таблица должна быть закрыта и не может использоваться другими программами, включая Database Desktop. В противном случае при попытке сохранить структуру таблицы возникает ошибка.
 
Параметры ссылочной целостности выбираются переключателями. Группа Update rule (Правила изменения) определяет вид взаимодействия таблиц при изменениях в главной таблице. Переключатель Cascade устанавливает режим каскадного удаления записей в подчиненной таблице при удалении соответствующей записи главной таблицы. Переключатель Prohibit устанавливает режим запрещения изменения поля связи или удаления записи главной таблицы, для которой имеются записи в подчиненной таблице.
 
Флажок Strict referential integrity (Жесткая ссылочная целостность) устанавливает защиту таблиц от модификации с использованием ранних версий программы Database Desktop (под DOS), которые не поддерживают ссылочную целостность.
 
После установки нужных режимов и нажатия кнопки ОК появляется окно Save Referential Integrity As, в котором нужно указать имя условия. Напомним, что для таблиц Paradox условия ссылочной целостности именуются. Для удобства обращения к условию в его имя можно включить имена полей и таблиц, задав при этом некоторый префикс, например, ri. После нажатия кнопки ОК сформированное условие ссылочной целостности добавляется к таблице, и его имя появляется в списке условий.
 
Созданное условие ссылочной целостности можно изменить, определив новый состав полей и новые значения параметров. Изменение условия ссылочной целостности практически не отличается от его создания: после вы деления имени условия в списке и нажатия кнопки Modify открывается окно определения ссылочной целостности. При нажатии кнопки ОК измененное условие ссылочной целостности сохраняется под тем же именем.
Условия ссылочной целостности задаются на физическом уровне и действуют для любых программ, выполняющих операции с таблицей: как для программ типа Database Desktop, так и для приложений, создаваемых в С++ Builder.
Для удаления условия ссылочной целостности нужно выделить его в списке и нажать кнопку Erase. Удаление производится без выдачи предупреждающих сообщений.
 
Кнопки Modify и Erase доступны, только если выбрано условие в списке.

Задание таблицы для выбора значений

На практике возможны случаи, когда в поле таблицы должны заноситься значения из какого-либо набора, который может формироваться различными способами. Одним из часто используемых является вариант, когда эти значения содержатся в поле другой таблицы, а совокупность значений всех записей этого поля образует набор допустимых значений.
 
Для полей некоторых типов, например, строкового, числового или даты, можно определить некоторую таблицу (таблицу выбора), поля которой будут использоваться для формирования набора допустимых значений. Если для поля задана таблица выбора, то в него можно ввести только значение, содержащееся в таблице выбора (в указанном поле любой записи). Задание таблицы выбора гарантирует, что в поле не будет введено недопустимое значение.
 
Действие набора допустимых значений распространяется также на редактирование записей таблицы программным способом: при попытке присвоить полю недопустимое значение генерируется исключение.
При вводе строковых значений учитывается регистр букв, поэтому, например, Водитель и ВОДИТЕЛЬ являются разными значениями.
В любом случае допустимым является пустое значение (Null), если, конечно, не задано ограничение, что поле не может быть пустым.
 
Для выполнения операций, связанных с полями выбора, предназначен пункт Table Lookup (Таблица выбора) комбинированного списка Table properties окна определения структуры таблицы. При этом под списком становится доступной кнопка Define, нажатие которой открывает окно Table Lookup.
 
В списке Fields выводятся имена всех полей таблицы, при этом имена полей, которые не допускают создание таблицы выбора, выделены серым цветом (например, поле автоинкрементного типа).
 
Имя поля, для которого задается таблица выбора, отображается в области Field name, для его указания следует выделить в списке Fields нужную строку и нажать кнопку с изображением стрелки вправо. Если указать другое поле и нажать кнопку, то имя этого поля перейдет в область Field name и заменит имя предыдущего поля.
 
В списке Lookup table задается таблица выбора, имя которой (имя главного файла) появляется в поле редактирования над списком. В списке Drive (or Alias) задается диск или псевдоним, которые определяют местоположение таблицы выбора. Название каталога, таблицы которого содержатся в списке Lookup table, отображается справа от названия списка Drive (or Alias). Таблицу также можно задать в окне Select File, открываемом нажатием кнопки Browse (Просмотр).
 
После задания таблицы выбора нажатие кнопки с изображением стрелки влево переводит имя ее первого поля, значения которого будут использованы для формирования набора допустимых значений, в область Lookup field (Поле выбора). Типы полей обеих таблиц должны совпадать, в противном случае в информационной панели выдается сообщение об ошибке.
 
С помощью группы переключателей Lookup type (Тип выбора) можно задать способ взаимодействия обеих таблиц. Если включен переключатель Just current field (Только текущее поле), то таблица выбора задается только для поля, указанного в области Field name. Переключатель All corresponding fields назначает таблицу выбора не только указанному полю, но и всем соответствующим полям. Имена и типы этих полей должны совпадать с соответствующими полями таблицы выбора.
 
Группа переключателей Lookup access (Доступ к таблице выбора) определяет, как пользователь использует значения из таблицы выбора. Если включен переключатель Fill no help (Вставка без помощи), то при редактировании поля, для которого определена таблица выбора, пользователь должен знать допустимые значения этого поля. При этом термин "выбор" не совсем точно отражает взаимосвязь полей таблиц, т. к. пользователю не предлагается список возможных значений, из которых он может выбрать нужное ему. Пользователь сам вводит значение в поле, при этом на уровне таблицы выполняется проверка, является ли это значение допустимым. Если значение отсутствует в указанном поле таблицы выбора, то оно не принимается. В этом случае может помочь отображение рядом с редактируемой таблицей таблицы выбора.
 
Установка переключателя Help and fill (Помощь и вставка) позволяет не только ввести значение в поле, как описано выше, но и действительно выбрать значение в списке. Список, сформированный на основании значений поля (полей) таблицы выбора, появляется при нажатии комбинации клавиш <Ctrl>+<пробел> в редактируемом поле. После выбора нужного значения и нажатия кнопки ОК оно заносится в поле.
 
В приведенном на этом рисунке примере в окне программы Database Desktop таблица worker содержит данные о сотрудниках организации. В частности, в ней определено строковое поле должности (Post), для которого задана таблица выбора posts. В это поле можно вводить только допустимое название должности. Перечень всех должностей содержится в единственном поле Post таблицы Posts. Для предотвращения ввода в таблицу Worker неправильных значений ее полю post назначена таблица выбора Posts с полем Post. В таблице worker для первых трех сотрудников введены Должности, имеющиеся в таблице Posts. Попытка задать для четвертого сотрудника любую должность, которая не входит в перечень должностей из таблицы Posts, будет блокироваться, т.к. эта должность не является разрешенной для ввода. При необходимости эту должность сначала нужно ввести в таблицу Posts, после чего она станет доступной для таблицы worker.
Из таблицы выбора могут быть удалены значения. Если эти значения содержатся в полях таблицы, использующей таблицу выбора, то при переходе в режим ее редактирования возникает ошибка. При использовании программы типа Database Desktop таблицу нельзя вывести из режима редактирования, пока все ее значения не приведены в соответствие с новыми значениями таблицы выбора. Во время выполнения приложения при доступе к таблице, использующей удаленные из таблицы выбора значения, генерируется исключение.
После задания для поля таблицы выбора в окне определения структуры таблицы становятся доступными кнопки Modify и Erase, а также список, в котором отображается имя этой таблицы.
 
Нажатие кнопки Modify вновь открывает окно задания таблицы выбора, в котором можно ввести новые данные. Кнопка Erase служит для отмены использования таблицы выбора и связанных с ней ограничений на значения поля.
 
Объекты поля типа TField наборов данных Table и Query, а также компонент DBGrid позволяют определить для поля список выбора, который также дает возможность пользователю выбирать значения при редактировании. Они задаются на программном уровне и действуют только в своем приложении.

Задание языкового драйвера

Для задания языкового драйвера нужно выбрать пункт Table Language (Язык таблицы) комбинированного списка Table properties окна определения структуры таблицы. При этом под списком становится доступной кнопка Modify, открывающая окно Table Language. Под «языком» таблицы понимается языковой драйвер, используемый для этой таблицы. В поле списка Language отображается текущий драйвер.
 
В списке можно выбрать драйвер нужного языка, для русского языка это драйвер Pdox ANSI Cyrillic, который корректно отображает символы русского алфавита и выполняет с ними операции сортировки.
 
По умолчанию языковой драйвер определяется установками процессора баз данных BDE, поэтому целесообразно установить его (параметр LANGDRIVER) в нужное значение, например, с помощью программы BDE Administrator.