При разработке внешних печатных форм (ВПФ) для таких конфигураций, как 1С:Комплексная автоматизация 2.5 или 1С:Управление торговлей 11, разработчики часто сталкиваются с проблемой: при попытке вывести «Номенклатуру контрагента» вместо собственной номенклатуры пропадают единицы измерения. В консоли запросов данные могут отображаться корректно, но в самой печатной форме поле остается пустым. В этой статье мы подробно разберем, почему это происходит и как правильно изменить запрос для корректного вывода данных.
В современных конфигурациях 1С на платформе 8.3 единицы измерения в документах (например, в Заказе клиента) хранятся не просто как ссылка на справочник. Система использует сложную иерархию, где приоритет отдается упаковкам. Проанализируем ситуацию: если в табличной части документа реквизит Упаковка заполнен, то единица измерения берется из нее. Если же упаковка не указана, система обращается к базовой единице измерения, указанной в карточке номенклатуры.
Для реализации этого в коде типовых менеджеров объектов используется специальный механизм динамической подстановки текста запроса. Рассмотрим метод Справочники.УпаковкиЕдиницыИзмерения.ТекстЗапросаЗначениеРеквизитаЕдиницыИзмерения. Этот метод генерирует сложную конструкцию ВЫБОР...КОГДА прямо во время выполнения программного кода, заменяя «заглушку» (параметр типа &ТекстЗапроса...) на реальный код SQL. Если мы нарушаем структуру связей в запросе (например, подменяем ссылку на номенклатуру ссылкой на номенклатуру контрагента во вложенном запросе), этот механизм перестает находить нужные данные.
Выясним причину, по которой единица измерения пропадает при использовании ОБЪЕДИНИТЬ ВСЕ или временных таблиц. Часто программисты пытаются подменить номенклатуру на номенклатуру партнера сразу в первом же запросе пакета:
ВЫБОР
КОГДА Таблица.НоменклатураПартнера = ЗНАЧЕНИЕ(Справочник.НоменклатураКонтрагентов.ПустаяСсылка)
ТОГДА Таблица.Номенклатура
ИНАЧЕ Таблица.НоменклатураПартнера
КОНЕЦ КАК Номенклатура
Проблема заключается в том, что поле ЕдиницаИзмерения (или упаковка) в дальнейшем коде пытается «зацепиться» за это новое поле Номенклатура. Однако у справочника НоменклатураКонтрагентов структура реквизитов отличается от справочника Номенклатура. Метод генерации текста запроса ожидает, что поле, отвечающее за номенклатуру, будет содержать ссылку именно на справочник Справочник.Номенклатура, иначе связи ЛЕВОЕ СОЕДИНЕНИЕ с таблицами единиц измерения просто не сработают.
Разберем, как правильно подготовить данные во временной таблице Товары. Нам необходимо сохранить оригинальную ссылку на номенклатуру, чтобы система могла вычислить единицу измерения, и отдельно вытянуть информацию о номенклатуре партнера. Изменим наш запрос во временной таблице следующим образом:
ВЫБРАТЬ
Таблица.Ссылка КАК Ссылка,
Таблица.Номенклатура КАК Номенклатура, -- Сохраняем оригинал!
Таблица.НоменклатураПартнера КАК НоменклатураПартнера,
Таблица.Упаковка КАК Упаковка,
Таблица.КоличествоУпаковок КАК Количество,
-- Другие поля...
ПОМЕСТИТЬ ВтТовары
ИЗ
Документ.ЗаказКлиента.Товары КАК Таблица
ГДЕ
Таблица.Ссылка В(&МассивОбъектов)
Теперь рассмотрим, как объединить эти данные в финальной выборке. Вместо того чтобы подменять саму ссылку на объект, мы будем подменять только его представление (наименование). Это позволит механизму 1С корректно отработать по стандартным связям для поиска единиц измерения. Проанализируем следующий пример кода в финальном запросе:
ВЫБРАТЬ
Товары.Ссылка КАК Ссылка,
-- Выбираем наименование: если есть партнерская номенклатура, берем её полное наименование
ЕСТЬNULL(НоменклатураПредставления.НаименованиеПолное,
ВЫБОР
КОГДА Товары.НоменклатураПартнера <> ЗНАЧЕНИЕ(Справочник.НоменклатураКонтрагентов.ПустаяСсылка)
ТОГДА Товары.НоменклатураПартнера.Наименование
ИНАЧЕ Товары.Номенклатура.НаименованиеПолное
КОНЕЦ) КАК НаименованиеПолное,
-- Оставляем стандартную заглушку для Единицы Измерения
&ТекстЗапросаНаименованиеЕдиницыИзмерения КАК ЕдиницаИзмерения,
Товары.Номенклатура КАК Номенклатура, -- Передаем оригинальную номенклатуру для работы &ТекстЗапроса
Товары.Упаковка КАК Упаковка
ИЗ
ВтТовары КАК Товары
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура.Представления КАК НоменклатураПредставления
ПО Товары.Номенклатура = НоменклатураПредставления.Ссылка
И НоменклатураПредставления.КодЯзыка = &КодЯзыка
После того как текст запроса подготовлен, необходимо вызвать методы, которые превратят наши заглушки в работающий код. Посмотрим на пример кода во внешней обработке (в модуле объекта или менеджера):
// Замена заглушки для коэффициента упаковки
Запрос.Текст = СтрЗаменить(Запрос.Текст,
"&ТекстЗапросаКоэффициентУпаковки",
Справочники.УпаковкиЕдиницыИзмерения.ТекстЗапросаКоэффициентаУпаковки(
"Товары.Упаковка",
"Товары.Номенклатура"));
// Замена заглушки для наименования единицы измерения
Запрос.Текст = СтрЗаменить(Запрос.Текст,
"&ТекстЗапросаНаименованиеЕдиницыИзмерения",
Справочники.УпаковкиЕдиницыИзмерения.ТекстЗапросаЗначениеРеквизитаЕдиницыИзмерения(
"Наименование",
"Товары.Упаковка",
"Товары.Номенклатура"));
Важный момент: обратите внимание на параметры функции ТекстЗапросаЗначениеРеквизитаЕдиницыИзмерения. Первым аргументом идет имя реквизита (в нашем случае "Наименование"), вторым — путь к полю упаковки в запросе ("Товары.Упаковка"), а третьим — путь к полю номенклатуры ("Товары.Номенклатура"). Именно поэтому крайне важно, чтобы в итоговой выборке поле Товары.Номенклатура содержало именно ссылку на Справочник.Номенклатура, а не на контрагента.
СтрЗаменить) в консоль запросов. Вы увидите, что вместо &ТекстЗапроса... там появился огромный ВЫБОР. Проверьте, не возвращает ли он NULL.ВариантыКомплектацииНоменклатуры.Характеристика, и оно также корректно передается в функции подсистемы упаковок, если это предусмотрено логикой вашей конфигурации.Подведем итог: секрет успеха при выводе единиц измерения в ВПФ заключается в сохранении оригинальных ссылок на Номенклатуру и Упаковку для служебных функций системы, в то время как для пользователя мы подменяем только текстовые представления этих объектов. Такой подход гарантирует стабильную работу печатной формы даже при сложных обновлениях конфигурации 1С.