Встала задача - перед записью документа произвести некоторые проверки и задать вопрос пользователю, в зависимости от ответа - провести документ или нет.
Все бы хорошо, но логика не модальных диалогов приводит нас к тому, что вопрос еще не отвечен, а процедура, вызвавшая ее, уже завершила свою работу.
Есть несколько вариантов решения, один - это замена стандартных команд своими, второй использование дополнительных переменных и повторный вызов процедуры.
//Объявляем ряд глобальных переменных в контексте клиента
//Пока переменные не переопределены их значение равно - Неопределено
&НаКлиенте
Перем ОтказатьВПроведении;
&НаКлиенте
Перем глПараметрыЗаписи;
&НаКлиенте
Процедура Расш1_ПередЗаписьюПеред(Отказ, ПараметрыЗаписи)
Если ПараметрыЗаписи.РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
глПараметрыЗаписи=ПараметрыЗаписи;
Если ОтказатьВПроведении=Неопределено Тогда
ДиалогСВопросом();
Отказ=Истина; // завершаем работу процедуры в самом ее зачатке
Иначе
Отказ=ОтказатьВПроведении;
ОтказатьВПроведении=Неопределено;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ДиалогСВопросом()
Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияВопроса",ЭтотОбъект);
ПоказатьВопрос(Оповещение,Строка("Вы уверены что хотите провести отгрузку?"),
РежимДиалогаВопрос.ДаНет,0,КодВозвратаДиалога.Да,"Отгрузить товар?");
КонецПроцедуры
&НаКлиенте
Процедура ПослеЗакрытияВопроса(Результат, Параметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
ОтказатьВПроведении=Ложь;
Иначе
ОтказатьВПроведении=Истина;
КонецЕсли;
Записать(глПараметрыЗаписи);
КонецПроцедуры
Вся мысль заключается в следующем:
После нажатия кнопки провести проверяется переменная ОтказатьВПроведении, если она равна неопределено, тогда вопрос еще не задавался запускаем выполнение процедур вопроса и ставим отказ в истину, чтобы документ не провелся. В процедуре после вопроса формируются новые значения переменной ОтказатьВПроведении (на этот момент ПередЗаписью уже завершился), и в конце снова запускаем запись с параметрами проведения. Переменная ОтказатьВПроведении уже имеет значение отличное от Неопределено, значит вопрос задавался, выполняем дальше процедуры/функции сообразуясь с ответом пользователя. Незабываем очистить переменную ОтказатьВПроведении.
После нажатия кнопки провести проверяется переменная ОтказатьВПроведении, если она равна неопределено, тогда вопрос еще не задавался запускаем выполнение процедур вопроса и ставим отказ в истину, чтобы документ не провелся. В процедуре после вопроса формируются новые значения переменной ОтказатьВПроведении (на этот момент ПередЗаписью уже завершился), и в конце снова запускаем запись с параметрами проведения. Переменная ОтказатьВПроведении уже имеет значение отличное от Неопределено, значит вопрос задавался, выполняем дальше процедуры/функции сообразуясь с ответом пользователя. Незабываем очистить переменную ОтказатьВПроведении.
UP 21/05/2022
Был много удивлен, увидев свой пост на этот вопрос заданный мной в гугле, но даже при этом я не удовлетворился описанным методом и упростил его использовав ПараметрыЗаписи:
ПередЗаписью (BeforeWrite)
Синтаксис:
ПередЗаписью(<Отказ>, <ПараметрыЗаписи>)Параметры:
Тип: Булево.<Отказ>
Признак отказа от записи. Если в теле процедуры-обработчика установить данному параметру значение Истина, запись выполнена не будет и будет вызвано исключение.
Значение по умолчанию: Ложь.Тип: Структура.<ПараметрыЗаписи>
Структура, содержащая параметры записи. Для формы документа существует два предопределенных параметра - РежимЗаписи и РежимПроведения. Они добавляются автоматически при вызове команд "Провести", "Провести и закрыть", "Отмена проведения".
Параметр РежимПроведения может отсутствовать, если режим проведения в документе не определен.
//НЕ Объявляем ряд глобальных переменных в контексте клиента
&НаКлиенте
Процедура Расш1_ПередЗаписьюПеред(Отказ, ПараметрыЗаписи)
Если ПараметрыЗаписи.РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
Если ПараметрыЗаписи.Свойство("ОтказатьВПроведении") Тогда
ДиалогСВопросом();
Отказ=Истина; // завершаем работу процедуры в самом ее зачатке
Иначе
Отказ=ПараметрыЗаписи.ОтказатьВПроведении;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ДиалогСВопросом()
Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияВопроса",ЭтотОбъект);
ПоказатьВопрос(Оповещение,Строка("Вы уверены что хотите провести отгрузку?"),
РежимДиалогаВопрос.ДаНет,0,КодВозвратаДиалога.Да,"Отгрузить товар?");
КонецПроцедуры
&НаКлиенте
Процедура ПослеЗакрытияВопроса(Результат, Параметры) Экспорт
ПараметрыЗаписи=Новый Структура;
ПараметрыЗаписи.Вставить("ОтказатьВПроведении",Результат = НЕ КодВозвратаДиалога.Да);
Записать(ПараметрыЗаписи);
КонецПроцедуры
Здесь логика почти такая же, но переменная ОтказатьВПроведнии превращается в свойство стандартной структуры ПараметрыЗаписи, что уменьшает код и улучшает его читаемость.
Сейчас столкнулся с такой задачей, решение в голову пришло такое же. Но есть одна проблема: мы не можем отследить нажал пользователь кнопку "Провести и закрыть" или просто "Провести". Можно, конечно, не закрывать, но у пользователей сразу возникнет большое количество вопросов: "Почему я нажал "Закрыть", но ничего не закрылось".
ОтветитьУдалитьХм, интересная мысль. Нет возможности сейчас проверить
ОтветитьУдалить