Как найти номенклатуру с одинаковыми артикулами в 1С?

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

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

Вариант 1. Простой поиск повторяющихся артикулов

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


ВЫБРАТЬ
    Номенклатура.Артикул КАК Артикул
ИЗ
    Справочник.Номенклатура КАК Номенклатура
СГРУППИРОВАТЬ ПО
    Номенклатура.Артикул
ИМЕЮЩИЕ
    КОЛИЧЕСТВО(Номенклатура.Артикул) > 1

В данном запросе мы выбираем поле Артикул, группируем все записи по этому полю и с помощью условия ИМЕЮЩИЕ отсекаем те значения, которые встречаются в справочнике только один раз. Однако этот запрос покажет нам только сами строки артикулов, но не даст ссылок на конкретные карточки номенклатуры.

Вариант 2. Получение списка номенклатуры с дублями (Оптимальный способ)

Чтобы увидеть не просто «плохой» артикул, а все ссылки на элементы справочника, которые его используют, нам необходимо соединить справочник сам с собой или со вложенным запросом. Рассмотрим наиболее изящное и производительное решение с использованием ВНУТРЕННЕЕ СОЕДИНЕНИЕ:


ВЫБРАТЬ
    Н.Ссылка КАК Ссылка,
    Т.Артикул КАК Артикул
ИЗ
    Справочник.Номенклатура КАК Н
ВНУТРЕННЕЕ СОЕДИНЕНИЕ (
    ВЫБРАТЬ
        Артикул
    ИЗ
        Справочник.Номенклатура
    СГРУППИРОВАТЬ ПО
        Артикул
    ИМЕЮЩИЕ
        КОЛИЧЕСТВО(Ссылка) > 1
) КАК Т
ПО
    Т.Артикул = Н.Артикул
ГДЕ
    Н.Артикул <> ""

Разберем, как работает этот запрос по шагам:

  1. Вложенный запрос: Сначала система выполняет выборку внутри скобок, находя все артикулы, которые повторяются более одного раза (аналогично первому варианту).
  2. Внутреннее соединение: Затем мы соединяем весь справочник Номенклатура с этим списком «проблемных» артикулов. Условие соединения Т.Артикул = Н.Артикул гарантирует, что в итоговую выборку попадут только те элементы, чей артикул оказался в списке дублей.
  3. Фильтрация: Мы добавили условие ГДЕ Н.Артикул <> "", чтобы исключить из результата пустые артикулы. Если в базе много товаров без артикула, система посчитает их дублями, что обычно не является целью поиска.

Вариант 3. Использование временных таблиц

Иногда задача требует предварительной подготовки данных, например, если мы ищем дубли среди определенного массива входящих значений. В таком случае удобно использовать МенеджерВременныхТаблиц. Посмотрим на пример более сложной структуры:


ВЫБРАТЬ
    Номенклатура.Артикул КАК Артикул
ПОМЕСТИТЬ ВТ_ДублирующиеАртикулы
ИЗ
    Справочник.Номенклатура КАК Номенклатура
СГРУППИРОВАТЬ ПО
    Номенклатура.Артикул
ИМЕЮЩИЕ
    КОЛИЧЕСТВО(Номенклатура.Ссылка) > 1
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка,
    Номенклатура.Артикул КАК Артикул
ИЗ
    ВТ_ДублирующиеАртикулы КАК ВТ_ДублирующиеАртикулы
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
ПО
    ВТ_ДублирующиеАртикулы.Артикул = Номенклатура.Артикул

Такой подход делает код более читаемым при разработке сложных отчетов или обработок. Мы сначала четко выделяем проблему во временную таблицу ВТ_ДублирующиеАртикулы, а затем «вытягиваем» нужные нам данные по ссылке.

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

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

  1. Невидимые символы и пробелы: Артикулы "123" и " 123" (с пробелом впереди) для базы данных являются абсолютно разными строками. Перед выполнением запроса в реальных задачах часто требуется очистка данных.
  2. Регистр символов: В зависимости от настроек базы данных (SQL Collation), артикулы "abc" и "ABC" могут считаться как одинаковыми, так и разными. Если поиск не дает результатов, попробуйте использовать функции приведения к регистру.
  3. Характеристики: Выясним, не задаются ли артикулы на уровне характеристик. В некоторых конфигурациях (например, УТ 11 или ERP) артикул может храниться не в самой номенклатуре, а в подчиненном справочнике ХарактеристикиНоменклатуры. В этом случае запрос нужно строить именно по нему.

Оптимизация производительности

Если в вашем справочнике Номенклатура сотни тысяч записей, выполнение группировки может занять длительное время и заблокировать работу других пользователей. Чтобы ускорить процесс, убедитесь, что для реквизита Артикул в конфигураторе установлено свойство Индексировать. Наличие индекса позволяет СУБД мгновенно выполнять группировку, не сканируя всю таблицу целиком.

Типовые инструменты 1С:Предприятие 8

Не всегда обязательно писать код вручную. Проанализируем стандартные возможности современных конфигураций (БП 3.0, УТ 11, УНФ). В разделе Администрирование — Обслуживание существует типовая обработка «Поиск и удаление дублей».

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

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

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

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

Рассмотрим пример кода для проверки перед записью:


Процедура ПередЗаписью(Отказ)
    Если ЗначениеЗаполнено(ЭтотОбъект.Артикул) Тогда
        Запрос = Новый Запрос;
        Запрос.Текст = 
            "ВЫБРАТЬ ПЕРВЫЕ 1
            |	Номенклатура.Ссылка КАК Ссылка
            |ИЗ
            |	Справочник.Номенклатура КАК Номенклатура
            |ГДЕ
            |	Номенклатура.Артикул = &Артикул
            |	И Номенклатура.Ссылка <> &Ссылка";
        
        Запрос.УстановитьПараметр("Артикул", ЭтотОбъект.Артикул);
        Запрос.УстановитьПараметр("Ссылка", ЭтотОбъект.Ссылка);
        
        РезультатЗапроса = Запрос.Выполнить();
        Если Не РезультатЗапроса.Пустой() Тогда
            Сообщить("Внимание! Номенклатура с таким артикулом уже существует.");
            // Если нужно запретить запись, раскомментируйте строку ниже:
            // Отказ = Истина;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

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

← На главную