В процессе разработки на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с необходимостью передать какой-либо флаг или статус, вычисленный в модуле объекта (в процедуре ОбработкаЗаполнения), непосредственно в модуль управляемой формы (в процедуру ПриСозданииНаСервере или ПриОткрытии). Типичный пример: при создании документа на основании нужно проверить определенные условия, и если они не выполняются, передать в форму сигнал о том, что нужно вывести предупреждение или изменить доступность элементов.
Однако стандартные механизмы, такие как экспортные переменные модуля объекта или использование коллекции ДополнительныеСвойства, в данном случае не работают. Давайте разберем, почему это происходит и какие существуют надежные способы решения этой задачи.
Проанализируем ситуацию с точки зрения жизненного цикла управляемой формы. Когда платформа инициирует создание нового объекта (например, при нажатии кнопки "Создать" или "Создать на основании"), происходят следующие события:
ДокументОбъект).ОбработкаЗаполнения в модуле этого объекта.ДокументОбъект копируются (сериализуются) в реквизит управляемой формы (тип ДанныеФормыСтруктура, обычно это реквизит Объект).ДокументОбъект уничтожается.ПриСозданииНаСервере модуля управляемой формы.Поскольку ДополнительныеСвойства и переменные модуля объекта живут только "внутри" конкретного экземпляра объекта, они бесследно исчезают в момент перехода от шага 4 к шагу 5. Платформа переносит в форму только те данные, которые входят в структуру реквизитов объекта, определенных в метаданных.
Рассмотрим подробнее три основных способа, которые позволяют обойти это ограничение.
Это самый простой и эффективный метод, который часто применяется в типовых конфигурациях (УТ 11, ERP 2.5, БП 3.0). Суть метода заключается в том, чтобы обмануть механизм сериализации платформы, заставив её передать нужные нам данные как часть структуры объекта.
Разберем реализацию по шагам:
РеализацияТоваровУслуг).СлужебныйСтатусЗаполнения (тип может быть любым: Число, Булево, Строка).Теперь этот реквизит будет существовать в объекте в памяти, будет копироваться в форму, но никогда не будет записан в таблицу базы данных. Посмотрим на пример кода в модуле объекта:
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
// Какая-то логика проверки
Если ДанныеЗаполнения = Неопределено Тогда
ЭтотОбъект.СлужебныйСтатусЗаполнения = "НовыйОбъектБезОснования";
Иначе
ЭтотОбъект.СлужебныйСтатусЗаполнения = "ЗаполненоНаОсновании";
КонецЕсли;
КонецПроцедуры
Теперь проанализируем, как получить эти данные в модуле управляемой формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Платформа автоматически перенесла значение в реквизит формы "Объект"
Если Объект.СлужебныйСтатусЗаполнения = "НовыйОбъектБезОснования" Тогда
// Выполняем действия в форме
Элементы.ГруппаСпецУсловия.Видимость = Ложь;
КонецЕсли;
КонецПроцедуры
Преимущество метода: полная бесшовность. Вам не нужно заботиться об адресах временных хранилищ или параметрах сеанса.
Если открытие формы происходит программно (например, через команду или из другой формы с помощью ОткрытьФорму), мы можем воспользоваться механизмом передачи параметров. Рассмотрим ситуацию, когда мы хотим передать данные прямо в ОбработкуЗаполнения и одновременно иметь к ним доступ в форме.
При вызове ОткрытьФорму мы передаем структуру Параметры, в которой есть специальный ключ ЗначенияЗаполнения.
Пример программного открытия:
ПараметрыЗаполнения = Новый Структура;
ПараметрыЗаполнения.Вставить("ЗапретитьРедактирование", Истина);
ПараметрыЗаполнения.Вставить("СпецРежим", 1);
ПараметрыОткрытия = Новый Структура;
ПараметрыОткрытия.Вставить("ЗначенияЗаполнения", ПараметрыЗаполнения);
ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта", ПараметрыОткрытия);
Посмотрим, что происходит внутри платформы:
ОбработкаЗаполнения в параметр ДанныеЗаполнения придет ваша структура.ПриСозданииНаСервере эта же структура будет доступна через Параметры.ЗначенияЗаполнения.Это позволяет "прокинуть" данные сквозь все этапы инициализации объекта и формы.
Современные стандарты разработки рекомендуют минимизировать логику внутри ОбработкиЗаполнения, если она влияет на интерфейс. Проанализируем более архитектурно правильный подход: выполнение проверок до того, как форма вообще начнет открываться.
Вместо того чтобы пытаться остановить открытие формы изнутри модуля объекта (где вы ограничены только вызовом исключения), создайте экспортную функцию в модуле менеджера:
// В модуле менеджера документа
Функция ПроверитьВозможностьСоздания(ДанныеОснования) Экспорт
Результат = Новый Структура("Разрешено, Сообщение", Истина, "");
// Проводим сложные проверки
// ...
Возврат Результат;
КонецФункции
Тогда в месте вызова (например, в обработчике команды) вы сначала вызываете проверку, и только потом — ОткрытьФорму. Это избавляет от необходимости передавать статусы "неудачного заполнения" между сеансами сервера.
Если вам нужно передать не просто флаг, а тяжелую таблицу или структуру, которую не хочется добавлять в реквизиты объекта, можно использовать ВременноеХранилище. Однако здесь есть нюанс: в ОбработкеЗаполнения мы не знаем уникальный идентификатор формы.
Решением является генерация УникальныйИдентификатор вручную (или использование ГУИД-а пользователя) и передача адреса через те же ЗначенияЗаполнения или через параметры сеанса. Но помните, что этот способ считается "избыточным" для простых задач и требует контроля очистки хранилища.
Мы выяснили, что передать данные напрямую через ДополнительныеСвойства из модуля объекта в форму невозможно из-за особенностей работы управляемого интерфейса.
Рассмотрим краткий алгоритм выбора решения:
Использование любого из этих методов сделает ваш код более стабильным и соответствующим стандартам разработки 1С.