#delphi #tadodataset
#delphi #tadodataset
Вопрос:
Я использую Dephi 10.1 Berlin и Access 2013.
Моя проблема связана с TADODataSet.Cancel()
.
Я хочу показать моему пользователю окно сообщения с запросом подтверждения перед публикацией, в случае, если данные были изменены.
В этом TADODataSet.BeforePost
случае я добавил следующий код:
if Application.MessageBox('Save changes?', '', 52) = idNo then
ADODataSet1.Cancel;
Если пользователь нажмет на btnNo
, произойдет что-то неожиданное.
Изменения отменяются из текущей записи, но создается новая запись со всеми пустыми полями.
Единственное поле с некоторыми данными — это поле, которое было ранее изменено пользователем.
Если я отменю изменение с помощью кнопки отмены TDBNavigator
, все будет в порядке.
Если я имитирую нажатие кнопки отмены TDBNnavigator
в BeforePost
событии:
if Application.MessageBox('Save changes?', '', 52) = idNo then
DBNavigator1.BtnClick(nbCancel);
У меня такое же поведение, поэтому создается новая пустая запись.
Есть предложения?
Комментарии:
1. Вы перемещаетесь с помощью клавиши со стрелкой вниз? Если да, то в конце сетки обычно создается новая запись…
2. idNo и mrNo, похоже, работают одинаково
Ответ №1:
В справке для TADODataSet.BeforePost частично говорится:
вызовите Abort, чтобы отменить операцию Post (Delphi) или вызвать исключение (C ).
Итак:
if Application.MessageBox('Save changes?', '', 52) = idNo then
abort;
Обратите внимание, что это предназначено для предотвращения публикации изменений, которые не проходят проверку (обычно используется для публикации перед публикацией). Он не сбрасывает буферы редактирования, как это делает отмена. Обычно это отдельная функция в пользовательском интерфейсе, поэтому пользователю не нужно повторно вводить все измененные данные при редактировании каждый раз, когда публикация отклоняется вызовом abort в BeforePost .
Комментарии:
1. При прерывании набор данных остается в состоянии редактирования, и изменения не отменяются. При отмене изменения отменяются, и набор данных переводится в состояние просмотра, так что было бы лучше. Я попробовал этот код, и, похоже, он работает: если приложение. MessageBox(‘Сохранить изменения?’, «, 52) = idNo затем запустите dbnavigator1.BtnClick(nbCancel); Прервать; завершить; Таким образом, набор данных переходит в состояние просмотра, а изменения отменяются. На самом деле не очень элегантно, но это работает.
2. Решение с вызовом buttonclick изнутри post, а затем вызовом Abort после этого кажется пугающим. Это нарушает поток событий, и я не удивлюсь, если это сработает случайно и в какой-то момент приведет к странному, сложному для отладки поведению. Я думаю, что лучше задать вопрос, прежде чем вызывать Post в первую очередь, хотя я не уверен, насколько это просто с DBNavigator
3. По крайней мере, вызовите
ADODataSet1.Cancel()
вместоDBNavigator1.BtnClick(nbCancel)
, перед вызовомAbort()
. И на заметку, не используйте магические числа .MB_YESNO or MB_ICONEXCLAMATION
вместо этого используется 52, чтобы смысл кода был более читаемым. Я бы также предложил использовать<> idYes
вместо= idNo
, если диалоговое окно сообщения возвращает сбой:if Application.MessageBox('Save changes?', '', MB_YESNO or MB_ICONEXCLAMATION) <> IDYES then begin ADODataSet1.Cancel; SysUtil.Abort; end;
4. Большое спасибо всем за предложения и комментарии.