Как вывести дополнительный реквизит номенклатуры в печатную форму ТОРГ-12 в 1С:Управление торговлей 11.4?

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

При разработке внешних печатных форм (ВПФ) для конфигураций на базе БСП (Библиотека стандартных подсистем), таких как Управление торговлей 11.4, ERP 2 или Комплексная автоматизация, программисты часто сталкиваются с необходимостью вывода данных, которые отсутствуют в типовом наборе полей. Одной из самых частых задач является вывод дополнительного реквизита номенклатуры (например, «Срок годности», «Цвет» или «Производитель») в форму ТОРГ-12.

Однако простое внедрение подзапроса в основной текст типовой печати часто приводит к неожиданным ошибкам, наиболее распространенная из которых: «В документе отсутствуют товары, печать товарной накладной не требуется». В этой статье мы подробно разберем, почему возникает эта ошибка и какими способами можно реализовать вывод дополнительных реквизитов правильно и стабильно.

Анализируем причину ошибки «В документе отсутствуют товары»

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

  1. Использование ВНУТРЕННЕГО СОЕДИНЕНИЯ (INNER JOIN): Если вы соединяете основную таблицу товаров с таблицей дополнительных реквизитов через ВНУТРЕННЕЕ СОЕДИНЕНИЕ, то в выборку попадут только те товары, у которых данный реквизит заполнен. Если хотя бы у одной позиции в документе «Срок годности» не указан, вся выборка может «схлопнуться», и система решит, что товаров нет.
  2. Дублирование строк: Если у номенклатуры в базе данных несколько дополнительных реквизитов, а фильтр в запросе настроен некорректно, запрос может выдать несколько строк на одну позицию товара. Система БСП может не пройти проверку на соответствие количества строк в документе и в результате запроса.
  3. Неверная работа с временными таблицами: В типовых запросах ТОРГ-12 активно используются временные таблицы (ВТ_Товары, ВТ_Суммы). Если вы добавляете свою таблицу, но не включаете её в итоговый срез данных, параметры печати могут не инициализироваться.

Способ 1. Прямая модификация основного запроса (SQL-метод)

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


// Сначала подготавливаем данные по доп. реквизитам во временную таблицу
ВЫБРАТЬ
    НоменклатураДополнительныеРеквизиты.Ссылка КАК Товар,
    НоменклатураДополнительныеРеквизиты.Значение КАК СрокГодности
ПОМЕСТИТЬ ВТ_СрокиГодности
ИЗ
    Справочник.Номенклатура.ДополнительныеРеквизиты КАК НоменклатураДополнительныеРеквизиты
ГДЕ
    НоменклатураДополнительныеРеквизиты.Свойство = &СвойствоСрокГодности;

////////////////////////////////////////////////////////////////////////////////
// Соединяем с основной таблицей товаров (условно ВТ_Товары)
ВЫБРАТЬ
    Тк.Ссылка КАК Ссылка,
    Тк.Номенклатура КАК Номенклатура,
    ЕСТЬNULL(ВТ_СрокиГодности.СрокГодности, "") КАК СрокГодности
ИЗ
    ВТ_Товары КАК Тк
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_СрокиГодности КАК ВТ_СрокиГодности
    ПО Тк.Номенклатура = ВТ_СрокиГодности.Товар

Важные моменты:

Способ 2. Использование программных функций БСП (Метод постобработки)

Если вы не хотите рисковать стабильностью основного запроса, можно использовать стандартные механизмы Библиотеки Стандартных Подсистем. Выясним, как это сделать программно. Рассмотрим алгоритм:

  1. Выполняем штатный запрос на получение данных для печати.
  2. Получаем результат в виде ТаблицыЗначений.
  3. Обходим таблицу или используем пакетный метод получения свойств.

В БСП есть мощный инструмент — функция УправлениеСвойствами.ПолучитьЗначенияСвойств. Разберем пример реализации в коде обработки:


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

// Добавляем колонку в основную таблицу
ДанныеПечати.Колонки.Добавить("СрокГодности");

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

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

Способ 3. Получение значения через отдельную функцию

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


Функция ПолучитьСрокГодности(СсылкаНоменклатура, НужноеСвойство) Экспорт
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |    ДополнительныеРеквизиты.Значение
        |ИЗ
        |    Справочник.Номенклатура.ДополнительныеРеквизиты КАК ДополнительныеРеквизиты
        |ГДЕ
        |    ДополнительныеРеквизиты.Ссылка = &Ссылка
        |    И ДополнительныеРеквизиты.Свойство = &Свойство";
    
    Запрос.УстановитьПараметр("Ссылка", СсылкаНоменклатура);
    Запрос.УстановитьПараметр("Свойство", НужноеСвойство);
    
    РезультатЗапроса = Запрос.Выполнить();
    Если Не РезультатЗапроса.Пустой() Тогда
        Выборка = РезультатЗапроса.Выбрать();
        Выборка.Следующий();
        Возврат Выборка.Значение;
    КонецЕсли;
    
    Возврат "";
КонецФункции

Почему этот способ хуже? При печати ТОРГ-12 на 50 строк, система выполнит 50 дополнительных обращений к базе данных. В случае использования ЛЕВОГО СОЕДИНЕНИЯ в основном запросе или метода ПолучитьЗначенияСвойств, обращение будет всего одно.

Настройка макета и вывод данных

После того как данные получены (независимо от выбранного способа), их нужно вывести в печатную форму. Рассмотрим шаги настройки макета:

  1. Откройте макет внешней печатной формы ТОРГ-12.
  2. Найдите область Строка.
  3. Добавьте новую колонку или вставьте параметр в существующую ячейку.
  4. В свойствах ячейки укажите Заполнение: Параметр и назовите его СрокГодности.
  5. В коде формирования печатной формы, там где заполняется область строки (обычно это ОбластьМакета.Параметры.Заполнить(СтрокаДанных)), убедитесь, что в структуре СтрокаДанных присутствует поле с таким же именем.

Рекомендации по работе с ПланВидовХарактеристик

Никогда не делайте поиск свойства по строковому наименованию прямо в запросе. Пользователь может легко переименовать «Срок годности» в «Срок годности (дни)», и ваш код перестанет работать. Правильнее всего:

Рассмотрим пример получения ссылки на свойство:


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

Заключение

Мы проанализировали ситуацию и выяснили, что ошибка «отсутствуют товары» в ТОРГ-12 чаще всего вызвана некорректным соединением таблиц в запросе. Оптимальным решением для современных конфигураций 1С является либо использование ЛЕВОГО СОЕДИНЕНИЯ с предварительно отобранной временной таблицей доп. реквизитов, либо использование механизмов БСП для программного получения свойств. Это обеспечит высокую скорость работы и надежность вашей печатной формы даже при больших объемах данных.

← На главную