Когда мы работаем с управляемыми формами в 1С:Предприятии, часто возникает задача передать некоторые данные, которые пользователь ввел или которые были рассчитаны на форме, непосредственно в модуль объекта для дальнейшей обработки – например, при записи или проведении документа. Это может быть табличная часть, которая временно формируется на форме, или какие-либо служебные параметры. Давайте рассмотрим эту ситуацию подробнее и выясним, как правильно организовать такой обмен данными. Мы проанализируем наиболее эффективный и рекомендуемый способ решения этой проблемы, а также обсудим другие подходы и их применимость.
Мы выясним, что основным и наиболее гибким инструментом для передачи временных данных из формы в модуль объекта является свойство ДополнительныеСвойства объекта.
Что такое ДополнительныеСвойства?
ДополнительныеСвойства – это мощный инструмент, который позволяет нам временно хранить произвольные данные, связанные с объектом, без необходимости изменять структуру метаданных конфигурации. Представьте его как временный "контейнер" или "портфель", куда мы можем положить нужную информацию, чтобы затем достать ее в другом месте при обработке того же объекта.
Мы выясним, что это свойство доступно для всех объектных метаданных, то есть для тех объектов, которые могут быть записаны в базу данных (документы, справочники, планы видов характеристик и т.д.). Оно представляет собой структуру, в которую разработчик может добавлять свои ключи и значения.
Типичные сценарии использования ДополнительныеСвойства включают:
Давайте разберем по шагам, как мы можем использовать ДополнительныеСвойства для передачи данных из формы в модуль объекта.
Основная идея заключается в том, что в серверной процедуре формы (например, ПередЗаписьюНаСервере) мы помещаем необходимые данные в структуру ДополнительныеСвойства объекта, который мы собираемся записать. После этого, когда управление переходит в модуль объекта (например, в процедуру ОбработкаПроведения или ПередЗаписью), мы можем легко получить доступ к этим данным через то же свойство ДополнительныеСвойства.
Посмотрим на пример кода, который демонстрирует этот подход, основанный на опыте коллег с форума:
// В модуле формы документа (например, в процедуре ПередЗаписьюНаСервере)
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
// Здесь может быть типовой код обработки формы перед записью
// Предположим, нам нужно передать табличную часть "Товары"
// из формы в модуль объекта для проведения.
// Мы выгружаем табличную часть Объект.Товары в ТаблицуЗначений.
тзТовары = Объект.Товары.Выгрузить();
// Мы вставляем эту табличную часть в ДополнительныеСвойства
// ТекущегоОбъекта под ключом "тзТовары".
ТекущийОбъект.ДополнительныеСвойства.Вставить("тзТовары", тзТовары);
КонецПроцедуры
// В модуле объекта документа (например, в процедуре ОбработкаПроведения)
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
// Здесь может быть типовой код проведения документа
// Мы проверяем, было ли свойство с ключом "тзТовары" передано.
Если ДополнительныеСвойства.Свойство("тзТовары") Тогда
// Если да, то получаем нашу табличную часть.
ТаблицаТоваровИзФормы = ДополнительныеСвойства.тзТовары;
// Теперь мы можем работать с ТаблицаТоваровИзФормы
// для выполнения логики проведения.
// Например, как упоминалось на форуме, можем итерироваться по строкам:
// Для Каждого Стр Из ТаблицаТоваровИзФормы Цикл
// // Доступ к данным строки:
// // Значение = Стр.ИмяКолонки;
// // Если в табличной части есть номер строки, то можно использовать его
// // для позиционирования или сопоставления с данными объекта.
// // Например, если в тзТовары есть колонка "НомерСтроки",
// // то Стр.НомерСтроки может помочь.
// КонецЦикла;
КонецЕсли;
КонецПроведения;
В этом примере мы видим, как в процедуре ПередЗаписьюНаСервере мы выгружаем табличную часть Объект.Товары в переменную тзТовары. Затем мы используем метод Вставить() для помещения этой табличной части в коллекцию ДополнительныеСвойства объекта, который будет записан (ТекущийОбъект). Мы даем ей имя-ключ "тзТовары".
Далее, в модуле объекта, в процедуре ОбработкаПроведения, мы сначала проверяем наличие свойства с ключом "тзТовары" с помощью метода Свойство(). Если свойство существует, мы получаем его значение (нашу табличную часть) и далее можем использовать ее для логики проведения документа.
Мы можем сформулировать схему использования ДополнительныеСвойства следующим образом:
ПередЗаписьюНаСервере) добавляем нужный ключ и устанавливаем его значение в структуру ТекущийОбъект.ДополнительныеСвойства.ДополнительныеСвойства в модуль объекта.ОбработкаПроведения) проверяем наличие добавленного элемента с помощью метода ДополнительныеСвойства.Свойство("ИмяКлюча").
Мы часто сталкиваемся с вопросами о других возможных способах передачи данных. Давайте проанализируем, почему некоторые из них не применимы или менее предпочтительны для этой конкретной задачи.
* Прямой доступ к элементам формы из модуля объекта: Мы должны четко понимать, что прямой доступ к элементам формы из модуля объекта абсолютно невозможен. Модуль объекта выполняется на сервере, в то время как элементы формы существуют только на клиенте. Это фундаментальное разделение архитектуры 1С:Предприятия в режиме управляемого приложения.
* Использование реквизитов объекта: Если данные должны сохраняться с объектом постоянно и являться частью его структуры, то для них, конечно, следует создавать реквизиты объекта в метаданных. Если реквизит объекта вынесен на форму, он сохраняется "сам" при записи. Однако ДополнительныеСвойства предназначены для временных значений, которые нужны только в рамках одной операции (например, записи или проведения) и не должны постоянно храниться в базе данных как часть объекта.
Хотя ДополнительныеСвойства является оптимальным решением для нашей задачи, рассмотрим кратко другие механизмы, которые используются для передачи данных в 1С, но в других контекстах:
* Параметры функций/процедур: В некоторых случаях данные могут быть переданы напрямую как параметры при вызове серверной процедуры или функции из клиента, или при вызове процедур модуля объекта из других модулей. Это применимо, когда мы явно вызываем процедуры и можем контролировать передаваемые параметры.
* Временное хранилище: Для передачи больших объемов данных (например, таблиц значений, двоичных данных) между клиентом и сервером или между различными формами, особенно при работе с подборами, может использоваться временное хранилище. Например, форма подбора может поместить данные во временное хранилище, а затем передать только адрес хранилища в форму документа, которая затем получит доступ к данным по этому адресу. Это полезно, когда данные не связаны напрямую с записываемым объектом, а используются для обмена между несвязанными операциями.
* Дополнительные реквизиты и сведения (Библиотека стандартных подсистем - БСП): В 1С существуют механизмы "дополнительных реквизитов" и "дополнительных сведений", которые позволяют пользователям создавать свойства объектов без изменения конфигурации. Эти механизмы используются для хранения постоянно связанных с объектом данных, которые могут быть настроены пользователями. Однако это отличается от ДополнительныеСвойства, которое предназначено для временных данных в рамках одного сеанса или операции и управляется программно разработчиком.
Мы видим, что решение, предложенное в нашем примере и подтвержденное опытом коллег, с использованием ДополнительныеСвойства для передачи выгруженной табличной части или других данных из формы в модуль объекта для обработки проведения, является стандартным, корректным и наиболее гибким подходом в 1С для управляемых форм. Мы рекомендуем использовать именно этот метод для решения подобных задач, так как он соответствует архитектурным принципам платформы и обеспечивает чистоту кода и легкость поддержки.