Почему во внешней обработке БГУ 2.0 не выводятся сообщения пользователю и как это исправить?

Программист 1С v8.3 (Управляемые формы) Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При разработке внешних дополнительных отчетов и обработок на базе «1С:Библиотеки стандартных подсистем» (БСП), в том числе для конфигурации «Бухгалтерия государственного учреждения 2.0» (БГУ 2.0), разработчики часто сталкиваются с ситуацией, когда процедура успешно отрабатывает при прямом открытии файла через меню «Файл — Открыть», но при подключении через справочник «Дополнительные отчеты и обработки» перестает выводить пользователю информационные сообщения.

Проанализируем причины такого поведения платформы 1С:Предприятие 8.3 в управляемом интерфейсе и рассмотрим правильные варианты реализации вывода сообщений и прерывания некорректных операций.

Выясним причину проблемы

В управляемом приложении вывод сообщений имеет контекстную специфику:

  1. Подавление метода Сообщить() на сервере. Процедура Сообщить() исторически предназначалась для толстого клиента и обычных форм. При выполнении серверной команды БСП (действие с типом «ВызовСерверногоМетода») выполнение происходит в отдельном серверном вызове или фоновом задании. В таких сценариях платформа не гарантирует передачу текстовых потоков от Сообщить() обратно на клиент, и сообщения попросту игнорируются.
  2. Фиксированная сигнатура экспортных методов БСП. Когда обработка вызывается подсистемой дополнительных обработок, платформа обращается к стандартной экспортной процедуре модуля объекта:
    
    Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, СозданныеОбъекты, ПараметрыВыполненияКоманды) Экспорт
    
    Попытка произвольно добавить в эту процедуру собственный параметр (например, для передачи массива сообщений) приводит к ошибке «Недостаточно фактических параметров», поскольку вызывающий код общего модуля конфигурации передает строго определенное число аргументов.

Способ 1. Использование объекта «СообщениеПользователю»

Для того чтобы серверные сообщения гарантированно были доставлены пользователю в управляемом интерфейсе, платформа предоставляет объект СообщениеПользователю. Платформа собирает такие объекты во время серверного вызова и отображает их в окне сообщений после завершения процедуры.

Заменим вызов Сообщить() на создание объекта СообщениеПользователю в модуле объекта обработки:


Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения = Неопределено, СозданныеОбъекты = Неопределено, ПараметрыВыполненияКоманды = Неопределено) Экспорт

    Если ИдентификаторКоманды = "СозданиеПринятияКУчетуОС" Тогда
        ВыполнитьПроверкуИСоздание(ОбъектыНазначения);
    КонецЕсли;

КонецПроцедуры

Процедура ВыполнитьПроверкуИСоздание(ОбъектыНазначения)

    // Пример серверной проверки наличия дубликата
    Если ОбъектНайден Тогда
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Основное средство с указанным инвентарным номером уже существует! Запись отменена.";
        // При необходимости можно привязать сообщение к реквизиту
        Сообщение.Поле = "ИнвентарныйНомер";
        Сообщение.Сообщить();
        Возврат;
    КонецЕсли;

    // Дальнейший алгоритм формирования документов
    // ...

КонецПроцедуры

Способ 2. Использование сервисных функций БСП

В конфигурациях, использующих БСП (включая БГУ 2.0), предусмотрен общий модуль ОбщегоНазначенияКлиентСервер, который берет на себя корректную инициализацию сообщений в любом контексте.

Посмотрим на пример использования универсальной функции:


Если РезультатЗапроса.Пустой() Тогда
    ТекстОшибки = "Не найдены данные для формирования документа принятия к учету ОС.";
    ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстОшибки);
    Возврат;
КонецЕсли;

Способ 3. Прерывание операции через «ВызватьИсключение»

Если обнаружение дубликата или некорректных данных делает дальнейшую работу бессмысленной и требует гарантированной отмены всех транзакций, правильным архитектурным решением является вызов исключения. Подсистема БСП перехватывает исключение и выводит понятный диалог ошибки пользователю.

Разберем пример прерывания:


Если НайденДубликат Тогда
    ВызватьИсключение "Операция прервана: обнаружено дублирование основного средства в базе данных.";
КонецЕсли;

Способ 4. Использование клиентской команды с открытием формы

Если требуется интерактивное взаимодействие с пользователем (например, вывод предупреждений через ПоказатьПредупреждение, отображение списка ошибок или запрос подтверждения), серверный вызов не подходит. В этом случае обработку регистрируют как клиентскую.

Разберем по шагам настройку команды в функции СведенияОВнешнейОбработке():

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

Важный вывод: для простых серверных обработок без экранных форм достаточно заменить Сообщить() на Новый СообщениеПользователю или вызов ОбщегоНазначенияКлиентСервер.СообщитьПользователю(). Это сохраняет целостность сигнатуры БСП и гарантирует доставку уведомлений в интерфейс пользователя.

← На главную