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

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

При работе с современными типовыми конфигурациями на платформе «1С:Предприятие 8.3» (такими как 1С:Комплексная автоматизация, 1С:ERP или 1С:Управление торговлей) часто возникает необходимость кастомизации печатных форм. Одна из самых распространенных задач — вывод дополнительного реквизита, созданного пользователем в режиме «1С:Предприятие», в стандартную печатную форму (например, в счет на оплату из заказа клиента).

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

Разбор типичных ошибок начинающих разработчиков

Часто начинающие разработчики и аналитики при попытке дописать код в модуле менеджера печати сталкиваются с ошибками компиляции вида Переменная не определена. Давайте разберем типичный ошибочный код и выясним причины его неработоспособности:


// Ошибочный код
СтруктураДанныхДатаИзгТовара.Вставить(УправлениеСвойствами.ЗначениеСвойства(ДокументСсылка.ТекущийДокумент, ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения, ДатаИсполненияЗаказа));

Проанализируем, почему этот код вызывает ошибки компилятора:

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

Теперь, когда мы понимаем физику процесса, перейдем к правильным методам реализации нашей задачи.

Способ 1. Использование механизмов БСП (Рекомендуемый метод)

Современные конфигурации 1С построены на базе БСП (Библиотеки стандартных подсистем). В ней присутствует мощный модуль УправлениеСвойствами, который позволяет получить значение любого дополнительного реквизита буквально одной строкой кода без написания громоздких запросов.

Для этого нам понадобится так называемое Имя для разработчиков. Его можно найти в режиме «1С:Предприятие»: откройте карточку вашего дополнительного реквизита и найдите на вкладке «Главное» (или в меню «Еще» -> «Для разработчиков») уникальный идентификатор. Обычно он выглядит как ИмяРеквизита_УникальныйХэш, например: ДатаИсполненияЗаказа_cb85b7049ecf49b78e5150a610da5b33.

Рассмотрим пример кода, который мы вставим в процедуру формирования печатной формы:


// 1. Получаем область из нашего макета печати
ОбластьМакета = Макет.ПолучитьОбласть("ДатаИзгТовара");

// 2. Определяем ссылку на текущий документ (в контексте цикла печати БСП это обычно Переменная Ссылка или ДанныеПечати.Ссылка)
СсылкаНаДокумент = ДанныеПечати.Ссылка; // Имя переменной зависит от конкретной процедуры печати

// 3. Задаем имя свойства "для разработчиков"
ИмяСвойства = "ДатаИсполненияЗаказа_cb85b7049ecf49b78e5150a610da5b33";

// 4. Вызываем стандартный метод БСП для получения значения реквизита
ЗначениеДопРеквизита = УправлениеСвойствами.ЗначениеСвойства(СсылкаНаДокумент, ИмяСвойства);

// 5. Если значение заполнено, выводим область на печать
Если ЗначениеЗаполнено(ЗначениеДопРеквизита) Тогда
    
    СтруктураПараметров = Новый Структура;
    СтруктураПараметров.Вставить("ДатаИзготовленияТовара", ЗначениеДопРеквизита);
    
    ОбластьМакета.Параметры.Заполнить(СтруктураПараметров);
    ТабличныйДокумент.Вывести(ОбластьМакета);
    
КонецЕсли;

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

Способ 2. Получение значения через прямой запрос

Если вам требуется интегрировать получение дополнительного реквизита в уже существующий сложный пакетный запрос печатной формы (для экономии обращений к базе данных), оптимально использовать классический запрос к табличной части дополнительных реквизитов документа.

Проанализируем структуру запроса и напишем правильный вариант с отбором по конкретному документу и имени свойства:


