Т.к. часто возникают вопросы по программному созданию/копированию/обработке объектов 1С:Предприятие в режиме "Управляемые формы", то решил скомпоновать в данной публикации примеры решения таких задач, с комментариями по каждому действию. Поначалу кажется все достаточно запутанно, но если по шагам все разложить и немного вникнуть, то всё должно встать на свои места.
При переходе с "обычных форм" на "управляемые формы" нужно понимать, что теперь имеем клиент-серверной вариант работы программы.
А это означает что то что мы могли ранее программно напрямую изменять объекты в "обычных формах" и видеть на экране результат наших действий, то в "управляемых формах" объект на сервере и объект на клиенте (видимый пользователю) разделены. Так же частично разделены функции и процедуры которые можно выполнять на сервере и на клиенте. Так например на сервере выполняются в основном сложные вычисления и функции связанные с изменениями в базе данных, а на клиенте выполняются не сложные расчеты и функции юзабилити.
ПРИМЕРЫ:
Ниже я приведу пример как создавать/копировать/изменять документы. Данный пример досконально разобран и позволит понять клиент-серверную архитектуру работы и распространить эти знания на другие объекты 1С (справочники, отчеты...).
Задача была такая: есть справочник номенклатуры, в которые заведены блюда (общепит). Каждое блюдо имеет свою калькуляцию (состав продуктов). Калькуляции хранятся в периодическом регистре сведений. В форме элемента размещен динамический список с калькуляциями, принадлежащими открытому блюду (это могла быть любая другая таблица данных). Необходимо было добавить две кнопки "Создать калькуляцию" (новую) и "Скопировать калькуляцию" (активную из списка).
Для этого я создал соответствующие команды и разместил их на форме.
1. "Создать калькуляцию".
&НаКлиенте Процедура СоздатьКалькуляцию(Команда) // Создаем форму объекта/документа на клиенте мФорма = ПолучитьФорму("Документ.Калькуляция.ФормаОбъекта"); // В переменную передаем объект(данные) открытой формы ДанныеФормы = мФорма.Объект; // выполняем простейшие операции ДанныеФормы.Блюдо = Объект.Ссылка; ДанныеФормы.Дата = ТекущаяДата(); // Открываем заполненную форму объекта (показываем для пользователя) мФорма.Открыть(); КонецПроцедуры
В данном варианте все просто: мы создаем на клиенте процедуру и все действия выполняем прямо на клиенте, т.к. ничего требующего вызова сервера не делаем. Создаем/получаем форму объекта, передаем в переменную ДанныеФормы Объект формы, выполняем элементарные действия с ДанныеФормы и открываем уже заполненную форму.
2. "Скопировать калькуляцию" .
С данной операцией уже немного сложнее, часть процедур выполняется на клиенте, а часть на сервере.
&НаКлиенте Процедура СкопироватьКалькуляцию() // Создаем и открываем форму объекта/документа на клиенте Форма = ОткрытьФорму("Документ.Калькуляция.Форма.ФормаДокумента",); // В переменную передаем объект(данные) открытой формы ДанныеФормы = Форма.Объект; // Получаем ссылку на существующий документ (который хотим скопировать) - активную строку динамического списка в рабочем окне Калькуляция = Элементы.Калькуляции.ТекущиеДанные.Калькуляция; // Т.к. прямую ссылку на сервер не передать, закидываем в структуру (иначе выдаст ошибку) СтруктураДанных = Новый Структура("Калькуляция", Калькуляция); // Передаем необходимые параметры и проводим манипуляции с переменной ДанныеФормы на сервере СкопироватьОбъектДокументаНаСервере(ДанныеФормы, СтруктураДанных); // Теперь необходимо передать изменения из переменной ДанныеФормы в ранее открытую нами форму - для обновления данных в самой форме КопироватьДанныеФормы(ДанныеФормы, Форма.Объект); КонецПроцедуры
Порядок действий таков: Мы на клиенте создаем форму нужного нам объекта и сразу открываем её (ОткрытьФорму...). Далее как и ранее мы передаем в переменную ДанныеФормы Объект открытой формы.
Т.к. задача состоит в том чтобы скопировать уже существующий в базе документ (старую калькуляцию, которую выбрал пользователь в динамическом списке), то действия с данными ДБ можно производить только на сервере. Таким образом, мы получаем необходимые параметры из формы номенклатуры (в моем случае старую калькуляцию) и передаем через Структуру эти параметры в серверную процедуру без контекста вместе с переменной ДанныеФормы: СкопироватьОбъектДокументаНаСервере(ДанныеФормы, СтруктураДанных).
&НаСервереБезКонтекста Процедура СкопироватьОбъектДокументаНаСервере(ДанныеФормы, СтруктураДанных) // Получаем обычный объект на сервере по данным формы // используется с указанием типа в случае изменения документа (&НаСервереБезКонтекста) //Док = ДанныеФормыВЗначение(ДанныеФормы, Тип("ДокументОбъект.Калькуляция")); // Выше строка не используется, т.к. мы копируем существующий объект Док = СтруктураДанных.Калькуляция.Скопировать(); // Работаем с объектом (разные манипуляции) // вызываем экспортные процедуры из модуля объекта Док.ПересчитатьЦены(); // заполняем его реквизиты Док.Дата = ТекущаяДата(); // Передаем обратно в переменную ДанныеФормы уже измененный объект (документ) ЗначениеВДанныеФормы(Док, ДанныеФормы); КонецПроцедуры
Уже на сервере мы с помощью функции ДанныеФормыВЗначение() преобразуем ДанныеФормы в привычный нам из "обычных форм" объект документа и работаем с ним с использованием серверных процедур. Копируем данные из другого документа, запускаем экспортные процедуры из модуля объекта, дозаполняем прочие реквизиты.
Функция ДанныеФормыВЗначение() требует указания соответствия (типа получаемого объекта): Тип("ДокументОбъект.Калькуляция").
При этом измененные на сервере ДанныеФормы сами не попадут в нашу созданную и открыую в самом начале форму, поэтому мы выполняем процедуру КопироватьДанныеФормы(ДанныеФормы, Форма.Объект) - тем самым запихаем изменения в видимую для пользователя форму документа Калькуляция (обновим в ней данные) .
Выше приведённые примеры решения задач, не являются единственными и в каждом индивидуальном случае могут быть оптимизированы или решены иным способом.
Думаю, начинающим познавать клиент-серверную архитектуру 1С пригодится данная статья)
Программное открытие форм в управляемом приложении 1С значительно отличается от их открытия в обычном приложении. Рассмотрим для начала старый метод. Он заключается в получении формы и ее последующем открытии в обычном или модальном режиме (при открытии в модальном режиме форма блокирует работу программы).
ПолучитьФорму() . Открыть()
Это самый медленный метод открытия форм. Тем не менее, он позволяет программно обработать форму перед открытием. Для обработки код нужно немного изменить:
Форма=
ПолучитьФорму("Документ.ПоступлениеТоваровУслуг.ФормаДокумента"
)
;
//Тут выполняем действия с формой
Форма.
Открыть()
;
Надо учитывать, что при получении формы будет выполняться еще процедура события ПриСозданииНаСервере.
Рассмотрим другие методы, которые позволяют открывать формы в управляемом приложении 1С быстрее и удобнее. В зависимости от конкретной ситуации могут использоваться разные методы.
1. Как открыть форму объекта в управляемом приложении, если есть ссылка на него.
В этом случае все предельно просто.
СпрСсылка=
Справочники.
Номенклатура.
НайтиПоКоду("000000001"
)
;
ОткрытьЗначение(СпрСсылка)
;
2. Как открыть форму выбора и получить потом выбранное значение.
Для этого существует функция ВвестиЗначение(). У функции 3 параметра:
- Переменная, в которую будет записано выбранное значение;
- Подсказка, которая будет отображена в окне выбора;
- Описание типов выбираемых значений. Может быть несколько типов, тогда перед выбором конкретного значения будет предложено выбрать тип.
В результате выполнения функции откроется форма выбора по умолчанию для объекта указанного типа.
Перем
Значение;
Массив=
новый массив;
Массив.
Добавить(Тип("СправочникСсылка.Номенклатура"
)
)
;
Массив.
Добавить(Тип("СправочникСсылка.Контрагенты"
)
)
;
ОписаниеТипов= новый ОписаниеТипов(Массив) ;
Рез= ВвестиЗначение(Значение, "Подсказка" , ОписаниеТипов) ;
Предыдущие способы позволяли открывать только формы, установленные для объектов по умолчанию (форму объекта или форму выбора). Если нужно открыть произвольную форму, то можно воспользоваться функцией ОткрытьФорму().
Эта функция имеет довольно много параметров. Рассмотрим некоторые из них:
- Имя формы — тут можно выбрать либо одну из стандартных форм объекта, например, ФормаВыбора или ФормаСписка . Или конкретную, созданную разработчиками форму.
- Параметры — позволяет передать в форму в виде структуры некоторые параметры перед ее открытием, тем самым определив выводимые данные. Параметры могут представлять собой любые данные, которые можно передавать с клиента на сервер. Переданные при открытии формы параметры можно обработать в процедуре ПриСозданииНаСервере() у открываемой формы.
- Режим открытия формы — имеет 3 варианта: независимый, блокировать весь интерфейс, блокировать форму владельца.
Рассмотрим, как применяется функция ОткрытьФорму() в различных ситуациях.
3. Как открыть форму существующего объекта
У каждой формы есть один ключевой реквизит. Он выделен жирным в списке реквизитов формы и обычно называется Объект у форм элементов справочников, документов. У других объектов название может быть другим. Для открытия формы существующего объекта нужно передать в открываемую форму параметр Ключ со значением в виде ссылки на объект.
&НаКлиенте
Процедура
Команда1
(Команда)
Параметр=
новый структура;
Параметр.
Вставить("Ключ"
,
НайтиС()
)
;
ОткрытьФорму(,
Параметр)
;
КонецПроцедуры
&НаСервере
Функция
НайтиС()
;
Возврат
Справочники.
Контрагенты.
НайтиПоРеквизиту ("ИНН"
,
"745107734623"
)
КонецФункции
4. Как открыть форму нового объекта
Тут подойдет просто функция ОткрытьФорму() без всяких параметров.
&НаКлиенте
Процедура
Команда1
(Команда)
ОткрытьФорму("Справочник.Контрагенты.ФормаОбъекта"
)
;
КонецПроцедуры
5. Как открыть форму нового объекта и заполнить ее на основании чего-либо
Нужно передать параметр Основание , значением которого будет являться ссылка на объект-основание заполнения. При этом будет запущена процедура ОбработкаЗаполнения().
&НаКлиенте
Процедура
Команда1
(Команда)
Параметр=
новый структура;
Параметр.
Вставить("Основание"
,
СсылкаНаСчетПокупателю)
;
ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта"
,
Параметр)
;
КонецПроцедуры
В этом примере будет создан документ Реализация товаров и услуг и заполнен на основании счета на оплату покупателю, ссылка на который была передана.
6. Как открыть форму и задать на ней отбор
Отбор на формах 1С может быть простым и сложным. Простой отбор предусматривает выражения типа Организация = ООО «Рога и копыта». Сложный отбор предполагает и другие типы сравнения, например, В списке . В данной статье рассмотрим организацию простого отбора, а сложному будет посвящена отдельная статья.
Чтобы организовать простой отбор, нужно передать в открываемую форму параметр с ключом Отбор , значением будет являться структура, в которой ключ — имя поля динамического списка, а значение — искомые данные.
Например, откроем форму списка справочника НомераГТД и сделаем там отбор по владельцу — элементу справочника Номенклатура .
&НаКлиенте
Процедура
Команда1
(Команда)
Параметр=
новый структура;
Отбор=
новый Структура;
Отбор.
Вставить("Владелец"
,
СсылкаНаНоменклатуру)
;
Параметр. Вставить("Отбор" , Отбор) ;
ОткрытьФорму("Справочник.НомераГТД.ФормаСписка"
,
Параметр)
;
КонецПроцедуры
7. Как открыть форму записи регистра сведений
Для этого понадобится ключ записи регистра сведений.
Ключ записи — это значения всех измерений и период (если регистр периодический). То есть ключ записи — это параметры, по которым можно однозначно идентифицировать запись.
Алгоритм открытия следующий:
- Заносим в структуру данные ключа записи с необходимыми значениями.
- Помещаем полученную структуру в массив.
- Из массива создаем ключ записи.
- Передаем в открываемую форму параметр Ключ с ключом записи из п.3 в качестве значения.
&НаКлиенте
Процедура
Команда1
(Команда)
Параметр=
новый структура;
ПараметрыКлюча=
новый Структура;
ПараметрыКлюча.
Вставить("Номенклатура"
,
СсылкаНаНоменклатуру)
;
ПараметрыКлюча.
Вставить("ТипЦены"
,
СсылкаНаТипЦен)
;
ПараметрыКлюча.
Вставить("Период"
,
Дата)
;
МассивКлюча =
Новый
Массив;
МассивКлюча.
Добавить(ПараметрыКлюча)
;
КлючЗаписи = Новый("РегистрСведенийКлючЗаписи.ЦеныНоменклатуры" , МассивКлюча) ;
Параметр. Вставить("Ключ" , КлючЗаписи) ;
ОткрытьФорму("РегистрСведений.ЦеныНоменклатуры.ФормаЗаписи"
,
Параметр)
;
КонецПроцедуры
Вопрос: Получить форму "На Сервере"
Есть следующая проблема нужно передать форму на сервер. Так понимаю нужно получить на клиенте структуру и передавать ее на сервер. Помогите подредактировать следующий код
Код 1C | ||
|
Ответ: Сделал так и заработало:
Код 1C | ||
|
Вопрос: v7: Открыть форму("не работает!")!
пишу, ОткрытьФорму("Документ.Бронь_Подрезки",Контекст);
но не открывает этот документ, если кто знает, помогите пожалуйста!
пробовал разные варианты и этот документ существует.
Ответ:
() Так-так.. значит в 0 ты соврал? Ввёл сообщество в заблуждение? Отвлёк от важных дел? Заставил кого-то поставить давно забытую 1С 7.7, а кого-то даже поднять SQL-сервер для проверки работы в разных вариантах работы базы? И всё это только потому что ты не смог корректно нажать Ctrl+C / Ctrl+V?!
Вопрос: Внешняя печатная форма "Платежное поручение" для документа "Поступление на расчетный счет"(БП 3.0)