notify

Передача описания оповещения

Режим отказа от модальности в 1С, помимо очевидных преимуществ в виде поддержки веб-клиента, нередко усложняет тривиальные ранее действия. Одной из таких задач является проверка записи (и вопрос пользователю только в случае отрицательного результата проверки) — с последующим выполнением действием над объектом. Рассмотрим её решение через такой механизм, как передача описания оповещения в метод и использование конструкции ВыполнитьОбработкуОповещения().
Итак, у нас есть некий объект конфигурации (например, справочник). Выполнять действия над ним в форме стоит только тогда, когда есть уверенность, что объект записан в базу. Если же это не так — мы спросим пользователя, согласен ли он записать объект, а после продолжим исполнение. Важно, что в случае успешной проверки, работа не должна прерываться.

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

Что-то вроде

Если ПроверитьИЗаписатьОбъект() Тогда КонецЕсли;

Идея состоит в том, чтобы вызывать метод проверки, передавая ему нужный callback, в котором уже размещён специфический алгоритм для данной ситуации.

Для начала, опишем наш алгоритм в виде callback-завершения оповещения:

&НаКлиенте
Процедура МояКоманда_Завершение(Результат, ДополнительныеПараметры) Экспорт
    Если ОбработатьРезультатЗапись(Результат) Тогда
        ОткрытьФорму("Справочник.Номенклатура.Форма", Новый Структура("МойПараметр", Истина));
    Иначе
        // Не требуется выполнения действий.
    КонецЕсли;
КонецПроцедуры

Использоваться он будет из основной команды МояКоманда. Команда содержит описание оповещения, в котором указана ссылка на наш алгоритм, и которое будет передано в качестве параметра нашей универсальной функции проверки записи:

&НаКлиенте
Процедура МояКоманда(Команда)
    ОписаниеОповещениеЗапись = Новый ОписаниеОповещения("МояКоманда_Завершение", ЭтотОбъект);
    ЗаписатьСПроверкой(ОписаниеОповещениеЗапись);
КонецПроцедуры

Функция задаёт вопрос пользователю, если объект не записан (т.е. его форма имеет флаг модифицированности):

// Проверяет форму на модифицированность. В случае модифицированности
// предлагает перезаписать объект. После чего выполняет обработчик
// из описания ОписаниеВход.
&НаКлиенте
Процедура ЗаписатьСПроверкой(ОписаниеВход)
    Если Параметры.Ключ.Пустая() ИЛИ Модифицированность Тогда
        ТекстВопроса = НСтр("ru = 'Объект еще не записан. Записать?'");
        ПоказатьВопрос(ОписаниеВход, ТекстВопроса, РежимДиалогаВопрос.ДаНет, 30);
    Иначе
        ВыполнитьОбработкуОповещения(ОписаниеВход, Неопределено);
    КонецЕсли;    
КонецПроцедуры

Здесь самым интересным является метод ВыполнитьОбработкуОповещения(). Он позволяет вызвать callback-метод, содержащийся в описании оповещения, из произвольного места кода. В нашем случае это требуется, чтобы исполнить алгоритм в случае, когда объект не был модифицирован, и вопрос пользователю задавать не нужно (т.к. дополнительной записи объекта не происходит).

Остаётся лишь решить, что делать с самим объектом в зависимости от ответа пользователя:
// Выполняет перезапись в зависимости от результата выбора пользователя
// РезультатВход. Возвращает флаг возможности выполнения дальнейших операций.
&НаКлиенте
Функция ОбработатьРезультатЗапись(РезультатВход)
    РезультатФункции = Истина;
    Если РезультатВход = КодВозвратаДиалога.Да Тогда
        Записать();
        РезультатФункции = Истина;
    ИначеЕсли РезультатВход = КодВозвратаДиалога.Нет Тогда    
        РезультатФункции = Ложь;            // Пользователь отказался от выполнения.
    ИначеЕсли РезультатВход = Неопределено Тогда    
        РезультатФункции = Истина;            // Непосредственный вызов. Выполняем далее без перезаписи.
    Иначе
        ТекстСообщения = НСтр("ru = 'Выбрано неизвестное значение: %ВыбранноеЗначение%. Операция отменена.'");
        ТекстСообщения = СтрЗаменить(ТекстСообщения, "%ВыбранноеЗначение%", Строка(РезультатВход));
        ОбщегоНазначенияУХ.СообщитьОбОшибке(ТекстСообщения);
        РезультатФункции = Ложь;            // Т.к. возникла ошибка.
    КонецЕсли;
    Возврат РезультатФункции;
КонецФункции

Таким образом, мы получаем универсальную функцию ЗаписатьСПроверкой(), которая проверит запись объекта, задаст вопрос пользователю о согласии с записью, а после вызовет исполнение некоего алгоритма.

Проиллюстрирую вышесказанное на схеме:

PS. Спасибо Даниле за идею.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *