При автоматизации загрузки данных из внешних источников, таких как Excel, программисты 1С часто сталкиваются с загадочной ситуацией: визуально наименование номенклатуры в файле и в справочнике абсолютно идентичны, но встроенная функция НайтиПоНаименованию упорно возвращает пустую ссылку. При этом ручной поиск в справочнике по той же строке может давать разные результаты в зависимости от того, копируете ли вы текст или вводите его вручную. Проанализируем ситуацию и разберем причины этого «глюка», который на самом деле является стандартным поведением системы при работе с разными кодировками символов.
Основная причина проблемы кроется в существовании символов, которые выглядят как обычный пробел, но имеют совершенно другой внутренний код. Самый частый виновник — неразрывный пробел (NBSP). В кодировке Unicode обычный пробел имеет код 32, в то время как неразрывный пробел — код 160. Для человека на экране монитора они выглядят одинаково, но для поисковых механизмов базы данных 1С — это два абсолютно разных символа.
Рассмотрим подробнее, откуда берутся такие символы:
превращается в тот самый символ 160.Строка() для чисел, 1С по умолчанию форматирует число, добавляя неразрывные пробелы для читаемости.Самый простой и эффективный способ решить проблему при загрузке — выполнить замену всех спецсимволов на стандартные пробелы. Для этого в языке 1С предусмотрена системная константа Символы.НПП (Неразрывный Пробел). Разберем по шагам, как это реализовать в коде обработки загрузки.
Вместо прямого использования считанной строки, пропустим её через функцию СтрЗаменить:
НаименованиеИзФайла = ОбработкаExcel.ПрочитатьЗначение(Строка, Колонка);
// Заменяем неразрывный пробел на обычный
НаименованиеДляПоиска = СтрЗаменить(НаименованиеИзФайла, Символы.НПП, " ");
// Очищаем лишние пробелы по краям
НаименованиеДляПоиска = СокрЛП(НаименованиеДляПоиска);
НайденнаяСсылка = Справочники.Номенклатура.НайтиПоНаименованию(НаименованиеДляПоиска, Истина);
Использование параметра Истина в методе НайтиПоНаименованию означает поиск по точному соответствию. Важно помнить, что даже если в середине строки останется «не тот» пробел, поиск не сработает.
Существует более «хитрый» и иногда более универсальный способ очистки данных, который упоминался опытными разработчиками. Это прогон строки через механизмы XML-сериализации. Посмотрим на пример использования функции XMLЗначение:
НаименованиеДляПоиска = XMLЗначение(Тип("Строка"), НаименованиеИзФайла);
Этот метод помогает потому, что при сериализации и десериализации строк механизмы XML часто нормализуют специфические разделители, которые не соответствуют стандартным представлениям строковых данных в XML-пакетах. Это позволяет быстро избавиться от некоторых видов «мусорных» символов без написания сложных функций очистки.
Если замена Символы.НПП не помогла, проанализируем ситуацию глубже. В строке могут быть и другие «невидимые» вредители, такие как мягкий перенос, табуляция или нулевой пробел. Чтобы точно понять, что мешает поиску, используем отладчик и функцию КодСимвола().
Рассмотрим пример диагностического цикла, который можно запустить в табло или в тексте обработки:
Для Индекс = 1 По СтрДлина(НаименованиеИзФайла) Цикл
Код = КодСимвола(НаименованиеИзФайла, Индекс);
Сообщить("Символ №" + Индекс + " имеет код: " + Код);
КонецЦикла;
Если вы увидите код, отличный от 32 (обычный пробел) или кодов букв и цифр, значит, вы нашли виновника. Часто встречаются следующие коды:
Еще один важный момент, который стоит проверить — это раскладка клавиатуры. Символы «С», «А», «Е», «О», «Р», «Х» в русской и английской раскладке выглядят одинаково. Выясним причину, почему это критично: метод НайтиПоНаименованию работает на уровне SQL-запроса, и для базы данных буква «С» (код 1057) и «C» (код 67) — это совершенно разные символы. Если в Excel часть наименования набрана в латинице, а в 1С в кириллице (или наоборот), поиск не даст результатов.
Для решения этой проблемы можно написать функцию, которая приводит все потенциально проблемные буквы к одной раскладке, но лучше всего обеспечить чистоту данных на этапе ввода в систему.
Чтобы избежать подобных проблем в будущем, проанализируем лучшие практики написания обработок загрузки:
СтрЗаменить для неразрывных пробелов и СокрЛП для удаления случайных пробелов в начале и в конце строки.RegExp для удаления всех непечатных символов (символов с кодами меньше 32).НайтиПоНаименованию не сработало, попробуйте реализовать «нечеткий» поиск через запрос с оператором ПОДОБНО, заменяя пробелы в искомой строке на символ маски %.Подведем итог: «Странные глюки» поиска в 1С почти всегда имеют логическое объяснение в виде различия кодов символов. Внимательное отношение к очистке данных при импорте из Excel — залог стабильной работы вашей системы.