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

Программист 1С v8.3 (Управляемые формы) Управленческий учет Промышленность, строительство и АПК
← На главную

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

Анализ типичной ошибки: вложенный запрос в полях выборки

Рассмотрим ситуацию: автор пытается получить штрихкод, используя конструкцию (ВЫБРАТЬ ШтрихкодыНоменклатуры.Штрихкод ...) внутри основного списка полей. Это называется коррелированным подзапросом. Проанализируем, почему это плохо:

  1. Производительность: СУБД будет выполнять отдельный поиск в регистре штрихкодов для каждой строки вашего документа. Если в документе 100 строк, будет выполнено 100 микро-запросов.
  2. Ограничения платформы: Платформа 1С накладывает жесткие ограничения на использование табличных частей во вложенных запросах такого типа, что часто вызывает ошибку «В условиях соединения запроса не допускается обращение к табличным частям».

Правильный подход: Использование ЛЕВОЕ СОЕДИНЕНИЕ

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

Для начала выберем данные из табличной части Продукция документа ОТК_КонтрольПроволоки и присоединим к ней регистр сведений ШтрихкодыНоменклатуры. Посмотрим на базовую структуру запроса:


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

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

Как получить данные из шапки документа

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

Проанализируем пример кода, который позволяет достать дату производства и диаметр из основного документа:


ВЫБРАТЬ
    ТЧ_Продукция.Ссылка.ДатаПроизводства КАК ДатаПроизводства,
    ТЧ_Продукция.Ссылка.ДиаметрНоминальный КАК Диаметр,
    ТЧ_Продукция.Номенклатура,
    Штрихкоды.Штрихкод
ИЗ
    Документ.ОТК_КонтрольПроволоки.Продукция КАК ТЧ_Продукция
...

Важный совет по оптимизации: В 1С обращение через точку в запросе (ТЧ.Ссылка.Дата) на уровне СУБД создает еще одно неявное левое соединение с таблицей документа. Если реквизитов шапки много, правильнее будет один раз явно соединиться с таблицей Документ.ОТК_КонтрольПроволоки по полю Ссылка.

Решение проблемы дублирования (Группировка)

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

Рассмотрим итоговый рабочий алгоритм запроса:


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

В данном примере мы используем агрегатную функцию МИНИМУМ(Штрихкод). Это гарантирует, что для каждой строки табличной части будет выбран только один штрихкод, и строки документа не будут дублироваться в печатной форме.

Дополнительные рекомендации для профессиональной разработки

Чтобы ваш код был надежным и быстрым, обратите внимание на следующие моменты:

  1. Обработка пустых значений (NULL): Если штрихкод не найден, в поле попадет NULL. Чтобы избежать проблем при выводе, используйте функцию ЕСТЬNULL(Штрихкоды.Штрихкод, ""). Это заменит пустое значение на пустую строку.
  2. Индексация: Проверьте, что в регистре штрихкодов измерение Номенклатура проиндексировано. В типовых конфигурациях это обычно так, но в самописных решениях отсутствие индекса на больших объемах данных (сотни тысяч штрихкодов) приведет к зависанию системы.
  3. Использование Временных Таблиц: Если документ очень большой или логика получения штрихкода сложнее (например, нужно учитывать упаковки или характеристики), рекомендуется сначала выбрать уникальную номенклатуру из документа во Временную Таблицу, соединить её с регистром, и только потом результат соединять с исходной табличной частью.
  4. Система Компоновки Данных (СКД): Если вы делаете отчет, а не жесткую форму печати на принтер, лучше использовать СКД. В СКД связи между наборами данных настраиваются визуально, и система сама эффективно управляет получением данных и их группировкой.

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

← На главную