При разработке обработок по загрузке данных из внешних источников (Excel, текстовые документы или табличные документы 1С) программисты часто сталкиваются с проблемой лишних символов в штрихкодах. Штрихкод типа 4 605 572 007 851 выглядит корректно для глаза человека, но абсолютно непригоден для поиска в базе или печати этикеток, так как содержит пробелы. Рассмотрим подробно, как решить эту задачу, разберем типичные ошибки и выработаем надежный алгоритм обработки данных.
Первое, что нам необходимо проанализировать — это то, как 1С работает с числами. Если мы получаем штрихкод из ячейки как число, платформа автоматически применяет к нему региональные настройки. В русской локализации это означает разделение групп разрядов пробелами (по три цифры).
Многие разработчики пытаются использовать функцию Формат() с параметром ЧГ=0 (ЧГ — группировка разрядов), но это помогает только в момент вывода числа в строку. Если же мы совершаем ошибку и пытаемся присвоить числовое значение реквизиту, имеющему тип строка, платформа может снова добавить разделители.
Золотое правило: Штрихкод всегда должен обрабатываться как Строка. Никогда не преобразовывайте его в тип Число, так как штрихкод может начинаться с нуля (например, 090123...), и при преобразовании в число этот важный ноль будет безвозвратно потерян.
Разберем ситуацию, когда данные уже считаны в строковую переменную, но содержат пробелы. Самый простой и очевидный метод — использование функции СтрЗаменить(). Однако здесь кроется подвох: пробелы могут быть разными.
Существует обычный пробел (код 32) и "неразрывный пробел" (код 160 или Символы.НПП), который часто попадает в 1С при копировании из Excel. Обычная замена " " его не удалит. Проанализируем правильный подход к очистке:
// Получаем сырые данные из формы или таблицы
СыройШтрихкод = ПараметрыФормы[ИндексСтрока][5];
// Принудительно приводим к строке, чтобы избежать проблем с типами
ТекстовыйШтрихкод = Строка(СыройШтрихкод);
// Удаляем обычные пробелы
ТекстовыйШтрихкод = СтрЗаменить(ТекстовыйШтрихкод, " ", "");
// Удаляем неразрывные пробелы (символы НПП)
ТекстовыйШтрихкод = СтрЗаменить(ТекстовыйШтрихкод, Символы.НПП, "");
// Теперь записываем в справочник
НовыйШтрихкод = Справочники.ШтрихКоды.СоздатьЭлемент();
НовыйШтрихкод.Владелец = СтрокаНоменклатура;
НовыйШтрихкод.Наименование = ТекстовыйШтрихкод;
НовыйШтрихкод.Единица = СтрокаНоменклатура.БазоваяЕдиница;
НовыйШтрихкод.Записать();
Если мы заранее знаем, что данные в табличном документе могут восприниматься как число, мы можем предотвратить появление пробелов еще на этапе считывания. Рассмотрим, как правильно использовать конструкцию Формат().
Важно помнить порядок действий: сначала получаем значение, а потом форматируем его. Ошибка в коде автора темы заключалась в том, что он пытался форматировать еще не заполненное поле Наименование.
Правильная последовательность действий:
ЧГ=0, который подавляет группировку разрядов.СокрЛП().
// Индекс 5 — это номер колонки со штрихкодом
ЗначениеИзЯчейки = ПараметрыФормы[ИндексСтрока][5];
// Преобразуем в строку БЕЗ группировки разрядов
Результат = Формат(ЗначениеИзЯчейки, "ЧГ=0");
// Дополнительно страхуемся от случайных пробелов
Результат = СтрЗаменить(Результат, " ", "");
Результат = СтрЗаменить(Результат, Символы.НПП, "");
Строка1 = Справочники.ШтрихКоды.СоздатьЭлемент();
Строка1.Наименование = СокрЛП(Результат);
// ... заполнение остальных реквизитов ...
Строка1.Записать();
Иногда в строке штрихкода могут оказаться не только пробелы, но и другие невидимые символы (табуляция, переносы строк, случайные буквы). В таких случаях лучше всего использовать функцию, которая оставляет в строке только цифры. Проанализируем пример такой функции:
Функция ОчиститьШтрихкод(Знач ВходнаяСтрока) Экспорт
Результат = "";
// Приводим к строке на случай, если пришло число
ВходнаяСтрока = Строка(ВходнаяСтрока);
Для Позиция = 1 По СтрДлина(ВходнаяСтрока) Цикл
Символ = Сред(ВходнаяСтрока, Позиция, 1);
// Проверяем, является ли символ цифрой
Если Найти("0123456789", Символ) > 0 Тогда
Результат = Результат + Символ;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Этот метод является самым надежным, так как он гарантированно удаляет любой "мусор", оставляя только валидную последовательность цифр для штрихкода.
Выясним причину, по которой СокрЛП() часто не помогает. При чтении данных из ТабличногоДокумента у ячейки есть два важных свойства: Текст и Значение.
Текст вернет строку с пробелами.Число).Если вы используете Значение, то при попытке преобразовать его в строку через Строка(Значение), 1С применит стандартный формат с пробелами. Поэтому всегда используйте Формат(Значение, "ЧГ=0").
В современных типовых конфигурациях (УТ 11, ERP 2.x, УНФ) штрихкоды хранятся не в справочниках, а в Регистрах сведений (например, РегистрСведений.ШтрихкодыНоменклатуры). Если вы дорабатываете современную базу, вместо СоздатьЭлемент() вам потребуется использовать менеджер записи регистра:
МенеджерЗаписи = РегистрыСведений.ШтрихкодыНоменклатуры.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Штрихкод = ОчищенныйШтрихкод;
МенеджерЗаписи.Номенклатура = СсылкаНоменклатура;
МенеджерЗаписи.Характеристика = Справочники.ХарактеристикиНоменклатуры.ПустаяСсылка();
МенеджерЗаписи.Упаковка = Справочники.УпаковкиНоменклатуры.ПустаяСсылка();
// Тип штрихкода обычно определяется автоматически или задается вручную (например, EAN13)
МенеджерЗаписи.ТипШтрихкода = ПланыВидовХарактеристик.ТипыШтрихкодов.EAN13;
МенеджерЗаписи.Записать();
Подводя итог, можно сказать, что решение проблемы с пробелами заключается в комплексном подходе: правильном выборе типа данных (только Строка), очистке от всех видов пробелов (код 32 и код 160) и использовании функции Формат для подавления стандартной группировки чисел в платформе 1С.