Как заменить стандартное количество на произвольный реквизит в ВПФ УПД для 1С:Бухгалтерии 3.0

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

При разработке внешних печатных форм (ВПФ) для конфигурации «1С:Бухгалтерия предприятия 3.0» (БП 3.0), особенно для таких сложных документов, как УПД (Универсальный передаточный документ), разработчики часто сталкиваются с необходимостью вывода нестандартных данных. Типичная задача — заменить системное поле Количество на кастомное (например, КоличествоВЛитрах или Вес), которое добавлено в табличную часть документа.

В этой статье мы подробно разберем, почему простая правка финального запроса приводит к ошибке «Поле не найдено», и как правильно модифицировать пакетный запрос для получения нужного результата.

Анализ механизма формирования данных для печати

Рассмотрим ситуацию: вы создали внешнюю печатную форму, скопировали стандартный запрос из менеджера документа, заменили в тексте ТаблицаДокумента.Количество на ТаблицаДокумента.КоличествоВЛитрах и получили ошибку. Выясним причину этого поведения.

Печать УПД и Счетов-фактур в БП 3.0 построена на использовании пакетных запросов. Данные собираются не одним обращением к базе, а последовательностью запросов, результаты которых помещаются во временные таблицы. Основная таблица с данными строк документа обычно называется ТаблицаДокумента.

Когда вы видите в тексте функции ТекстЗапросаДанныеДляПечатиСчетовФактур обращение ИЗ ТаблицаДокумента КАК ТаблицаДокумента, это означает, что запрос обращается к уже созданной ранее временной таблице. Если ваше поле КоличествоВЛитрах не было помещено в эту временную таблицу на этапе её формирования, финальный запрос о нем ничего не узнает.

Решение проблемы: Модификация пакетного запроса

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

Шаг 1. Поиск места формирования временной таблицы.

В типовом коде за формирование первой части пакета запросов отвечает функция менеджера документа. Обычно это выглядит так:


ТекстЗапроса = Документы[ДокументОснование.Метаданные.Имя].ТекстЗапросаДанныеДляПечатиСчетовФактур(НомераТаблиц);

Именно этот метод формирует текст запроса, который выбирает данные из физических таблиц (например, РеализацияТоваровУслуг.Товары) и делает ПОМЕСТИТЬ ТаблицаДокумента. Нам нужно добавить наше поле именно в этот сегмент текста.

Шаг 2. Программная модификация текста запроса.

Поскольку мы работаем во внешней печатной форме, мы можем изменить строку текста запроса перед его выполнением. Проанализируем пример кода с использованием функции СтрЗаменить:


// Получаем стандартный текст запроса
ТекстЗапроса = Документы[ДокументОснование.Метаданные.Имя].ТекстЗапросаДанныеДляПечатиСчетовФактур(НомераТаблиц);

// Добавляем наше поле в выборку временной таблицы
// Важно найти место, где данные выбираются из ТЧ Товары
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, 
    "ТаблицаДокумента.Количество КАК Количество,", 
    "ТаблицаДокумента.Количество КАК Количество, ТаблицаДокумента.КоличествоВЛитрах КАК КоличествоВЛитрах,");

Обратите внимание: если поле КоличествоВЛитрах является реквизитом табличной части, его нужно включить в список полей в самом первом запросе пакета, где происходит выборка из реальных таблиц документа.

Корректировка расчета цены и итогов

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


ВЫБОР 
    КОГДА ТаблицаДокумента.Количество = 0 ТОГДА 0 
    ИНАЧЕ ВЫРАЗИТЬ((ТаблицаДокумента.Сумма - ТаблицаДокумента.СуммаНДС) / ТаблицаДокумента.Количество КАК ЧИСЛО(15, 2)) 
КОНЕЦ КАК Цена

Если вы просто подмените Количество на КоличествоВЛитрах, программа пересчитает цену за единицу (за литр). Если это именно то, что вам нужно — отлично. Если же цена должна остаться «за штуку», а количество должно отображаться в «литрах», вам придется пересмотреть алгоритм расчета в запросе или в последующем цикле обработки таблицы значений.

Рассмотрим подробнее обработку в цикле после выполнения запроса:


Результат = Запрос.ВыполнитьПакет();
ТаблицаДокумента = Результат[НомераТаблиц.ТаблицаДокумента].Выгрузить();

Для каждого СтрокаДокумента Из ТаблицаДокумента Цикл
    // Если нам нужно, чтобы в печатной форме в колонке количество 
    // стояли литры, просто переопределяем значение
    Если СтрокаДокумента.КоличествоВЛитрах <> 0 Тогда
        СтрокаДокумента.Количество = СтрокаДокумента.КоличествоВЛитрах;
        
        // ВАЖНО: пересчитываем цену, если это требуется для корректности УПД
        Если СтрокаДокумента.Количество <> 0 Тогда
             СтрокаДокумента.Цена = Окр(СтрокаДокумента.СуммаБезНДС / СтрокаДокумента.Количество, 2);
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

Рекомендации по работе с метаданными

Проанализируем ситуацию, когда ВПФ используется для нескольких видов документов (например, «Реализация товаров и услуг» и «Оказание услуг»). Если вы добавили реквизит КоличествоВЛитрах только в Реализацию, то при попытке печати из Оказания услуг ваш программный код СтрЗаменить может не найти нужных вхождений или вызвать ошибку обращения к полю.

Рекомендуется:

  1. Всегда проверять наличие реквизита в метаданных документа-основания перед модификацией запроса.
  2. Использовать конструкцию Попытка...Исключение или метод Метаданные.НайтиПоПолномуИмени().
  3. Если реквизит отсутствует, оставлять стандартную логику вывода количества.

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

← На главную