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

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

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

Разберем детально, почему так происходит, какие скрытые символы подменяет Excel и какими инструментами платформы 1С очистить входящие данные для гарантированного поиска.

В чем кроется причина: неразрывные пробелы и служебные символы

Проанализируем типовую ситуацию. Предположим, мы выполняем поиск следующего вида:


СсылкаИзExcel = Справочники.ТипыПитания.НайтиПоНаименованию("все включено");
СсылкаРучная = Справочники.ТипыПитания.НайтиПоНаименованию("все включено");
Результат = (СсылкаИзExcel = СсылкаРучная); // Возвращает Ложь!

Если разбить строку на отдельные слова и выполнить поиск по каждому из них, то слова по отдельности находятся без проблем. Проблема заключается в разделяющем знаке — обычном на вид пробеле.

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

  1. Неразрывный пробел (NBSP, код 160): в платформе 1С он представлен системной константой Символы.НПП. Веб-страницы, отчеты и таблицы Excel часто форматируют текст с использованием символа неразрывного пробела (Unicode U+00A0), чтобы предотвратить нежелательный перенос слов на новую строку. Для человеческого глаза это стандартный пробел (код 32), но для компьютера и базы данных 1С это совершенно разные символы с разными числовыми кодами.
  2. Служебные переводы строк буфера обмена Excel: когда пользователь копирует ячейку целиком (выделив саму рамку ячейки, а не текст внутри строки формул), Excel автоматически дописывает в буфер обмена невидимые символы перевода строки — Символы.ВК (код 13) и Символы.ПС (код 10).
  3. Символы табуляции: при копировании нескольких колонок разделителем выступает знак табуляции Символы.Таб (код 9), который также может отображаться как пробельный отступ.
  4. Невидимые Unicode-маркеры: в скопированную строку могут попасть маркер последовательности байтов BOM (код 65279) или пробел нулевой ширины (код 8203). Они имеют нулевую визуальную ширину, но изменяют длину строки и ломают точное сравнение.
  5. Смешение раскладок и буквы: визуально одинаковые символы кириллицы и латиницы (например, русская «с» и английская «c», русская «а» и английская «a»), а также различие между буквами «е» и «ё». При строгом поиске буква «ё» не эквивалентна «е».

Диагностика строки с помощью функции КодСимвола

Чтобы точно определить, какой именно символ мешает поиску, разберем по шагам посимвольный анализ подозрительной строки. Для этого используем метод встроенного языка КодСимвола.

Посмотрим на пример диагностического фрагмента кода:


СтрокаДляПроверки = "все включено"; // Вставляем скопированное значение

Для Позиция = 1 По СтрДлина(СтрокаДляПроверки) Цикл
    ТекущийСимвол = Сред(СтрокаДляПроверки, Позиция, 1);
    Код = КодСимвола(ТекущийСимвол);
    Сообщить(СтрШаблон("Позиция %1: символ '%2', код: %3", Позиция, ТекущийСимвол, Код));
КонецЦикла;

Если на месте пробела мы увидим код 160 вместо ожидаемого 32, значит, в строке присутствует Символы.НПП. Если в конце строки обнаружатся коды 10 или 13 — это невидимый перевод строки из Excel.

Способ 1: Очистка неразрывных пробелов и обрезка краев

Для базовой нормализации текста, полученного из Excel или внешних файлов обмена, достаточно применить функции СокрЛП и СтрЗаменить. Заменим неразрывный пробел на обычный пробел и удалим случайные краевые отступы:


ИсходныйТекст = "все включено"; // Значение из Excel

// Заменяем неразрывный пробел обычным пробелом
НормализованныйТекст = СтрЗаменить(ИсходныйТекст, Символы.НПП, " ");

// Удаляем концевые переводы строк и пробелы по краям
НормализованныйТекст = СокрЛП(НормализованныйТекст);

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

Способ 2: Комплексная очистка от скрытых символов и переносов строк

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


