Как правильно написать запрос для получения технических характеристик номенклатуры из табличной части в 1С?

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

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

Разбор исходной структуры данных

Прежде чем приступать к написанию кода, проанализируем объекты, с которыми нам предстоит работать:

  1. Документ.КоммерческоеПредложение: имеет табличную часть Составляющие. В этой ТЧ есть реквизит Номенклатура (тип СправочникСсылка.Номенклатура).
  2. Справочник.Номенклатура: содержит подчиненную табличную часть ТехническиеХарактеристики с реквизитами Свойство и Значение.

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

Анализ типичных ошибок при соединении таблиц

Рассмотрим ситуацию, когда разработчик пытается соединить таблицы «напрямую» через реквизит наименования. Посмотрим на пример некорректного кода:


ВЫБРАТЬ
    КоммерческоеПредложениеСоставляющие.Наименование КАК Наименование,
    ЕСТЬNULL(НоменклатураТехническиеХарактеристики.Значение, "-") КАК Значение
ИЗ
    Документ.КоммерческоеПредложение.Составляющие КАК КоммерческоеПредложениеСоставляющие
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура.ТехническиеХарактеристики КАК НоменклатураТехническиеХарактеристики
        ПО КоммерческоеПредложениеСоставляющие.Наименование = НоменклатураТехническиеХарактеристики.Ссылка

В данном примере мы видим две критические ошибки, которые могут привести к зависанию или неверному результату:

  1. Сравнение ссылки со строкой: Поле Наименование в табличной части документа часто является строковым представлением, в то время как Ссылка в табличной части справочника — это всегда ссылка на владельца (объект Номенклатура). Соединение по разным типам данных работает крайне медленно и некорректно.
  2. Использование Левого соединения с условием в ГДЕ: Если мы хотим отфильтровать пустые характеристики, новички часто пишут ГДЕ НоменклатураТехническиеХарактеристики.Свойство <> "". В этом случае ЛЕВОЕ СОЕДИНЕНИЕ превращается во ВНУТРЕННЕЕ, и если у товара вообще нет характеристик, он просто исчезнет из результата запроса.

Правильная реализация запроса

Теперь разберем, как написать запрос правильно. Мы будем использовать ЛЕВОЕ СОЕДИНЕНИЕ, чтобы сохранить в списке все позиции из документа, даже если для них не заполнены характеристики. Условия фильтрации «мусорных» или пустых строк мы вынесем непосредственно в условие связи ПО.

Рассмотрим по шагам оптимальный вариант запроса:


ВЫБРАТЬ
    КоммерческоеПредложениеСоставляющие.Ссылка.Номер КАК НомерДокумента,
    КоммерческоеПредложениеСоставляющие.Номенклатура КАК Номенклатура,
    НоменклатураТехническиеХарактеристики.Свойство КАК Свойство,
    НоменклатураТехническиеХарактеристики.Значение КАК Значение
ИЗ
    Документ.КоммерческоеПредложение.Составляющие КАК КоммерческоеПредложениеСоставляющие
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура.ТехническиеХарактеристики КАК НоменклатураТехническиеХарактеристики
        ПО КоммерческоеПредложениеСоставляющие.Номенклатура = НоменклатураТехническиеХарактеристики.Ссылка
            И (НоменклатураТехническиеХарактеристики.Свойство <> "")
ГДЕ
    КоммерческоеПредложениеСоставляющие.Ссылка = &Ссылка

Что мы сделали в этом запросе:

Обработка пустых значений и NULL

Выясним причину, по которой стандартная функция ЕСТЬNULL может не работать так, как ожидается. В 1С NULL появляется только тогда, когда при левом соединении в правой таблице вообще не найдено соответствующей записи. Однако, если запись в табличной части справочника существует, но поле Свойство (типа Строка) в ней просто не заполнено, запрос вернет не NULL, а пустую строку "".

Проанализируем ситуацию, когда нам нужно вывести прочерк вместо пустого значения. В этом случае лучше использовать конструкцию ВЫБОР:


ВЫБОР
    КОГДА НоменклатураТехническиеХарактеристики.Свойство ЕСТЬ NULL ИЛИ НоменклатураТехническиеХарактеристики.Свойство = ""
        ТОГДА "-"
    ИНАЧЕ НоменклатураТехническиеХарактеристики.Свойство
КОНЕЦ КАК СвойствоВывод

Рекомендации по улучшению архитектуры

Рассмотрим более продвинутый подход. Хранение характеристик в виде обычных строк в табличной части номенклатуры — решение простое, но имеющее ряд недостатков: сложность поиска, риск опечаток и невозможность типизации значений (например, нельзя автоматически сравнить вес, если он записан строкой).

Для более профессиональной разработки рекомендуем рассмотреть следующие варианты:

  1. План видов характеристик (ПВХ): Использование объекта ПланВидовХарактеристик позволяет задать жесткий список свойств (Мощность, Цвет, Габариты) и определить для каждого из них свой тип данных.
  2. Дополнительные реквизиты (БСП): Если ваша конфигурация основана на Библиотеке стандартных подсистем, лучше использовать штатный механизм дополнительных реквизитов. В этом случае данные будут храниться в регистре сведений ЗначенияСвойствОбъектов, а запрос будет строиться к этому регистру, что значительно ускорит работу системы при больших объемах данных.

Таким образом, мы разобрали, как эффективно выбирать технические характеристики из вложенных табличных частей. Помните: правильный выбор полей для соединения (ссылка к ссылке) и грамотное использование секции ПО вместо ГДЕ — залог быстрого и корректного запроса.

← На главную