В процессе автоматизации складского учета или розничных продаж часто возникает ситуация, когда при сканировании штрихкодов в документ попадают дублирующиеся позиции. Это может происходить по разным причинам: от невнимательности сотрудника до технических особенностей реализации справочника Номенклатура. В данной статье мы подробно разберем, как обеспечить уникальность наименований в базе данных и как правильно настроить обработку сканирования, чтобы избежать повторного ввода одних и тех же позиций в табличную часть.
Разберем ситуацию, когда нам необходимо запретить создание в справочнике Номенклатура двух элементов с абсолютно одинаковыми названиями. По умолчанию платформа 1С контролирует уникальность Кода, но не Наименования. Для реализации такой проверки нам потребуется написать обработчик в модуле объекта справочника.
Рассмотрим пример кода, который следует разместить в процедуре ПередЗаписью. Этот метод позволяет проверить наличие дублей в базе данных еще до того, как изменения будут сохранены.
Процедура ПередЗаписью(Отказ)
// Исключаем проверку, если запись производится при обмене данными
Если ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Наименование = &Наименование
| И Номенклатура.Ссылка <> &ЭтаСсылка";
Запрос.УстановитьПараметр("Наименование", Наименование);
Запрос.УстановитьПараметр("ЭтаСсылка", Ссылка);
РезультатЗапроса = Запрос.Выполнить();
Если НЕ РезультатЗапроса.Пустой() Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Элемент с таким наименованием уже существует в справочнике!";
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Проанализируем этот код. Мы используем условие Ссылка <> &ЭтаСсылка, чтобы запрос не находил сам текущий элемент, который мы в данный момент редактируем. Если запрос возвращает результат, это означает, что в базе уже есть другая номенклатура с таким именем. Установка параметра Отказ = Истина прерывает процесс записи.
Часто задача стоит иначе: пользователь сканирует штрихкод, и система должна проверить, нет ли этого товара уже в списке (документе). Если товар найден, мы не добавляем новую строку, а, например, увеличиваем количество в существующей. Это критически важно при формировании комплектов или отгрузке товаров на складе.
Посмотрим, как реализовать проверку внутри табличной части документа. Для этого лучше всего подходит метод Найти(). Предположим, что сканер передает нам найденную ссылку на номенклатуру.
// Предположим, НайденныйТовар — это ссылка на Номенклатуру после поиска по штрихкоду
ПараметрыОтбора = Новый Структура("Номенклатура", НайденныйТовар);
СтрокиТоваров = Объект.Товары.НайтиСтроки(ПараметрыОтбора);
Если СтрокиТоваров.Количество() > 0 Тогда
// Товар уже есть в таблице, просто увеличиваем количество
ТекущаяСтрока = СтрокиТоваров[0];
ТекущаяСтрока.Количество = ТекущаяСтрока.Количество + 1;
Сообщить("Количество товара '" + НайденныйТовар + "' увеличено.");
Иначе
// Товара еще нет, добавляем новую строку
НоваяСтрока = Объект.Товары.Добавить();
НоваяСтрока.Номенклатура = НайденныйТовар;
НоваяСтрока.Количество = 1;
КонецЕсли;
Использование метода НайтиСтроки() или Найти() позволяет мгновенно проверить содержимое табличной части, не обращаясь повторно к серверу базы данных, что значительно ускоряет работу интерфейса при поточном сканировании.
Выясним причину, по которой поиск по наименованию может работать некорректно. Работа со строками в 1С имеет свои нюансы:
ВРЕГ() (в верхний регистр) или НРЕГ() (в нижний регистр).СокрЛП() перед сохранением или сравнением наименований.Наименование в справочнике Номенклатура следует включить свойство Индексировать.Проанализируем ситуацию в современных типовых конфигурациях (УТ 11, ERP, Розница). В них работа с торговым оборудованием строится на базе Библиотеки Стандартных Подсистем (БСП). В этом случае логику проверки дублей следует встраивать в обработчик оповещения.
Как правило, это процедура в модуле формы документа, которая получает данные от сканера. Рассмотрим примерную структуру такой обработки:
&НаКлиенте
Процедура ОбработатьШтрихкод(ДанныеШтрихкода)
// Вызываем серверный метод для поиска номенклатуры и проверки дублей
РезультатОбработки = ОбработатьСканированиеНаСервере(ДанныеШтрихкода);
Если РезультатОбработки.Статус = "Дубль" Тогда
// Оповещаем пользователя звуком или визуально
Сигнал();
ПоказатьОповещениеПользователя("Внимание", , "Товар уже добавлен в список!");
КонецЕсли;
КонецПроцедуры
При работе на складе сотрудник редко смотрит в монитор. Поэтому простого сообщения об ошибке на экране недостаточно. Разберем «лучшие практики» интерфейсного взаимодействия:
Сигнал() для уведомления о дубле. В идеале можно подключить разные звуковые файлы: короткий приятный звук для успешного сканирования и резкий/двойной для ошибки или повтора.Подводя итог, отметим: если ваша цель — чистота справочника, используйте проверку в ПередЗаписью модуля объекта. Если же нужно ускорить работу оператора при вводе данных — реализуйте поиск дублей непосредственно в табличной части документа перед добавлением новой строки.