Как программно заполнить динамические реквизиты документа и типовую операцию без открытия формы в 1С?

Программист 1С v8.3 (Управляемые формы) Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При программном создании документов во внешних обработках разработчики часто сталкиваются с ситуацией, когда некоторые важные реквизиты (например, ТиповаяОперация и связанные с ней параметры) отсутствуют в самом объекте базы данных, а формируются динамически прямо на управляемой форме в событии ПриСозданииНаСервере. В этой статье мы подробно разберем, почему возникает такая ситуация и как правильно программно заполнить документ и связанные с ним документы без интерактивного открытия формы пользователем.

Выясним причину: почему реквизиты формы недоступны в объекте документа

Для понимания логики работы 1С важно четко разделять контекст объекта метаданных и контекст управляемой формы:

  1. Контекст объекта (ДокументОбъект): создается вызовом метода СоздатьДокумент(). В нем доступны только те реквизиты и табличные части, которые явно добавлены в конфигураторе в состав данного документа. Метод СоздатьДокумент() работает исключительно на сервере и не инициализирует события управляемых форм.
  2. Контекст формы: динамические реквизиты, добавляемые через метод формы СоздатьРеквизиты(), существуют только в памяти конкретного экземпляра формы во время ее работы. Как только форма закрывается, динамические реквизиты прекращают свое существование.

В конфигурациях 1С (в частности, в «Бухгалтерии государственного учреждения») параметр ТиповаяОперация на форме отображается как динамический реквизит, но данные о нем в базе данных сохраняются в служебных табличных частях или с помощью дополнительных реквизитов документа. Поэтому попытка обратиться к динамическому реквизиту формы напрямую из объекта ДокументОбъект приведет к ошибке.

Вариант 1. Инициализация формы на сервере без вызова Открыть()

Рассмотрим способ, когда необходимо выполнить серверную логику формы, включая событие ПриСозданииНаСервере, но без визуального показа формы пользователю. Для этого вызовем метод ПолучитьФорму(), зафиксируем данные и преобразуем их в объект.

Проанализируем пример кода:


ПараметрыФормы = Новый Структура;
ФормаДокумента = ПолучитьФорму("Документ.АктОказанияУслуг.Форма.ФормаДокумента", ПараметрыФормы);

// При вызове ПолучитьФорму отрабатывает событие ПриСозданииНаСервере
// Заполняем реквизиты формы, если требуется
ФормаДокумента.Объект.ВидОперации = Перечисления.ВидыОпераций.ОказаниеУслуг;

// Преобразуем данные формы в объект для последующей записи
ДокументОбъект = ДанныеФормыВЗначение(ФормаДокумента.Объект, Тип("ДокументОбъект.АктОказанияУслуг"));
ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);

Этот подход позволяет задействовать механизмы формы, однако стоит учитывать, что создание формы создает дополнительную нагрузку на сервер.

Вариант 2. Вынос алгоритма заполнения в модуль объекта или обработку

Посмотрим на более производительный и архитектурно правильный вариант. Чтобы не завязываться на форму, необходимо изучить, какие именно реквизиты и табличные части объекта заполняются при выборе типовой операции на форме, и повторить этот алгоритм в своей обработке или в процедуре ОбработкаЗаполнения модуля объекта.

Рассмотрим по шагам логику программного заполнения:

  1. Устанавливаем ключевой реквизит шапки (например, ВидОперации или Организация).
  2. Заполняем табличную часть документа нужными услугами или номенклатурой.
  3. Указываем служебные реквизиты, отвечающие за типовую операцию (например, заполняем реквизиты счета учета, статьи расходов и счет контрагента).
  4. Вызываем стандартный метод Заполнить(), передав в него необходимые параметры.

Пример программного заполнения документа с использованием метода Заполнить():


НовыйАкт = Документы.АктОказанияУслуг.СоздатьДокумент();

ПараметрыЗаполнения = Новый Структура;
ПараметрыЗаполнения.Вставить("ВидОперации", Перечисления.ВидыОпераций.ОказаниеУслуг);
ПараметрыЗаполнения.Вставить("Организация", НашаОрганизация);
ПараметрыЗаполнения.Вставить("Контрагент", НашКонтрагент);

НовыйАкт.Заполнить(ПараметрыЗаполнения);
НовыйАкт.Записать(РежимЗаписиДокумента.Запись);

Вариант 3. Формирование подчиненного документа (Счет-фактура) на основании записанного Акта

Разберем ситуацию с созданием подчиненного документа. Чтобы создать документ «Счет-фактура выданный» на основании Акта оказания услуг, платформа 1С использует данные уже записанного документа-основания (его реквизиты шапки и движения), а не визуальные элементы формы.

Схема создания подчиненного документа выглядит следующим образом:


// Сначала создаем и записываем документ-основание
АктОбъект = Документы.АктОказанияУслуг.СоздатьДокумент();
// ... заполнение реквизитов Акта ...
АктОбъект.Записать(РежимЗаписиДокумента.Проведение);

// Затем создаем Счет-фактуру на основании ссылки записанного Акта
СчетФактураОбъект = Документы.СчетФактураВыданный.СоздатьДокумент();
СчетФактураОбъект.Заполнить(АктОбъект.Ссылка);
СчетФактураОбъект.Записать(РежимЗаписиДокумента.Запись);

Важное замечание: Метод Заполнить(СсылкаНаАкт) обращается к процедуре ОбработкаЗаполнения в модуле объекта Счета-фактуры. Если в записанном Акте корректно заполнены реквизиты ВидОперации, организация, контрагент и табличные части, Счет-фактура сформируется без ошибок даже без открытых форм.

← На главную