В практике разработчика 1С часто встречается загадочная ситуация: мы видим в отладчике две абсолютно идентичные строки, но функция СтрНайти (или Найти) упорно возвращает 0. Особенно часто это происходит при обработке данных, полученных из внешних систем: банковских выписок, Excel-файлов, PDF-документов или веб-сервисов. Давайте вместе разберем эту проблему, выясним скрытые причины и выработаем надежный алгоритм поиска.
Представим ситуацию, описанную в теме: у нас есть строка назначения платежа:
"(08-08) Перечисление заработной платы за 07.2018г. на б/к сотрудников согласно реестру №..."
Мы пытаемся найти в ней подстроку "Перечисление заработной платы". Визуально фраза присутствует, но программно результат поиска отрицательный. Проанализируем, почему это происходит.
Самая распространенная причина — использование разных типов пробелов. В 1С стандартный пробел имеет код 32. Однако при копировании из текстов или банковских программ часто попадает «неразрывный пробел» (NBSP), код которого 160. Визуально они неразличимы, но для системы это разные символы.
Рассмотрим, как очистить строку от таких символов перед поиском:
// Удаляем стандартный неразрывный пробел
ПодстрокаПоиска = СтрЗаменить(ПодстрокаПоиска, Символы.НПП, " ");
ТекстИсточника = СтрЗаменить(ТекстИсточника, Символы.НПП, " ");
// Выполняем поиск после очистки
Позиция = СтрНайти(ТекстИсточника, ПодстрокаПоиска);
Однако существуют и более экзотические варианты, такие как «узкий неразрывный пробел» (код 8239) или «нулевой пробел» (код 8203). Если обычная замена Символы.НПП не помогает, проанализируем строку посимвольно.
Это классическая «ловушка» при ручном вводе или некорректном распознавании текста. Некоторые буквы кириллицы выглядят в точности как латинские: «а», «е», «о», «р», «с», «у», «х». Если в слове «Перечисление» первая буква «П» кириллическая, а «е» случайно введена на английской раскладке, СтрНайти не найдет совпадения.
Чтобы проверить это, воспользуемся функцией КодСимвола в цикле. Давайте посмотрим на пример кода для диагностики:
Для Индекс = 1 По СтрДлина(ПодозрительнаяСтрока) Цикл
Символ = Сред(ПодозрительнаяСтрока, Индекс, 1);
Сообщить("Символ: " + Символ + " Код: " + КодСимвола(Символ));
КонецЦикла;
Если вы видите коды в диапазоне 65-122 для русских слов — перед вами латиница.
Функция СтрНайти может быть чувствительна к регистру в зависимости от настроек базы данных (SQL Collation). Чтобы гарантированно избежать ошибок, всегда приводите обе строки к одному регистру, обычно к нижнему.
Проанализируем правильный подход к поиску:
Позиция = СтрНайти(НРег(ТекстИсточника), НРег(ПодстрокаПоиска));
Существуют символы, которые вообще не отображаются в конфигураторе 1С:
Если стандартные методы не помогают, рассмотрим более радикальные, но эффективные способы.
Мы можем создать вспомогательную функцию, которая оставляет в строке только буквы и цифры, заменяя всё остальное на пробелы или вовсе удаляя. Это позволит игнорировать любые виды пробелов, тире и переносов.
Функция ОчиститьСтрокуДляПоиска(Знач ВхСтрока)
Результат = "";
ДопустимыеСимволы = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя0123456789 ";
ВхСтрока = НРег(ВхСтрока);
Для К = 1 По СтрДлина(ВхСтрока) Цикл
Символ = Сред(ВхСтрока, К, 1);
Если СтрНайти(ДопустимыеСимволы, Символ) > 0 Тогда
Результат = Результат + Символ;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Начиная с версии платформы 8.3.24, в 1С появились встроенные функции для работы с регулярными выражениями. Это мощный инструмент, позволяющий искать текст, игнорируя количество пробелов между словами или наличие спецсимволов.
Выясним, как это упрощает жизнь:
// Ищем фразу, где между словами может быть любое количество пробельных символов
Шаблон = "Перечисление\s+заработной\s+платы";
Результат = СтрНайтиПоРегулярномуВыражению(ТекстИсточника, Шаблон);
Если ваша платформа ниже 8.3.24, можно использовать объект VBScript.RegExp через COM-соединение.
Чтобы подобные ошибки не возникали в будущем, придерживайтесь следующих правил:
Символы.НПП на обычные пробелы.НРег() — ваш лучший друг при сравнении строк.СтрНайти третий параметр (НачальнаяПозиция) не установлен случайно в значение больше 1.Подводя итог, можно сказать: чудес в программировании не бывает. Если 1С говорит, что подстроки нет — значит, на уровне кодов символов строки действительно различаются. Использование посимвольного анализа через КодСимвола — самый быстрый способ найти "виновника" и устранить проблему раз и навсегда.