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

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

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

Проблема уникальности наименования в справочнике

Разберем ситуацию, когда нам необходимо запретить создание в справочнике Номенклатура двух элементов с абсолютно одинаковыми названиями. По умолчанию платформа 1С контролирует уникальность Кода, но не Наименования. Для реализации такой проверки нам потребуется написать обработчик в модуле объекта справочника.

Рассмотрим пример кода, который следует разместить в процедуре ПередЗаписью. Этот метод позволяет проверить наличие дублей в базе данных еще до того, как изменения будут сохранены.


Процедура ПередЗаписью(Отказ)
    
    // Исключаем проверку, если запись производится при обмене данными
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

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

    Запрос.УстановитьПараметр("Наименование", Наименование);
    Запрос.УстановитьПараметр("ЭтаСсылка", Ссылка);

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

    Если НЕ РезультатЗапроса.Пустой() Тогда
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Элемент с таким наименованием уже существует в справочнике!";
        Сообщение.УстановитьДанные(ЭтотОбъект);
        Сообщение.Сообщить();
        
        Отказ = Истина;
    КонецЕсли;

КонецПроцедуры

Проанализируем этот код. Мы используем условие Ссылка <> &ЭтаСсылка, чтобы запрос не находил сам текущий элемент, который мы в данный момент редактируем. Если запрос возвращает результат, это означает, что в базе уже есть другая номенклатура с таким именем. Установка параметра Отказ = Истина прерывает процесс записи.

Предотвращение дублей в табличной части при сканировании

Часто задача стоит иначе: пользователь сканирует штрихкод, и система должна проверить, нет ли этого товара уже в списке (документе). Если товар найден, мы не добавляем новую строку, а, например, увеличиваем количество в существующей. Это критически важно при формировании комплектов или отгрузке товаров на складе.

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


// Предположим, НайденныйТовар — это ссылка на Номенклатуру после поиска по штрихкоду
ПараметрыОтбора = Новый Структура("Номенклатура", НайденныйТовар);
СтрокиТоваров = Объект.Товары.НайтиСтроки(ПараметрыОтбора);

Если СтрокиТоваров.Количество() > 0 Тогда
    // Товар уже есть в таблице, просто увеличиваем количество
    ТекущаяСтрока = СтрокиТоваров[0];
    ТекущаяСтрока.Количество = ТекущаяСтрока.Количество + 1;
    Сообщить("Количество товара '" + НайденныйТовар + "' увеличено.");
Иначе
    // Товара еще нет, добавляем новую строку
    НоваяСтрока = Объект.Товары.Добавить();
    НоваяСтрока.Номенклатура = НайденныйТовар;
    НоваяСтрока.Количество = 1;
КонецЕсли;

Использование метода НайтиСтроки() или Найти() позволяет мгновенно проверить содержимое табличной части, не обращаясь повторно к серверу базы данных, что значительно ускоряет работу интерфейса при поточном сканировании.

Особенности поиска по наименованию и строковым полям

Выясним причину, по которой поиск по наименованию может работать некорректно. Работа со строками в 1С имеет свои нюансы:

  1. Чувствительность к регистру. В зависимости от настроек SQL-сервера, "Молоко" и "молоко" могут считаться разными строками. Для надежности при сравнении рекомендуется использовать функции ВРЕГ() (в верхний регистр) или НРЕГ() (в нижний регистр).
  2. Лишние пробелы. Пользователи часто случайно нажимают пробел в конце или начале слова. Обязательно используйте функцию СокрЛП() перед сохранением или сравнением наименований.
  3. Индексация. Если в вашей базе десятки тысяч наименований, поиск по этому полю будет медленным. В конфигураторе для реквизита Наименование в справочнике Номенклатура следует включить свойство Индексировать.

Использование современных механизмов (БСП)

Проанализируем ситуацию в современных типовых конфигурациях (УТ 11, ERP, Розница). В них работа с торговым оборудованием строится на базе Библиотеки Стандартных Подсистем (БСП). В этом случае логику проверки дублей следует встраивать в обработчик оповещения.

Как правило, это процедура в модуле формы документа, которая получает данные от сканера. Рассмотрим примерную структуру такой обработки:


&НаКлиенте
Процедура ОбработатьШтрихкод(ДанныеШтрихкода)
    
    // Вызываем серверный метод для поиска номенклатуры и проверки дублей
    РезультатОбработки = ОбработатьСканированиеНаСервере(ДанныеШтрихкода);
    
    Если РезультатОбработки.Статус = "Дубль" Тогда
        // Оповещаем пользователя звуком или визуально
        Сигнал();
        ПоказатьОповещениеПользователя("Внимание", , "Товар уже добавлен в список!");
    КонецЕсли;
    
КонецПроцедуры

Визуальный и звуковой контроль

При работе на складе сотрудник редко смотрит в монитор. Поэтому простого сообщения об ошибке на экране недостаточно. Разберем «лучшие практики» интерфейсного взаимодействия:

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

← На главную