Разработка и Конфигурация · 10 мин
Сравнение чисел как строк в 1С: методы и подводные камни
Как в 1С сравнить числа как строки: приведение типов, Строка(), СравнениеСтрок, сортировка и лексикографическое сравнение. Примеры кода, ошибки и FAQ.
В 1С:Предприятии тип данных определяет правила сравнения: числа сравниваются арифметически, строки — лексикографически, посимвольно. Из-за этого выражение «10 < 9» даёт разный результат в зависимости от того, сравниваются числа или строки: для чисел это ложь, для строк — истина, потому что символ «1» идёт раньше «9» в порядке сортировки.
Задача сравнить числа как строки возникает при работе с номерами документов, артикулами, кодами контрагентов, штрихкодами и другими «числовыми» идентификаторами, которые на самом деле являются строками с ведущими нулями и префиксами. Также такое сравнение нужно при сортировке списков, поиске дубликатов и сопоставлении данных из внешних источников, где тип мог быть потерян при загрузке.
Ниже разобраны способы явного приведения типов, функции сравнения строк, особенности запросов и типичные ошибки, которые приводят к неверным результатам в отчётах и обработках.
Чем строковое сравнение отличается от числового
Числа в 1С сравниваются по значению: 2 меньше 10, а 100 больше 99. Строки сравниваются посимвольно слева направо по кодам символов: сначала первый символ, при равенстве — второй и так далее. Поэтому строка «10» меньше строки «2», потому что «1» идёт раньше «2» в таблице символов.
Это принципиально для номеров документов. Номер «000000010» и номер «000000009» при строковом сравнении упорядочатся правильно благодаря ведущим нулям, но «10» и «9» без нулей — уже нет. Именно поэтому платформа хранит номера документов как строки фиксированной длины с дополнением нулями слева.
Ещё одно отличие — обработка пустых значений. Пустая строка меньше любой непустой, а незаполненное число равно нулю. При смешанном сравнении это даёт неочевидные результаты, особенно в отборах динамических списков и отчётов СКД.
Как привести число к строке перед сравнением
Базовый способ — функция Строка(). Она возвращает строковое представление значения: Строка(123) даст «123». После этого сравнение выполняется по строковым правилам:
Число1 = 10;
Число2 = 9;
Если Строка(Число1) < Строка(Число2) Тогда
// Условие выполнится: "10" < "9" лексикографически
КонецЕсли;
У Строка() есть ограничение: результат зависит от региональных настроек и может содержать разделители групп разрядов для больших чисел. Для предсказуемого результата надёжнее использовать Формат() с форматной строкой:
Стр = Формат(Число1, "ЧГ=0"); // без группировки разрядов
СтрФикс = Формат(Число1, "ЧЦ=10; ЧВН=; ЧГ=0"); // "0000000123"
Параметр ЧЦ задаёт общую длину, ЧВН включает дополнение ведущими нулями, ЧГ=0 отключает разделители групп. Строки одинаковой длины с ведущими нулями сравниваются лексикографически так же, как числа арифметически — это удобный приём для сортировки.
Стр = Формат(Номер, "ЧЦ=11; ЧВН=; ЧГ=0"); // "00000000123" — сравнение как строки даст числовой порядокФункции сравнения строк: Найти, СтрСравнить и операторы
Встроенные операторы =, <>, <, > работают со строками напрямую и учитывают регистр: «АБВ» не равно «абв». Для чисел в строковом виде регистр роли не играет, но играет роль длина и пробелы — строка «123 » с пробелом не равна «123».
Для сравнения без учёта регистра удобна функция СтрСравнить() (в новых версиях платформы) либо приведение обеих строк к одному регистру через ВРег() или НРег() перед сравнением. Перед сравнением также стоит убрать лишние пробелы функцией СокрЛП(), особенно если данные пришли из файла или формы ввода.
Если нужно проверить вхождение одной строки в другую (например, номера по маске), используйте СтрНайти() — она возвращает позицию вхождения или 0. Для точного равенства вхождение не подходит: «1234» содержит «123», но это разные значения.
Сравнение чисел как строк в запросах
В языке запросов нет прямой функции «число в строку», но есть обходные пути. Если поле уже строковое (номер документа, код), сравнение и сортировка выполняются лексикографически автоматически. Упорядочивание по номеру документа в запросе даст строковый порядок, что для номеров с ведущими нулями совпадает с хронологическим.
Для приведения типов используйте ВЫРАЗИТЬ(Поле КАК Строка(Длина)). Это работает, когда поле составного типа и его нужно трактовать как строку. Прямое приведение числа к строке через ВЫРАЗИТЬ платформа не выполняет — для таких случаев данные готовят заранее во временной таблице или сравнение выносят в код после выборки.
В условиях отбора помните: сравнение строкового поля со строковым литералом идёт посимвольно. Условие ГДЕ Код > "100" отберёт и код «99», если такого быть не должно по бизнес-логике, — проверяйте длину и формат кодов в справочнике.
Сортировка номеров и кодов: практический сценарий
Типовая задача — упорядочить список номеров, где часть записана как «1», «2», «10», а часть как «А-1», «Б-2». Прямая строковая сортировка поставит «10» перед «2». Решение — нормализация: выделить числовую часть и дополнить её нулями до фиксированной длины, после чего сравнивать как строки.
Порядок действий в коде: извлечь цифры из номера, преобразовать в число функцией Число(), затем вернуть в строку через Формат(..., "ЧЦ=10; ЧВН=") и склеить с нечисловым префиксом. Полученные ключи помещают в список значений или таблицу значений и сортируют методом Сортировать() — строковый порядок ключей совпадёт с ожидаемым числовым.
Для таблицы значений добавьте служебную колонку «КлючСортировки», заполните её нормализованными строками и вызовите Таблица.Сортировать("КлючСортировки"). Исходные номера при этом не меняются — меняется только порядок вывода.
- 1Извлеките из каждого номера цифровую часть и преобразуйте её функцией Число()
- 2Сформируйте ключ: Формат(ЧисловаяЧасть, "ЧЦ=10; ЧВН=; ЧГ=0") плюс префикс
- 3Запишите ключ в служебную колонку таблицы значений
- 4Вызовите Сортировать() по колонке ключа
- 5Проверьте порядок на контрольном наборе: 1, 2, 9, 10, 100
Проверка результата и границы применения
После реализации сравнения проверьте его на граничных наборах: значения разной длины («9» и «10»), с ведущими нулями («009» и «9»), с пробелами и без, пустые строки и ноль. Для чисел, преобразованных через Формат с ЧВН, строковое и числовое сравнение должны давать одинаковый порядок — это главный признак корректной нормализации.
Строковое сравнение не подходит для отрицательных чисел и дробных значений: «-10» лексикографически больше «-9», а «9.5» и «9.45» сравниваются корректно только при выравнивании дробной части. Если в данных возможны такие значения, сравнивайте их как числа, а строковое представление используйте только для вывода.
Отдельный риск — производительность. Преобразование типов в цикле по большой таблице или в условии запроса по неиндексированному выражению заметно замедляет работу. На больших объёмах готовьте ключи сравнения один раз при загрузке данных, а не при каждом сравнении.
Как проверить результат
9, 10, 100 — совпадает с числовым порядком при нормализации нулями
10, 100, 9 — сортировка строк без дополнения нулями
Результат соответствует задуманному: равны после приведения к числу или различаются осознанно
Поведение случайное, зависит от источника данных
СокрЛП() применён, сравнение стабильно
Периодические ложные неравенства из-за пробелов
FAQ
Почему в 1С «10» меньше «9» при сравнении?
Потому что сравниваются строки, а не числа. Строковое сравнение идёт посимвольно: первый символ «1» имеет меньший код, чем «9», поэтому «10» считается меньше. Чтобы получить числовой порядок, либо сравнивайте значения как числа, либо дополните строки ведущими нулями до одинаковой длины.
Как сравнить номера документов без учёта префикса?
Отделите цифровую часть, например перебором символов или регулярным выражением через СтрРазделить по нецифровым символам, преобразуйте её функцией Число() и сравнивайте уже числа. Если нужен единый ключ сортировки, склейте префикс с нормализованной числовой частью через Формат с ЧВН.
Можно ли в запросе 1С преобразовать число в строку?
Напрямую — нет, функции преобразования числа в строку в языке запросов отсутствует. ВЫРАЗИТЬ(... КАК Строка) работает только для выбора строкового представления из составного типа. Обходной путь — вычисляемое поле в СКД, предварительная подготовка временной таблицы в коде или сортировка результата запроса после выгрузки в таблицу значений.
Что надёжнее для приведения числа к строке: Строка() или Формат()?
Для сравнения надёжнее Формат() с явной форматной строкой: он гарантирует отсутствие разделителей разрядов (ЧГ=0), заданную длину и ведущие нули. Строка() зависит от настроек и для больших чисел может вернуть представление с группировкой разрядов, что нарушит лексикографическое сравнение.
Как сравнить строки без учёта регистра?
Приведите обе строки к одному регистру функцией ВРег() или НРег() перед сравнением, либо используйте СтрСравнить() с параметром нечувствительности к регистру в версиях платформы, где она доступна. Для чисто цифровых строк регистр не влияет на результат, но префиксы с буквами требуют единообразия.
Почему сравнение одинаковых на вид номеров даёт «не равно»?
Чаще всего виноваты неразрывные пробелы, обычные пробелы в конце или невидимые символы, попавшие из Excel или сканера штрихкодов. Примените СокрЛП() к обеим строкам; если проблема сохраняется, сравните коды символов через КодСимвола() по позициям — так находится первый расходящийся символ.
Что важно запомнить
Строковое сравнение в 1С лексикографическое: «10» меньше «9». Для сравнения чисел как строк приводите значения через Формат() с ЧГ=0 и ведущими нулями, очищайте строки через СокрЛП(), а в запросах помните, что прямого преобразования числа в строку нет — готовьте ключи заранее.