Почему в 1С строчные буквы при сравнении меньше прописных и как правильно сравнивать строки?

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

При разработке на платформе 1С:Предприятие 8 многие программисты сталкиваются с неожиданным поведением системы при сравнении строковых данных. Казалось бы, сравнение должно происходить по кодам символов (как в большинстве языков программирования), но на практике результат часто противоречит таблице Unicode. Давайте подробно разберем, почему так происходит, и какие инструменты предоставляет платформа для решения этой задачи.

Лингвистическое сравнение против бинарного

Разберем ситуацию, которая часто вводит в заблуждение: почему выражение "а" < "А" возвращает Истина, хотя код строчной "а" (1072) значительно больше кода заглавной "А" (1040)?

Дело в том, что встроенный язык 1С по умолчанию использует лингвистическое сравнение. Это сделано для того, чтобы при сортировке списков (например, справочников или таблиц) данные выстраивались в естественном для человека порядке. В правилах большинства современных языков, включая русский, принято, что строчная буква идет перед заглавной того же типа, но любая вариация буквы "А" всегда стоит в алфавите раньше, чем любая вариация буквы "Б".

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

  1. "а" < "А" — Истина (лингвистически строчная буква предшествует заглавной).
  2. "б" < "А" — Ложь (потому что буква "б" в алфавите стоит после "а/А").
  3. "а" < "б" — Истина (стандартный алфавитный порядок).

Важно понимать, что это поведение не является ошибкой платформы. Это использование системного порядка сортировки (Collation), который зависит от настроек операционной системы и региональных стандартов (локали).

Использование функции СтрСравнить

Начиная с версии платформы 8.3.6, у разработчиков появился мощный инструмент — функция СтрСравнить(). Она позволяет явно указать, по каким правилам мы хотим сопоставить строки. Рассмотрим подробнее ее работу.

Функция возвращает число:

Посмотрим на пример использования с различными вариантами сравнения:


// Лингвистическое сравнение (по умолчанию)
Результат = СтрСравнить("а", "А", ВариантСравненияСтрок.Лингвистическое); 
// Результат будет -1, так как "а" меньше "А" лингвистически

// Сравнение по кодам символов (Бинарное)
РезультатКоды = СтрСравнить("а", "А", ВариантСравненияСтрок.ПоКодамСимволов);
// Результат будет 1, так как код "а" (1072) больше кода "А" (1040)

Именно использование ВариантСравненияСтрок.ПоКодамСимволов позволяет добиться поведения, аналогичного низкоуровневым языкам программирования, где приоритет отдается весу символа в таблице кодировки.

Сравнение без учета регистра

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


Если НРег(ВведеннаяСтрока) = НРег(ЭталоннаяСтрока) Тогда
    // Строки идентичны без учета регистра
КонецЕсли;

Методы НРег() (нижний регистр) и ВРег() (верхний регистр) позволяют нормализовать данные, исключая влияние лингвистических особенностей сортировки на результат проверки равенства.

Особенности сравнения в запросах и коде

Необходимо учитывать критически важное различие между работой программного кода и запросов к базе данных (SQL). Выясним причину возможных расхождений:

  1. В программном коде: Сравнение через оператор = всегда чувствительно к регистру (Case Sensitive). Строка "Админ" не равна строке "админ".
  2. В запросах: Поведение определяется настройками сортировки (Collation) самой базы данных на SQL-сервере. В большинстве инсталляций 1С используется режим _CI_AS (Case Insensitive), что означает регистронезависимость. В таком запросе ГДЕ Наименование = "админ" найдет и "Админ", и "АДМИН".

Поэтому, если вы переносите логику проверки из кода в запрос (или наоборот), всегда проверяйте, как настроена ваша база данных.

Коварная буква "Ё"

При написании проверок на принадлежность символа русскому алфавиту разработчики часто используют диапазоны, например: Символ >= "а" И Символ <= "я". Однако здесь кроется ловушка. Рассмотрим проблему буквы "ё".

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


Если (Символ >= "а" И Символ <= "я") Или Символ = "ё" Или Символ = "Ё" Тогда
    // Это русская буква
КонецЕсли;

Сравнение строк по кодам символов вручную

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


КодА_Малая = КодСимвола("а"); // 1072
КодА_Большая = КодСимвола("А"); // 1040

Если КодА_Малая > КодА_Большая Тогда
    // Здесь мы работаем напрямую с числами, лингвистика не влияет
КонецЕсли;

Итоги и рекомендации

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

Понимание этих нюансов позволит вам создавать более надежный код и избегать трудноуловимых ошибок при обработке текстовой информации.

← На главную