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

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

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

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

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

Чаще всего сортировка таблицы значений нужна при подготовке данных к выводу в отчёт, при заполнении табличных частей документов, при сравнении наборов данных или перед выгрузкой в файл. Неотсортированная таблица затрудняет поиск дублей, ломает логику «первого подходящего» значения и делает непредсказуемым порядок строк в печатной форме.

Материал ориентирован на разработчиков и внедренцев, работающих в конфигураторе 1С:Предприятие 8.3. Все примеры кода можно проверить в консоли кода или в отладчике на тестовой копии базы.

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

Основной инструмент — метод таблицы значений Сортировать(КолонкиСортировки, ОбъектСравнения). Первый параметр — строка с именами колонок и направлениями, разделёнными запятыми. Направление задаётся словом Возр (по возрастанию, используется по умолчанию) или Убыв (по убыванию).

Метод работает «на месте»: он не возвращает новую таблицу, а перестраивает строки в существующей. Возвращаемого значения у него нет, поэтому конструкция вида Результат = ТЗ.Сортировать(..) бессмысленна.

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

ТаблицаТоваров.Сортировать("Цена Убыв");

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

Порядок перечисления колонок определяет приоритет: сначала строки сравниваются по первой колонке, при равенстве значений — по второй и так далее. Это позволяет строить многоуровневую сортировку, например сгруппировать строки по складу, а внутри склада выстроить по наименованию.

Порядок действий
  1. 1
    Убедитесь, что колонки, по которым сортируете, существуют в таблице значений
  2. 2
    Проверьте, что типы значений в колонке сопоставимы (числа с числами, даты с датами)
  3. 3
    Вызовите ТЗ.Сортировать() с нужными колонками и направлениями
  4. 4
    Проверьте результат в отладчике, просмотрев первые и последние строки таблицы

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

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

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

Сравнение значений и параметр ОбъектСравнения

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

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

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

Типичные ошибки
01
Указание несуществующего имени колонки — ошибка времени выполнения и остановка обработки
02
Ожидание, что Сортировать() вернёт новую таблицу — метод меняет исходную, а возвращает ничего
03
Сортировка колонки со смешанными типами — визуально непредсказуемый порядок строк
04
Сортировка уже отсортированной таблицы другим методом без учёта, что прежний порядок будет потерян

Сортировка через запрос

Альтернатива методу Сортировать() — поместить таблицу значений во временную таблицу запроса и упорядочить её конструкцией УПОРЯДОЧИТЬ ПО. Такой подход оправдан, когда вместе с сортировкой нужно обогатить данные соединением с таблицами базы, сгруппировать их или отфильтровать.

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

Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;

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

"ВЫБРАТЬ

| ТЗ.Номенклатура КАК Номенклатура,

| ТЗ.Количество КАК Количество

|ПОМЕСТИТЬ ВТ_Данные

|ИЗ &ТЗ КАК ТЗ

|;

|ВЫБРАТЬ * ИЗ ВТ_Данные

|УПОРЯДОЧИТЬ ПО Номенклатура.Наименование";

Запрос.УстановитьПараметр("ТЗ", ТаблицаТоваров);

Результат = Запрос.Выполнить().Выгрузить();

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

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

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

Быстро и просто для таблиц в памяти; ограничение — сортировка только по колонкам самой таблицы

Запрос с УПОРЯДОЧИТЬ ПО

Подходит, когда нужно сортировать по полям ссылок или соединять с данными базы; требует передачи ТЗ в запрос

Сортировка в СКД

Удобна для отчётов: порядок задаётся в настройках, пользователь может менять его сам без изменения кода

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

Для форм списков: задаётся через свойство Порядок, не требует выгрузки данных в таблицу значений

Сортировка данных на форме и в отчётах

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

В отчётах на СКД сортировку обычно не делают в коде вовсе. Порядок строк задаётся на закладке «Сортировка» в настройках варианта отчёта, а пользователь может переопределить его самостоятельно. Программная сортировка в СКД выполняется через коллекцию Настройки.Порядок.Элементы, куда добавляются элементы с полем и направлением.

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

Маршрут решения

Как выбрать действие

Таблица значений собрана в коде и нужна простая сортировка по её колонкамИспользуйте метод ТЗ.Сортировать() с указанием колонок и направлений
Нужно сортировать по полям ссылок или дополнить данные из базыПоместите таблицу в запрос и примените УПОРЯДОЧИТЬ ПО
Сортировка нужна в отчёте, который настраивает пользовательЗадайте порядок в настройках СКД, не сортируя данные в коде
Речь о списке документов или справочника на формеНастройте свойство Порядок динамического списка

Производительность и ограничения

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

Отдельное ограничение связано с передачей данных между клиентом и сервером. Таблица значений как самостоятельный тип недоступна в тонком и веб-клиенте вне контекста формы, поэтому код сортировки серверной таблицы выполняют в серверных процедурах, а на клиент возвращают уже упорядоченные данные.

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

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

Проверять результат удобнее всего в отладчике: поставьте точку останова после вызова Сортировать() и просмотрите таблицу через «Вычислить выражение» → «Показать значение в отдельном окне». Первые и последние строки покажут, правильно ли выбрано направление.

Для автоматической проверки можно пройтись по таблице циклом и убедиться, что каждое следующее значение ключа не меньше предыдущего (при сортировке по возрастанию). Это полезно в юнит-тестах обработок, где сортировка — часть контракта процедуры.

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

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

Первая строка таблицы
Норма

Содержит минимальное значение ключа при сортировке по возрастанию

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

Первой идёт строка с большим значением — перепутано направление

Строки с пустыми значениями
Норма

Собраны в ожидаемом месте (обычно в начале при возрастании)

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

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

Многоуровневая сортировка
Норма

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

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

Вторая колонка не влияет на порядок — проверьте запятые и имена колонок

Частые вопросы

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

Да, но направление указывается для каждой колонки отдельно: ТЗ.Сортировать("Колонка1 Убыв, Колонка2 Убыв"). Единого модификатора «все по убыванию» в синтаксисе метода нет.

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

Табличная часть поддерживает тот же метод: ОбъектДокумента.Товары.Сортировать("Номенклатура"). Учтите, что после изменения порядка строк документ нужно записать, чтобы изменения сохранились в базе.

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

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

Можно ли отменить сортировку и вернуть исходный порядок строк?

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

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

Для таблицы, уже находящейся в памяти, метод Сортировать() обычно быстрее, так как не требует передачи данных в запрос и обратно. Запрос выигрывает, когда сортировка совмещена с выборкой дополнительных данных из базы.

Работает ли Сортировать() на тонком клиенте?

Таблица значений как самостоятельный объект на тонком клиенте недоступна, но реквизиты формы типа «ТаблицаЗначений» и «ДанныеФормыКоллекция» сортировать можно. Тяжёлые обработки корректно выполнять в серверных процедурах.

Итог

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

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