1С нет свободных кодов весовых штрихкодов
2024-01-24
Эта статья актуальна для конфигураций 1C Управление торговлей и Комплексная автоматизация.
Многие магазины используют весы с печатью этикеток для фасовки товаров типа конфет, печенья, заморозки и т.п. Это удобно, т.к. на кассе, кассиру не нужно вводить штрихкод и отдельно взвешивать товар, это очень ускоряет обслуживание.
Если магазин большой или это сеть магазинов, то, со временем, количество весовых товаров может перевалить за 10000, и тогда 1С больше не сможет выгрузить товары в весы. Дело в том, что каждый весовой товар имеет свой уникальный штрихкод в котором зашифрован префикс, код и вес. Стандартная длина штрихкода 13 символов, формула штрихкода такая - 23УТТТТВВВВВК:
23 - префикс штрихкода;
У - код узла;
ТТТТ - код товара;
ВВВВВ - вес товара;
К - контрольное число;
В 1С весовые штрихкоды хранятся в таком виде - 2_0000100000_.
Как понятно из формулы - код товара состоит из четырех цифр, а значит максимум составляет 9999. В большинстве случаев этого достаточно и очень редко весовых товаров может быть больше 10000, но как я уже говорил, что со временем, они могут накопиться. Самое интересное в этом то, что даже удаление устаревших товаров и штрихкодов не поможет в этом случае, потому что 1С просто берет максимальный код и сравнивает его с предельным значением.
На скриншоте выше, видно, что есть 1207 свободных кодов между 2_0878700000_ и 2_0999500000_, но 1С не будет пользоваться этим свободным диапазоном, а забьет свободные коды между 2_0999500000_ и 2_0999900000_, и когда она это сделает, то сформировать новые коды больше не получится.
Почему не хватает штрихкодов?
При выгрузке на весы, 1С формирует штрихкоды по порядку.
Разберем ситуацию: сеть магазинов работает более 10 лет. За это время в базе накопилось много устаревшей номенклатуры. По мере необходимости базу сворачивали и удаляли неиспользуемую номенклатуру вместе со штрихкодами, следовательно, некоторые штрихкоды освободились. И теперь мы имеем список штрихкодов, со свободными кодами не в конце(т.к. последние пришедшие товары их заняли), а внутри всего списка.
Видимо по логике разработчиков 1С такая ситуация или невозможна, или надо просто удалить все штрихкоды и сформировать их заново. Но этот вариант совершенно не приемлем: в магазине могут быть расфасованные товары со старыми этикетками, а после этой процедуры пробить на кассе их не получится.
Идеальным вариантом было бы чтобы 1С искала свободные коды не в конце, а по всему диапазону и занимала бы их.
Решение нехватки штрихкодов
Для решения этой проблемы нужно не просто брать максимальный штрихкод, а нужно найти все свободные штрихкоды и выбрать минимальный.
Функция формирования штрихкодов находится в регистре сведений "Штрихкоды номенклатуры" - ПолучитьМаксимальноеЗначениеКодаВесовыхШтрихкодов().
В нем находится простейший запрос:
"ВЫБРАТЬ | ШтрихкодыНоменклатуры.Штрихкод КАК Штрихкод, | ПОДСТРОКА(ШтрихкодыНоменклатуры.Штрихкод, 4, 4) КАК КодСтрока |ИЗ | РегистрСведений.ШтрихкодыНоменклатуры КАК ШтрихкодыНоменклатуры |ГДЕ | ШтрихкодыНоменклатуры.Штрихкод ПОДОБНО ""2_#ПрефиксУзла#____00000_"" | |УПОРЯДОЧИТЬ ПО | КодСтрока УБЫВ";
Нам же надо совсем другое: нужно получить все штрихкоды и вычесть их пула кодов от 0000 до 9999.
В общем, сначала формируем таблицу значений от 0000 до 9999, потом запросом вытаскиваем ее во временную таблицу, потом в другую временную таблицу выбираем все занятые штрихкоды, и третьим этапом объединяем таблицы и выбираем те коды, которых нет во второй.
Функция ПолучитьМаксимальноеЗначениеКодаВесовыхШтрихкодов()
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("КодСтрока",Новый ОписаниеТипов("Строка",,,,Новый КвалификаторыСтроки(4,ДопустимаяДлина.Фиксированная)));
Номер = 1;
Пока Номер < 10000 Цикл
НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.КодСтрока = Формат(Номер, "ЧЦ=4; ЧВН=; ЧГ=0");
Номер = Номер + 1;
КонецЦикла;
ПрефиксУзла = Строка(Константы.ПрефиксШтрихкодовУзлаРИБ.Получить());
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ *
|ПОМЕСТИТЬ ВТРядЧисел
|ИЗ
|&РядЧисел КАК РядЧисел;
|//
|ВЫБРАТЬ
| ШтрихкодыНоменклатуры.Штрихкод КАК Штрихкод,
| ПОДСТРОКА(ШтрихкодыНоменклатуры.Штрихкод, 4, 4) КАК КодСтрока
|ПОМЕСТИТЬ ВТЗанятыеШК
|ИЗ
| РегистрСведений.ШтрихкодыНоменклатуры КАК ШтрихкодыНоменклатуры
|ГДЕ
| ШтрихкодыНоменклатуры.Штрихкод ПОДОБНО ""2_#ПрефиксУзла#____00000_"" ;
|
|//
|ВЫБРАТЬ ПЕРВЫЕ 1 *
|ИЗ
|ВТРядЧисел КАК РядЧисел
|ЛЕВОЕ СОЕДИНЕНИЕ
|ВТЗанятыеШК КАК ЗанятыеШК
|ПО РядЧисел.КодСтрока = ЗанятыеШК.КодСтрока
|ГДЕ ЗанятыеШК.КодСтрока is NULL
|УПОРЯДОЧИТЬ ПО
|РядЧисел.КодСтрока
|";
Запрос.Текст = СтрЗаменить(Запрос.Текст, "#ПрефиксУзла#", ПрефиксУзла);
Запрос.УстановитьПараметр("РядЧисел", ТЗ);
РезультатЗапроса = Запрос.Выполнить();
ОписаниеТипаЧисла = ОбщегоНазначения.ОписаниеТипаЧисло(15, 0);
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
СвободныйКод = Новый Массив;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Возврат ОписаниеТипаЧисла.ПривестиЗначение(ВыборкаДетальныеЗаписи.КодСтрока) - 1;
КонецЦикла;
Возврат Неопределено;
КонецФункции
Но и это еще не все, еще нужно изменить функцию в общем модуле ПодключаемоеОборудованиеOfflineВызовСервера - ДанныеТоваровДляВыгрузки.
Там формируются и записываются штрихкоды, причем берется самый последний и записывается следующий, нам же надо перед формированием штрихкода вызывать ранее измененную функцию и каждый раз получать новый свободный штрихкод. Для этого нужно изменить одну строчку:
МаксимальноеЗначениеКодаВесовыхШтрихкодов = МаксимальноеЗначениеКодаВесовыхШтрихкодов + 1; Заменяем на МаксимальноеЗначениеКодаВесовыхШтрихкодов = РегистрыСведений.ШтрихкодыНоменклатуры.ПолучитьМаксимальноеЗначениеКодаВесовыхШтрихкодов() + 1;
Конечно же, для удобства, я оформил эту функцию в виде расширения конфигурации.
