При автоматизации загрузки данных из внешних файлов, таких как таблицы Excel, разработчики часто сталкиваются с неприятной особенностью: числовые коды или артикулы, которые в файле выглядят монолитно, после попадания в 1С внезапно «разрываются» пробелами. Например, артикул 123456 превращается в 123 456. Это критично, так как поиск по такому артикулу в справочнике Номенклатура перестает работать.
В этой статье мы подробно разберем, почему возникают эти фантомные пробелы, как правильно очищать данные и что делать, если отладчик отказывается «видеть» ваш код в процессе загрузки.
Проанализируем ситуацию: почему обычная строка внезапно получает лишние символы? Основная причина кроется в том, как 1С интерпретирует данные, полученные через COM-соединение из Excel. Если в ячейке Excel находится число (или нечто, похожее на число с точки зрения Excel), при чтении свойства Value система 1С получает именно числовой тип данных.
Когда это число преобразуется в строку для записи в реквизит 1С, платформа применяет стандартное форматирование — разделение групп разрядов пробелом. Однако это не обычный пробел (код 32), а так называемый неразрывный пробел (код 160). Именно поэтому стандартная функция СтрЗаменить(Строка, " ", "") часто не приносит результата.
Рассмотрим самый эффективный и быстрый способ исправления ситуации. Поскольку мы имеем дело со специальным символом, нам нужно явно указать системе, что именно подлежит удалению. В языке 1С для этого зарезервирована константа Символы.НПП.
Посмотрим на пример кода, который решает проблему непосредственно перед записью данных в таблицу загрузки или поиском в справочнике:
// Очищаем код от неразрывных пробелов
ЧистыйКод = СтрЗаменить(ИсходныйКодИзExcel, Символы.НПП, "");
// Дополнительно удаляем обычные пробелы на случай ручного ввода
ЧистыйКод = СтрЗаменить(ЧистыйКод, " ", "");
// Теперь можно искать номенклатуру
Строка.Номенклатура = Справочники.Номенклатура.НайтиПоРеквизиту("Артикул", ЧистыйКод);
Важно помнить: форматирование и очистку нужно выполнять до того, как значение будет присвоено строковому реквизиту, или сразу в момент обработки строки. Как только данные попали в объект с типом Строка, они сохраняют все лишние символы, и работать с ними нужно как с текстом.
Если мы точно знаем, что входящее значение является числом, но хотим видеть его в виде сплошной строки без разделителей разрядов, можно воспользоваться функцией Формат с параметром ЧГ=0 (Группировка разрядов = 0).
Разберем по шагам, как это применить в цикле обработки данных:
Для Каждого СтрокаДанных Из Объект.ДанныеЗагрузки Цикл
// Если в колонке "Код" число, формат уберет разделители
// Если там уже строка с буквами, функция вернет пустую строку или отработает иначе,
// поэтому добавим проверку типа.
Если ТипЗнч(СтрокаДанных.Код) = Тип("Число") Тогда
СтрокаДанных.Код = Формат(СтрокаДанных.Код, "ЧГ=0");
Иначе
// Если это строка, применяем очистку от НПП
СтрокаДанных.Код = СтрЗаменить(СтрокаДанных.Код, Символы.НПП, "");
КонецЕсли;
КонецЦикла;
Иногда в данных из Excel встречаются не только неразрывные пробелы, но и символы табуляции, переносы строк или другие невидимые знаки форматирования. В современных версиях платформы 8.3 (начиная с 8.3.10) существует изящный способ очистить строку от всех видов «мусора» сразу.
Проанализируем следующий подход:
// Составляем список всех нежелательных символов
Разделители = " " + Символы.НПП + Символы.Таб + Символы.ПС + Символы.ВК;
// Разрезаем строку по этим разделителям и тут же соединяем обратно
ЧастиСтроки = СтрРазделить(ИсходноеЗначение, Разделители, Ложь);
Результат = СтрСоединить(ЧастиСтроки, "");
Этот метод хорош тем, что он «схлопывает» любые пустоты внутри артикула, независимо от их природы, оставляя только значащие цифры и буквы.
Часто программисты жалуются: «Я вношу правки в код, ставлю точку останова, но программа её игнорирует и продолжает загружать данные с пробелами». Выясним, в чем причина такого поведения системы.
В современных конфигурациях, таких как Бухгалтерия предприятия 3.0, длительные операции (загрузка больших файлов) часто выносятся в фоновые задания на стороне сервера. Стандартный отладчик по умолчанию не подключается к фоновым заданиям.
Чтобы успешно отладить процесс загрузки, выполните следующие действия:
Теперь, когда выполнение кода дойдет до процедуры ОбработатьДанныеЗагрузкиНаСервере, отладчик остановится, и вы сможете воочию убедиться, какой именно тип данных приходит из Excel и какие символы содержатся в строке (используйте функцию КодСимвола() в табло, чтобы узнать точный код «невидимого» знака).
Если вы пишете собственный алгоритм чтения файла через Excel.Application, попробуйте обращаться не к свойству Value, а к свойству Text ячейки.
Разница существенна:
Value возвращает типизированное значение (число, дату), которое 1С потом форматирует на свой вкус.Text возвращает строковое представление ячейки именно в том виде, в котором оно отображается на экране монитора в Excel.Использование .Text часто позволяет избежать проблем с разделителями разрядов еще на этапе получения данных из файла.
Мы рассмотрели основные способы борьбы с лишними пробелами при импорте. В большинстве случаев достаточно комбинации СтрЗаменить(Значение, Символы.НПП, "") и правильной настройки отладки фоновых заданий, чтобы понять, где именно закралась ошибка в логике обработки. Всегда проверяйте типы данных и помните, что визуальное отсутствие пробела в Excel не гарантирует отсутствие скрытых символов при программном чтении файла.