В практике разработки на платформе 1С:Предприятие 8.3 часто возникает задача визуального сопоставления данных. Типичный пример: в документе есть две табличные части (например, «Товары» и «Услуги» или «Состав» и «Материалы»), и пользователю необходимо видеть их не одну под другой, а в одной горизонтальной плоскости. Это позволяет компактно разместить информацию и упростить анализ документа. Рассмотрим подробнее, как реализовать такой вывод несколькими способами, проанализируем их плюсы и выберем оптимальный вариант в зависимости от ваших задач.
Разберем самый надежный с точки зрения подготовки данных метод — объединение таблиц непосредственно в запросе. Основная сложность здесь заключается в том, что количество строк в первой и второй табличных частях может не совпадать. Если мы просто используем ЛевоеСоединение, мы потеряем строки из второй таблицы, если их больше. Поэтому проанализируем алгоритм использования ПОЛНОЕ СОЕДИНЕНИЕ.
Для того чтобы строки выстроились «плечом к плечу», нам нужен общий ключ. В данном случае идеальным ключом будет НомерСтроки. Однако, чтобы запрос работал корректно для нескольких документов, соединение должно идти по паре полей: Ссылка и НомерСтроки.
Посмотрим на пример текста запроса:
ВЫБРАТЬ
ЕСТЬNULL(ТЧ_Товары.НомерСтроки, ТЧ_Услуги.НомерСтроки) КАК ОбщийНомерСтроки,
ТЧ_Товары.Номенклатура КАК Товар,
ТЧ_Товары.Количество КАК КолТовара,
ТЧ_Услуги.Номенклатура КАК Услуга,
ТЧ_Услуги.Количество КАК КолУслуги
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК ТЧ_Товары
ПОЛНОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.Услуги КАК ТЧ_Услуги
ПО ТЧ_Товары.Ссылка = ТЧ_Услуги.Ссылка
И ТЧ_Товары.НомерСтроки = ТЧ_Услуги.НомерСтроки
ГДЕ
ТЧ_Товары.Ссылка = &Ссылка ИЛИ ТЧ_Услуги.Ссылка = &Ссылка
ОБЪЕДИНИТЬ ВСЕ
...
Важный нюанс: использование функции ЕСТЬNULL для номера строки позволяет нам получить сквозную нумерацию, даже если в одной из таблиц строка отсутствует. Если строк в первой ТЧ пять, а во второй три, то для 4-й и 5-й строк поля второй ТЧ просто останутся пустыми (содержащими NULL), что нам и нужно для отчета.
Если вы формируете отчет программно, используя ТабличныйДокумент и Макет, то наиболее простым решением будет использование метода Присоединить(). В отличие от метода Вывести(), который всегда добавляет новую строку вниз, Присоединить() добавляет область справа от последней выведенной.
Выясним причину, по которой этот метод требует осторожности: нам нужно заранее определить, какая табличная часть длиннее, чтобы цикл прошел по всем строкам. Проанализируем пример кода для реализации этой логики:
МаксСтрок = Макс(Объект.Товары.Количество(), Объект.Услуги.Количество());
Для Индекс = 0 По МаксСтрок - 1 Цикл
// Выводим данные первой ТЧ (левая часть)
ОбластьЛево = Макет.ПолучитьОбласть("СтрокаЛево");
Если Индекс < Объект.Товары.Количество() Тогда
ТекущаяСтрокаТовары = Объект.Товары[Индекс];
ОбластьЛево.Параметры.Товар = ТекущаяСтрокаТовары.Номенклатура;
Иначе
ОбластьЛево.Параметры.Товар = ""; // Заполняем пустотой
КонецЕсли;
ТабДок.Вывести(ОбластьЛево);
// Присоединяем данные второй ТЧ (правая часть)
ОбластьПраво = Макет.ПолучитьОбласть("СтрокаПраво");
Если Индекс < Объект.Услуги.Количество() Тогда
ТекущаяСтрокаУслуги = Объект.Услуги[Индекс];
ОбластьПраво.Параметры.Услуга = ТекущаяСтрокаУслуги.Номенклатура;
Иначе
ОбластьПраво.Параметры.Услуга = "";
КонецЕсли;
ТабДок.Присоединить(ОбластьПраво);
КонецЦикла;
Используя такой подход, мы гарантируем, что верстка отчета не «поплывет», а данные будут выстроены строго по горизонтали. Обратите внимание: если вы не выведете пустую область (заглушку) для короткой таблицы, границы ячеек могут не отобразиться, что испортит визуальный вид отчета.
Рассмотрим ситуацию, когда отчет должен быть гибким и настраиваемым пользователем. В СКД вывод двух таблиц рядом можно реализовать через вложенные таблицы или через объединение наборов данных.
Посмотрим на шаги настройки через несколько наборов данных:
НаборДанныхЗапрос1 для первой табличной части. Обязательно добавляем поле НомерСтроки.НаборДанныхЗапрос2 для второй табличной части. Также добавляем НомерСтроки.Ссылка и НомерСтроки. Тип связи выбираем «Полное соединение» (если платформа позволяет) или используем общую таблицу-индекс.Для повышения производительности, особенно если документов в отчете много, рекомендуется использовать индексированные временные таблицы. Сначала поместите данные первой ТЧ во временную таблицу и проиндексируйте по паре Ссылка + НомерСтроки, затем сделайте то же самое для второй. Финальный запрос, соединяющий эти две временные таблицы, отработает значительно быстрее, чем прямое соединение физических таблиц базы данных.
Проанализируем ситуации для выбора:
ТаблицаЗначений в коде и передать ее в СКД как Внешний набор данных. Для описания такой логики удобно использовать модель СКД (DSL).Таким образом, мы разобрали основные методики решения задачи. Главное — помнить о корректной обработке разного количества строк в таблицах, чтобы ваш отчет всегда выглядел профессионально и содержал полные данные.