по значениям поля набора данных 5 глава




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

Поиск записей

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

При организации поиска записей важное значение имеет наличие индекса для полей, по которым ведется поиск. Индексирование значительно повышает ско­рость обработки данных, кроме того, ряд методов может работать только с ин­дексированными полями.

Далее мы рассмотрим средства, с помощью которых можно выполнить поиск записей в наборах данных Table и Query. Отметим, что к средствам поиска МОЖНО отнести также методы FindFirst, FindLast, FindNext И FindPrior, осуществляющие переход на записи, удовлетворяющие условиям фильтра.

Поиск в наборах данных

Для поиска записей по полям служат методы Locate и Lookup, причем поля могут быть неиндексированными.

Функция Locate (const KeyFields: String; const KeyValues: Variant; Options: TLocateOptions): Boolean ищет запись с заданными значениями полей. Если удовлетворяющие условиям поиска записи существуют, то указа­тель текущей записи устанавливается на первую из них. Если запись найдена,


198


Часть II. Технологии доступа к данным


функция возвращает значение True, в противном случае — значение False. Список полей, по которым ведется поиск, задается в параметре KeyFields, по­ля разделяются точкой с запятой. Параметр KeyValues типа Variant указывает значения полей для поиска. Если поиск ведется по одному полю, то параметр содержит одно значение, соответствующее типу поля, заданного для поиска.

Параметр Options позволяет задать значения, которые обычно используются при поиске строк. Этот параметр принадлежит к множественному типу TLocateOptions и принимает комбинации следующих значений:

□ loCaseinsensitive (регистр букв не учитывается);

□ loPartiaiKey (допускается частичное совпадение значений).

Отметим, что тип TLocateOptions по сути похож на тип TFilterOptions, оп­ределяющий параметры фильтрации по выражению, но значения loPartiaiKey и foNoPartialCompare имеют противоположное действие: первое из них до­пускает, а второе запрещает частичное совпадение значений.

СЗамечание^

При наличии у параметра Options значения loPartiaiKey к нему автоматически добавляется значение loCaseinsensitive.

Пример поиска по одному полю:

Tablel.Locate('Number', 123, []);

Поиск выполняется по полю Number и ищется первая запись, для которой зна­чением этого поля является число 123. Все параметры поиска отключены. Возвращаемый методом Locate результат не анализируется.

При поиске по нескольким полям в методе Locate параметр KeyValues является массивом значений типа Variant, в котором содержится несколько элементов. Для приведения к типу вариантного массива используется функция VarArrayOf. Значения разделяются запятыми и заключаются в квадратные скобки, поря­док значений должен соответствовать порядку полей параметра KeyFields. Вот пример:

Tablel.Locate('Name;Post;', VarArrayOf(['I', 'Инженер']), [loCaseinsensitive, loPartiaiKey]);

Поиск выполняется по полям Name и Post, ищется первая запись, для которой значение поля фамилии начинается с букв п или I, а значение поля должности содержит строку Инженер. Регистр букв значения не имеет. Результат поиска не анализируется.

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


Глава 7. Навигационный доступ к данным с помощью BDE


199


J

Замечание

Если имя поля или тип значения заданы неправильно, то при попытке выполнить метод Locate генерируется исключение.

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

В качестве примера рассмотрим обработчик события, обеспечивающий поиск в наборе данных. Вид формы приложения приведен на рис. 7.8.

Рис. 7.8. Вид диалогового окна поиска в наборе данных

Пользователь имеет возможность осуществлять поиск по полям названия (Name) и цены (Price) товара. Процесс поиска начинается при нажатии кнопки Поиск (btnFind). Ниже приведен текст обработчика события нажатия этой кнопки.

procedure TForml.btnFindClick(Sender: TObject); var KeyFields: String; KeyValues: Variant;

Options: TLocateOptions; begin if not (cbFindName.Checked or cbFindPrice.Checked) then begin

MessageDlg('He заданы условия поиска!', mtlnformation, [rrbOK], 0);

exit;

end; // Поиск одновременно по двум полям Name и Price


200


Часть II. Технологии доступа к данным


if cbFindName.Checked and cbFindPrice.Checked then begin KeyFields:= 'Name;Price';

