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