Разработка и Конфигурация · 9 мин
1С: сортировка строк как чисел
Как в 1С отсортировать строки как числа: приведение типов, таблица значений, запрос с ВЫРАЗИТЬ, заполнение ведущими нулями. Примеры кода и типичные ошибки.
В 1С строки сортируются посимвольно, поэтому последовательность «1, 10, 2, 25, 3» — типичный результат, когда номера документов, артикулы или коды хранятся как строка. Алгоритм сравнивает первый символ, затем второй и так далее: «10» оказывается раньше «2», потому что «1» меньше «2». Для человека такой порядок выглядит ошибкой, хотя с точки зрения платформы всё корректно.
Задача «отсортировать строки как числа» возникает при выводе списков в отчётах, при обработке табличных частей, при загрузке данных из Excel и при работе с номерами, которые не удаётся хранить числом из-за лидирующих нулей или смешанного формата. Ниже разобраны рабочие способы: от простого приведения типов до сортировки в запросе и дополнения строк нулями.
Почему строки сортируются «неправильно»
Строковое сравнение в 1С идёт по кодам символов слева направо. Сравнивая «10» и «2», платформа видит, что первый символ «1» меньше «2», и на этом сравнение заканчивается — длина строки и её числовой смысл не учитываются. Поэтому «10» < «2», «100» < «20», а «9» оказывается больше «10000».
Дополнительная сложность — смешанные значения. Если в колонке встречаются «12», «12а», «А-5» и пустые строки, любое автоматическое преобразование в число даст сбой или неожиданный результат. Перед выбором способа сортировки проверьте, действительно ли все значения — цифры.
Проверьте отсутствие букв, пробелов и дефисов
Сохраняйте исходную строку для отображения
Выделите числовую часть функцией или запросом
Проверьте, что приведение типов не даёт NULL
Способ 1: добавить числовую колонку в таблицу значений
Самый надёжный и прозрачный приём — не трогать исходную строку, а добавить служебную колонку с числовым представлением и сортировать по ней. Так вы сохраняете исходные значения с нулями и контролируете ошибки преобразования.
ТЗ.Колонки.Добавить("НомерЧислом", Новый ОписаниеТипов("Число",
Новый КвалификаторыЧисла(15, 0)));
Для Каждого СтрокаТЗ Из ТЗ Цикл
Попытка
СтрокаТЗ.НомерЧислом = Число(СтрокаТЗ.Номер);
Исключение
СтрокаТЗ.НомерЧислом = 0; // нечисловое значение — в начало
КонецПопытки;
КонецЦикла;
ТЗ.Сортировать("НомерЧислом");
Функция Число() вызывает исключение, если строка не является числом, поэтому оборачивайте преобразование в Попытка...Исключение или предварительно проверяйте строку. Учтите, что Число(" 12 ") с пробелами тоже может вызвать ошибку — применяйте СокрЛП() заранее.
Способ 2: сортировка в запросе через ВЫРАЗИТЬ
Если данные выбираются запросом, приведение типа выполняется прямо в нём. Конструкция ВЫРАЗИТЬ(Поле КАК ЧИСЛО(15, 0)) преобразует строку в число, а по полученному полю задаётся упорядочивание.
ВЫБРАТЬ
Товары.Артикул КАК Артикул,
ВЫРАЗИТЬ(Товары.Артикул КАК ЧИСЛО(15, 0)) КАК АртикулЧисло
ИЗ
Справочник.Номенклатура КАК Товары
УПОРЯДОЧИТЬ ПО
АртикулЧисло
Важное ограничение: если строка не приводится к числу, результатом будет NULL, а не ошибка. Записи с NULL обычно попадают в начало выборки при сортировке по возрастанию. Чтобы явно управлять такими строками, используйте ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ 0 КОНЕЦ или ЕСТЬNULL().
Способ 3: дополнение строк ведущими нулями
Если преобразовывать в число нельзя или нежелательно, строки можно выровнять по длине, дополнив слева нулями: «1» → «0001», «25» → «0025», «312» → «0312». После этого обычная строковая сортировка даёт числовой порядок, потому что сравнение фактически идёт по разрядам.
Функция ДополнитьНулями(Стр, Длина)
Пока СтрДлина(Стр) < Длина Цикл
Стр = "0" + Стр;
КонецЦикла;
Возврат Стр;
КонецФункции
Этот приём часто применяют к номерам документов. В типовых конфигурациях есть функции работы с номерами (например, префиксация и дополнение номера нулями в общих модулях работы с номерами объектов) — проверьте наличие таких механизмов в вашей конфигурации, прежде чем писать свою реализацию.
Ограничение способа: нужно заранее знать максимальную длину, и метод ломается, если появится значение длиннее заданной. Также результат дополнения меняет сами данные, если вы записываете их обратно, — для чистой сортировки храните дополненную строку в служебной колонке.
Сравнение вариантов
Универсально для таблиц значений; контроль ошибок через Попытка. Требует обхода всех строк в коде
Быстро на больших выборках, сортировка на стороне СУБД. Нечисловые строки дают NULL
Подходит для номеров и кодов фиксированной длины. Требует знать максимальную длину
Для форм списка: упорядочивание задаётся в тексте запроса динамического списка
Сортировка в динамическом списке и на форме
Когда «криво» сортируется список справочника или документов в пользовательском интерфейсе, причина та же: поле номера или кода имеет строковый тип. Для динамического списка с произвольным запросом добавьте в текст запроса вычисляемое числовое поле и установите упорядочивание по нему — либо через конструкцию УПОРЯДОЧИТЬ ПО, либо программно через Список.Порядок.
Для таблицы значений на форме сортировка выполняется методом Сортировать() перед выводом или по кнопке. Если пользователь должен сам переключать порядок, храните обе колонки — строковую для отображения и числовую для сортировки — и пересортировывайте по нужной.
- 1Добавьте служебную числовую колонку через Колонки.Добавить()
- 2Обойдите строки и заполните её через Число(СокрЛП(Значение)) с обработкой исключений
- 3Вызовите ТЗ.Сортировать("ИмяКолонки") с нужным направлением
- 4Выведите результат и проверьте порядок на значениях 1, 2, 10, 25, 100
- 5Убедитесь, что исходные строковые значения с нулями не изменились
Проверка результата и типичные ошибки
Проверять сортировку удобно на контрольном наборе: «1», «2», «10», «25», «100», «007». Правильный числовой порядок — 1, 2, 7 (из «007»), 10, 25, 100. Если «007» оказался в конце или «10» раньше «2» — сортировка всё ещё строковая или числовая колонка не заполнена.
Как проверить результат
Идут по возрастанию как числа
10 стоит между 1 и 2 — сортировка строковая
Отображаются с нулями, сортируются по числовому значению
Нули исчезли или строка уехала в конец
Попадают в предсказуемое место (начало/конец) без ошибок
Исключение Число() или неожиданный NULL-порядок
Частые вопросы
Почему Число() выдаёт ошибку на строке с цифрами?
Чаще всего в строке есть пробелы, неразрывные пробелы из Excel или невидимые символы. Примените СокрЛП(), а при загрузке из внешних файлов — дополнительно удалите неразрывные пробелы через СтрЗаменить(Стр, Символ(160), "").
Как отсортировать по убыванию?
Для таблицы значений укажите направление: ТЗ.Сортировать("НомерЧислом Убыв"). В запросе добавьте УБЫВ после поля в УПОРЯДОЧИТЬ ПО.
Можно ли отсортировать строки с буквами, например «А-1, А-10, А-2»?
Да, но нужно разделить значение на части: выделить числовую часть функцией или регулярным выражением, поместить её в служебную колонку и сортировать сначала по префиксу, затем по числу. Простого встроенного способа для «естественной» сортировки в платформе нет.
Работает ли ВЫРАЗИТЬ в СКД?
Да, в запросе набора данных СКД можно использовать ВЫРАЗИТЬ и упорядочивание. Также вычисляемое числовое поле можно добавить на закладке «Вычисляемые поля» и сортировать по нему в настройках отчёта.
Что быстрее на больших данных — запрос или обход таблицы?
Сортировка через ВЫРАЗИТЬ в запросе обычно быстрее, так как выполняется на стороне СУБД без перебора строк в коде. Обход таблицы значений оправдан, когда данные уже получены в память или нужна сложная логика преобразования.
Что важно запомнить
Строки в 1С сортируются посимвольно, поэтому числовой порядок достигается либо приведением к числу (служебная колонка, ВЫРАЗИТЬ в запросе), либо выравниванием длины ведущими нулями. Исходные строки с нулями сохраняйте, ошибки преобразования обрабатывайте, результат проверяйте на наборе 1, 2, 10, 100.