Как передать данные из формы в модуль объекта через ДополнительныеСвойства в 1С?

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

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

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

Причина: порядок выполнения событий платформы

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

  1. ОбработкаПроверкиЗаполненияНаСервере (модуль формы)
  2. ОбработкаПроверкиЗаполнения (модуль объекта)
  3. ПередЗаписьюНаСервере (модуль формы)
  4. ПередЗаписью (модуль объекта, начало транзакции)
  5. ОбработкаПроведения (модуль объекта, в транзакции)

Посмотрим на эту последовательность: событие ОбработкаПроверкиЗаполнения модуля объекта вызывается раньше, чем процедура формы ПередЗаписьюНаСервере. Именно поэтому любые попытки заполнить ТекущийОбъект.ДополнительныеСвойства в обработчике ПередЗаписьюНаСервере формы не приносят результата для модуля объекта в момент проверки заполнения — платформа уже завершила выполнение процедуры ОбработкаПроверкиЗаполнения.

Рассмотрим пример кода, который пытается записать данные в форму, но сталкивается с описанной проблемой:


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

Способ 1. Перенос дополнительных проверок из ОбработкаПроверкиЗаполнения в ПередЗаписью или ОбработкаПроведения

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

Проанализируем оптимальную схему реализации:

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

Рассмотрим код модуля объекта при таком подходе:


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

Способ 2. Передача параметров через структуру ПараметрыЗаписи

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

  1. На клиенте формируем структуру параметров записи и вызываем метод Записать():

&НаКлиенте
Процедура ВыполнитьЗаписьСПодтверждением()
    
    ПараметрыЗаписи = Новый Структура;
    ПараметрыЗаписи.Вставить("ПроверкаПользователемПройдена", Истина);
    
    Записать(ПараметрыЗаписи);
    
КонецПроцедуры
  1. В обработчике формы ПередЗаписьюНаСервере переносим данные из ПараметрыЗаписи в объект:

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

Ограничения при работе с типами данных и временным хранилищем

При передаче сложных данных между формой и объектом важно учитывать особенности типов данных 1С:

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

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

Временное хранилище: Для хранения промежуточных таблиц на форме рекомендуется использовать реквизиты формы с типом ТаблицаЗначений. Использование служебных табличных частей с последующей очисткой является избыточным и усложняет структуру метаданных.

← На главную