Как получить данные из справочника и штрихкоды из регистра сведений с фильтрацией

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

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

Постановка задачи и анализ ситуации

Представим ситуацию: у нас есть справочник Номенклатура и регистр сведений Штрихкоды. У одного товара может быть несколько штрихкодов, один или вообще ни одного. В регистре есть поле (реквизит или измерение) УДАЛЕНО с типом Булево. Нам нужно получить таблицу, где каждой строке товара соответствует его активный штрихкод. Если штрихкодов несколько — товар дублируется. Если штрихкода нет — товар все равно должен быть в списке с пустым полем кода.

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

  1. Первоочередными являются данные из справочника (все товары должны попасть в результат).
  2. К товару присоединяются только «живые» штрихкоды (где УДАЛЕНО = ЛОЖЬ).
  3. Если у товара нет активных штрихкодов, в колонке штрихкода должен быть NULL или пустая строка.

Главная техническая ловушка: Левое соединение и секция ГДЕ

Проанализируем самую распространенную ошибку. Многие начинающие разработчики пытаются наложить условие фильтрации регистра в секции ГДЕ. Посмотрим, к чему это приведет в коде:


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Товар,
    Штрихкоды.Штрихкод КАК Штрихкод
ИЗ
    Справочник.Номенклатура КАК Номенклатура
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Штрихкоды КАК Штрихкоды
        ПО Номенклатура.Ссылка = Штрихкоды.Владелец
ГДЕ
    Штрихкоды.УДАЛЕНО = ЛОЖЬ

Внимание! Такой запрос отработает неверно. При использовании ЛЕВОЕ СОЕДИНЕНИЕ для товаров без штрихкодов все поля таблицы регистра примут значение NULL. Условие NULL = ЛОЖЬ в секции ГДЕ даст результат «Ложь», и такие товары просто исчезнут из итоговой выборки. Фактически, запрос превратится во ВНУТРЕННЕЕ СОЕДИНЕНИЕ. Выясним, как сделать правильно.

Решение №1: Фильтрация непосредственно в условии связи

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

Разберем пример правильного кода:


ВЫБРАТЬ
    Товары.Ссылка КАК Товар,
    Товары.Наименование КАК Наименование,
    ЕСТЬNULL(Коды.Штрихкод, "") КАК Штрихкод
ИЗ
    Справочник.Номенклатура КАК Товары
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Штрихкоды КАК Коды
        ПО Товары.Ссылка = Коды.Владелец
            И (Коды.УДАЛЕНО = ЛОЖЬ)

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

Решение №2: Использование вложенного запроса

Если логика фильтрации регистра сложная (например, нужно проверять несколько условий или обращаться к другим таблицам), удобно использовать вложенный запрос. Сначала мы выбираем только нужные нам «чистые» данные из регистра, а затем соединяем полученную временную таблицу со справочником.

Посмотрим на пример со вложенным запросом:


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Товар,
    АктивныеШтрихкоды.Штрихкод КАК Штрихкод
ИЗ
    Справочник.Номенклатура КАК Номенклатура
        ЛЕВОЕ СОЕДИНЕНИЕ (
            ВЫБРАТЬ
                Штрихкоды.Владелец КАК Владелец,
                Штрихкоды.Штрихкод КАК Штрихкод
            ИЗ
                РегистрСведений.Штрихкоды КАК Штрихкоды
            ГДЕ
                Штрихкоды.УДАЛЕНО = ЛОЖЬ
        ) КАК АктивныеШтрихкоды
        ПО Номенклатура.Ссылка = АктивныеШтрихкоды.Владелец

Такой подход делает структуру запроса более прозрачной и позволяет избежать проблем с индексацией и производительностью на больших объемах данных.

Особенности работы в типовых конфигурациях (УТ 11, ERP, КА 2)

Если вы работаете в современных конфигурациях, штрихкоды часто хранятся в регистре ШтрихкодыНоменклатуры. Проанализируем важные нюансы, которые могут встретиться:

Производительность и индексирование

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

Также стоит помнить, что дублирование записей при наличии нескольких штрихкодов — это нормальное поведение SQL-запроса. Если вам нужно вывести данные красиво (товар один раз, а под ним список кодов), лучше использовать Систему компоновки данных (СКД) и настроить соответствующие группировки по товару.

Подведем итог: для корректного соединения справочника с регистром всегда используйте ЛЕВОЕ СОЕДИНЕНИЕ и выносите все фильтры правой таблицы (регистра) либо в условие ПО, либо во вложенный запрос. Это гарантирует полноту данных и корректность логики программы.

← На главную