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