К статье
Практический материал

Разработка и Конфигурация · 10 мин

Сортировка строки как числа в 1С: практическое руководство

Как в 1С отсортировать строки как числа: функции преобразования, сортировка таблицы значений, запросы с ВЫРАЗИТЬ, типичные ошибки и готовые примеры кода.

В 1С значения, хранящиеся как строки («10», «2», «100»), при обычной сортировке упорядочиваются лексикографически: сначала «1», «10», «100», потом «2». Для отчётов, нумерации документов, артикулов и кодов такая сортировка неприемлема — нужен числовой порядок. Задача решается несколькими способами в зависимости от того, где происходит сортировка: в запросе, в таблице значений, в динамическом списке или в СКД.

Ключевая идея во всех подходах одна: перед сравнением строку нужно преобразовать в число либо дополнить до фиксированной длины так, чтобы лексикографический порядок совпал с числовым. Выбор конкретного метода зависит от объёма данных, наличия нечисловых символов и места выполнения сортировки.

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

Почему строки сортируются «неправильно»

Строковое сравнение в 1С (как и в большинстве СУБД) выполняется посимвольно слева направо. Символ «2» больше символа «1», поэтому строка «2» окажется после «10» и «100», хотя число 2 меньше десяти. Это не ошибка платформы, а штатное поведение сравнения строк.

Проблема чаще всего всплывает в типовых местах: номера документов, хранящиеся как строка с префиксами; артикулы и коды номенклатуры; поля, импортированные из Excel или CSV, где числа попали в строковый тип. Перед выбором решения полезно понять, какие именно значения лежат в поле: чистые цифры, цифры с префиксами или смешанный формат.

Способ 1. Преобразование в число в коде

Если сортировка выполняется над таблицей значений или массивом в коде, самый прямой путь — добавить служебную числовую колонку, заполнить её преобразованными значениями и сортировать по ней. Функция Число() преобразует строку из цифр в число; для значений с пробелами или нечисловыми символами она вызовет ошибку, поэтому данные нужно предварительно очистить.

ТаблицаДанных.Колонки.Добавить("НомерЧислом", Новый ОписаниеТипов("Число"));

Для Каждого СтрокаТЗ Из ТаблицаДанных Цикл

Очищенная = СокрЛП(СтрокаТЗ.НомерСтрокой);

Если СтрДлина(Очищенная) > 0 Тогда

СтрокаТЗ.НомерЧислом = Число(Очищенная);

КонецЕсли;

КонецЦикла;

ТаблицаДанных.Сортировать("НомерЧислом");

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

bsl
Функция СтрокаВЧислоБезопасно(ЗначениеСтрокой)
    Попытка
        Возврат Число(СокрЛП(ЗначениеСтрокой));
    Исключение
        Возврат 0;
    КонецПопытки;
КонецФункции

Способ 2. Сортировка в запросе через ВЫРАЗИТЬ

В запросах 1С строковое поле можно привести к числу прямо в тексте запроса с помощью конструкции ВЫРАЗИТЬ(... КАК ЧИСЛО(...)) и использовать результат в секции УПОРЯДОЧИТЬ ПО. Это работает и в обычных запросах, и в запросах СКД.

ВЫБРАТЬ

Док.Номер,

ВЫРАЗИТЬ(Док.Номер КАК ЧИСЛО(10, 0)) КАК НомерЧислом

ИЗ

Документ.РеализацияТоваровУслуг КАК Док

УПОРЯДОЧИТЬ ПО

НомерЧислом

Ограничения важны: преобразование корректно работает только если строка содержит исключительно цифры (возможно, с ведущими нулями). При наличии букв, дефисов или префиксов результат зависит от СУБД — возможны ошибки выполнения запроса или значения NULL. Длина в описании типа ЧИСЛО должна покрывать максимальное значение, иначе большие номера усечены либо запрос упадёт с ошибкой переполнения.

Способ 3. Дополнение строки нулями слева

Когда преобразовать строку в число нельзя или нежелательно (например, нужно сохранить ведущие нули и исходный формат), применяют выравнивание: каждое значение дополняется нулями слева до одинаковой длины. Тогда «0002» при лексикографической сортировке встанет перед «0010», и порядок совпадёт с числовым.

Функция ДополнитьНулями(ЗначениеСтрокой, Длина)

Результат = СокрЛП(ЗначениеСтрокой);

Пока СтрДлина(Результат) < Длина Цикл

Результат = "0" + Результат;

КонецЦикла;

Возврат Результат;

КонецФункции

Длину выбирайте с запасом относительно максимального номера: если самый длинный номер — 6 символов, берите 8–10. В запросе аналогичный приём реализуется через ПОДСТРОКА и конкатенацию с заранее подготовленной строкой нулей, но читаемость такого запроса заметно хуже — обычно проще подготовить данные в коде.

Сортировка в динамическом списке и СКД

В динамическом списке сортировку задаёт запрос, поэтому применимы те же приёмы: вычисляемое поле с ВЫРАЗИТЬ и упорядочивание по нему. Если список построен на произвольном запросе, добавьте вычисляемое числовое поле и установите сортировку по нему в настройках списка, а само поле можно скрыть от пользователя.

В СКД удобно использовать вычисляемые поля: на закладке «Вычисляемые поля» добавьте поле с выражением на языке запросов или встроенном языке, затем включите его в сортировку набора. Для сложных случаев (например, номер вида «АБ-00123») выражение вычисляемого поля может отрезать префикс функциями строк и приводить остаток к числу.

