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

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

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

Анализ проблемы и постановка задачи

Рассмотрим классическую ситуацию: у нас есть основной набор данных (результат запроса) и вспомогательный набор данных (например, Таблица Значений), в котором жестко задан правильный порядок следования ключевых полей. Наша цель — вывести отчет так, чтобы колонки следовали именно в том порядке, который указан во вспомогательной таблице. Главная ошибка новичков — попытка «найти» уже выведенную колонку в готовом документе. Правильный подход заключается в управлении процессом вывода в момент формирования документа.

Метод 1: Использование именованных вертикальных областей

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

Во-первых, в макете создается область (например, с именем КолонкаДанных), охватывающая нужные колонки по вертикали. Во-вторых, мы организуем цикл не по результату основного запроса, а по той самой таблице, где задан верный порядок.

Рассмотрим пример кода:


// Получаем макет и создаем табличный документ
Макет = ПолучитьМакет("МойМакет");
ТабДок = Новый Табличный Документ;

// Область шапки (горизонтальная)
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ТабДок.Вывести(ОбластьШапка);

// Цикл по Таблице Значений, где задан ПРАВИЛЬНЫЙ порядок колонок
Для Каждого СтрокаПорядка Из ТЗ_ПравильныйПорядок Цикл
    
    // Получаем вертикальную область для колонки
    ОбластьКолонка = Макет.ПолучитьОбласть("Колонка");
    
    // Заполняем параметры области данными из основного набора
    // Предположим, у нас есть СтруктураДанных, где ключи - названия колонок
    ОбластьКолонка.Параметры.Заголовок = СтрокаПорядка.ИмяКолонки;
    
    // Присоединяем колонку справа к предыдущим
    ТабДок.Присоединить(ОбластьКолонка);
    
КонецЦикла;

Этот метод позволяет полностью абстрагироваться от того, в какой последовательности данные пришли из базы данных. Мы управляем порядком «на лету».

Метод 2: Использование объекта Соответствие (Map) для связи данных

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

Чтобы эффективно связать данные и порядок, мы рекомендуем использовать следующую связку:

  1. Выгружаем результат основного запроса в Соответствие, где ключом будет уникальный идентификатор колонки, а значением — данные для вывода.
  2. Используем Массив или Таблицу Значений для хранения ключей в нужном порядке.
  3. В цикле обходим массив ключей, достаем данные из Соответствия и выводим их в ТабДок.

Разберем пример реализации:


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

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

Метод 3: Программное управление выбранными полями в СКД

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

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

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

Пример программного добавления полей:


Настройки = КомпоновщикНастроек.Настройки;
Настройки.ВыбранныеПоля.Элементы.Очистить();

Для Каждого ИмяПоля Из МассивНужныхИмен Цикл
    НовоеПоле = Настройки.ВыбранныеПоля.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
    НовоеПоле.Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);
    НовоеПоле.Использование = Истина;
КонецЦикла;

Метод 4: Использование промежуточной Таблицы Значений

Иногда удобнее сначала «собрать» финальную таблицу данных в памяти, а потом просто вывести её целиком. В объекте ТаблицаЗначений можно программно управлять колонками.

Хотя метода «ПереместитьКолонку» с индексом в 1С нет, мы можем использовать метод Сдвинуть() для коллекции колонок. Однако надежнее создать новую ТЗ, добавить в нее колонки в нужном порядке и скопировать данные. После этого вывод в ТабличныйДокумент превращается в два простых вложенных цикла: по строкам и по колонкам ТЗ.

Важные нюансы идентификации колонок

В сообщении №4 автор спрашивает: «Как найти нужную колонку из таб дока для их связи?». Запомните: искать колонку в сформированном документе — это ресурсоемкая операция, требующая чтения текста ячеек.

Рекомендация: всегда используйте имена параметров в макете. В области макета ячейке можно назначить параметр (например, <текст>ТекущийПоказатель</текст>). При выводе области вы обращаетесь к нему напрямую: Область.Параметры.ТекущийПоказатель = Значение. Это исключает необходимость поиска «по координатам» или «по тексту».

Заключение

Мы выяснили причину сложности: попытка подстроиться под результат запроса вместо того, чтобы управлять выводом самостоятельно. Рассмотренные методы — использование вертикальных областей с Присоединить() и программная настройка СКД — являются профессиональными стандартами разработки в 1С. Выбор конкретного метода зависит от объема данных и используемого механизма отчетов в вашей конфигурации.

← На главную