Почему 1С не находит номенклатуру по наименованию при загрузке из Excel и как это исправить?

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием
← На главную

При автоматизации загрузки данных из внешних источников, таких как Excel, программисты 1С часто сталкиваются с загадочной ситуацией: визуально наименование номенклатуры в файле и в справочнике абсолютно идентичны, но встроенная функция НайтиПоНаименованию упорно возвращает пустую ссылку. При этом ручной поиск в справочнике по той же строке может давать разные результаты в зависимости от того, копируете ли вы текст или вводите его вручную. Проанализируем ситуацию и разберем причины этого «глюка», который на самом деле является стандартным поведением системы при работе с разными кодировками символов.

Выясняем причину: невидимые символы-разделители

Основная причина проблемы кроется в существовании символов, которые выглядят как обычный пробел, но имеют совершенно другой внутренний код. Самый частый виновник — неразрывный пробел (NBSP). В кодировке Unicode обычный пробел имеет код 32, в то время как неразрывный пробел — код 160. Для человека на экране монитора они выглядят одинаково, но для поисковых механизмов базы данных 1С — это два абсолютно разных символа.

Рассмотрим подробнее, откуда берутся такие символы:

  1. Особенности Microsoft Excel: Если в Excel ячейка имеет числовой формат или формат с разделителями разрядов, программа часто вставляет неразрывный пробел (код 160) между тысячами и миллионами. При чтении значения ячейки как строки этот символ попадает в 1С.
  2. Копирование из WEB: Если данные в таблицу копировались с веб-сайтов, HTML-сущность   превращается в тот самый символ 160.
  3. Механизмы самой 1С: При использовании функции Строка() для чисел, 1С по умолчанию форматирует число, добавляя неразрывные пробелы для читаемости.

Способ 1: Принудительная замена неразрывных пробелов

Самый простой и эффективный способ решить проблему при загрузке — выполнить замену всех спецсимволов на стандартные пробелы. Для этого в языке 1С предусмотрена системная константа Символы.НПП (Неразрывный Пробел). Разберем по шагам, как это реализовать в коде обработки загрузки.

Вместо прямого использования считанной строки, пропустим её через функцию СтрЗаменить:


НаименованиеИзФайла = ОбработкаExcel.ПрочитатьЗначение(Строка, Колонка);
// Заменяем неразрывный пробел на обычный
НаименованиеДляПоиска = СтрЗаменить(НаименованиеИзФайла, Символы.НПП, " ");
// Очищаем лишние пробелы по краям
НаименованиеДляПоиска = СокрЛП(НаименованиеДляПоиска);

НайденнаяСсылка = Справочники.Номенклатура.НайтиПоНаименованию(НаименованиеДляПоиска, Истина);

Использование параметра Истина в методе НайтиПоНаименованию означает поиск по точному соответствию. Важно помнить, что даже если в середине строки останется «не тот» пробел, поиск не сработает.

Способ 2: Использование нормализации через XMLЗначение

Существует более «хитрый» и иногда более универсальный способ очистки данных, который упоминался опытными разработчиками. Это прогон строки через механизмы XML-сериализации. Посмотрим на пример использования функции XMLЗначение:

НаименованиеДляПоиска = XMLЗначение(Тип("Строка"), НаименованиеИзФайла);

Этот метод помогает потому, что при сериализации и десериализации строк механизмы XML часто нормализуют специфические разделители, которые не соответствуют стандартным представлениям строковых данных в XML-пакетах. Это позволяет быстро избавиться от некоторых видов «мусорных» символов без написания сложных функций очистки.

Способ 3: Диагностика через коды символов

Если замена Символы.НПП не помогла, проанализируем ситуацию глубже. В строке могут быть и другие «невидимые» вредители, такие как мягкий перенос, табуляция или нулевой пробел. Чтобы точно понять, что мешает поиску, используем отладчик и функцию КодСимвола().

Рассмотрим пример диагностического цикла, который можно запустить в табло или в тексте обработки:


Для Индекс = 1 По СтрДлина(НаименованиеИзФайла) Цикл
    Код = КодСимвола(НаименованиеИзФайла, Индекс);
    Сообщить("Символ №" + Индекс + " имеет код: " + Код);
КонецЦикла;

Если вы увидите код, отличный от 32 (обычный пробел) или кодов букв и цифр, значит, вы нашли виновника. Часто встречаются следующие коды:

Проблема латинских «двойников»

Еще один важный момент, который стоит проверить — это раскладка клавиатуры. Символы «С», «А», «Е», «О», «Р», «Х» в русской и английской раскладке выглядят одинаково. Выясним причину, почему это критично: метод НайтиПоНаименованию работает на уровне SQL-запроса, и для базы данных буква «С» (код 1057) и «C» (код 67) — это совершенно разные символы. Если в Excel часть наименования набрана в латинице, а в 1С в кириллице (или наоборот), поиск не даст результатов.

Для решения этой проблемы можно написать функцию, которая приводит все потенциально проблемные буквы к одной раскладке, но лучше всего обеспечить чистоту данных на этапе ввода в систему.

Рекомендации по созданию надежной загрузки

Чтобы избежать подобных проблем в будущем, проанализируем лучшие практики написания обработок загрузки:

  1. Всегда очищайте входящие строки: Используйте связку СтрЗаменить для неразрывных пробелов и СокрЛП для удаления случайных пробелов в начале и в конце строки.
  2. Используйте регулярные выражения: Если вы работаете в среде, где разрешены COM-объекты или внешние компоненты, можно использовать RegExp для удаления всех непечатных символов (символов с кодами меньше 32).
  3. Проверяйте результат поиска: Если НайтиПоНаименованию не сработало, попробуйте реализовать «нечеткий» поиск через запрос с оператором ПОДОБНО, заменяя пробелы в искомой строке на символ маски %.

Подведем итог: «Странные глюки» поиска в 1С почти всегда имеют логическое объяснение в виде различия кодов символов. Внимательное отношение к очистке данных при импорте из Excel — залог стабильной работы вашей системы.

← На главную