Как вывести сообщение пользователю в документе, создаваемом на основании?

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

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

В этой статье мы подробно разберем, почему так происходит, и изучим несколько профессиональных способов решения этой проблемы, чтобы сообщения всегда находили своего адресата.

Почему Сообщить() работает «неправильно»?

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

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

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

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

Проанализируем пример кода в модуле документа (процедура ОбработкаЗаполнения):


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

Преимущество этого метода: сообщение «запоминается» платформой и при открытии формы нового документа оно будет выведено либо в нижней части окна, либо (если заполнено свойство Поле) непосредственно возле указанного реквизита.

Способ 2. Передача флага через ДополнительныеСвойства

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

Шаг 1: Записываем информацию в модуле объекта (ОбработкаЗаполнения):


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
    // Выполняем логику заполнения...
    Если УсловиеДляПредупреждения Тогда
        ЭтотОбъект.ДополнительныеСвойства.Вставить("ОшибкаЗаполненияПриСоздании", "Текст сообщения для формы");
    КонецЕсли;
КонецПроцедуры

Шаг 2: Читаем и выводим сообщение в модуле формы нового документа (ПриСозданииНаСервере):


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

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

Способ 3. Передача параметров через форму

Если создание документа инициируется программно (через ОткрытьФорму), мы можем передать сообщение напрямую в параметрах формы. Рассмотрим, как это работает, если вы переопределяете стандартную команду заполнения.

В коде, вызывающем создание документа (например, в форме-основании):


&НаКлиенте
Процедура КомандаСоздатьНаОсновании(Команда)
    
    ПараметрыЗаполнения = Новый Структура;
    ПараметрыЗаполнения.Вставить("Основание", Объект.Ссылка);
    ПараметрыЗаполнения.Вставить("ТекстСообщения", "Проверьте правильность заполнения реквизитов!");
    
    ПараметрыФормы = Новый Структура("ЗначенияЗаполнения", ПараметрыЗаполнения);
    
    ОткрытьФорму("Документ.ВашДокумент.ФормаОбъекта", ПараметрыФормы);
    
КонецПроцедуры

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

Рекомендации по реализации

Выясним, какой из методов лучше выбрать в вашей ситуации:

  1. Если проверка касается конкретного поля: используйте СообщениеПользователю с указанием свойства Поле. Это обеспечит лучшую визуальную связь для пользователя.
  2. Если проверка должна срабатывать при любом виде заполнения: (и на основании, и вручную) — лучше использовать связку ДополнительныеСвойства и модуль формы.
  3. Если вы хотите заблокировать открытие формы: в случае критической ошибки в ОбработкаЗаполнения, установите СтандартнаяОбработка = Ложь и вызовите исключение ВызватьИсключение "Текст ошибки". Это прервет процесс, и сообщение гарантированно отобразится в модальном окне, хотя форма документа при этом не откроется.

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

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

← На главную