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