Как отсортировать таблицу значений в 1С по колонке, которой нет в исходной ТЗ?

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

В процессе разработки на платформе 1С часто возникает ситуация, когда в табличном поле на форме выводятся дополнительные данные (например, родитель номенклатуры, артикул или вычисляемые показатели), но в самой исходной ТаблицаЗначений этих колонок нет. Если попытаться вызвать стандартный метод Сортировать() по имени колонки, которая отсутствует в структуре ТЗ, платформа выдаст ошибку или сортировка не применится.

Рассмотрим, почему это происходит и как правильно решить эту задачу программно.

Причина поведения платформы

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

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

Пошаговый алгоритм решения

Разберем классический порядок действий для решения этой задачи:

  1. Выгрузка данных: Получаем исходную таблицу значений из табличной части или реквизита формы.
  2. Добавление колонки: Используем метод Колонки.Добавить() для создания служебного поля.
  3. Заполнение значений: Обходим таблицу в цикле и записываем необходимый реквизит (например, Номенклатура.Родитель).
  4. Сортировка: Вызываем метод Сортировать() по новому полю.
  5. Загрузка данных: Возвращаем отсортированную таблицу обратно в табличное поле или табличную часть.

Пример программного кода

Рассмотрим практический пример реализации этого алгоритма:


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

// Добавляем отсутствующую колонку для сортировки
ТЗ.Колонки.Добавить("Реквизит1");

// Заполняем добавленную колонку необходимыми данными
Для Каждого СтрокаТЗ Из ТЗ Цикл
    СтрокаТЗ.Реквизит1 = СтрокаТЗ.Номенклатура.Родитель;
КонецЦикла;

// Выполняем сортировку по созданной колонке
ТЗ.Сортировать("Реквизит1 Возр");

// Загружаем отсортированную таблицу обратно в ТЧ
ТЧ.Загрузить(ТЗ);

Оптимизация заполнения через запрос (решение проблемы N+1)

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

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ТЗ.Номенклатура КАК Номенклатура,
    |	ТЗ.Количество КАК Количество
    |ПОМЕСТИТЬ ВТ_Данные
    |ИЗ
    |	&ТЗ КАК ТЗ
    |;
    |
    |ВЫБРАТЬ
    |	ВТ.Номенклатура КАК Номенклатура,
    |	ВТ.Количество КАК Количество,
    |	ВТ.Номенклатура.Родитель КАК Родитель
    |ИЗ
    |	ВТ_Данные КАК ВТ
    |УПОРЯДОЧИТЬ ПО
    |	Родитель ВОЗР";

Запрос.УстановитьПараметр("ТЗ", ИсходнаяТЗ);
ТаблицаРезультат = Запрос.Выполнить().Выгрузить();

Очистка служебных колонок

Если добавленная колонка нужна была только для упорядочивания элементов и не требуется в дальнейшем, после выполнения сортировки её можно удалить из структуры таблицы с помощью метода ТЗ.Колонки.Удалить("Реквизит1"). Это позволит сохранить исходную структуру данных и не перегружать оперативную память.

← На главную