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