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