При разработке на платформе 1С:Предприятие 8 многие программисты сталкиваются с неожиданным поведением системы при сравнении строковых данных. Казалось бы, сравнение должно происходить по кодам символов (как в большинстве языков программирования), но на практике результат часто противоречит таблице Unicode. Давайте подробно разберем, почему так происходит, и какие инструменты предоставляет платформа для решения этой задачи.
Разберем ситуацию, которая часто вводит в заблуждение: почему выражение "а" < "А" возвращает Истина, хотя код строчной "а" (1072) значительно больше кода заглавной "А" (1040)?
Дело в том, что встроенный язык 1С по умолчанию использует лингвистическое сравнение. Это сделано для того, чтобы при сортировке списков (например, справочников или таблиц) данные выстраивались в естественном для человека порядке. В правилах большинства современных языков, включая русский, принято, что строчная буква идет перед заглавной того же типа, но любая вариация буквы "А" всегда стоит в алфавите раньше, чем любая вариация буквы "Б".
Проанализируем примеры сравнения:
"а" < "А" — Истина (лингвистически строчная буква предшествует заглавной)."б" < "А" — Ложь (потому что буква "б" в алфавите стоит после "а/А")."а" < "б" — Истина (стандартный алфавитный порядок).Важно понимать, что это поведение не является ошибкой платформы. Это использование системного порядка сортировки (Collation), который зависит от настроек операционной системы и региональных стандартов (локали).
Начиная с версии платформы 8.3.6, у разработчиков появился мощный инструмент — функция СтрСравнить(). Она позволяет явно указать, по каким правилам мы хотим сопоставить строки. Рассмотрим подробнее ее работу.
Функция возвращает число:
Посмотрим на пример использования с различными вариантами сравнения:
// Лингвистическое сравнение (по умолчанию)
Результат = СтрСравнить("а", "А", ВариантСравненияСтрок.Лингвистическое);
// Результат будет -1, так как "а" меньше "А" лингвистически
// Сравнение по кодам символов (Бинарное)
РезультатКоды = СтрСравнить("а", "А", ВариантСравненияСтрок.ПоКодамСимволов);
// Результат будет 1, так как код "а" (1072) больше кода "А" (1040)
Именно использование ВариантСравненияСтрок.ПоКодамСимволов позволяет добиться поведения, аналогичного низкоуровневым языкам программирования, где приоритет отдается весу символа в таблице кодировки.
Если ваша задача — просто проверить равенство строк, не обращая внимания на то, большие это буквы или маленькие, самым простым и надежным способом будет приведение обеих строк к одному регистру перед сравнением. Проанализируем ситуацию, когда нам нужно проверить ввод пользователя:
Если НРег(ВведеннаяСтрока) = НРег(ЭталоннаяСтрока) Тогда
// Строки идентичны без учета регистра
КонецЕсли;
Методы НРег() (нижний регистр) и ВРег() (верхний регистр) позволяют нормализовать данные, исключая влияние лингвистических особенностей сортировки на результат проверки равенства.
Необходимо учитывать критически важное различие между работой программного кода и запросов к базе данных (SQL). Выясним причину возможных расхождений:
= всегда чувствительно к регистру (Case Sensitive). Строка "Админ" не равна строке "админ"._CI_AS (Case Insensitive), что означает регистронезависимость. В таком запросе ГДЕ Наименование = "админ" найдет и "Админ", и "АДМИН".Поэтому, если вы переносите логику проверки из кода в запрос (или наоборот), всегда проверяйте, как настроена ваша база данных.
При написании проверок на принадлежность символа русскому алфавиту разработчики часто используют диапазоны, например: Символ >= "а" И Символ <= "я". Однако здесь кроется ловушка. Рассмотрим проблему буквы "ё".
В лингвистической сортировке "ё" обычно стоит между "е" и "ж". Но в таблицах кодировок её код часто находится далеко за пределами основного диапазона кириллицы. При использовании лингвистического сравнения в 1С буква "ё" может вести себя непредсказуемо в зависимости от версии платформы. Чтобы гарантированно избежать ошибок, рекомендуется всегда проверять букву "ё" отдельным условием:
Если (Символ >= "а" И Символ <= "я") Или Символ = "ё" Или Символ = "Ё" Тогда
// Это русская буква
КонецЕсли;
В старых версиях платформы (до 8.3.6), где функции СтрСравнить не было, разработчики использовали функцию КодСимвола(). Этот метод до сих пор актуален, когда нужно проверить конкретный технический символ или убедиться в "бинарной" чистоте данных:
КодА_Малая = КодСимвола("а"); // 1072
КодА_Большая = КодСимвола("А"); // 1040
Если КодА_Малая > КодА_Большая Тогда
// Здесь мы работаем напрямую с числами, лингвистика не влияет
КонецЕсли;
Подведем итог нашему анализу правил сравнения строк в 1С:
СтрСравнить() с явным указанием варианта сравнения.НРег().Понимание этих нюансов позволит вам создавать более надежный код и избегать трудноуловимых ошибок при обработке текстовой информации.