Russian Belarusian English German Japanese Ukrainian

Rashka.studio - игры и приложения для Android! Заходи, ждём тебя =)

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

CuBook05

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

  1. Перевести набор данных в режим редактирования.
  2. Изменить значения полей записи.
  3. Подтвердить сделанные изменения или отказаться от них, в результате чего набор данных снова перейдет в режим просмотра.
Набор данных переводится в режим редактирования вызовом метода Edit, при этом возможны такие ситуации:
  • если набор данных немодифицируемый, то возбуждается исключение
  • если набор данных уже находился в режиме редактирования или вставки, то никакие действия не выполняются
  • если набор данных пуст, то он переходит в режим вставки
Если набор данных является модифицируемым и исключение не возбуждается, то при выполнении метода Edit производятся следующие действия:
  1. Для набора данных вызывается обработчик события BeforeEdit типа TDataSetNotifуEvent.
  2. Из набора данных заново считывается текущая запись и блокируется так, чтобы другие пользователи могли ее читать, но не могли изменять или блокировать. Если операция блокирования завершается неудачно, то генерируется исключение, а выполнение метода Edit прекращается.
  3. Если в записи есть вычисляемые поля, то они пересчитываются.
  4. Набор данных переходит в режим редактирования.
  5. Для связанного с набором данных источника данных DataSource вызывается обработчик события OnDataChange.
  6. Для набора данных вызывается обработчик события AfterEdit типа TDataSetNotifyEvent.
Указанные действия осуществляются только для модифицируемого набора данных, поэтому перед вызовом метода Edit следует выполнять проверку на возможность редактирования записи (например путем анализа свойства CanModify). Например:
if(Table1->CanModifу) Table1->Edit();
Пользователь осуществляет управление набором данных с помощью расположенных в форме элементов как связанных, так и не связанных с набором. Для отдельных визуальных компонентов, связанных с набором данных, переход в режим редактирования происходит различными способами. Например, для компонентов DBGrid и DBEdit надо сделать двойной щелчок на нужном поле или нажать алфавитно-цифровую клавишу, когда курсор находится в этом поле, а для компонента DBNavigator требуется нажать кнопку Edit Record. Таким образом, при управлении визуальными компонентами метод Edit вызывается пользователем косвенно. В случае, когда набор данных является немодифицируемым, блокировка перехода в режим его редактирования выполняется автоматически и не приводит к ошибке.
 
Для компонентов управления, не связанных с набором данных, например, кнопок Button или флажков CheckBox, программист должен самостоятельно кодировать действия по предотвращению попыток редактирования немодифицируемого набора данных. Блокировка попыток пользователя изменить немодифицируемый набор данных должна выполняться также при добавлении и удалении записей. При выполнении метода Edit непосредственно перед переводом набора данных в режим редактирования возникает событие BeforeEdit, которое можно использовать для проверки возможности перехода в этот режим. Например, при попытке пользователя редактировать запись ему можно предложить подтвердить свои действия. Для отмены процесса редактирования в обработчике события BeforeEdit можно сгенерировать «тихое» исключение. При переходе в режим редактирования обычно удобнее всего использовать обработчик события BeforeEdit, т.к. оно генерируется при переводе набора данных в режим редактирования любым способом. Например:
void __fastcall TForm1::Table1BeforeEdit(TDataSet *DataSet)
{
if(MessageDlg("Выполнить редактирование?",mtConfirmation,TMsgDlgButtons() << mbYes << mbNo, 0)== mrNo)
Abort();
}
После перевода набора данных в режим редактирования можно с помощью Инструкций присваивания изменять значения полей текущей записи. При
этом нужно учитывать тип поля, выполняя при необходимости операции приведения типов. Например:
Table1->FieldByName("Name")->AsString = Edit1->Text;
Table1->FieldByName("Area")->AsInteger = StrToInt(Edit2->Text);
Перед выполнением приведенных инструкций набор данных Table1 должен находиться в режиме редактирования или вставки. Если редактор Edit2 или Edit3 содержит данные в формате, не соответствующем целому и вещественному числам, то генерируется исключение. Для проверки, вносились ли изменения в запись, можно проанализировать свойство Modified типа bool. Если свойство имеет значение true, то было изменено значение как минимум одного поля текущей записи. После ввода информации сделанные изменения должны быть или подтверждены, или отменены.
 