Функция ОчиститьСтрокуДляПоиска(Знач ВходнаяСтрока)
    
    // Заменяем различные пробельные разделители на обычный пробел
    ВходнаяСтрока = СтрЗаменить(ВходнаяСтрока, Символы.НПП, " ");
    ВходнаяСтрока = СтрЗаменить(ВходнаяСтрока, Символы.Таб, " ");
    ВходнаяСтрока = СтрЗаменить(ВходнаяСтрока, Символы.ВК, "");
    ВходнаяСтрока = СтрЗаменить(ВходнаяСтрока, Символы.ПС, "");
    
    // Удаляем невидимые Unicode-маркеры (BOM и пробел нулевой ширины)
    ВходнаяСтрока = СтрЗаменить(ВходнаяСтрока, Символ(65279), "");
    ВходнаяСтрока = СтрЗаменить(ВходнаяСтрока, Символ(8203), "");
    
    // Удаляем двойные пробелы, если они образовались после замен
    Пока СтрНайти(ВходнаяСтрока, "  ") > 0 Цикл
        ВходнаяСтрока = СтрЗаменить(ВходнаяСтрока, "  ", " ");
    КонецЦикла;
    
    Возврат СокрЛП(ВходнаяСтрока);
    
КонецФункции

Способ 3: Нормализация с помощью регулярных выражений (платформа 8.3.23 и новее)

Начиная с версии платформы 8.3.23, в 1С появилась встроенная поддержка регулярных выражений. Это позволяет заменить любые комбинации пробельных символов (включая табуляции, переносы строк и неразрывные пробелы) всего одной строкой кода:


// Регулярное выражение \s+ находит любую непрерывную группу пробельных символов
СтрокаОчищенная = СокрЛП(СтрЗаменитьПоРегулярномуВыражению(СтрокаИзExcel, "\s+", " "));
НайденныйЭлемент = Справочники.ТипыПитания.НайтиПоНаименованию(СтрокаОчищенная, Истина);

Особенности работы метода НайтиПоНаименованию

Обратим внимание на синтаксис самого метода: НайтиПоНаименованию(<Наименование>, <ТочноеСоответствие>). Второй параметр по умолчанию равен Ложь. Это означает, что платформа выполняет поиск по совпадению первых символов (префиксу).

  1. Если невидимый спецсимвол или перевод строки оказался в самом начале строки, префиксный поиск с параметром Ложь сразу потерпит неудачу.
  2. Если передан параметр ТочноеСоответствие = Истина, 1С требует совпадения абсолютно всей длины строки, включая конечные пробелы.
  3. Учитывайте длину реквизита Наименование в конфигураторе. Если в Excel наименование содержит 120 символов, а в справочнике длина поля ограничена 100 символами, точный поиск никогда не увенчается успехом без предварительного усечения строки функцией Лев().

Способ 4: Гибкий поиск через объект Запрос

Когда качество входящих данных непредсказуемо, вместо жесткого метода НайтиПоНаименованию надежнее использовать объект Запрос с оператором ПОДОБНО. Это позволяет игнорировать нетипичные пробельные разделители между словами:


ШаблонПоиска = СтрЗаменить(СокрЛП(СтрокаИзExcel), " ", "%");
ШаблонПоиска = СтрЗаменить(ШаблонПоиска, Символы.НПП, "%");

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |	Спр.Ссылка КАК Ссылка
    |ИЗ
    |	Справочник.ТипыПитания КАК Спр
    |ГДЕ
    |	Спр.Наименование ПОДОБНО &ШаблонПоиска";

Запрос.УстановитьПараметр("ШаблонПоиска", "%" + ШаблонПоиска + "%");
РезультатЗапроса = Запрос.Выполнить();

Если Не РезультатЗапроса.Пустой() Тогда
    Выборка = РезультатЗапроса.Выбрать();
    Выборка.Следующий();
    НайденнаяСсылка = Выборка.Ссылка;
КонецЕсли;

Как правильно копировать данные из Excel вручную

Если пользователю требуется вручную перенести единичное наименование из Excel в 1С без попадания лишних переносов строк, рекомендуем следующий алгоритм:

  1. Выделите ячейку в таблице Excel.
  2. Нажмите клавишу F2 (вход в режим редактирования ячейки) либо перейдите курсором в строку формул над таблицей.
  3. Выделите именно текстовую цепочку и нажмите Ctrl + C. В этом случае Excel скопирует чистый текст без завершающего символа перевода каретки.
← На главную