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