Как передать параметры или статус из ОбработкаЗаполнения в ПриСозданииНаСервере управляемой формы?

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

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

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

Выясним причину: почему пропадают данные?

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

  1. На сервере создается экземпляр объекта (тип ДокументОбъект).
  2. Вызывается процедура ОбработкаЗаполнения в модуле этого объекта.
  3. Критический момент: после завершения обработки заполнения данные из экземпляра ДокументОбъект копируются (сериализуются) в реквизит управляемой формы (тип ДанныеФормыСтруктура, обычно это реквизит Объект).
  4. Сам экземпляр ДокументОбъект уничтожается.
  5. Вызывается процедура ПриСозданииНаСервере модуля управляемой формы.

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

Рассмотрим подробнее три основных способа, которые позволяют обойти это ограничение.

Способ 1: Использование несохраняемых реквизитов объекта

Это самый простой и эффективный метод, который часто применяется в типовых конфигурациях (УТ 11, ERP 2.5, БП 3.0). Суть метода заключается в том, чтобы обмануть механизм сериализации платформы, заставив её передать нужные нам данные как часть структуры объекта.

Разберем реализацию по шагам:

  1. В дереве конфигурации найдите ваш объект (например, документ РеализацияТоваровУслуг).
  2. Добавьте новый реквизит, назовите его, например, СлужебныйСтатусЗаполнения (тип может быть любым: Число, Булево, Строка).
  3. В свойствах этого реквизита на вкладке Основные снимите галочку Сохранять данные.

Теперь этот реквизит будет существовать в объекте в памяти, будет копироваться в форму, но никогда не будет записан в таблицу базы данных. Посмотрим на пример кода в модуле объекта:


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
    
    // Какая-то логика проверки
    Если ДанныеЗаполнения = Неопределено Тогда
        ЭтотОбъект.СлужебныйСтатусЗаполнения = "НовыйОбъектБезОснования";
    Иначе
        ЭтотОбъект.СлужебныйСтатусЗаполнения = "ЗаполненоНаОсновании";
    КонецЕсли;
    
КонецПроцедуры

Теперь проанализируем, как получить эти данные в модуле управляемой формы:


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

Преимущество метода: полная бесшовность. Вам не нужно заботиться об адресах временных хранилищ или параметрах сеанса.

Способ 2: Использование параметров формы и структуры ЗначенияЗаполнения

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

При вызове ОткрытьФорму мы передаем структуру Параметры, в которой есть специальный ключ ЗначенияЗаполнения.

Пример программного открытия:


ПараметрыЗаполнения = Новый Структура;
ПараметрыЗаполнения.Вставить("ЗапретитьРедактирование", Истина);
ПараметрыЗаполнения.Вставить("СпецРежим", 1);

ПараметрыОткрытия = Новый Структура;
ПараметрыОткрытия.Вставить("ЗначенияЗаполнения", ПараметрыЗаполнения);

ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта", ПараметрыОткрытия);

Посмотрим, что происходит внутри платформы:

  1. В модуле объекта в ОбработкаЗаполнения в параметр ДанныеЗаполнения придет ваша структура.
  2. В модуле формы в ПриСозданииНаСервере эта же структура будет доступна через Параметры.ЗначенияЗаполнения.

Это позволяет "прокинуть" данные сквозь все этапы инициализации объекта и формы.

Способ 3: Перенос логики в менеджер объекта

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

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


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

Тогда в месте вызова (например, в обработчике команды) вы сначала вызываете проверку, и только потом — ОткрытьФорму. Это избавляет от необходимости передавать статусы "неудачного заполнения" между сеансами сервера.

Способ 4: Временное хранилище (для сложных данных)

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

Решением является генерация УникальныйИдентификатор вручную (или использование ГУИД-а пользователя) и передача адреса через те же ЗначенияЗаполнения или через параметры сеанса. Но помните, что этот способ считается "избыточным" для простых задач и требует контроля очистки хранилища.

Подведем итоги

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

Рассмотрим краткий алгоритм выбора решения:

Использование любого из этих методов сделает ваш код более стабильным и соответствующим стандартам разработки 1С.

← На главную