При переносе данных из платформы 1С 7.7, внешних файлов или сторонних систем в справочниках 1С 8.x часто возникают ситуации, когда элемент визуально присутствует в базе, но метод НайтиПоКоду возвращает пустую ссылку. В отладчике код может выглядеть как обычные цифры с пробелами на конце, однако попытки найти его с помощью встроенной функции СокрЛП не дают результата.
Разберем причину этого поведения и проанализируем проверенные способы решения проблемы.
Встроенная функция СокрЛП в 1С удаляет из начала и конца строки только обычные пробелы (символ с кодом ASCII 32). Однако при импорте данных или переносе из 1С 7.7 в хвосте строки часто оказываются другие спецсимволы:
Символы.НПП) — визуально не отличается от обычного пробела, но функция СокрЛП его игнорирует.Символы.Таб).СУБД (MS SQL, PostgreSQL) выполняет точное сравнение кодов символов в байтовом представлении. Поскольку код обычного пробела (32) и неразрывного пробела (160) различен, СУБД считает строки непохожими, и метод НайтиПоКоду завершается неудачей.
Чтобы понять, с каким именно непечатным символом мы столкнулись, проверим коды символов строки поочередно с помощью функции КодСимвола и метода Сред.
Проанализируем пример кода для проверки состава строки:
ИскомыйКод = Строка.Код;
Для Индекс = 1 По СтрДлина(ИскомыйКод) Цикл
Символ = Сред(ИскомыйКод, Индекс, 1);
КодСимволаЗначение = КодСимвола(Символ);
Сообщить("Символ на позиции " + Индекс + " имеет код: " + КодСимволаЗначение);
КонецЦикла;
Если для символов в конце строки выводится код 160 (неразрывный пробел) или 9 (табуляция), мы точно определили причину сбоя при поиске.
Если в базе данных хранятся элементы со спецсимволами в коде, и мы не можем моментально перезаписать эти объекты, используем запрос с оператором ПОДОБНО или функцией ПОДСТРОКА.
Рассмотрим пример поиска по началу кода без учета хвостовых спецсимволов:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Контрагенты.Ссылка КАК Ссылка
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| Контрагенты.Код ПОДОБНО &ШаблонКода";
// Ищем код, начинающийся на значащие цифры, игнорируя символы в конце
Запрос.УстановитьПараметр("ШаблонКода", "12356%");
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
НайденнаяСсылка = Выборка.Ссылка;
Сообщить("Элемент найден: " + Направление);
КонецЦикла;
Самым правильным решением является однократная нормализация реквизита Код для всех элементов справочника. Для этого удалим неразрывные пробелы и знаки табуляции с помощью функции СтрЗаменить.
Выполним обработку элементов справочника следующим алгоритмом:
Выборка = Справочники.Контрагенты.Выбрать();
Пока Выборка.Следующий() Цикл
ОбъектКонтрагент = Выборка.ПолучитьОбъект();
СтарыйКод = ОбъектКонтрагент.Код;
// Удаляем неразрывные пробелы и табуляцию
ОчищенныйКод = СтрЗаменить(СтарыйКод, Символы.НПП, "");
ОчищенныйКод = СтрЗаменить(ОчищенныйКод, Символы.Таб, "");
// Удаляем обычные пробелы по краям
НовыйКод = СокрЛП(ОчищенныйКод);
Если СтарыйКод <> НовыйКод Тогда
ОбъектКонтрагент.Код = НовыйКод;
Попытка
ОбъектКонтрагент.Записать();
Сообщить("Код элемента '" + ОбъектКонтрагент + "' успешно исправлен: " + НовыйКод);
Исключение
Сообщить("Не удалось записать элемент: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
Важное замечание: При нормализации кодов убедитесь, что в конфигурации не используется уникальность кодов, которая может нарушиться при удалении хвостов, или предварительно проверьте базу на дубли. После очистки реквизита стандартный метод НайтиПоКоду снова начнет корректно находить элементы.