Как в 1С вывести две таблицы параллельно в одном отчете

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

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

Метод 1. Объединение и группировка в запросе

Самый надежный способ вывести данные параллельно — это подготовить их еще на этапе запроса так, чтобы они попали в одну строку. Если у нас есть общие поля для связи (например, Номенклатура или Цвет), мы можем использовать конструкцию ОБЪЕДИНИТЬ ВСЕ с последующей группировкой.

Разберем логику: мы выбираем данные из первой таблицы, подставляя «0» в колонки второй, а затем выбираем данные из второй таблицы, подставляя «0» в колонки первой. Проанализируем пример кода:


ВЫБРАТЬ
    ТЧ.Цвет КАК Цвет,
    ТЧ.Количество КАК КоличествоТЧ,
    0 КАК КоличествоРег
ПОМЕСТИТЬ ВТ_Данные
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК ТЧ
ГДЕ
    ТЧ.Ссылка = &Ссылка

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    Рег.Цвет,
    0,
    Рег.Количество
ИЗ
    РегистрНакопления.ОстаткиТоваров КАК Рег
ГДЕ
    Рег.Регистратор = &Ссылка
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ.Цвет,
    СУММА(ВТ.КоличествоТЧ) КАК КоличествоТЧ,
    СУММА(ВТ.КоличествоРег) КАК КоличествоРег,
    СУММА(ВТ.КоличествоТЧ - ВТ.КоличествоРег) КАК Разница
ИЗ
    ВТ_Данные КАК ВТ
СГРУППИРОВАТЬ ПО
    ВТ.Цвет

Этот метод идеально подходит, когда строки можно сопоставить по какому-то ключу. В результате мы получим одну таблицу, где в каждой строке слева будут данные из документа, а справа — из регистра.

Метод 2. Синтетическая нумерация и полное соединение

Что делать, если явного ключа связи (как «Цвет» или «Номенклатура») нет, и нам нужно просто вывести строки «как есть»? В этом случае нам поможет нумерация строк внутри каждого набора данных. Мы создадим искусственный ключ НомерСтроки и соединим таблицы по нему.

Рассмотрим, как пронумеровать записи внутри запроса без использования временных таблиц, используя механизм соединения таблицы самой с собой. Это классический прием для получения порядкового номера:


ВЫБРАТЬ
    Т1.Ссылка,
    Т1.Номенклатура,
    КОЛИЧЕСТВО(Т2.Номенклатура) КАК НомерСтроки
ПОМЕСТИТЬ ТЧ_С_Номером
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК Т1
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.Товары КАК Т2
        ПО Т1.Ссылка = Т2.Ссылка
            И Т1.НомерСтроки >= Т2.НомерСтроки
ГДЕ
    Т1.Ссылка = &Ссылка
СГРУППИРОВАТЬ ПО
    Т1.Ссылка,
    Т1.Номенклатура,
    Т1.НомерСтроки

Выполнив аналогичную операцию для второй таблицы (например, движений), мы получим два набора данных, где у каждой записи есть индекс 1, 2, 3 и так далее. Теперь используем ПОЛНОЕ СОЕДИНЕНИЕ по полю НомерСтроки. Таким образом, первая строка ТЧ встанет напротив первой строки движений, вторая — напротив второй, и так далее.

Метод 3. Горизонтальное расположение группировок в СКД

Если мы не хотим усложнять запрос, можно воспользоваться встроенными возможностями СКД. Система компоновки данных позволяет управлять расположением подчиненных элементов.

Выполним следующие шаги в настройках отчета:

  1. Добавим группировку верхнего уровня (например, по полю Ссылка документа).
  2. Внутри этой группировки добавим две детальные записи. Первая будет выводить поля первой таблицы, вторая — поля второй.
  3. Выделим родительскую группировку (Ссылка) и перейдем на вкладку «Другие настройки».
  4. Найдем параметр «Расположение группировок» и установим значение «Горизонтально».

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

Метод 4. Использование типа «Таблица» в структуре СКД

Еще один способ в СКД — использование элемента «Таблица» вместо привычного списка. В структуре отчета «Таблица» имеет строки и колонки.

Разберем алгоритм настройки:

  1. В «Строки» таблицы добавим группировку Ссылка.
  2. В «Колонки» таблицы добавим вычисляемое поле или группировку, которая будет разделять данные. Например, можно создать поле ТипИсточника (со значениями «Документ» и «Регистр»).
  3. В «Выбранные поля» добавим нужные ресурсы.

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

Метод 5. Программный вывод и метод Присоединить()

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

Проанализируем примерную логику работы в модуле отчета:


// Получаем данные
Результат = НаборДанных.Выполнить();
ВыборкаДокументы = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

Пока ВыборкаДокументы.Следующий() Цикл
    // Выводим шапку документа
    ТабДок.Вывести(ОбластьШапкаДокумента);
    
    // Получаем две выборки по ТЧ и движениям
    ВыборкаТЧ = ВыборкаДокументы.Выбрать();
    ВыборкаДвижения = ВыборкаДокументы.Движения.Выбрать(); // Условно
    
    // Цикл по строкам (пока есть данные в любой из таблиц)
    Пока ВыборкаТЧ.Следующий() Или ВыборкаДвижения.Следующий() Цикл
        // Сначала выводим левую часть (ТЧ)
        Если ДанныеТЧ_Есть Тогда
            ТабДок.Вывести(ОбластьСтрокаТЧ);
        Иначе
            ТабДок.Вывести(ОбластьПустаяСтрокаТЧ);
        КонецЕсли;
        
        // Присоединяем правую часть (Движения) к этой же строке
        Если ДанныеДвижения_Есть Тогда
            ТабДок.Присоединить(ОбластьСтрокаДвижения);
        КонецЕсли;
    КонецЦикла;
КонецЦикла;

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

Выводы и рекомендации

Выясним, какой метод лучше выбрать в зависимости от ситуации. Если данные логически связаны общим ключом (например, товаром), лучше всего использовать Метод 1 (Объединение в запросе) — это обеспечит максимальную производительность. Если нужно просто сопоставить списки по порядку, используйте Метод 2 (Синтетические индексы).

Для быстрого построения отчетов в СКД без написания лишнего кода рассмотрите Метод 3 (Горизонтальные группировки). А если требуется идеальное визуальное оформление «пиксель в пиксель», программный вывод с методом Присоединить() будет самым гибким решением.

← На главную