Как программно отсортировать колонки в Таблице значений 1С

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

В процессе разработки на платформе 1С:Предприятие часто возникают ситуации, когда ТаблицаЗначений формируется динамически. Например, при построении кросс-отчетов или аналитических панелей, где количество и названия колонок зависят от выбранного периода или набора аналитик. В таких случаях колонки могут добавляться в произвольном порядке, что затрудняет восприятие данных пользователем. В этой статье мы подробно разберем, как программно отсортировать колонки таблицы значений по алфавиту или в хронологическом порядке.

Постановка задачи и анализ ситуации

Представим ситуацию: в результате выполнения запроса или программного обхода данных у нас сформировалась таблица со следующими колонками: Факт_2024, Факт_2022, Факт_2023. Наша цель — привести их к логическому порядку: Факт_2022, Факт_2023, Факт_2024. Прямого метода СортироватьКолонки() в объекте ТаблицаЗначений не существует, поэтому нам придется использовать комбинацию встроенных механизмов.

Метод 1: Использование вспомогательного Списка значений и метода Скопировать

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

Рассмотрим по шагам реализацию этого алгоритма:

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

Проанализируем пример кода:


// Пусть ТЗ_Исходная - наша таблица с неправильным порядком колонок

// 1. Создаем список для сортировки имен
СписокИмен = Новый СписокЗначений;
Для Каждого Колонка Из ТЗ_Исходная.Колонки Цикл
    СписокИмен.Добавить(Колонка.Имя);
КонецЦикла;

// 2. Сортируем имена (по умолчанию — по алфавиту)
СписокИмен.СортироватьПоЗначению();

// 3. Формируем строку колонок для метода Скопировать
МассивИмен = СписокИмен.ВыгрузитьЗначения();
СтрокаКолонок = СтрСоединить(МассивИмен, ",");

// 4. Получаем новую таблицу с правильным порядком
ТЗ_Упорядоченная = ТЗ_Исходная.Скопировать(, СтрокаКолонок);

Важный нюанс: метод Скопировать() не только создает структуру, но и переносит данные. Если данных очень много, этот процесс может занять время. Если же вам нужна только "пустая" структура, используйте метод СкопироватьКолонки().

Метод 2: Использование метода Сдвинуть

Если мы не хотим создавать новую таблицу, а планируем изменить текущую, можно воспользоваться методом Сдвинуть() коллекции Колонки. Однако здесь есть подводный камень: при перемещении одной колонки индексы всех остальных колонок в коллекции пересчитываются. Это делает использование простых циклов "в лоб" крайне рискованным.

Разберем, как правильно реализовать перемещение:


// Пример перемещения колонки "НужнаяКолонка" на первую позицию (индекс 0)
КолонкиТЗ = ТЗ_Исходная.Колонки;
ТекущийИндекс = КолонкиТЗ.Индекс(КолонкиТЗ.НужнаяКолонка);
КолонкиТЗ.Сдвинуть(ТекущийИндекс, -ТекущийИндекс); 

Для полной сортировки этим методом обычно применяют алгоритм "пузырька" или другой алгоритм сравнения имен колонок, последовательно вызывая Сдвинуть(). Однако первый метод (через копирование) считается более надежным и понятным для чтения кода.

Метод 3: Сортировка колонок на управляемой форме

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

Рассмотрим ситуацию, когда нам нужно визуально перестроить колонки. Для этого мы будем использовать метод Переместить() для элементов формы.


// Допустим, ТаблицаНаФорме - это путь к данным таблицы,
// а Элементы.ТаблицаНаФорме - сам элемент управления

СписокПолей = Новый СписокЗначений;
Для Каждого Поле Из Элементы.ТаблицаНаФорме.ПодчиненныеЭлементы Цикл
    СписокПолей.Добавить(Поле.Имя, Поле.Заголовок); // Сортируем, например, по заголовку
КонецЦикла;

СписокПолей.СортироватьПоПредставлению();

// Перемещаем элементы в соответствии с отсортированным списком
Для Каждого ЭлементСписка Из СписокПолей Цикл
    ТекущееПоле = Элементы[ЭлементСписка.Значение];
    // Перемещаем в конец группы, последовательно выстраивая нужный порядок
    Элементы.Переместить(ТекущееПоле, Элементы.ТаблицаНаФорме);
КонецЦикла;

Особенности хронологической сортировки

Выясним причину, по которой обычная сортировка может не подойти. Если ваши колонки называются Январь_2023, Февраль_2023, то алфавитная сортировка поставит "Февраль" после "Января" только случайно. Если же в именах содержатся даты в формате 01_2023, 10_2023, то строковая сортировка может поставить 10_2023 раньше, чем 02_2023.

Чтобы избежать этой проблемы, при заполнении СпискаЗначений (как в Методе 1) рекомендуется:

  1. В значение элемента списка записывать реальное имя колонки.
  2. В параметр Представление записывать "ключ сортировки" (например, дату в формате ГГГГММДД).
  3. Использовать метод СписокИмен.СортироватьПоПредставлению().

Пример подготовки ключа для хронологической сортировки:


// Имя колонки: "Месяц_2023_05" (Май 2023)
КлючСортировки = "202305"; 
СписокИмен.Добавить("Месяц_2023_05", КлючСортировки);
// ... добавление других месяцев ...
СписокИмен.СортироватьПоПредставлению();

Сохранение типов данных при перестроении

Проанализируем ситуацию с типизацией. При использовании метода Скопировать() платформа автоматически сохраняет ОписаниеТипов для каждой колонки. Это критически важно, так как если вы попытаетесь создать новую таблицу "вручную" через Добавить(), не указав типы из исходной таблицы, вы потеряете точность чисел или длину строк. Всегда старайтесь использовать штатные методы копирования или явно извлекать Колонка.ТипЗначения.

Резюме

Мы рассмотрели несколько подходов к решению задачи. Наиболее универсальным и рекомендуемым является Метод №1 (Копирование со списком имен), так как он обеспечивает корректную работу с данными и типами при минимальном количестве кода. Не забывайте также проверять, требуется ли визуальное изменение порядка колонок на форме, и при необходимости используйте метод Элементы.Переместить().

← На главную