// Создаем объект Запрос
Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	ЗаказКлиентаДополнительныеРеквизиты.Значение КАК ДатаИзготовленияТовара
|ИЗ
|	Документ.ЗаказКлиента.ДополнительныеРеквизиты КАК ЗаказКлиентаДополнительныеРеквизиты
|ГДЕ
|	ЗаказКлиентаДополнительныеРеквизиты.Ссылка = &Ссылка
|	И (ЗаказКлиентаДополнительныеРеквизиты.Свойство.Имя = &ИмяСвойства 
|		ИЛИ ЗаказКлиенаДополнительныеРеквизиты.Свойство.Наименование = &НаименованиеСвойства)";

// Передаем параметры в запрос
Запрос.УстановитьПараметр("Ссылка", СсылкаНаДокумент);
// Поиск по внутреннему имени (более надежно)
Запрос.УстановитьПараметр("ИмяСвойства", "ДатаИсполненияЗаказа_cb85b7049ecf49b78e5150a610da5b33");
// Либо поиск по представлению для пользователя (синониму)
Запрос.УстановитьПараметр("НаименованиеСвойства", "Дата изготовления товара");

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда
    
    ОбластьМакета = Макет.ПолучитьОбласть("ДатаИзгТовара");
    ОбластьМакета.Параметры.ДатаИзготовленияТовара = Выборка.ДатаИзготовленияТовара;
    ТабличныйДокумент.Вывести(ОбластьМакета);
    
КонецЕсли;

Обратите внимание: При использовании запроса крайне важно устанавливать параметр &Ссылка, чтобы ограничить выборку только текущим обрабатываемым документом. В противном случае запрос вернет данные по всем документам базы данных, что приведет к фатальному снижению производительности.

Способ 3. Поиск значения в табличной части объекта (без обращения к БД)

Этот способ идеально подходит, если объект (документ) уже полностью прочитан в память и находится в транзакции или в процедуре формы. Мы можем осуществить поиск непосредственно в коллекции строк его табличной части ДополнительныеРеквизиты.

Рассмотрим пример реализации:


// Получаем область макета
ОбластьМакета = Макет.ПолучитьОбласть("ДатаИзгТовара");

// Находим элемент плана видов характеристик по его представлению (заголовку)
СвойствоДопРеквизита = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Заголовок", "Дата изготовления товара");

Если ЗначениеЗаполнено(СвойствоДопРеквизита) Тогда
    
    // Выполняем поиск строки в табличной части текущего документа
    ОтборСтрок = Новый Структура("Свойство", СвойствоДопРеквизита);
    НайденныеСтроки = СсылкаНаДокумент.ДополнительныеРеквизиты.НайтиСтроки(ОтборСтрок);
    
    Если НайденныеСтроки.Количество() > 0 Тогда
        // Заполняем параметр полученным значением из первой найденной строки
        ОбластьМакета.Параметры.ДатаИзготовленияТовара = НайденныеСтроки[0].Value;
        ТабличныйДокумент.Вывести(ОбластьМакета);
    КонецЕсли;
    
КонецЕсли;

Как правильно встроить доработку в систему

Крайне не рекомендуется вносить изменения непосредственно в типовую конфигурацию «1С:Комплексная автоматизация», так как это существенно усложнит последующие обновления системы. Для безопасного внедрения кода воспользуемся механизмом Расширений конфигурации:

  1. Создайте новое расширение конфигурации в конфигураторе.
  2. Перенесите в расширение обработку ПечатьСчетовНаОплату и ее макет (в котором вы предварительно добавили область ДатаИзгТовара с параметром ДатаИзготовленияТовара).
  3. В модуле менеджера обработки найдите процедуру, отвечающую за вывод областей (например, ЗаполнитьТабличныйДокументСчетаНаОплату).
  4. Примените директиву компиляции &После или &Вместо для кастомизации вывода печатной формы. Например, с помощью метода &После вы можете дописать вывод вашей области в самом конце формирования табличного документа.

Таким образом, ваша доработка останется полностью изолированной от типового кода, а обновление системы пройдет в штатном автоматическом режиме.

← На главную