Приветствуем вас! При работе кассиров в режиме рабочего места кассира (РМК) в программе 1С:Розница периодически могут возникать непредвиденные сбои, которые блокируют продажи на кассе и вызывают панику у персонала, особенно во время ночных смен. Одной из таких коварных неполадок является критическая ошибка «получение элемента по индексу для значения не определено», возникающая непосредственно в момент сканирования акцизной марки на алкогольную продукцию.
В этой статье мы подробно разберем, почему возникает этот сбой, проанализируем его внутренние технические причины на уровне платформы 1С:Предприятие 8.3, выясним, откуда в информационной базе берутся некорректные данные, и рассмотрим несколько эффективных способов решения проблемы — от быстрого временного обхода до полноценного исправления кода и настроек торгового оборудования.
Давайте проанализируем ситуацию, в которой проявляется эта ошибка. Как показывает практика работы торговых точек, сбой происходит далеко не при каждой продаже алкоголя. Более того, если кассир сразу сканирует акцизную марку бутылки, система отрабатывает штатно — товар быстро и без проблем добавляется в чек.
Однако классический и наиболее правильный алгоритм продажи алкогольной продукции (рекомендованный ФС-РАР) выглядит иначе:
Давайте выясним, почему порядок действий кассира кардинально влияет на стабильность работы программы.
В процессе исследования базы данных мы можем обнаружить удивительный факт: некоторые штрихкоды упаковок сохранены в справочнике ШтрихкодыУпаковокТоваров строчными (маленькими) буквами, например: 22n000004cvf7rda7q30... вместо стандартного верхнего регистра: 22N000004CVF7RDA7Q30....
Каким же образом данные элементы попадают в базу в таком виде? Выделим две основные причины:
1С:Розница (в частности, в ветке 2.2.8) парсер XML-данных записывал эти штрихкоды в справочник «как есть», без принудительной конвертации символов в верхний регистр.Разберем, почему разница в регистре символов приводит к аварийному завершению работы РМК. Для этого сопоставим поведение платформы в двух разных сценариях работы:
Сценарий без ошибки (сканирование сразу по марке): Когда кассир считывает марку напрямую, система выполняет полнотекстовый SQL-запрос к базе данных для поиска соответствующей номенклатуры. Поиск в СУБД (MS SQL, PostgreSQL или файловой СУБД 1С) по умолчанию является регистронезависимым. База данных успешно находит нужную запись в справочнике ШтрихкодыУпаковокТоваров, сопоставляет её с алкогольной продукцией и добавляет товар в корзину.
Сценарий с ошибкой (сначала EAN-13, затем марка): Здесь логика работы программы кардинально меняется:
Соответствие (в коде за это отвечает переменная, условно назовем ее Результат), где ключом выступает сам текст штрихкода.Соответствие в платформе 1С:Предприятие является регистрозависимым. Если в базе марка была записана строчными буквами, то в коллекции Соответствие ключ сохранится в виде "22n..."."22N...".Результат[Штрихкод]. Из-за несовпадения регистров (строчные буквы в ключе против прописных в запросе) поиск возвращает пустое значение — Неопределено.
МассивУпаковок = Результат[Штрихкод][0];
Поскольку Результат[Штрихкод] вернул Неопределено, платформа выполняет операцию Неопределено[0], что моментально вызывает исключение: «Получение элемента по индексу для значения не определено».
Рассмотрим по шагам все доступные методы устранения этой проблемы, начиная с самых простых и заканчивая технически правильными.
Разработчики 1С признали данное поведение ошибкой и исправили его в последующих релизах. Начиная с релиза 2.2.11.29 (и далее во всех версиях линейки 2.3), в модули работы с ЕГАИС и штрихкодами было добавлено принудительное преобразование всех считываемых и загружаемых марок к верхнему регистру с помощью функции ВРег(). Если у вас есть возможность, выполните обновление вашей конфигурации 1С:Розница до актуального релиза.
Если ваша база сильно доработана или оперативно обновиться нет возможности, мы можем внести точечное исправление в код конфигурации. Для этого выполним следующие действия:
ШтрихкодыУпаковокТоваров.Результат.Вставить(...)).ВРег() для приведения ключа к верхнему регистру.Пример изменения строки кода:
// Было:
Результат.Вставить(СтрокаТЧ.ЗначениеШтрихкода, МассивУпаковок);
// Стало:
Результат.Вставить(ВРег(СтрокаТЧ.ЗначениеШтрихкода), МассивУпаковок);
Это простое исправление гарантирует, что даже если марка записана в базе маленькими буквами, в коллекцию поиска она попадет в верхнем регистре, и сбой при сканировании прекратится.
Чтобы окончательно очистить базу от некорректных записей в нижнем регистре, нам необходимо преобразовать их к верхнему регистру. Для этого мы можем написать и запустить простую одноразовую обработку.
Рассмотрим пример кода внешней обработки, выполняющей обход справочника ШтрихкодыУпаковокТоваров:
Выборка = Справочники.ШтрихкодыУпаковокТоваров.Выбрать();
Пока Выборка.Следующий() Цикл
// Проверяем, отличается ли текущий регистр от верхнего
Если Выборка.ЗначениеШтрихкода <> ВРег(Выборка.ЗначениеШтрихкода) Тогда
Попытка
ОбъектМарки = Выборка.ПолучитьОбъект();
ОбъектМарки.ЗначениеШтрихкода = ВРег(Выборка.ЗначениеШтрихкода);
ОбъектМарки.Записать();
Исключение
ЗаписьЖурналаРегистрации("ИсправлениеМарок", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
Важно: Перед запуском любого корректирующего кода обязательно выполните резервное копирование вашей информационной базы!
Для предотвращения искажения регистра символов в процессе сканирования крайне рекомендуется отказаться от работы сканера в режиме эмуляции клавиатуры. Выполним следующие настройки:
1С:Розница перейдем в меню «Администрирование» — «Подключаемое оборудование» и настроим сканер штрихкода на работу через СОМ-порт с использованием интерфейса 1С:Предприятие (NativeAPI).Это полностью исключит влияние раскладки клавиатуры операционной системы на регистр передаваемых в 1С символов.
Если ошибка произошла прямо посреди рабочей смены и у вас нет возможности немедленно программировать или менять настройки оборудования, проинструктируйте кассира выполнять продажу по альтернативному сценарию:
При таком алгоритме программа задействует другие механизмы сопоставления данных, которые не вызывают критического падения системы.
Используя приведенные инструкции, вы сможете быстро локализовать и устранить сбой, обеспечив бесперебойную работу кассового узла торговой точки!