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

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

Как упорядочить таблицу значений в 1С

Как упорядочить таблицу значений в 1С: метод Сортировать, сортировка по нескольким колонкам, по убыванию, в запросе. Примеры кода, ошибки и проверка результата.

Таблица значений в 1С — это универсальная структура для промежуточного хранения данных: результатов запросов, выгрузок из файлов, подготовленных к печати строк. Почти всегда после наполнения таблицы возникает задача вывести её строки в определённом порядке — по дате документа, по наименованию товара, по убыванию суммы. Для этого во встроенном языке предусмотрен метод Сортировать(), а для части сценариев есть альтернативы — упорядочивание ещё на уровне запроса или перенос данных в дерево значений.

Метод Сортировать() работает на месте: он физически перестраивает строки уже существующей таблицы и ничего не возвращает. Это значит, что до вызова метода таблица должна быть заполнена, а колонки, по которым идёт сортировка, должны существовать и иметь сравнимые типы данных. Нарушение этих условий — самая частая причина ошибок «Поле объекта не обнаружено» и «Несоответствие типов».

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

Метод Сортировать(): синтаксис и базовый пример

Метод вызывается у объекта типа ТаблицаЗначений и принимает один обязательный параметр — строку со списком колонок и направлением сортировки. Формат каждого элемента: ИмяКолонки [Возр|Убыв]. Если направление не указано, по умолчанию используется сортировка по возрастанию.

ТаблицаТоваров = Новый ТаблицаЗначений;

ТаблицаТоваров.Колонки.Добавить("Номенклатура");

ТаблицаТоваров.Колонки.Добавить("Сумма");

// ... заполнение таблицы ...

// Сортировка по наименованию по возрастанию

ТаблицаТоваров.Сортировать("Номенклатура");

// Сортировка по сумме по убыванию

ТаблицаТоваров.Сортировать("Сумма Убыв");

После вызова метода исходный порядок строк теряется безвозвратно — метод не создаёт копию, а перестраивает саму таблицу. Если исходный порядок понадобится позже, перед сортировкой сделайте копию методом Скопировать() и работайте с ней.

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

1c
ТЗ.Сортировать("Номенклатура Возр, Сумма Убыв");

Сортировка по нескольким колонкам

Когда значения в первой колонке совпадают, порядок строк определяется следующей колонкой из списка. Имена перечисляются через запятую, у каждой колонки — своё направление. Типичный пример: сначала по дате документа по возрастанию, внутри одной даты — по сумме по убыванию.

// Сначала по дате, внутри даты — по убыванию суммы

ТаблицаДокументов.Сортировать("Дата Возр, Сумма Убыв");

Количество колонок в списке практически не ограничено, но на больших таблицах (десятки тысяч строк и больше) сортировка по многим полям заметно нагружает память и процессор сервера. Если таблица получена запросом, многоуровневую сортировку эффективнее делать в самом запросе — сервер СУБД справится с ней быстрее.

Порядок колонок в строке сортировки имеет значение: «Дата, Сумма» и «Сумма, Дата» дадут разный результат. Всегда проверяйте итог на реальных данных, где встречаются повторяющиеся значения в первой колонке.

Типы данных и особенности сравнения значений

Корректная сортировка возможна только если значения в колонке сравнимы между собой. Числа сравниваются арифметически, строки — по алфавиту с учётом регистра и языковых правил, даты — хронологически, ссылки — по внутреннему представлению, а не по представлению пользователя. Именно поэтому сортировка ссылочной колонки «по алфавиту» иногда выглядит неожиданно.

Если колонка объявлена с составным типом (например, Число и Строка одновременно) или тип не задан вовсе, сравнение значений разных типов может завершиться ошибкой «Несоответствие типов». Надёжное решение — при создании колонки явно задавать тип через ОписаниеТипов:

ОписаниеЧисла = Новый ОписаниеТипов("Число", , , Новый КвалификаторыЧисла(15, 2));

ТЗ.Колонки.Добавить("Сумма", ОписаниеЧисла);

Если нужно отсортировать ссылки по наименованию, добавьте отдельную строковую колонку, заполните её представлениями ссылок (или выгрузите наименование запросом) и сортируйте по ней. Это предсказуемее, чем полагаться на внутреннее сравнение ссылок.

Альтернатива: упорядочивание в запросе

Если таблица значений получается выгрузкой результата запроса, сортировку почти всегда правильнее выполнять на стороне запроса с помощью конструкции УПОРЯДОЧИТЬ ПО. Запрос выполняется на сервере СУБД, где упорядочивание оптимизировано и использует индексы.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Продажи.Номенклатура КАК Номенклатура,

| СУММА(Продажи.СуммаОборот) КАК Сумма

|ИЗ

| РегистрНакопления.Продажи.Обороты КАК Продажи

|СГРУППИРОВАТЬ ПО

| Продажи.Номенклатура

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

| Сумма УБЫВ";

ТЗ = Запрос.Выполнить().Выгрузить(); // таблица уже упорядочена

