Разработка и Конфигурация · 10 мин
Сортировка строки как числа в 1С: практическое руководство
Как в 1С отсортировать строки как числа: функции преобразования, сортировка таблицы значений, запросы с ВЫРАЗИТЬ, типичные ошибки и готовые примеры кода.
В 1С значения, хранящиеся как строки («10», «2», «100»), при обычной сортировке упорядочиваются лексикографически: сначала «1», «10», «100», потом «2». Для отчётов, нумерации документов, артикулов и кодов такая сортировка неприемлема — нужен числовой порядок. Задача решается несколькими способами в зависимости от того, где происходит сортировка: в запросе, в таблице значений, в динамическом списке или в СКД.
Ключевая идея во всех подходах одна: перед сравнением строку нужно преобразовать в число либо дополнить до фиксированной длины так, чтобы лексикографический порядок совпал с числовым. Выбор конкретного метода зависит от объёма данных, наличия нечисловых символов и места выполнения сортировки.
Ниже разобраны рабочие варианты с примерами кода, ограничения каждого подхода и способы проверить результат до выкладки в рабочую базу.
Почему строки сортируются «неправильно»
Строковое сравнение в 1С (как и в большинстве СУБД) выполняется посимвольно слева направо. Символ «2» больше символа «1», поэтому строка «2» окажется после «10» и «100», хотя число 2 меньше десяти. Это не ошибка платформы, а штатное поведение сравнения строк.
Проблема чаще всего всплывает в типовых местах: номера документов, хранящиеся как строка с префиксами; артикулы и коды номенклатуры; поля, импортированные из Excel или CSV, где числа попали в строковый тип. Перед выбором решения полезно понять, какие именно значения лежат в поле: чистые цифры, цифры с префиксами или смешанный формат.
Способ 1. Преобразование в число в коде
Если сортировка выполняется над таблицей значений или массивом в коде, самый прямой путь — добавить служебную числовую колонку, заполнить её преобразованными значениями и сортировать по ней. Функция Число() преобразует строку из цифр в число; для значений с пробелами или нечисловыми символами она вызовет ошибку, поэтому данные нужно предварительно очистить.
ТаблицаДанных.Колонки.Добавить("НомерЧислом", Новый ОписаниеТипов("Число"));
Для Каждого СтрокаТЗ Из ТаблицаДанных Цикл
Очищенная = СокрЛП(СтрокаТЗ.НомерСтрокой);
Если СтрДлина(Очищенная) > 0 Тогда
СтрокаТЗ.НомерЧислом = Число(Очищенная);
КонецЕсли;
КонецЦикла;
ТаблицаДанных.Сортировать("НомерЧислом");
После сортировки служебную колонку можно удалить, чтобы она не попадала в выгрузку. Для безопасного преобразования смешанных данных удобно обернуть вызов в попытку/исключение или использовать собственную функцию проверки.
Функция СтрокаВЧислоБезопасно(ЗначениеСтрокой)
Попытка
Возврат Число(СокрЛП(ЗначениеСтрокой));
Исключение
Возврат 0;
КонецПопытки;
КонецФункцииСпособ 2. Сортировка в запросе через ВЫРАЗИТЬ
В запросах 1С строковое поле можно привести к числу прямо в тексте запроса с помощью конструкции ВЫРАЗИТЬ(... КАК ЧИСЛО(...)) и использовать результат в секции УПОРЯДОЧИТЬ ПО. Это работает и в обычных запросах, и в запросах СКД.
ВЫБРАТЬ
Док.Номер,
ВЫРАЗИТЬ(Док.Номер КАК ЧИСЛО(10, 0)) КАК НомерЧислом
ИЗ
Документ.РеализацияТоваровУслуг КАК Док
УПОРЯДОЧИТЬ ПО
НомерЧислом
Ограничения важны: преобразование корректно работает только если строка содержит исключительно цифры (возможно, с ведущими нулями). При наличии букв, дефисов или префиксов результат зависит от СУБД — возможны ошибки выполнения запроса или значения NULL. Длина в описании типа ЧИСЛО должна покрывать максимальное значение, иначе большие номера усечены либо запрос упадёт с ошибкой переполнения.
Способ 3. Дополнение строки нулями слева
Когда преобразовать строку в число нельзя или нежелательно (например, нужно сохранить ведущие нули и исходный формат), применяют выравнивание: каждое значение дополняется нулями слева до одинаковой длины. Тогда «0002» при лексикографической сортировке встанет перед «0010», и порядок совпадёт с числовым.
Функция ДополнитьНулями(ЗначениеСтрокой, Длина)
Результат = СокрЛП(ЗначениеСтрокой);
Пока СтрДлина(Результат) < Длина Цикл
Результат = "0" + Результат;
КонецЦикла;
Возврат Результат;
КонецФункции
Длину выбирайте с запасом относительно максимального номера: если самый длинный номер — 6 символов, берите 8–10. В запросе аналогичный приём реализуется через ПОДСТРОКА и конкатенацию с заранее подготовленной строкой нулей, но читаемость такого запроса заметно хуже — обычно проще подготовить данные в коде.
Сортировка в динамическом списке и СКД
В динамическом списке сортировку задаёт запрос, поэтому применимы те же приёмы: вычисляемое поле с ВЫРАЗИТЬ и упорядочивание по нему. Если список построен на произвольном запросе, добавьте вычисляемое числовое поле и установите сортировку по нему в настройках списка, а само поле можно скрыть от пользователя.
В СКД удобно использовать вычисляемые поля: на закладке «Вычисляемые поля» добавьте поле с выражением на языке запросов или встроенном языке, затем включите его в сортировку набора. Для сложных случаев (например, номер вида «АБ-00123») выражение вычисляемого поля может отрезать префикс функциями строк и приводить остаток к числу.
- 1Откройте настройку произвольного запроса динамического списка
- 2Добавьте вычисляемое поле с ВЫРАЗИТЬ(Поле КАК ЧИСЛО(15,0))
- 3Добавьте это поле в секцию УПОРЯДОЧИТЬ ПО
- 4В настройках списка скройте служебное поле от пользователя
- 5Проверьте сортировку на данных с разной длиной номеров
Смешанные данные: префиксы и нечисловые символы
Реальные номера часто выглядят как «ПР-00456» или «А-12». Здесь единственно надёжный подход — разбить значение на префикс и числовую часть, сортировать сначала по префиксу, затем по числу. В коде это делается перебором символов с конца строки: пока символ — цифра, он относится к числовой части.
Альтернатива — хранить числовую часть отдельным полем на этапе проектирования конфигурации. Если вы разрабатываете собственный документ, добавьте реквизит «НомерЧисловой» и заполняйте его при записи: это избавит от всех трюков при сортировке и поиске в дальнейшем.
Сравнение подходов
Просто и надёжно для таблиц значений; требует цикла и не подходит для больших выборок напрямую из СУБД
Быстро на больших данных; ломается на нечисловых значениях и требует контроля длины типа
Сохраняет исходный формат и ведущие нули; нужно знать максимальную длину и обновлять служебное поле
Самый надёжный вариант на этапе проектирования; требует изменения конфигурации и заполнения для старых данных
Проверка результата и типичные ошибки
После внедрения сортировки проверьте её на контрольном наборе: значения «1», «2», «10», «100», значение с максимальной длиной и пустое значение. Правильный порядок — 1, 2, 10, 100. Если пустые строки превращаются в 0 и всплывают в начало списка, добавьте условие или отбор, чтобы обработать их отдельно.
Отдельно проверьте производительность: упорядочивание по вычисляемому выражению в запросе не использует индексы, поэтому на больших таблицах (сотни тысяч записей) запрос может заметно замедлиться. В таких случаях лучше материализовать числовое поле — хранить его физически и поддерживать при записи.
Как проверить результат
Выводятся строго по возрастанию
10 и 100 стоят перед 2 — сортировка осталась строковой
Префиксы сгруппированы, внутри группы числовой порядок
Ошибка запроса или пустые значения в поле сортировки
Обработаны отдельно, не ломают выборку
Код падает с ошибкой преобразования
Запрос выполняется без заметной задержки
Таймауты — нужно материализовать числовое поле
FAQ
Можно ли отсортировать строку как число без изменения запроса и кода?
Нет, штатной настройки «сортировать как число» для строкового поля в платформе нет. Всегда требуется либо вычисляемое числовое поле, либо преобразование типа, либо выравнивание длины строки нулями.
Почему ВЫРАЗИТЬ(... КАК ЧИСЛО) возвращает NULL или ошибку?
Потому что в поле встречаются символы, не являющиеся цифрами: буквы, дефисы, пробелы внутри числа. Выполните запрос с отбором таких значений (например, через ПОДСТРОКА и проверку символов) и очистите данные либо перейдите на сортировку с разбором префикса.
Как сохранить ведущие нули после сортировки?
Не преобразуйте исходное значение, а сортируйте по отдельному служебному полю — числовому или дополненному нулями. Исходная строка при этом выводится без изменений.
Что делать с номерами вида «АБ-00123»?
Разделите значение на префикс и числовую часть (перебором символов с конца строки в коде или функциями строк в вычисляемом поле) и сортируйте по двум полям: сначала префикс, затем число. Универсальной встроенной функции для этого нет.
Влияет ли сортировка по вычисляемому полю на скорость?
Да. Выражение в УПОРЯДОЧИТЬ ПО не использует индексы, поэтому СУБД сортирует всю выборку вручную. На небольших таблицах это незаметно, на больших — ощутимо. Решение: хранить числовой аналог поля физически и индексировать его.
Работает ли приём в файловой и клиент-серверной базе одинаково?
Синтаксис запроса одинаков, но поведение при ошибках преобразования может отличаться: на клиент-серверной базе ошибку вернёт СУБД. Всегда тестируйте запрос на копии рабочей базы целевого типа.
Что важно запомнить
Строки в 1С сортируются посимвольно, поэтому числовой порядок достигается только через преобразование: Число() в коде, ВЫРАЗИТЬ КАК ЧИСЛО в запросе или дополнение нулями до фиксированной длины. Для смешанных данных с префиксами разделяйте значение на части, а на больших таблицах храните числовое поле физически. Перед применением проверяйте данные на нечисловые символы и тестируйте на копии базы.