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