Порядок действий для динамического списка
  1. 1
    Откройте настройку произвольного запроса динамического списка
  2. 2
    Добавьте вычисляемое поле с ВЫРАЗИТЬ(Поле КАК ЧИСЛО(15,0))
  3. 3
    Добавьте это поле в секцию УПОРЯДОЧИТЬ ПО
  4. 4
    В настройках списка скройте служебное поле от пользователя
  5. 5
    Проверьте сортировку на данных с разной длиной номеров

Смешанные данные: префиксы и нечисловые символы

Реальные номера часто выглядят как «ПР-00456» или «А-12». Здесь единственно надёжный подход — разбить значение на префикс и числовую часть, сортировать сначала по префиксу, затем по числу. В коде это делается перебором символов с конца строки: пока символ — цифра, он относится к числовой части.

Альтернатива — хранить числовую часть отдельным полем на этапе проектирования конфигурации. Если вы разрабатываете собственный документ, добавьте реквизит «НомерЧисловой» и заполняйте его при записи: это избавит от всех трюков при сортировке и поиске в дальнейшем.

Сравнение подходов

Число() в коде

Просто и надёжно для таблиц значений; требует цикла и не подходит для больших выборок напрямую из СУБД

ВЫРАЗИТЬ в запросе

Быстро на больших данных; ломается на нечисловых значениях и требует контроля длины типа

Дополнение нулями

Сохраняет исходный формат и ведущие нули; нужно знать максимальную длину и обновлять служебное поле

Отдельное числовое поле

Самый надёжный вариант на этапе проектирования; требует изменения конфигурации и заполнения для старых данных

Проверка результата и типичные ошибки

После внедрения сортировки проверьте её на контрольном наборе: значения «1», «2», «10», «100», значение с максимальной длиной и пустое значение. Правильный порядок — 1, 2, 10, 100. Если пустые строки превращаются в 0 и всплывают в начало списка, добавьте условие или отбор, чтобы обработать их отдельно.

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

Типичные ошибки
01
Применение ВЫРАЗИТЬ КАК ЧИСЛО к полю с префиксами — ошибка СУБД или NULL вместо значений
02
Недостаточная длина типа ЧИСЛО(5,0) для длинных номеров — переполнение и падение запроса
03
Число() без СокрЛП и обработки исключений — падение кода на строке с пробелом или пустом значении
04
Сортировка по вычисляемому полю на большой таблице без индекса — тяжёлые запросы и таймауты
05
Дополнение нулями до длины меньше максимального номера — порядок снова ломается
Контрольные точки

Как проверить результат

Порядок значений 1, 2, 10, 100
Норма

Выводятся строго по возрастанию

Тревожный признак

10 и 100 стоят перед 2 — сортировка осталась строковой

Значения с префиксами
Норма

Префиксы сгруппированы, внутри группы числовой порядок

Тревожный признак

Ошибка запроса или пустые значения в поле сортировки

Пустые и нечисловые строки
Норма

Обработаны отдельно, не ломают выборку

Тревожный признак

Код падает с ошибкой преобразования

Время выполнения на рабочем объёме
Норма

Запрос выполняется без заметной задержки

Тревожный признак

Таймауты — нужно материализовать числовое поле

FAQ

Можно ли отсортировать строку как число без изменения запроса и кода?

Нет, штатной настройки «сортировать как число» для строкового поля в платформе нет. Всегда требуется либо вычисляемое числовое поле, либо преобразование типа, либо выравнивание длины строки нулями.

Почему ВЫРАЗИТЬ(... КАК ЧИСЛО) возвращает NULL или ошибку?

Потому что в поле встречаются символы, не являющиеся цифрами: буквы, дефисы, пробелы внутри числа. Выполните запрос с отбором таких значений (например, через ПОДСТРОКА и проверку символов) и очистите данные либо перейдите на сортировку с разбором префикса.

Как сохранить ведущие нули после сортировки?

Не преобразуйте исходное значение, а сортируйте по отдельному служебному полю — числовому или дополненному нулями. Исходная строка при этом выводится без изменений.

Что делать с номерами вида «АБ-00123»?

Разделите значение на префикс и числовую часть (перебором символов с конца строки в коде или функциями строк в вычисляемом поле) и сортируйте по двум полям: сначала префикс, затем число. Универсальной встроенной функции для этого нет.

Влияет ли сортировка по вычисляемому полю на скорость?

Да. Выражение в УПОРЯДОЧИТЬ ПО не использует индексы, поэтому СУБД сортирует всю выборку вручную. На небольших таблицах это незаметно, на больших — ощутимо. Решение: хранить числовой аналог поля физически и индексировать его.

Работает ли приём в файловой и клиент-серверной базе одинаково?

Синтаксис запроса одинаков, но поведение при ошибках преобразования может отличаться: на клиент-серверной базе ошибку вернёт СУБД. Всегда тестируйте запрос на копии рабочей базы целевого типа.

Итог

Что важно запомнить

Строки в 1С сортируются посимвольно, поэтому числовой порядок достигается только через преобразование: Число() в коде, ВЫРАЗИТЬ КАК ЧИСЛО в запросе или дополнение нулями до фиксированной длины. Для смешанных данных с префиксами разделяйте значение на части, а на больших таблицах храните числовое поле физически. Перед применением проверяйте данные на нечисловые символы и тестируйте на копии базы.