Здравия всем!
Такой вопрос. Может баян, но я как-то не нашёл решения.
Есть элемент справочника. Перед записью производится проверка значения номера. Если найден недопустимый символ в реквизите, то задаётся вопрос() "В номере содержится недопустимый символ! Продолжить?".
Всё просто. Но суть в том, что сейчас нужно изменить Вопрос() на ПоказатьВопрос(). А специфика подразумевает, что мне нужно отменить запись, задать вопрос, а в функции обработки результата при положительном ответе записать программно элемент справочника.
Вопрос вот в чем. Пользователь мог нажать "Записать" и "Записать и закрыть". Как определить какую команду он вызвал и нужно ли мне закрывать текущую форму после записи?
В обработчике события формы ПередЗаписью также может возникнуть потребность задать вопрос. Как и в предыдущем примере. Однако здесь вопрос так просто не решается. Отличие заключается в следующем.
В предыдущем примере, оказываясь в обработчике ПередЗакрытием, мы однозначно знали действие, которое должно быть выполнено. Это закрытие формы. Поэтому в обработке оповещения мы смело писали Закрыть().
Но в обработчике ПередЗаписью мы такой однозначной информации не имеем. В этом обработчике мы можем оказаться по двум причинам: если пользователь нажал Записать, или если он нажал Записать и закрыть. То есть дальнейший сценарий действий нам неизвестен. Определить его стандартными способами, находясь внутри этого обработчика, мы не можем.
Поэтому тут можно предложить три варианта, но все они, к сожалению, обладают недостатками:
Изменить логику прикладного решения так, чтобы не было диалога с пользователем в этом обработчике. Это не всегда возможно;
В обработке оповещения с помощью собственной блокирующей формы задавать пользователю развернутый вопрос, предполагающий точное описание дальнейших действий: Отказаться?, Только записать?, Записать и закрыть? Это может выглядеть не очень красиво, ведь пользователь уже нажал "Записать и закрыть", а его опять об этом спрашивают;
Не использовать стандартные команды формы Записать, "Записать и закрыть". Вместо них создать собственные команды, в которых и выполнять необходимые алгоритмы. Создание собственных команд потребует дополнительных трудозатрат.
(1) SeiOkami, можно поступить так: Добавить реквизит формы ФлагВопроса - Булево. В ПередЗаписью поставить вашу проверку, которая будет отрабатывать пока ФлагВопроса = Ложь. В случае если найдены недопустимые символы выставляем Отказ в истину, реквизит ФлагВопроса в Истину и вызываем ваш ПоказатьВопрос, в обработчике оповещения которого в случае ответа "Да" вы вызовите запись повторно.
Чуть позже выложу код.
(2), прочтите внимательнее, пожалуйста, вопрос. Проблема не в том, как спросить пользователя. И не в том как записать. А в том, как определить, закрывать форму после записи, аль нет.
В обработчике события формы ПередЗаписью также может возникнуть потребность задать вопрос. Как и в предыдущем примере. Однако здесь вопрос так просто не решается. Отличие заключается в следующем.
В предыдущем примере, оказываясь в обработчике ПередЗакрытием, мы однозначно знали действие, которое должно быть выполнено. Это закрытие формы. Поэтому в обработке оповещения мы смело писали Закрыть().
Но в обработчике ПередЗаписью мы такой однозначной информации не имеем. В этом обработчике мы можем оказаться по двум причинам: если пользователь нажал Записать, или если он нажал Записать и закрыть. То есть дальнейший сценарий действий нам неизвестен. Определить его стандартными способами, находясь внутри этого обработчика, мы не можем.
Поэтому тут можно предложить три варианта, но все они, к сожалению, обладают недостатками:
Изменить логику прикладного решения так, чтобы не было диалога с пользователем в этом обработчике. Это не всегда возможно;
В обработке оповещения с помощью собственной блокирующей формы задавать пользователю развернутый вопрос, предполагающий точное описание дальнейших действий: Отказаться?, Только записать?, Записать и закрыть? Это может выглядеть не очень красиво, ведь пользователь уже нажал "Записать и закрыть", а его опять об этом спрашивают;
Не использовать стандартные команды формы Записать, "Записать и закрыть". Вместо них создать собственные команды, в которых и выполнять необходимые алгоритмы. Создание собственных команд потребует дополнительных трудозатрат.
Сталкивался с подобной задачей.
Мне предлагали убрать кнопку "Записать и закрыть" и оставить только "Записать" и "Закрыть".
И в вашем случае для "закрыть" свой обработчик
что мешает добавить пару реквизитов ДалиОтвет и КодВозврата формы,
проверять потом в ПриЗаписи на клиенте в цикле ДалиОтвет и делать отказ если отказались?
&НаКлиенте
Перем ВыполняетсяЗакрытие;
&НаКлиенте
Перем _МодифицированностьФормы;
&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
Если Модифицированность Тогда
_МодифицированностьФормы = Истина;
//При закрытии форма этого вопроса оказывается под формой вопроса вызваной из ПередЗакрытием и закрывается вместе с формой
Режим = РежимДиалогаВопрос.ДаНет;
Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияВопроса", ЭтаФорма, "ПередЗаписью");
ПоказатьВопрос(Оповещение, НСтр("ru = 'Обновить значения?';"), Режим, 0);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
Если _МодифицированностьФормы
И НЕ ВыполняетсяЗакрытие Тогда
Отказ = Истина;
Режим = РежимДиалогаВопрос.ДаНет;
Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияВопроса", ЭтаФорма, "ПередЗакрытием");
ПоказатьВопрос(Оповещение, НСтр("ru = 'Обновить значения?';"), Режим, 0);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПослеЗакрытияВопроса(Результат, Параметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
Объект.ДатаОбновления = ТекущаяДата();
Записать();
Если Параметры = "ПередЗакрытием" Тогда
ВыполняетсяЗакрытие = Истина;
Закрыть();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
ВыполняетсяЗакрытие = Ложь;
_МодифицированностьФормы = Ложь;
Приведу пример с проведением документа, та же самая задача - в событии ПередЗаписью узнать что форма будет закрываться. Пример является наброском и требует более внимательной проработки кода написанного в обработчике события.
1. В форме необходимо добавить команду "ПровестиИЗакрыть", ее свойства должны быть максимально схожи с оригинальной командой (Синоним, картинки, подписи и т.д.). Кнопку при этом создавать не нужно.
2. Описать действия на данную команду. Примерно такие:
&НаКлиенте
Процедура ПровестиИЗакрыть(Команда)
ПровестиДокумент(Истина, Истина);
КонецПроцедуры
&НаКлиенте
Процедура ПровестиДокумент(ЗакрыватьПослеПроведения = Истина, ЗадаватьВопрос = Истина)
сткПараметры = Новый Структура();
сткПараметры.Вставить("ПослеЗаписиЗакрытьФорму", ЗакрыватьПослеПроведения);
сткПараметры.Вставить("ЗадаватьВопрос", ЗадаватьВопрос);
сткПараметры.Вставить("РежимЗаписи", РежимЗаписиДокумента.Проведение);
сткПараметры.Вставить("РежимПроведения", РежимПроведенияДокумента.Неоперативный);
Результат = ЭтотОбъект.Записать(сткПараметры);
Если Результат и ЗакрыватьПослеПроведения Тогда
Закрыть();
КонецЕсли;
КонецПроцедуры
Показать
3. При создании формы на сервере у стандартной кнопки переопределить действие
4. Теперь в событие ПередЗаписью, вы получите необходимые свойства в параметрах. И можете уже обрабатывать вопрос согласно рекомендаций от 1С. Можно аналогичную команду создать и для кнопки Провести
Естественно при создании формы на сервере необходимо проконтролировать, что пользователь может выполнять данные действия.
&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
Если Не ПараметрыЗаписи.Свойство("ВопросУжеЗадан") Тогда
Отказ = истина;
Оповещение = Новый ОписаниеОповещения(
"ПередЗаписьюЗавершение",
ЭтотОбъект,ПараметрыЗаписи);
ПоказатьВопрос(Оповещение, "Документ будет записан, продолжить?", РежимДиалогаВопрос.ДаНет);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПередЗаписьюЗавершение(Результат, Параметры) ЭКСПОРТ
Если Результат = КодВозвратаДиалога.Да Тогда
Параметры.Вставить("ВопросУжеЗадан",Истина);
Записать(Параметры);
КонецЕсли;
КонецПроцедуры