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