Разработка и Конфигурация · 11 мин
Как отсортировать строку в 1С: практические способы и примеры
Как отсортировать строку в 1С: сортировка массива, списка значений, таблицы значений и символов строки. Примеры кода, типичные ошибки и ответы на вопросы.
Встроенного метода «отсортировать строку» в языке 1С нет: строка является неизменяемым значением, и переставить символы внутри неё напрямую нельзя. На практике задача сводится к одному из двух сценариев: либо нужно отсортировать коллекцию строк (массив, список значений, таблицу значений, строки динамического списка), либо разобрать строку на символы или подстроки, отсортировать их и собрать обратно. Оба сценария решаются штатными средствами платформы без внешних компонент.
Выбор инструмента зависит от того, где данные находятся. Для таблиц значений и динамических списков есть встроенная сортировка, для массивов её нет, и приходится либо переносить данные в сортируемую структуру, либо писать алгоритм вручную. Ниже разобраны рабочие примеры кода для каждого случая, ограничения методов и типичные ошибки.
Что именно нужно отсортировать: определяем задачу
Прежде чем писать код, уточните постановку. «Сортировка строки» в 1С обычно означает одно из четырёх: упорядочить массив строк по алфавиту, отсортировать строки табличной части или таблицы значений, отсортировать подстроки, разделённые запятой или переносом строки, либо переставить символы внутри одной строки по алфавиту. Для каждого случая свой инструмент.
Второй важный вопрос — нужна ли сортировка с учётом регистра и локали. Строковое сравнение в 1С по умолчанию выполняется с учётом регистра и правил языка, заданных в информационной базе. Это значит, что «Яблоко» и «яблоко» могут оказаться в разных позициях в зависимости от настроек, а буква «Ё» в некоторых конфигурациях сортируется не так, как ожидает пользователь.
Как выбрать способ
Сортировка коллекции строк через СписокЗначений
Самый простой способ отсортировать набор строк — поместить их в объект СписокЗначений и вызвать метод СортироватьПоЗначению(). Метод принимает необязательный параметр направления сортировки: по умолчанию по возрастанию, для обратного порядка передайте НаправлениеСортировки.Убыв.
Список = Новый СписокЗначений;
Список.Добавить("Банан");
Список.Добавить("Апельсин");
Список.Добавить("Вишня");
Список.СортироватьПоЗначению(НаправлениеСортировки.Возр);
Для Каждого Элемент Из Список Цикл
Сообщить(Элемент.Значение);
КонецЦикла;
Если исходные данные лежат в массиве, перенесите их в список значений, отсортируйте и выгрузите обратно через метод ВыгрузитьЗначения(). Это короче и надёжнее, чем писать собственный алгоритм сортировки: штатный метод отлажен и работает быстрее интерпретируемого кода на больших объёмах.
Список = Новый СписокЗначений;
Список.ЗагрузитьЗначения(МассивСтрок);
Список.СортироватьПоЗначению();
МассивСтрок = Список.ВыгрузитьЗначения();
Сортировка строк таблицы значений и табличной части
Таблица значений имеет собственный метод Сортировать(), который принимает строку с перечислением колонок и направлений через запятую, например: "Наименование Возр, Дата Убыв". Это основной способ упорядочить строки, когда у каждой записи несколько полей.
ТаблицаТоваров.Сортировать("Наименование Возр");
Для табличной части объекта (документа, справочника) метод Сортировать() тоже доступен, но вызывается он через выгрузку: часто удобнее выгрузить табличную часть в таблицу значений методом Выгрузить(), отсортировать и загрузить обратно методом Загрузить(). Учтите, что прямая пересортировка табличной части меняет порядок строк в объекте — при записи документа новый порядок сохранится в базе.
Если сортировка нужна только для вывода пользователю, а не для хранения, безопаснее работать с копией данных: выгрузить таблицу, отсортировать копию и показать её, не трогая исходный объект. Это исключит случайное изменение порядка строк в проведённых документах.
Сортировка символов внутри одной строки
Когда задача — переставить символы самой строки по алфавиту (например, из "вба" получить "абв"), строку нужно разобрать на отдельные символы. Удобнее всего снова воспользоваться СписокЗначений: добавить каждый символ как элемент, отсортировать и склеить результат.
Функция СортироватьСимволыСтроки(Строка)
Список = Новый СписокЗначений;
Для Позиция = 1 По СтрДлина(Строка) Цикл
Список.Добавить(Сред(Строка, Позиция, 1));
КонецЦикла;
Список.СортироватьПоЗначению();
Результат = "";
Для Каждого Элемент Из Список Цикл
Результат = Результат + Элемент.Значение;
КонецЦикла;
Возврат Результат;
КонецФункции
Аналогично сортируются подстроки, разделённые разделителем. Функция СтрРазделить() превращает строку "Груша,Апельсин,Банан" в массив, далее массив сортируется через список значений, а СтрСоединить() собирает итоговую строку обратно с тем же разделителем. Это типовой приём для списков, хранящихся в одном реквизите.
- 1Разбейте строку функцией СтрРазделить(Строка, ",") в массив
- 2Загрузите массив в СписокЗначений через ЗагрузитьЗначения()
- 3Вызовите СортироватьПоЗначению() с нужным направлением
- 4Соберите результат функцией СтрСоединить(Массив, ",")
- 5Проверьте результат на тестовой строке с разным регистром и пробелами
Сортировка на стороне запроса и в динамическом списке
Если строки выбираются из базы данных, сортировать их в коде поздно и неэффективно — правильнее упорядочить данные сразу в запросе секцией УПОРЯДОЧИТЬ ПО. Запрос вернёт уже отсортированную выборку, что заметно быстрее на больших объёмах, потому что сортировку выполняет СУБД.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|УПОРЯДОЧИТЬ ПО
| Наименование";
В динамических списках управляемых форм сортировка настраивается через свойство «Порядок» в настройках списка либо программно через элементы отбора-порядка компоновки данных. Пользовательская сортировка по щелчку на заголовок колонки работает автоматически, если поле доступно для упорядочивания. В обычных формах для табличного поля сортировка задаётся через свойство колонки или метод настройки порядка.
Если данные уже выбираются запросом, добавление УПОРЯДОЧИТЬ ПО почти всегда предпочтительнее последующей сортировки таблицы значений в коде: меньше кода, выше скорость, меньше расход памяти на сервере.
Направление сортировки, регистр и особенности сравнения строк
Направление сортировки задаётся системным перечислением НаправлениеСортировки со значениями Возр и Убыв. В методе Сортировать() таблицы значений направление указывается словом после имени колонки; если слово опущено, применяется сортировка по возрастанию.
Сравнение строк в 1С выполняется посимвольно с учётом настроек информационной базы. Практические следствия: строки в разном регистре могут сортироваться не так, как ожидается; цифры внутри строк сравниваются как символы, поэтому "Товар10" окажется раньше "Товар2". Если нужен «естественный» порядок с числами, потребуется собственная функция сравнения или добавление служебной колонки с числовой частью.
Для сортировки без учёта регистра приведите значения к одному регистру функцией ВРег() или НРег() в отдельной колонке и сортируйте по ней, сохраняя исходное значение для вывода. Это стандартный обходной приём, когда пользователю нужен алфавитный порядок независимо от того, с какой буквы введены данные.
Проверка результата и производительность
После сортировки проверьте результат на контрольном наборе: первый и последний элементы, значения с разным регистром, строки с цифрами и спецсимволами. Для отладки выводите содержимое списка или таблицы в цикле через Сообщить() либо откройте значение в отладчике через «Вычислить выражение».
По производительности штатные методы (СортироватьПоЗначению, Сортировать, УПОРЯДОЧИТЬ ПО) реализованы на уровне платформы и выигрывают у любых самописных циклов. Собственный алгоритм (пузырьковая сортировка и подобные) оправдан только в учебных целях или при нестандартном правиле сравнения, которое нельзя выразить штатными средствами. На коллекциях в десятки тысяч строк разница между штатным методом и ручным циклом становится ощутимой.
Как проверить результат
Значения идут по алфавиту в заданном направлении
Элементы перемешаны или порядок обратный ожидаемому
Осознанно выбран строковый или числовой порядок
'Товар2' стоит после 'Товар10', а нужен числовой порядок
Регистр учтён или нормализован через ВРег()
Строки с заглавной буквы сгруппированы отдельно от строчных
Объекты базы не изменились, если это не требовалось
Порядок строк в документе изменился без необходимости
Частые вопросы
Можно ли отсортировать массив строк напрямую без списка значений?
Штатного метода сортировки у массива нет. Варианты: перенести значения в СписокЗначений, отсортировать и выгрузить обратно, либо реализовать собственный алгоритм. Первый способ короче и быстрее, самописная сортировка нужна только при нестандартном правиле сравнения.
Как отсортировать строки в обратном порядке?
Передайте направление: СписокЗначений.СортироватьПоЗначению(НаправлениеСортировки.Убыв), а для таблицы значений укажите "Убыв" после имени колонки в методе Сортировать(). В запросе используйте конструкцию УПОРЯДОЧИТЬ ПО Поле УБЫВ.
Почему "10" оказывается раньше "2" при сортировке?
Потому что сравниваются строки, а не числа: посимвольно "1" меньше "2". Решение — добавить числовую колонку с числовым представлением и сортировать по ней либо привести значения к типу Число до сортировки.
Как отсортировать строки табличной части документа?
Выгрузите табличную часть в таблицу значений методом Выгрузить(), вызовите Сортировать() по нужной колонке и загрузите результат обратно методом Загрузить(). Помните: после записи объекта новый порядок сохранится в базе данных.
Влияет ли регистр букв на сортировку?
Да, строковое сравнение в 1С учитывает регистр и настройки локали информационной базы. Если нужен порядок без учёта регистра, создайте служебную колонку со значением ВРег(Наименование) и сортируйте по ней.
Что быстрее: сортировка в запросе или в коде?
Сортировка в запросе через УПОРЯДОЧИТЬ ПО быстрее и экономичнее по памяти, так как её выполняет СУБД. Сортировку в коде используйте, когда данные собираются из разных источников или правило упорядочивания нельзя выразить в запросе.
Что важно запомнить
Для сортировки набора строк используйте СписокЗначений.СортироватьПоЗначению(), для таблиц — метод Сортировать(), для данных из базы — УПОРЯДОЧИТЬ ПО в запросе. Символы внутри одной строки сортируются через разбор в список и обратную сборку. Учитывайте регистр, строковое сравнение чисел и не меняйте порядок строк в объектах базы без необходимости.