Почему метод НайтиПоКоду не находит элемент и как найти объект с непечатаемыми символами в коде 1С

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

При переносе данных из платформы 1С 7.7, внешних файлов или сторонних систем в справочниках 1С 8.x часто возникают ситуации, когда элемент визуально присутствует в базе, но метод НайтиПоКоду возвращает пустую ссылку. В отладчике код может выглядеть как обычные цифры с пробелами на конце, однако попытки найти его с помощью встроенной функции СокрЛП не дают результата.

Разберем причину этого поведения и проанализируем проверенные способы решения проблемы.

Выясняем причину: почему СокрЛП не помогает

Встроенная функция СокрЛП в 1С удаляет из начала и конца строки только обычные пробелы (символ с кодом ASCII 32). Однако при импорте данных или переносе из 1С 7.7 в хвосте строки часто оказываются другие спецсимволы:

  1. Неразрывный пробел (символ с кодом 160 или Символы.НПП) — визуально не отличается от обычного пробела, но функция СокрЛП его игнорирует.
  2. Символ табуляции (код 9 или Символы.Таб).
  3. Управляющие и непечатные символы (переносы строк, нулевые байты).

СУБД (MS SQL, PostgreSQL) выполняет точное сравнение кодов символов в байтовом представлении. Поскольку код обычного пробела (32) и неразрывного пробела (160) различен, СУБД считает строки непохожими, и метод НайтиПоКоду завершается неудачей.

Шаг 1. Диагностика кодов символов в отладчике

Чтобы понять, с каким именно непечатным символом мы столкнулись, проверим коды символов строки поочередно с помощью функции КодСимвола и метода Сред.

Проанализируем пример кода для проверки состава строки:


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

Если для символов в конце строки выводится код 160 (неразрывный пробел) или 9 (табуляция), мы точно определили причину сбоя при поиске.

Шаг 2. Поиск элементов через язык запросов

Если в базе данных хранятся элементы со спецсимволами в коде, и мы не можем моментально перезаписать эти объекты, используем запрос с оператором ПОДОБНО или функцией ПОДСТРОКА.

Рассмотрим пример поиска по началу кода без учета хвостовых спецсимволов:


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

// Ищем код, начинающийся на значащие цифры, игнорируя символы в конце
Запрос.УстановитьПараметр("ШаблонКода", "12356%");

РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл
    НайденнаяСсылка = Выборка.Ссылка;
    Сообщить("Элемент найден: " + Направление);
КонецЦикла;

Шаг 3. Очистка и нормализация кодов в базе данных

Самым правильным решением является однократная нормализация реквизита Код для всех элементов справочника. Для этого удалим неразрывные пробелы и знаки табуляции с помощью функции СтрЗаменить.

Выполним обработку элементов справочника следующим алгоритмом:


Выборка = Справочники.Контрагенты.Выбрать();
Пока Выборка.Следующий() Цикл
    ОбъектКонтрагент = Выборка.ПолучитьОбъект();
    СтарыйКод = ОбъектКонтрагент.Код;
    
    // Удаляем неразрывные пробелы и табуляцию
    ОчищенныйКод = СтрЗаменить(СтарыйКод, Символы.НПП, "");
    ОчищенныйКод = СтрЗаменить(ОчищенныйКод, Символы.Таб, "");
    
    // Удаляем обычные пробелы по краям
    НовыйКод = СокрЛП(ОчищенныйКод);
    
    Если СтарыйКод <> НовыйКод Тогда
        ОбъектКонтрагент.Код = НовыйКод;
        Попытка
            ОбъектКонтрагент.Записать();
            Сообщить("Код элемента '" + ОбъектКонтрагент + "' успешно исправлен: " + НовыйКод);
        Исключение
            Сообщить("Не удалось записать элемент: " + ОписаниеОшибки());
        КонецПопытки;
    КонецЕсли;
КонецЦикла;

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

← На главную