При разработке внешних обработок заполнения документов в среде управляемого приложения часто возникает необходимость предупредить пользователя о перезаписи или очистке уже заполненной табличной части. Однако при использовании серверных команд обработка выполняется полностью в контексте сервера, где интерактивные методы взаимодействия с пользователем недоступны.
Разберем, как правильно организовать архитектуру внешней обработки заполнения по стандартам БСП (Библиотеки стандартных подсистем), чтобы перед заполнением проверить табличную часть и при необходимости задать немодальный вопрос пользователю, не открывая лишних визуальных окон.
Если команда заполнения должна взаимодействовать с пользователем (задавать вопросы, выдавать предупреждения, проверять состояние элементов формы документа), в функции регистрации внешней обработки необходимо использовать вариант запуска ВызовКлиентскогоМетода вместо ВызовСерверногоМетода или ЗаполнениеФормы.
Рассмотрим структуру функции регистрации в модуле объекта внешней обработки:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();
ПараметрыРегистрации.Версия = "1.0";
ПараметрыРегистрации.Назначение.Добавить("Документ.РеализацияТоваровУслуг");
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = "Заполнить табличную часть";
НоваяКоманда.Идентификатор = "ЗаполнитьТЧ";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода();
НоваяКоманда.ПоказыватьОповещение = Истина;
Возврат ПараметрыРегистрации;
КонецФункции
В платформе «1С:Предприятие 8.3» на управляемых формах исполняемый клиентский контекст во внешних обработках привязан к форме. В модуле объекта объявлять клиентские процедуры с директивой &НаКлиенте нельзя. Поэтому для обработки необходимо добавить основную форму.
Важный нюанс: создавать элементы управления и визуально открывать форму пользователю не требуется. БСП при вызове клиентской команды создает экземпляр формы обработки в памяти, вызывает стандартную экспортную процедуру ВыполнитьКоманду и после завершения уничтожает объект.
Разберем по шагам, как построить алгоритм в модуле созданной формы обработки:
ВладелецФормы.Посмотрим на реализацию с использованием метода ПоказатьВопрос и описания оповещения:
&НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначенияМассив) Экспорт
Если ИдентификаторКоманды = "ЗаполнитьТЧ" Тогда
// Проверяем заполненность ТЧ документа на клиенте через форму-владелец
Если ВладелецФормы.Объект.Товары.Количество() > 0 Тогда
Оповещение = Новый ОписаниеОповещения("ПослеОтветаНаВопрос", ЭтотОбъект, ОбъектыНазначенияМассив);
ТекстВопроса = "Табличная часть уже заполнена. Текущие данные будут перезаписаны. Продолжить?";
ПоказатьВопрос(Оповещение, ТекстВопроса, РежимДиалогаВопрос.ДаНет, 0, КодВозвратаДиалога.Нет);
Иначе
// Табличная часть пустая - выполняем заполнение сразу
ВыполнитьЗаполнение(ОбъектыНазначенияМассив);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПослеОтветаНаВопрос(РезультатВопроса, ДополнительныеПараметры) Экспорт
Если РезультатВопроса = КодВозвратаДиалога.Да Тогда
ВыполнитьЗаполнение(ДополнительныеПараметры);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ВыполнитьЗаполнение(ОбъектыНазначенияМассив)
// Вызов серверного метода заполнения
ЗаполнитьТабличнуюЧастьНаСервере();
// Оповещаем пользователя об успешном завершении
ПоказатьОповещениеПользователя("Заполнение ТЧ", , "Табличная часть успешно заполнена!");
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьТабличнуюЧастьНаСервере()
// Логика подбора данных и переноса в контекст ВладелецФормы.Объект
КонецПроцедуры
В современных версиях платформы 1С (начиная с 8.3.18) доступна работа с асинхронными функциями через конструкцию Ждать и метод ВопросАсинх. Это позволяет избавиться от процедур обратного вызова и писать линейный код:
&НаКлиенте
Асинх Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначенияМассив) Экспорт
Если ИдентификаторКоманды = "ЗаполнитьТЧ" Тогда
Если ВладелецФормы.Объект.Товары.Количество() > 0 Тогда
Текст = "Табличная часть содержит данные. Очистить и перезаполнить?";
Ответ = Ждать ВопросАсинх(Текст, РежимДиалогаВопрос.ДаНет, 0, КодВозвратаДиалога.Нет);
Если Ответ <> КодВозвратаДиалога.Да Тогда
Возврат;
КонецЕсли;
КонецЕсли;
ЗаполнитьТабличнуюЧастьНаСервере();
ПоказатьОповещениеПользователя("Готово", , "Данные успешно обновлены.");
КонецЕсли;
КонецПроцедуры
Таким образом, для реализации диалога очистки табличной части достаточно переключить команду на клиентский вызов и разместить обработчик в модуле пустой формы обработки. Пользователь не увидит окна самой обработки, получив только стандартный диалог подтверждения.