В процессе работы кассиров часто возникает ситуация, когда при сканировании одного и того же товара несколько раз (особенно если между ними сканировались другие позиции), программа добавляет их в разные строки чека. Например, если сначала отсканировать "Адреналин", затем "Сникерс", а потом снова "Адреналин", в чеке появятся три строки вместо двух. Это неудобно для визуального контроля и увеличивает длину печатного чека. Проанализируем, почему так происходит и как это исправить, особенно в старых конфигурациях вроде 1С:Управление торговлей 10.3.
Разберем логику стандартного механизма. В типовых конфигурациях на обычных формах (УТ 10.3) разработчики заложили алгоритм «проверки только последней строки». Это сделано для максимальной производительности: системе не нужно перебирать сотни строк чека при каждом сканировании. Программа просто смотрит: совпадает ли текущий товар с тем, который был добавлен только что? Если да — количество увеличивается. Если нет — создается новая строка.
Рассмотрим фрагмент стандартного кода, который отвечает за это поведение:
ПоследняяСтрока = Товары.Количество() - 1;
Если Товары.Количество() > 0
И Товары[ПоследняяСтрока].Номенклатура = Номенклатура
И Товары[ПоследняяСтрока].ЕдиницаИзмерения = ЕдиницаИзмерения
И Товары[ПоследняяСтрока].ХарактеристикаНоменклатуры = Характеристика
Тогда
// Нашли совпадение в последней строке, увеличиваем количество
СтрокаТабличнойЧасти = Товары[ПоследняяСтрока];
СтрокаТабличнойЧасти.Количество = СтрокаТабличнойЧасти.Количество + Количество;
Иначе
// Товар не совпал с последним или таблица пуста — добавляем новую строку
СтрокаТабличнойЧасти = Товары.Добавить();
// ... заполнение реквизитов новой строки
КонецЕсли;
Как мы видим, если между двумя «Адреналинами» затесался «Сникерс», условие Товары[ПоследняяСтрока].Номенклатура = Номенклатура не сработает, и программа принудительно создаст новую запись.
Чтобы программа искала товар по всей табличной части, нам нужно изменить алгоритм поиска. Вместо обращения к индексу ПоследняяСтрока, мы воспользуемся методом НайтиСтроки(). Проанализируем, как можно модифицировать этот кусок кода без потери производительности.
Рассмотрим пример реализации:
// Формируем структуру параметров для поиска
СтрукПоиска = Новый Структура();
СтрукПоиска.Вставить("Номенклатура", Номенклатура);
СтрукПоиска.Вставить("ЕдиницаИзмерения", ЕдиницаИзмерения);
СтрукПоиска.Вставить("ХарактеристикаНоменклатуры", Характеристика);
// Важно: если используется учет по сериям, добавьте и их
СтрукПоиска.Вставить("СерияНоменклатуры", Серия);
// Ищем все подходящие строки в табличной части "Товары"
ПоискСтрок = Товары.НайтиСтроки(СтрукПоиска);
Если ПоискСтрок.Количество() > 0 Тогда
// Если нашли хотя бы одну строку, берем первую из найденных
СтрокаТабличнойЧасти = ПоискСтрок[0];
СтрокаТабличнойЧасти.Количество = СтрокаТабличнойЧасти.Количество + Количество;
Иначе
// Если ничего не нашли, создаем новую позицию
СтрокаТабличнойЧасти = Товары.Добавить();
// ... стандартное заполнение новой строки
КонецЕсли;
Преимущество этого метода: поиск по структуре работает очень быстро даже на средних чеках. Кассир не заметит задержки, а товар будет корректно суммироваться независимо от очередности сканирования.
Если вы работаете в 1С:Розница 2.3/3.0 или УТ 11, программирование может не понадобиться. В современных решениях на управляемых формах эта опция вынесена в настройки Рабочего Места Кассира (РМК). Проанализируем, где ее найти:
Если эта галочка установлена, система будет автоматически выполнять поиск дублей по всей корзине при каждом событии сканирования штрихкода.
В процессе обсуждения часто звучит предложение использовать метод Товары.Свернуть("Номенклатура...", "Количество"). Проанализируем ситуацию: почему профессиональные разработчики предостерегают от этого метода в интерактивном режиме?
Во-первых, метод Свернуть полностью перестраивает таблицу. Это приводит к тому, что порядок товаров в чеке может измениться случайным образом. Кассиру будет трудно сопоставить бумажный список товаров с экраном монитора.
Во-вторых, при сворачивании могут «потеряться» специфические данные строк, которые не указаны в группировке (например, ручные скидки, особые комментарии или привязка к конкретному продавцу-консультанту).
В-третьих, это ресурсоемкая операция для больших документов, которую нецелесообразно запускать на каждое сканирование штрихкода.
Выясним причину, по которой суммирование может быть категорически запрещено или недоступно. Это касается товаров с обязательной маркировкой (Честный Знак: табак, обувь, одежда) и алкоголя (ЕГАИС).
Для таких товаров каждая единица имеет уникальный идентификатор (DataMatrix или акцизная марка). В системе 1С такие позиции всегда должны идти отдельными строками, так как к каждой строке «привязан» свой уникальный код маркировки. Если вы попытаетесь суммировать 5 пачек сигарет в одну строку, возникнет конфликт при передаче данных в ОФД, так как система не сможет корректно сопоставить 5 кодов с одной позицией.
Совет: при доработке кода (Способ 1) обязательно добавьте проверку: если товар подлежит маркировке, поиск существующей строки должен игнорироваться, и всегда должна добавляться новая строка.
Если НЕ ТоварПодлежитМаркировке Тогда
// Пытаемся найти существующую строку и суммировать
// ... код из Способа 1
Иначе
// Для маркировки всегда добавляем новую строку
СтрокаТабличнойЧасти = Товары.Добавить();
КонецЕсли;
Рассмотрим ситуацию с точки зрения пользователя (UX). Когда кассир сканирует товар, он привык видеть, что внизу списка появилась новая строка. Если товар суммировался где-то в середине чека, кассир может подумать, что сканер не сработал, и отсканирует товар еще раз, что приведет к пересортице.
Рекомендация по внедрению: при программном суммировании в старой строке, добавьте команду активации этой строки. Используйте метод ЭлементыФормы.Товары.ТекущаяСтрока = СтрокаТабличнойЧасти;. В этом случае курсор «прыгнет» на обновленную строку, и кассир визуально подтвердит изменение количества.
Мы проанализировали проблему отсутствия суммирования в 1С и выяснили, что это не ошибка, а особенность стандартного алгоритма. Для исправления ситуации в 1С 8.3 на обычных формах необходимо:
НайтиСтроки().Эти действия позволят сделать работу торговой точки более эффективной, не создавая при этом критических нагрузок на систему 1С.