Обратите внимание: в запросе направление задаётся словами УБЫВ / ВОЗР, а в методе Сортировать() — Убыв / Возр. Смешение синтаксиса — распространённая опечатка: запрос с Убыв не скомпилируется, а метод сортировки с УБЫВ в строке параметра, наоборот, примет его, так как регистр в строке не важен.

Сравнение вариантов

Метод Сортировать()

Подходит для таблиц, собранных вручную, из файлов или нескольких источников. Ограничение: выполняется в памяти сервера 1С, медленнее на больших объёмах.

УПОРЯДОЧИТЬ ПО в запросе

Подходит, когда данные берутся из информационной базы. Быстрее и использует индексы СУБД. Ограничение: неприменимо к таблицам, полученным не из запроса.

Дерево значений

Подходит, когда нужна иерархия с сортировкой на каждом уровне. Ограничение: требует перестроения структуры данных, избыточен для плоского списка.

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

Самый быстрый способ убедиться, что сортировка отработала, — вывести первые и последние строки таблицы в сообщения или посмотреть таблицу в отладчике через «Вычислить выражение» / табло. Для таблиц значений в конфигураторе доступен просмотр содержимого в виде таблицы.

// Быстрая проверка в отладке

Для Индекс = 0 По Мин(4, ТЗ.Количество() - 1) Цикл

Сообщить(ТЗ[Индекс].Номенклатура);

КонецЦикла;

Признак корректной сортировки по нескольким колонкам: значения первой колонки не убывают (или не возрастают — по заданному направлению), а внутри групп одинаковых значений соблюдается порядок второй колонки. Если порядок «прыгает», чаще всего колонка имеет составной тип или в ней остались пустые значения.

Контрольные точки

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

Порядок значений первой колонки
Норма

Значения монотонно возрастают или убывают по всей таблице

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

Порядок нарушается в середине таблицы — вероятен составной тип колонки

Группы одинаковых значений
Норма

Внутри группы соблюдается порядок второй колонки

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

Внутри группы порядок случайный — вторая колонка не указана или пуста

Пустые и NULL-значения
Норма

Таких значений нет либо они сгруппированы предсказуемо

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

Ошибка «Несоответствие типов» при вызове Сортировать()

Типичные ошибки и их устранение

Ошибка «Поле объекта не обнаружено» означает, что в строке сортировки указано имя несуществующей колонки. Имена колонок чувствительны к написанию: «СуммаДокумента» и «Сумма» — разные колонки. Проверьте состав колонок через ТЗ.Колонки в отладчике.

Ошибка «Несоответствие типов» возникает, когда в колонке смешаны несравнимые значения — например, числа и строки, или встречается NULL из левого соединения запроса. Лечение: задать колонке строгий тип при создании, а NULL заменить через ЕСТЬNULL() в запросе.

Тихая ошибка — сортировка строковой колонки, содержащей числа: «10» окажется раньше «2», потому что сравнение идёт посимвольно. Если колонка хранит номера или суммы, объявляйте её числовой, а не строковой.

Типичные ошибки
01
Сортировка по несуществующей колонке — ошибка «Поле объекта не обнаружено» при выполнении.
02
Числа хранятся как строки — получается порядок 1, 10, 2 вместо 1, 2, 10.
03
Сортировка копии, а вывод исходной таблицы — пользователь видит неупорядоченные данные.
04
Сортировка большой таблицы в памяти вместо УПОРЯДОЧИТЬ ПО в запросе — лишняя нагрузка на сервер.
Итог

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

Метод Сортировать() перестраивает таблицу на месте по строке вида «Колонка Возр, Колонка2 Убыв». Для данных из запроса предпочтительнее УПОРЯДОЧИТЬ ПО. Перед сортировкой убедитесь, что колонки существуют, имеют однородный тип и не содержат NULL.

FAQ

Как отсортировать таблицу значений по убыванию?

Передайте в метод Сортировать() имя колонки с ключевым словом «Убыв»: ТЗ.Сортировать("Сумма Убыв"). Без указания направления сортировка выполняется по возрастанию.

Можно ли отсортировать только часть строк таблицы?

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

Как упорядочить табличную часть документа?

Табличная часть — не таблица значений, метод Сортировать() у неё отсутствует. Решение: выгрузите табличную часть методом Выгрузить() в таблицу значений, отсортируйте её и загрузите обратно методом Загрузить(). Учтите, что номера строк будут пересчитаны.

Почему сортировка по колонке со ссылками идёт не по алфавиту?

Ссылки сравниваются по внутренним значениям, а не по представлению. Чтобы получить алфавитный порядок, добавьте строковую колонку с наименованиями (например, выгрузив их запросом) и сортируйте по ней.

Что быстрее: Сортировать() или УПОРЯДОЧИТЬ ПО в запросе?

Для данных из информационной базы быстрее и экономичнее упорядочивание в запросе — оно выполняется на сервере СУБД и может использовать индексы. Метод Сортировать() уместен, когда таблица собрана вручную или получена не из запроса.

Как отсортировать по нескольким колонкам с разным направлением?

Перечислите колонки через запятую, указав направление для каждой: ТЗ.Сортировать("Дата Возр, Сумма Убыв"). Сначала строки упорядочатся по дате, а внутри одинаковых дат — по убыванию суммы.