Как в процедуре ПриСозданииНаСервере вывести сообщение и привязать его к форме

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

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

Почему сообщение не привязывается к форме автоматически?

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

Способ 1: Использование ИдентификатораНазначения

Наиболее «чистый» с точки зрения архитектуры способ — это использование свойства ИдентификаторНазначения объекта СообщениеПользователю. Этот идентификатор позволяет платформе понять, какому именно окну адресовано сообщение. В качестве значения мы должны передать уникальный идентификатор текущей формы.

Разберем по шагам, как это реализовать в коде:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = "Добро пожаловать в форму! Пожалуйста, проверьте данные.";
    
    // Привязываем сообщение к текущей форме через ее уникальный идентификатор
    Сообщение.ИдентификаторНазначения = ЭтаФорма.УникальныйИдентификатор;
    
    Сообщение.Сообщить();
    
КонецПроцедуры

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

Способ 2: Привязка к пути к данным (самый надежный метод)

Если нам нужно не просто вывести текст, а подсветить конкретное поле или привязать сообщение к объекту (например, к документу или справочнику), мы используем метод УстановитьДанные(). Платформа 1С устроена так, что если сообщение связано с путем к данным, которые отображаются на форме, оно автоматически «прилипает» к этой форме и выводится в ее панели сообщений.

Рассмотрим пример, где сообщение привязывается к основному реквизиту Объект:


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

Проанализируем ситуацию: когда мы используем УстановитьДанные(Объект), платформа ищет форму, которая редактирует этот объект, и выводит сообщение именно там. Это самый эффективный способ избежать «всплытия» сообщений в главном окне.

Способ 3: Передача флага на клиент через параметры или реквизиты

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

Разберем этот алгоритм:

  1. Создадим вспомогательный реквизит формы ТекстСообщенияПриОткрытии (тип Строка).
  2. В процедуре ПриСозданииНаСервере заполним этот реквизит.
  3. В процедуре ПриОткрытии проверим реквизит и выведем сообщение.

Пример кода на сервере:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Логика проверки
    Если Объект.Сумма = 0 Тогда
        ЭтаФорма.ТекстСообщенияПриОткрытии = "Не забудьте указать сумму документа!";
    КонецЕсли;
КонецПроцедуры

Пример кода на клиенте:


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

Этот подход хорош тем, что в момент выполнения ПриОткрытии окно формы уже гарантированно существует и является активным, поэтому сообщение будет выведено корректно.

Способ 4: Использование декораций и надписей

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

Разберем, как это сделать:

  1. Добавим на форму элемент ИнформационнаяНадпись.
  2. Установим ему свойство ЦветТекста (например, Красный) и сделаем его по умолчанию невидимым.
  3. В процедуре ПриСозданииНаСервере будем управлять его видимостью и текстом.

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    Если Объект.Статус = Перечисления.СтатусыДокументов.Заблокирован Тогда
        Элементы.ИнформационнаяНадпись.Заголовок = "ВНИМАНИЕ: Редактирование запрещено!";
        Элементы.ИнформационнаяНадпись.Видимость = Истина;
    Иначе
        Элементы.ИнформационнаяNadpis.Видимость = Ложь;
    КонецЕсли;
    
КонецПроцедуры

Такой способ исключает риск того, что сообщение «улетит» в другое окно, так как текст является частью самой формы.

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

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

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

← На главную