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