KeyValues:= VarArrayOf([edtFindName.Text, edtFindPrice.Text]); end // Поиск по одному из двух полей else begin

//По полю Name

if cbFindName.Checked then begin KeyFields:= 'Name'; KeyValues:= edtFindName.Text; end; // По полю Price

if cbFindPrice.Checked then begin KeyFields:= 'Price'; KeyValues:= edtFindPrice.Text; end; end; // Поиск выполняется независимо от регистра букв // с возможностью частичного совпадения Options:= [loCaselnsensitive, loPartialKey]; // Запись не найдена

if not Tablel.Locate(KeyFields, KeyValues, Options) then begin Beep;

MessageDlg('Запись не найдена!', mtlnformation, [mbOK], 0); exit; end; // Здесь могут быть выполнены действия по обработке найденной записи end;

Включать или не включать поля в поиск — определяется с помощью флажков cbFindName и cbFindPrice, значения для поиска вводятся в полях редактиро­вания edtFindName и edtFindPrice.

Если включен параметр loPartialKey, то в процессе поиска допускаются час­тичные совпадения значений. Используя это, можно организовать поиск путем последовательного приближения к требуемой записи. Такой последовательный поиск реализован, например, на страницах Предметный указатель и Поиск окна справочной системы Windows, где после ввода очередного символа выполняется автоматический переход на подходящую строку. Последовательный поиск мож­но организовать также с помощью методов FindNearest, SetNearest, EditNearest и GotoNearest, предназначенных для поиска с частичным совпа­дением заданных для поиска значений и значений полей записей.

Рассмотрим в качестве примера обработчики событий формы приложения, ис­пользуемой для последовательного поиска записей (рис. 7.9).


Глава 7. Навигационный доступ к данным с помощью BDE


201


 



 


Рис. 7.9. Вид диалогового окна для последовательного поиска

Ниже приведен код обработчиков событий для компонентов формы Forml при­ложения.

procedure TForml.edtSearchChange(Sender: TObject);

var strField: String;

begin

// Если режим поиска выключен, то выйти из процедуры

if not cbSearch.Checked then exit;

// Выбрать поле для поиска

case RadioGroupl.Itemlndex of

 

  strField = 'Name';
  strField = 'Firm';
  strField = 'City';

end; // Выполнить поиск

Tablel.Locate(strField, edtSearch.Text,

[loCaselnsensitive, loPartialKey]); end;

procedure TForml.cbSearchClick(Sender: TObject); begin

edtSearchChange(Sender); end;

procedure TForml.RadioGrouplClick(Sender: TObject)

begin

edtSearchChange(Sender);

end;


202


Часть II. Технологии доступа к данным


Здесь при установке флажка cbSearch включается режим поиска, и указатель текущей записи перемещается на запись, удовлетворяющую условиям поиска. Поле, по которому ведется поиск, выбирается с помощью группы переключате­лей. Процесс поиска запускается каждый раз при изменении содержимого ре­дактора edtSearch.

Для поиска в наборе данных также используется метод Lookup, который работа­ет аналогично методу Locate. Функция Lookup (const KeyFields: String; const KeyValues: Variant; const ResultFields: String): Variant осу­ществляет поиск записи, удовлетворяющей определенным условиям, но, в отли­чие от метода Locate, не перемещает указатель текущей записи на найденную запись, а считывает информацию из полей записи. Еще одно различие между двумя методами заключается в том, что метод Lookup осуществляет поиск на точное соответствие значений для поиска и значений в полях записей с учетом регистра букв.

Параметры KeyFields и KeyValues имеют такое же назначение, как и в методе Locate, и используются аналогичным образом.

В параметре ResultFields через точку с запятой перечисляются названия по­лей, значения которых будут получены в случае успешного поиска. Эти значе­ния считываются из первой найденной записи, удовлетворяющей условиям по­иска. Порядок перечисления полей в ResultFields может отличаться от порядка полей в наборе данных. Например, если набор данных имеет поля Code, Name, Salary и Note, то в ResultFields можно задать Salary и Name.

