Как вывести данные СКД в два разных табличных документа на одной форме

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

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

Метод 1. Использование реквизитов отчета

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

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


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

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

Метод 2. Использование дополнительных свойств настроек

Для более чистого разделения кода и избежания жесткой привязки к реквизитам, мы можем использовать механизм дополнительных свойств компоновщика настроек. Проанализируем, как передать ссылку на табличный документ с формы в модуль объекта.

В коде формы, перед тем как вызвать команду формирования отчета (или переопределив стандартную кнопку), выполним следующий код:


&НаКлиенте
Процедура СформироватьОтчет(Команда)
    
    // Помещаем ссылку на второй табличный документ в настройки
    СтруктураДопСвойств = Новый Структура;
    СтруктураДопСвойств.Вставить("ВторойТабДок", Элементы.ТабличныйДокументСводно);
    
    Отчет.КомпоновщикНастроек.Настройки.ДополнительныеСвойства.Вставить("КонтекстВывода", СтруктураДопСвойств);
    
    // Вызываем стандартное формирование или программное
    СформироватьПрограммно();
    
КонецПроцедуры

В модуле объекта в процедуре ПриКомпоновкеРезультата мы извлекаем этот документ:


Если Настройки.ДополнительныеСвойства.Свойство("КонтекстВывода") Тогда
    ВторойТабДок = Настройки.ДополнительныеСвойства.КонтекстВывода.ВторойТабДок;
    // Теперь мы можем программно выводить в него данные
КонецЕсли;

Метод 3. Полное программное формирование с двумя процессорами вывода

Выясним причину, почему стандартный механизм не всегда подходит: он инициализирует только один ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент. Чтобы вывести данные профессионально, мы можем создать два разных процессора вывода. Рассмотрим пример реализации:

  1. Инициализируем схему и настройки компоновки.
  2. Создаем МакетКомпоновки с помощью КомпоновщикМакета.
  3. Создаем ПроцессорКомпоновкиДанных.
  4. Создаем два процессора вывода для разных табличных документов.

// Пример программного вывода в два документа
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки);

// Процессор для основного документа
ПроцессорВывода1 = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода1.УстановитьДокумент(ДокументРезультат1);

// Процессор для второго документа
ПроцессорВывода2 = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода2.УстановитьДокумент(ДокументРезультат2);

// Начинаем вывод
ПроцессорВывода1.НачатьВывод();
ПроцессорВывода2.НачатьВывод();

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

ПроцессорВывода1.ЗакончитьВывод();
ПроцессорВывода2.ЗакончитьВывод();

Этот метод дает максимальный контроль над процессом формирования и позволяет распределять данные между документами буквально "на лету".

Метод 4. Метод копирования областей

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

Для этого используем метод ПолучитьОбласть() и Вывести(). Посмотрим на пример кода:


// Копируем шапку из основного результата во второй документ
ОбластьШапки = ДокументРезультат.ПолучитьОбласть(1, 1, 5, ДокументРезультат.ШиринаТаблицы);
ТабДокНаФорме2.Вывести(ОбластьШапки);

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

Метод 5. Использование разных вариантов отчета

Посмотрим на ситуацию с точки зрения архитектуры. Самый "правильный" способ с точки зрения платформы 1С — это использование разных вариантов настроек в рамках одной схемы. Мы можем настроить "Вариант 1" для детальных данных и "Вариант 2" для сводных.

При нажатии кнопки Сформировать на форме, мы программно запускаем компоновку дважды: сначала с настройками первого варианта (вывод в первый табличный документ), затем с настройками второго варианта (вывод во второй документ).

Преимущества этого подхода:

Рекомендации по производительности

При выводе в несколько табличных документов, особенно если они содержат тысячи строк, важно помнить о производительности отрисовки интерфейса. Проанализируем несколько советов:

  1. Используйте ТабличныйДокумент.Обновление(Ложь) перед началом заполнения и Истина после завершения. Это значительно ускорит процесс.
  2. Для второго документа, если он носит справочный характер, можно отключить авторасчет итогов: ТабДок.АвтоРасчетИтогов = Ложь.
  3. Если данные во втором документе не требуют расшифровки, не забудьте очистить ДанныеРасшифровки для второго процессора вывода, чтобы сэкономить память.

Таким образом, мы рассмотрели пять различных стратегий решения задачи. Выбор конкретного метода зависит от сложности вашего отчета и требований к гибкости настроек. Для простых задач вполне подойдет использование реквизитов отчета, в то время как для сложных аналитических инструментов лучше использовать программный вывод с разделением элементов результата или работу с разными вариантами настроек.

← На главную