Как программно отсортировать определенный диапазон строк в табличной части документа 1С?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При разработке документации и обработке табличных частей в «1С:Предприятие» часто возникает задача упорядочить не всю таблицу целиком, а только определенную ее группу. Например, в табличной части документа присутствуют разделители или группы товаров, и отсортировать по наименованию требуется только строки с 5-й по 10-ю, не затрагивая остальные позиции.

Стандартный метод Сортировать(), доступный у объекта ТабличнаяЧасть или ТаблицаЗначений, производит сортировку всех записей без исключения. Разберем по шагам, как правильно и оптимально решить эту задачу с помощью программного кода.

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

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

Проанализируем пример кода с использованием таблицы значений:


// Указываем номера строк (включая начальную и конечную)
НачС = 5;
КонС = 10;

// Формируем массив ссылок на строки табличной части
Масс = Новый Массив;
Для к = НачС - 1 По КонС - 1 Цикл
    Масс.Добавить(Товары.Получить(к));
КонецЦикла;    

// Выгружаем выбранные строки во вспомогательную таблицу значений
НьюТЗ = Товары.Выгрузить(Масс);

// Сортируем полученный диапазон по нужной колонке
НьюТЗ.Сортировать("Номенклатура");

// Переносим отсортированные данные обратно в исходную ТЧ
Для к = НачС - 1 По КонС - 1 Цикл
    стр = Товары.Получить(к);
    ЗаполнитьЗначенияСвойств(стр, НьюТЗ.Получить(к - НачС + 1));
КонецЦикла;

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


ТекРазделитель = ЭлементыФормы.Товары.ТекущаяСтрока;
НачСтрока = ТекРазделитель.НомерСтроки + 1;
КонСтрока = ПолучитьКонечнуюСтрокуПоРазделителю(ТекРазделитель);

Список = Новый СписокЗначений;
Для Н = НачСтрока - 1 По КонСтрока - 1 Цикл
    СтрокаТЧ = Товары.Получить(Н);
    Список.Добавить(СтрокаТЧ, СтрокаТЧ.Номенклатура.Наименование);
КонецЦикла;    

// Сортировка по представлению (по алфавиту)
Список.СортироватьПоПредставлению(НаправлениеСортировки.Возраст);

М = 0;
Для К = НачСтрока - 1 По КонСтрока - 1 Цикл
    СтрокаТЧ = Товары.Получить(К);
    ЗаполнитьЗначенияСвойств(СтрокаТЧ, Список.Получить(М).Значение);
    М = М + 1;    
КонецЦикла;

Способ 2. Использование вспомогательного поля порядка

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

  1. Выгрузим всю табличную часть через метод Выгрузить().
  2. Добавим во вспомогательную таблицу колонку Порядок с типом Число.
  3. Для строк, находящихся вне целевого диапазона, в колонку Порядок запишем их текущий индекс.
  4. Для строк внутри диапазона рассчитаем и присвоим новые порядковые номера в соответствии с условием сортировки.
  5. Выполним единый вызов метода Сортировать("Порядок").
  6. Загрузим данные обратно в табличную часть с помощью метода Загрузить().

Важные нюансы и возможные ошибки

При использовании описанных алгоритмов необходимо учитывать следующие моменты:

1. Подчиненные табличные части и ключи связи
Использование ЗаполнитьЗначенияСвойств() копирует реквизиты строк, но сохраняет исходные физические объекты строк и их идентификаторы. Если к табличной части привязаны подчиненные таблицы (например, серии или комплектующие по полю КлючСвязи), простое копирование данных между строками может привести к рассинхронизации подчиненных строк.

2. Сортировка ссылочных типов по умолчанию
При вызове метода Сортировать() по колонке с ссылочным типом (например, СправочникСсылка.Номенклатура), платформа производит сортировку по внутреннему уникальному идентификатору (GUID), а не по алфавитному названию. Для правильной сортировки по наименованию выгружайте представление в отдельную колонку или используйте СписокЗначений.СортироватьПоПредставлению().

3. Различия между обычными и управляемыми формами
В управляемых формах на клиенте коллекция строк имеет тип ДанныеФормыКоллекция. Для выполнения скоординированной сортировки больших массивов выносите выгрузку и обработку табличной части на сервер в контексте объекта Объект.Товары.

← На главную