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

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

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

Причины некорректного поиска и дублирования позиций

По умолчанию обработка загрузки работает по следующим строгим правилам платформы 1С:

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

Способ 1. Проверка уникальности в событии «Перед записью объекта»

Если требуется загружать номенклатуру напрямую в справочник и при этом строго запретить создание новых элементов при совпадении артикула, наиболее надежным способом является написание кода проверки в событии обработки ПередЗаписьюОбъекта.

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |	Номенклатура.Ссылка КАК Ссылка
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |	Номенклатура.Артикул = &Артикул";

Запрос.УстановитьПараметр("Артикул", Объект.Артикул);

РезультатЗапроса = Запрос.Выполнить();

Если НЕ РезультатЗапроса.Пустой() Тогда
    // Товар уже существует в базе — отменяем создание дубля
    Отказ = Истина;
КонецЕсли;

Если артикул в файле может быть не заполнен, но в таких случаях необходимо сопоставлять товары по наименованию, усложним условие с помощью оператора ВЫБОР в тексте запроса:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |	Номенклатура.Ссылка КАК Ссылка
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |	ВЫБОР
    |		КОГДА &ЕстьАртикул ТОГДА Номенклатура.Артикул = &Артикул
    |		ИНАЧЕ Номенклатура.Наименование = &Наименование
    |	КОНЕЦ";

Запрос.УстановитьПараметр("Наименование", Объект.Наименование);
Запрос.УстановитьПараметр("Артикул", Объект.Артикул);
Запрос.УстановитьПараметр("ЕстьАртикул", ЗначениеЗаполнено(Объект.Артикул));

РезультатЗапроса = Запрос.Выполнить();

Если НЕ РезультатЗапроса.Пустой() Тогда
    Отказ = Истина;
КонецЕсли;

Способ 2. Поиск и создание через вычисляемое выражение поля

Другой удобный подход — переопределить логику получения ссылки на номенклатуру в колонке «Выражение» настроек загрузки. Это позволяет программно найти элемент по строгому соответствию и вернуть готовую ссылку, не перезаписывая остальные реквизиты найденного объекта.

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


АртикулПоиска = СокрЛП(ТекстЯчейки);
СсылкаНайденная = Справочники.Номенклатура.НайтиПоРеквизиту("Артикул", АртикулПоиска);

Если ЗначениеЗаполнено(СсылкаНайденная) Тогда
    Результат = СсылкаНайденная;
Иначе
    НовыйОбъект = Справочники.Номенклатура.СоздатьЭлемент();
    НовыйОбъект.Артикул = АртикулПоиска;
    НовыйОбъект.Наименование = СокрЛП(ТекстЯчейки);
    
    Попытка
        НовыйОбъект.Записать();
        Результат = НовыйОбъект.Ссылка;
    Исключение
        Сообщить("Не удалось записать новую позицию: " + ОписаниеОшибки());
        Результат = Справочники.Номенклатура.ПустаяСсылка();
    КонецПопытки;
КонецЕсли;

При поиске по наименованию обратим внимание на параметры стандартного метода Справочники.Номенклатура.НайтиПоНаименованию(). Второй параметр метода управляет точностью поиска: передача значения Истина означает поиск по точному совпадению всей строки, а не по началу наименования.


СсылкаПоНаименованию = Справочники.Номенклатура.НайтиПоНаименованию(СокрЛП(ТекстЯчейки), Истина);

Способ 3. Загрузка напрямую в табличную часть документа

Если конечной целью является оформление накладной (например, документа ПоступлениеТоваров / ПоступлениеТоваровУслуг), оптимальнее загружать данные не в справочник Номенклатура, а сразу в табличную часть документа:

  1. В верхней части обработки переключим режим загрузки на «Табличная часть» и выберем нужный документ.
  2. Для реквизита Номенклатура в табличной части настроим поле поиска только по артикулу или коду.
  3. Установим флаг автоматического создания новых элементов при их отсутствии в справочнике. В таком случае система подставит существующие ссылки без изменения их наименований, а новые карточки создаст только для тех строк, которые действительно не найдены.

Особенности работы с автозапчастями (конфигурации линейки «Альфа-Авто»)

При работе с отраслевыми решениями для автобизнеса важно учитывать специфику учета каталожных номеров:

  1. Составная уникальность: каталожный номер запчасти уникален только в связке с конкретным брендом (производителем). Один и тот же артикул может принадлежать разным деталям разных заводов. Поиск рекомендуется выполнять по комбинации Каталожный номер + Производитель.
  2. Очистка артикулов: в специализированных конфигурациях артикулы хранятся в нормализованном виде (без дефисов, точек и пробелов). Перед выполнением поиска программным кодом строку артикула из накладной следует очищать от лишних разделителей.
← На главную