При разработке внешних печатных форм (ВПФ) для конфигурации «1С:Бухгалтерия предприятия 3.0» (БП 3.0), особенно для таких сложных документов, как УПД (Универсальный передаточный документ), разработчики часто сталкиваются с необходимостью вывода нестандартных данных. Типичная задача — заменить системное поле Количество на кастомное (например, КоличествоВЛитрах или Вес), которое добавлено в табличную часть документа.
В этой статье мы подробно разберем, почему простая правка финального запроса приводит к ошибке «Поле не найдено», и как правильно модифицировать пакетный запрос для получения нужного результата.
Рассмотрим ситуацию: вы создали внешнюю печатную форму, скопировали стандартный запрос из менеджера документа, заменили в тексте ТаблицаДокумента.Количество на ТаблицаДокумента.КоличествоВЛитрах и получили ошибку. Выясним причину этого поведения.
Печать УПД и Счетов-фактур в БП 3.0 построена на использовании пакетных запросов. Данные собираются не одним обращением к базе, а последовательностью запросов, результаты которых помещаются во временные таблицы. Основная таблица с данными строк документа обычно называется ТаблицаДокумента.
Когда вы видите в тексте функции ТекстЗапросаДанныеДляПечатиСчетовФактур обращение ИЗ ТаблицаДокумента КАК ТаблицаДокумента, это означает, что запрос обращается к уже созданной ранее временной таблице. Если ваше поле КоличествоВЛитрах не было помещено в эту временную таблицу на этапе её формирования, финальный запрос о нем ничего не узнает.
Для того чтобы ваше поле стало доступно, нам необходимо вмешаться в процесс формирования временной таблицы. Разберем по шагам, как это реализовать в модуле внешней печатной формы.
Шаг 1. Поиск места формирования временной таблицы.
В типовом коде за формирование первой части пакета запросов отвечает функция менеджера документа. Обычно это выглядит так:
ТекстЗапроса = Документы[ДокументОснование.Метаданные.Имя].ТекстЗапросаДанныеДляПечатиСчетовФактур(НомераТаблиц);
Именно этот метод формирует текст запроса, который выбирает данные из физических таблиц (например, РеализацияТоваровУслуг.Товары) и делает ПОМЕСТИТЬ ТаблицаДокумента. Нам нужно добавить наше поле именно в этот сегмент текста.
Шаг 2. Программная модификация текста запроса.
Поскольку мы работаем во внешней печатной форме, мы можем изменить строку текста запроса перед его выполнением. Проанализируем пример кода с использованием функции СтрЗаменить:
// Получаем стандартный текст запроса
ТекстЗапроса = Документы[ДокументОснование.Метаданные.Имя].ТекстЗапросаДанныеДляПечатиСчетовФактур(НомераТаблиц);
// Добавляем наше поле в выборку временной таблицы
// Важно найти место, где данные выбираются из ТЧ Товары
ТекстЗапроса = СтрЗаменить(ТекстЗапроса,
"ТаблицаДокумента.Количество КАК Количество,",
"ТаблицаДокумента.Количество КАК Количество, ТаблицаДокумента.КоличествоВЛитрах КАК КоличествоВЛитрах,");
Обратите внимание: если поле КоличествоВЛитрах является реквизитом табличной части, его нужно включить в список полей в самом первом запросе пакета, где происходит выборка из реальных таблиц документа.
После того как поле добавлено во временную таблицу, его можно использовать в финальном запросе. Однако здесь возникает важный нюанс: в УПД цена обычно рассчитывается динамически. Посмотрим на фрагмент типового кода:
ВЫБОР
КОГДА ТаблицаДокумента.Количество = 0 ТОГДА 0
ИНАЧЕ ВЫРАЗИТЬ((ТаблицаДокумента.Сумма - ТаблицаДокумента.СуммаНДС) / ТаблицаДокумента.Количество КАК ЧИСЛО(15, 2))
КОНЕЦ КАК Цена
Если вы просто подмените Количество на КоличествоВЛитрах, программа пересчитает цену за единицу (за литр). Если это именно то, что вам нужно — отлично. Если же цена должна остаться «за штуку», а количество должно отображаться в «литрах», вам придется пересмотреть алгоритм расчета в запросе или в последующем цикле обработки таблицы значений.
Рассмотрим подробнее обработку в цикле после выполнения запроса:
Результат = Запрос.ВыполнитьПакет();
ТаблицаДокумента = Результат[НомераТаблиц.ТаблицаДокумента].Выгрузить();
Для каждого СтрокаДокумента Из ТаблицаДокумента Цикл
// Если нам нужно, чтобы в печатной форме в колонке количество
// стояли литры, просто переопределяем значение
Если СтрокаДокумента.КоличествоВЛитрах <> 0 Тогда
СтрокаДокумента.Количество = СтрокаДокумента.КоличествоВЛитрах;
// ВАЖНО: пересчитываем цену, если это требуется для корректности УПД
Если СтрокаДокумента.Количество <> 0 Тогда
СтрокаДокумента.Цена = Окр(СтрокаДокумента.СуммаБезНДС / СтрокаДокумента.Количество, 2);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Проанализируем ситуацию, когда ВПФ используется для нескольких видов документов (например, «Реализация товаров и услуг» и «Оказание услуг»). Если вы добавили реквизит КоличествоВЛитрах только в Реализацию, то при попытке печати из Оказания услуг ваш программный код СтрЗаменить может не найти нужных вхождений или вызвать ошибку обращения к полю.
Рекомендуется:
Попытка...Исключение или метод Метаданные.НайтиПоПолномуИмени().Таким образом, успех при создании ВПФ УПД в БП 3.0 зависит от понимания того, что данные проходят через цепочку временных таблиц. Добавление поля на самом раннем этапе (в запросе формирования ТаблицаДокумента) гарантирует его доступность во всех последующих частях пакета и исключает ошибку «Поле не найдено».