В случае удачного поиска метод Lookup в качестве результата возвращает значе­ние типа Variant, размерность которого зависит от списка полей ResultFields. Если список содержит одно значение, то метод возвращает зна­чение одного поля, если в списке задано несколько полей, то метод возвращает массив Variant, число элементов которого совпадает с числом полей в списке ResultFields.

(_____ ЗамечаниеJ

Перед использованием результирующие значения элементов массива variant следует самостоятельно преобразовать к требуемому типу, например, String,

Real или Integer.

Для работы с массивом Variant, число элементов которого заранее неизвестно, предназначены следующие функции:

□ VarlsArray (const V: Variant): Boolean — проверяет, является ли па­раметр v массивом типа Variant;

□ VarArrayLowBound (const A: Variant; Dim: Integer): Integer — воз­вращает нижнюю границу массива, заданного параметром а, параметр Dim определяет размерность массива;

□ VarArrayHighBound (const A: Variant; Dim: Integer): Integer — воз­вращает верхнюю границу массива, заданного параметром а, параметр Dim определяет размерность массива.


Глава 7. Навигационный доступ к данным с помощью BDE


203


При неудачном поиске метод Lookup возвращает значение Null. Для анализа такого результата можно использовать функцию VarisNull (const V: Variant): Boolean, возвращающую значение True при значении параметра v, равном Null.

СЗамечание^

Не следует путать Null, соответствующее пустому (нулевому) значению, и Nil, означающее отсутствие значения.

(Замечание^

Если из найденной записи считываются значения нескольких полей, то даже в слу­чае успешного поиска часть полей может быть не определена и содержать пустые значения. Поэтому при операциях с элементами массива Variant следует прове­рять значение каждого из них на равенство Null.

Рассмотрим, как проводится анализ значений полей найденной записи:

procedure TForml.btnFindClick(Sender: TObject); var KeyFields, ResultFields: String; KeyValues, vrntResult: Variant; strResult: String; begin

KeyFields:= 'Name'; KeyValues:= edtFindName.Text;

// Порядок полей результата отличается от порядка полей набора данных ResultFields:= 'Name;Price;Code'; // Выполнение поиска

vrntResult:= Tablel.Lookup(KeyFields, KeyValues, ResultFields); // Проверка, успешный ли поиск if not VarisNull(vrntResult) then begin // Поиск завершился успешно

// Анализ поля Name

if not VarisNull(vrntResult[0])

then strResult:= 'Название: ' + String(vrntResult[0]) else strResult:= 'Название: -';

// Анализ поля Price

if not VarisNull(vrntResult[1])

then strResult:= strResult + #13#10 + 'Цена: ' + String(vrntResult[1])

else strResult:= strResult + #13#10 + 'Цена: -';

// Анализ поля Code

if not VarisNull(vrntResult[2])

then strResult:= strResult + #13#10 + 'Код: ' + String(vrntResult[2])


204


Часть II. Технологии доступа к данным


else strResult:= strResult + #13#10 + 'Код: -'; // Вывод значений полей найденной записи MessageDlg('Данные найденной записи:' + #13#10 + strResult,

mtlnformation, [mbOK], 0); end; // Поиск завершился неудачно else begin Веер;

MessageDlg('Запись не найдена!', mtlnformation, [mbOK], 0); end; end;

В примере поиск ведется по полю названия товара (Name), а из найденной запи­си считываются значения полей названия (Name), цены (Price) и кода (code). Порядок считываемых полей отличается от порядка этих полей в таблице БД. Значение, по которому ищется запись, вводится в редакторе edtFindName. По­сле поиска выполняется анализ его успешности, и при положительном результа­те выводится диалоговое окно с данными полей найденной записи. Если запись не найдена, то выводится соответствующее сообщение. Перед анализом каждого из возвращенных значений проверяется его равенство Null (пустое значение). Если поле не пустое, то тип Variant преобразовывается в строковый.

Поиск по индексным полям

Для набора данных Table имеются методы, позволяющие вести поиск записей только по индексным полям. Перед вызовом любого из этих методов следует установить в качестве текущего индекс, построенный по используемым для по­иска полям. Методы поиска можно разделить на две группы, в первую из кото­рых входят методы FindKey, SetKey, EditKey и GotoKey, предназначенные для поиска на точное соответствие, а другую образуют методы FindNearest, SetNearest, EditNearest и GotoNearest, допускающие только частичное сов­падение заданных для поиска значений и значений полей записей.

Метод FindKey (const KeyValues: array of const): Boolean выполняет поиск в наборе данных Table записи, у которой значения полей совпадают со значениями, указанными в параметре KeyValues. Список полей для поиска не задается, а берутся индексные поля в соответствии с текущим индексом. Если поиск завершился успешно, то найденная запись становится текущей, а метод возвращает значение True. При неудачном поиске указатель текущей записи не перемещается, а метод возвращает значение False.

Если заданным условиям поиска соответствует несколько записей, то указатель текущей записи устанавливается на первую из них. Порядок сортировки и, со­ответственно, порядок расположения записей в наборе данных определяется текущим индексом, по которому и ведется поиск.


Глава 7. Навигационный доступ к данным с помощью BDE


205


Например:

procedure TForml.btnFindClick(Sender: TObject);

begin

Tablel.IndexFieldNames:= 'City;Date';

if not Tablel.FindKey ([edtFindCity.Text, edtFindDate.Text])

then ShowMessage('Запись не найдена!'); end;

Здесь в наборе данных выполняется поиск первой записи, поля city и Date которой содержат значения, введенные в редакторы edtFindCity и edtFindDate. В случае неудачного поиска пользователю выдается соответст­вующее сообщение. Перед выполнением поиска текущим устанавливается ин­декс, построенный по поисковым полям.

Вместо метода FindKey можно вызывать методы SetKey, EditKey и GotoKey, которые применяются совместно. Их использование похоже на применение рас­смотренных ранее методов SetRangeStart, EditRangeStart И ApplyRange ДЛЯ фильтрации набора данных по диапазону значений.

Метод SetKey переводит набор данных в режим поиска записи dsSetKey; этот метод вызывается один раз для текущего индекса. Впоследствии для перехода в режим поиска можно вызывать метод EditKey. Если набор данных находится в режиме поиска, значения полей устанавливаются с помощью инструкций при­сваивания. Метод GotoKey: Boolean выполняет собственно поиск записи, удовлетворяющей заданному условию. Использовать комбинацию названных методов менее удобно, чем метод FindKey. Вот еще один пример, иллюстри­рующий точный поиск:

procedure TForml.btnFindClick(Sender: TObject);

begin

Tablel.IndexFieldNames:= 'City';

// Впоследствии вместо этого метода можно вызывать EditKey

Tablel.SetKey;

Tablel.FieldByName('City').AsString:= edtFindCity.Text;

if not Tablel.GotoKey

then ShowMessage('Запись не найдена!'); end;

Приведенная процедура обработки события нажатия кнопки выполняет точный поиск записей по полю города (city).

Метод FindNearest, в отличие от метода FindKey, производит поиск значений полей записей набора данных Table, которые только частично совпадают со значениями, заданными для поиска. Сравнение проводится, начиная с первого стоящего в поле символа. Поиск по частичному совпадению можно применять к строкам или к данным других типов, например, целым. Поиск с помощью про-


206


Часть II. Технологии доступа к данным


цедуры FindNearest (const KeyValues: array of const) всегда является успешным и перемещает указатель текущей записи на запись, в наибольшей степени отвечающую условиям поиска.

Вместо метода FindNearest можно использовать комбинацию методов SetNearest, EditNearest и GotoNearest, работа с которыми аналогична работе с соответствующими методами поиска на точное соответствие значений полей.

Например:

procedure TForml.btnFindClick(Sender: TObject);

begin

Tablel.IndexFieldNames:= 'Name';

Tablel.FindNearest (['И']);

end;

В приведенной процедуре указатель текущей записи перемещается на запись, поле фамилии которой содержит значение, начинающееся с буквы и. Если та­кой фамилии нет, то будет найдена фамилия, начинающаяся с ближайшей к и следующей буквы.

При поиске по нескольким полям текущего индекса используется свойство KeyFieldCount типа Boolean, указывающее, сколько полей индекса, начиная с первого, участвует в поиске. По умолчанию поиск осуществляется по всем по­лям текущего индекса.

Модификация набора данных

Модификация (изменение) набора данных представляет собой редактирование, добавление и удаление его записей. Модифицируемость набора данных зависит от различных условий. Разработчик может разрешить или запретить изменение набора данных с помощью соответствующих свойств.

Управлять возможностью изменения набора данных Table можно посредством свойства Readonly типа Boolean, при установке которого в значение True из­менение записей запрещается. По умолчанию свойство Readonly имеет значе­ние False, и набор данных можно модифицировать.

(_____ ЗамечаниеJ

Значение свойства Readonly можно изменять только у закрытого набора данных.

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

Возможность модификации набора данных Query определяет свойство RequestLive типа Boolean. По умолчанию это свойство имеет значение False, и набор данных Query доступен только для чтения. Чтобы получить разрешение визуально и программно редактировать записи, свойство RequestLive нужно


Глава 7. Навигационный доступ к данным с помощью BDE


207


установить в значение True. Кроме этого свойства, возможность изменения на­бора Query зависит также от содержания SQL-запроса. Например, если при запросе отбираются записи из нескольких таблиц, то набор данных не может быть модифицируемым, и значение True свойства RequestLive не учитывается.

Для проверки, можно ли изменять набор данных, предназначено свойство CanModify типа Boolean, действующее при выполнении приложения и доступ­ное только для чтения. Если это свойство имеет значение True, то набор дан­ных изменять можно, а если False, то изменения в наборе данных запрещены, и любая попытка сделать это визуально или программно вызовет исключение.

(_____ ЗамечаниеJ

Можно запретить редактирование отдельных полей набора данных даже в том слу­чае, если он является модифицируемым.

Для программного изменения набора данных вызываются соответствующие ме­тоды, например, метод Edit редактирования текущей записи или метод Append вставки новой записи.

Пользователь редактирует набор данных с помощью визуальных компонентов, например, редактора DBEdit или сетки DBGrid, управляя ими с помощью мыши и клавиатуры. Набор данных может автоматически переводиться в режимы редак­тирования или вставки, для этого свойство AutoEdit источника данных DateSource для визуальных компонентов должно быть установлено в значение True (по умолчанию). Если это свойство установить в значение False, то пользо­ватель не сможет изменять набор данных с помощью визуальных компонентов.

(_____ ЗамечаниеJ

Свойство AutoEdit влияет на визуальные компоненты, подключенные к источнику данных DateSource, и не оказывает никакого влияния на другие элементы управ­ления, такие как, например, кнопка Button или флажок CheckBox.

При модификации набора данных для связанного с ним источника данных DateSource генерируется событие OnUpdateData.

После модификации набора данных возможна ситуация, когда изменения сде­ланы, но не отображены визуальными компонентами, связанными с этим набо­ром. В таких случаях нужно вызывать метод Refresh, который повторно считы­вает набор данных и тем самым гарантирует, что визуальные компоненты будут отображать текущие, а не устаревшие данные. При работе в многопользователь­ской системе рекомендуется периодически вызывать метод Refresh, чтобы своевременно учитывать изменения, сделанные другими пользователями.

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


208


Часть II. Технологии доступа к данным


Компоненты Table обоих наборов могут находиться в разных формах. После редактирования списка клиентов следует обновить оба набора данных, в про­тивном случае возможна ситуация, когда данные о новом клиенте не будут дос­тупны для ввода в накладную. Вот фрагмент кода, в котором проводится обнов­ление набора данных:

Tablel.Edit;

Tablel.FieldByName('Name').AsString:=Editl.Text;

Tablel.Post;

Tablel.Refresh;

Form2.Table2.Refresh;

В этом примере при программном изменении набора данных Tablel, находяще­гося в форме Forml, обновляется он сам, а также набор данных ТаЫе2, распо­ложенный в форме Form2. Оба набора связаны с одной и той же физической таблицей. В модуле формы Forml должна быть ссылка на модуль формы Form2.

Редактирование записей

Редактирование записей заключается в изменении значений их полей. Отредак­тирована может быть только текущая запись, поэтому перед действиями, свя­занными с редактированием, обычно выполняются операции поиска и переме­щения на требуемую запись. После того как указатель текущей записи установлен на нужную запись, и набор данных находится в режиме просмотра, для редактирования записи следует:

1. Перевести набор данных в режим редактирования.

2. Изменить значения полей записи.

3. Подтвердить сделанные изменения или отказаться от них, в результате чего набор данных снова перейдет в режим просмотра.

Набор данных переводится в режим редактирования вызовом метода Edit, при этом возможны такие ситуации:

□ если набор данных немодифицируемый, то возбуждается исключение;

□ если набор данных уже находился в режиме редактирования или вставки, то никакие действия не выполняются;

□ если набор данных пуст, то он переходит в режим вставки.

Если набор данных является модифицируемым и исключение не возбуждается, то при выполнении метода Edit производятся следующие действия:

1. Для набора данных вызывается обработчик события BeforeEdit типа TdataSetNotifyEvent.

2. Из набора данных заново считывается текущая запись и блокируется так, чтобы другие пользователи могли ее читать, но не могли изменять или бло­кировать. Если операция блокирования завершается неудачно, например, в случае, когда запись уже редактирует другой пользователь, то генерируется


Глава 7. Навигационный доступ к данным с помощью BDE 209

исключение, а выполнение метода Edit прекращается. Возникшее на этом шаге исключение можно обработать с помощью обработчика события

OnEditError типа TDataSetErrorEvent, если он назначен.

3. Если в записи есть вычисляемые поля, то они пересчитываются.

4. Набор данных переходит в режим редактирования.

5. Для связанного с набором данных источника данных DataSource вызывается обработчик события OnDataChange.

6. Для набора данных вызывается обработчик события AfterEdit типа TDataSetNotifyEvent.

Указанные действия осуществляются только для модифицируемого набора дан­ных, поэтому перед вызовом метода Edit следует выполнять проверку на возмож­ность редактирования записи (например, путем анализа свойства CanModify). На­пример:

if Tablel.CanModify then Tablel.Edit;

Пользователь осуществляет управление набором данных с помощью располо­женных в форме элементов как связанных, так и не связанных с набором. Для отдельных визуальных компонентов, связанных с набором данных, переход в режим редактирования происходит различными способами. Например, для ком­понентов DBGrid и DBEdit надо сделать двойной щелчок на нужном поле или нажать алфавитно-цифровую клавишу, когда курсор находится в этом поле, а для компонента DBNavigator требуется нажать кнопку Edit Record. Таким обра­зом, при управлении визуальными компонентами метод Edit вызывается поль­зователем косвенно. В случае, когда набор данных является немодифицируе-мым, блокировка перехода в режим его редактирования выполняется автоматически и не приводит к ошибке.

Для компонентов управления, не связанных с набором данных, например, кно­пок Button или флажков checkBox программист должен самостоятельно коди­ровать действия по предотвращению попыток редактирования немодифицируе-мого набора данных. Вот пример осуществления такой блокировки:

procedure TForml.btnEditClick(Sender: TObject);

begin

if not Tablel.CanModify then begin

Beep;

MessageDlg('Редактирование запрещено!', mtlnformation, [mbOK], 0);

exit;

end; Tablel.Edit; end;

Здесь переход в режим редактирования осуществляется при нажатии кнопки btnEdit, которая может иметь заголовок Редактировать или Edit. Перед перево­дом в этот режим выполняется проверка, можно ли изменять записи набора


210


Часть II. Технологии доступа к данным


данных Table 1, и если нет, то процедура выдает соответствующее сообщение и завершается.

Другой способ предотвратить редактирование — заблокировать элементы управ­ления, для которых в настоящий момент времени невозможно выполнить обра­ботчики событий. Рассмотрим в качестве примера следующую процедуру:

procedure TForml. cbEditBanClick(Sender: TObject);

begin

if cbEditBan.Checked then begin

Tablel.Active:= False;

Tablel.Readonly:= True;

btnEdit.Enabled:= False;

Tablel.Active:= True;

end

else begin

Tablel.Active:= False;

Tablel.Readonly:= False;

btnEdit.Enabled:= True;

Tablel.Active:= True;

end; end;

В ней флажок cbEditBan (с возможным заголовком Редактирование запрещено) указывает, допустимо ли изменять записи набора данных Tablel. Если этот флажок установлен, то модификация набора данных запрещается, при этом также блокируется кнопка btnEdit вызова метода Edit.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: