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

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

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

Анализ исходной проблемы

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

  1. Разная природа данных: Штрихкод может быть присвоен номенклатуре в целом, а серийный номер — конкретной единице товара.
  2. Производительность: Соединение по строковому полю (Наименование серийного номера и Штрихкод) — ресурсоемкая операция, которая замедляется при росте базы данных.
  3. Структура метаданных: В конфигурации УНФ справочник СерийныеНомера подчинен справочнику Номенклатура через поле Владелец, что необходимо учитывать при построении связей.

Метод 1: Использование конструкции ОБЪЕДИНИТЬ ВСЕ

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

Сначала мы выбираем данные из регистра штрихкодов, а затем добавляем к ним данные из справочника серийных номеров. Посмотрим на пример кода:


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

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    СерийныеНомера.Наименование,
    СерийныеНомера.Владелец,
    СерийныеНомера.Ссылка
ИЗ
    Справочник.СерийныеНомера КАК СерийныеНомера
ГДЕ
    СерийныеНомера.Наименование В(&МассивКодов)

В данном примере мы используем ЗНАЧЕНИЕ(Справочник.СерийныеНомера.ПустаяСсылка) в первой части объединения. Это критически важно для соблюдения типизации колонок. Если вместо пустой ссылки использовать NULL, система может создать составной тип данных, что негативно скажется на скорости дальнейшей обработки таблицы.

Метод 2: Работа через временные таблицы с последующей группировкой

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

Рассмотрим алгоритм работы с временными таблицами:

  1. Помещаем массив искомых кодов во временную таблицу ВТ_ИскомыеКоды.
  2. Выполняем поиск по штрихкодам и сериям, сохраняя результат в ВТ_Результаты.
  3. Делаем финальную выборку с группировкой, чтобы исключить дубли.

Пример продвинутого запроса:


// 1. Помещаем коды во временную таблицу
ВЫБРАТЬ
    Тк.Код КАК Код
ПОМЕСТИТЬ ВТ_Коды
ИЗ
    &ТаблицаКодов КАК Тк
;

// 2. Собираем данные
ВЫБРАТЬ
    Рег.Номенклатура КАК Номенклатура,
    ЗНАЧЕНИЕ(Справочник.СерийныеНомера.ПустаяСсылка) КАК Серия,
    ВТ_Коды.Код КАК ИсходныйКод
ПОМЕСТИТЬ ВТ_ОбщийПоиск
ИЗ
    ВТ_Коды КАК ВТ_Коды
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ШтрихкодыНоменклатуры КАК Рег
        ПО ВТ_Коды.Код = Рег.Штрихкод

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    Серии.Владелец,
    Серии.Ссылка,
    ВТ_Коды.Код
ИЗ
    ВТ_Коды КАК ВТ_Коды
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.СерийныеНомера КАК Серии
        ПО ВТ_Коды.Код = Серии.Наименование
;

// 3. Финальный результат
ВЫБРАТЬ
    ВТ.ИсходныйКод,
    ВТ.Номенклатура,
    МАКСИМУМ(ВТ.Серия) КАК Серия
ИЗ
    ВТ_ОбщийПоиск КАК ВТ
СГРУППИРОВАТЬ ПО
    ВТ.ИсходныйКод,
    ВТ.Номенклатура

Важные технические нюансы

При работе с серийными номерами в УНФ следует учитывать настройки учета. Проанализируем объект Справочник.СерийныеНомера. Его поле Владелец всегда содержит ссылку на Справочник.Номенклатура или Справочник.ХарактеристикиНоменклатуры (в зависимости от настроек). Если ваша логика предполагает работу с характеристиками, обязательно добавьте поле Характеристика в выборку запроса.

Рекомендация по нормализации: Перед передачей массива &МассивКодов в запрос, убедитесь, что строки очищены от лишних пробелов и спецсимволов. Для штрихкодов стандарта EAN-13 это критично. В современных версиях платформы для этих целей удобно использовать программные методы обработки строк перед формированием параметров запроса.

Также стоит помнить о производительности ПОЛНОГО СОЕДИНЕНИЯ. В сообщениях форума предлагался этот вариант, однако в задачах поиска по кодам он крайне нежелателен, так как порождает избыточное количество строк в промежуточных результатах, которые потом приходится отсекать через ГДЕ. Использование ОБЪЕДИНИТЬ ВСЕ с временными таблицами — это "золотой стандарт" для подобных задач в 1С.

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

← На главную