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