Метод Post записывает модифицированную запись в таблицу БД, снимает блокировку записи и переводит набор данных в режим просмотра. Если набор данных не находился в режиме редактирования, то вызов метода Post приведет к генерации исключения. Перед его выполнением автоматически вызывается обработчик события BeforePost типа TDataSetNotifyEvent, а сразу после выполнения обработчик события AfterPost типа TdataSetNotifyEvent. Используя событие BeforePost, можно проверить сделанные изменения и при необходимости отменить их, например, прервав выполнение метода с помощью вызова «тихого» исключения.
Например, ниже приведен фрагмент кода, в котором осуществляется редактирование записей:
// Изменение площади в текущей записи
Table1->Edit();
Table1->FieldByName("Area")->AsInteger = StrToInt(Edit2->Text);
Table1->Post();
// Переход к следующей записи
Table1->Next();
Метод Post вызывается автоматически при переходе к другой записи с помощью методов First, Last, Next и Prior, если набор данных находится в режиме редактирования, и изменения в записях не подтверждены. Поэтому в приведенном примере метод Post можно было не вызывать, т.к. сразу после него вызывается метод Next. Однако при использовании методов FindFirst, FindLast, FindNext и FindPrior неподтвержденные изменения в записях будут потеряны.
Пользователь подтверждает сделанные в записях изменения, управляя соответствующими компонентами, явно или неявно вызывающими метод Post. Конкретные действия пользователя зависят от используемых компонентов. Например, при работе с компонентом DBGrid изменения подтверждаются (фиксируются) при переходе к другой записи или нажатии клавиши <Enter>, а в компоненте DBNavigator можно нажать кнопку Post Edit (Подтвердить изменения).
 
Независимо от способа вызова, метод Post может завершиться неудачно, например, если не заданы значения полей, которые не могут быть пустыми, или значение выходит за установленные для него допустимые пределы. В этом случае набор данных обычно возвращается в состояние, которое было до перехода в режим редактирования. При ошибке выполнения метода Post генерируется событие OnPostError типа TDataSetErrorEvent. Кодируя обработчик этого события, можно попытаться исправить ошибку.
 
Метод Cancel отменяет изменения, выполненные в текущей записи, и возвращает набор данных в режим просмотра. При выполнении метода Cancel вызываются обработчики событий BeforeCancel и AfterCancel типа TDataSеtNotifуEvent. Пользователь может отменить сделанные в записях изменения, используя элементы управления компонентов. Например, при работе с сеткой DBGrid изменения отменяются нажатием клавиши <Esc>, а в компоненте DBNavigator нажатием кнопки Cancel Edit.
 
В случае применения механизма транзакций для отмены изменений сразу в нескольких записях можно обратиться к методу RollBack класса TDateBase.
При редактировании текущей записи последовательность инструкций присваивания и вызовов метода Post можно заменить вызовом метода SetFields.
Метод имеет объявление:
void __fastcall SetFields(const System::TvarRec *Values, const int Values_Size);
и устанавливает все или часть значений полей текущей записи. Параметр Values содержит массив значений, которые присваиваются этим полям, при этом порядок значений соответствует порядку полей в наборе данных. Кроме того, должны соответствовать типы полей и типы присваиваемых им значений. Если значений в массиве меньше, чем полей в наборе данных, то эти значения присваиваются первым полям, а оставшиеся поля не изменяются. Если в качестве значения элемента массива задать NULL, то соответствующее поле примет значение 0. Если число значений в массиве превышает число полей, то при выполнении метода SetFields генерируется исключение.
Если для набора данных использовался Редактор полей, то при выполнении метода SetFields учитывается порядок полей, установленный с помощью этого Редактора. В противном случае принимается порядок полей, определенный при создании таблицы БД.
Метод SetFields удобно использовать для изменения значений нескольких полей. После его выполнения набор данных автоматически возвращается в режим просмотра. Пример использования метода SetFields в программе:
Table1->Edit();
Table1->SetFields(ARRAYOFCONST(("Country", "Capital", NULL, NULL, 22222)));
Здесь в первое, второе и пятое поля текущей записи набора данных Table1 заносятся страна, столица и численность населения соответственно. Третье и четвертое поля этой записи принимают значение 0.
Если заметили ошибку, выделите фрагмент текста и нажмите Ctrl+Enter

Добавить комментарий