Как объединить повторяющиеся данные в колонках печатной формы 1С

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

При формировании печатных форм в 1С часто возникает ситуация, когда в таблице отображается список товаров для одного и того же контрагента или физического лица. По умолчанию платформа выводит каждую строку независимо, из-за чего ФИО и паспортные данные дублируются в каждой строке. Это делает документ «шумным» и неудобным для чтения. Рассмотрим подробнее, как программно реализовать группировку данных, чтобы личные данные выводились один раз, а список товаров — последовательно рядом.

Метод 1. Использование программного сравнения с предыдущим значением

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

Разберем по шагам реализацию в коде:

  1. Создаем переменную для хранения предыдущего значения вне цикла.
  2. Внутри цикла проверяем, совпадает ли текущее ФИО с предыдущим.
  3. Если совпадает — очищаем параметр макета для этой колонки.
  4. Если не совпадает — заполняем параметр и обновляем переменную «предыдущего значения».

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


ПеременнаяФИОПредыдущее = "";
Для Каждого СтрокаДанных Из ТаблицаРезультатов Цикл
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    
    Если СтрокаДанных.ФИО = ПеременнаяФИОПредыдущее Тогда
        ОбластьСтрока.Параметры.ФИО = "";
        ОбластьСтрока.Параметры.Паспорт = "";
    Иначе
        ОбластьСтрока.Параметры.ФИО = СтрокаДанных.ФИО;
        ОбластьСтрока.Параметры.Паспорт = СтрокаДанных.Паспорт;
        ПеременнаяФИОПредыдущее = СтрокаДанных.ФИО;
    КонецЕсли;
    
    ОбластьСтрока.Параметры.Товар = СтрокаДанных.Товар;
    ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;

Важно: При использовании этого метода нужно следить за границами ячеек. Если у вас в макете заданы границы для всех ячеек, то при очистке текста ФИО границы всё равно будут видны, создавая пустые ячейки. Чтобы таблица выглядела как единое целое, можно программно отключать верхнюю границу для повторяющихся строк через свойство ЛинияСверху.

Метод 2. Профессиональный подход через итоги в запросе

Если данных много, лучше использовать возможности языка запросов 1С. Это позволит нам разделить данные на иерархические уровни: уровень «Человек» и уровень «Товары». Выясним, как это реализовать.

В тексте запроса необходимо добавить конструкцию ИТОГИ ПО. Например:


ВЫБРАТЬ
    ФИО,
    Паспорт,
    Товар
ИЗ
    РегистрСведений.ДанныеПродаж
ИТОГИ ПО
    ФИО,
    Паспорт

При обходе такого результата мы используем метод Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам). Рассмотрим подробнее структуру вложенных циклов:


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

Этот метод считается более «штатным» для платформы 1С, так как логика группировки перекладывается на СУБД, а код становится более структурированным.

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

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

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

Метод 4. Вертикальное объединение ячеек через Объединить()

Если вы хотите, чтобы ФИО и паспорт занимали одну физическую ячейку, растянутую на несколько строк (как это часто делается в Excel), используется метод Объединить() объекта ТабличныйДокумент.

Разберем алгоритм действий:

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

Пример реализации:


НачалоГруппы = ТабДок.ВысотаТаблицы + 1;
Пока ВыборкаТовары.Следующий() Цикл
    // Вывод строк...
КонецЦикла;
КонецГруппы = ТабДок.ВысотаТаблицы;

Если КонецГруппы > НачалоГруппы Тогда
    // Объединяем колонку ФИО (допустим, это колонка №1)
    ОбластьФИО = ТабДок.Область(НачалоГруппы, 1, КонецГруппы, 1);
    ОбластьФИО.Объединить();
    ОбластьФИО.ВертикальноеПоложение = ВертикальноеПоложение.Центр;
    
    // Объединяем колонку Паспорт (колонка №2)
    ОбластьПаспорт = ТабДок.Область(НачалоГруппы, 2, КонецГруппы, 2);
    ОбластьПаспорт.Объединить();
КонецЕсли;

Этот метод создает наиболее эстетичный вид печатной формы, так как текст ФИО будет центрирован вертикально относительно списка товаров.

Метод 5. Группировка строк (сворачиваемые списки)

Если печатная форма предназначена для анализа на экране, а не только для печати на бумаге, можно добавить интерактивности. Платформа 1С позволяет группировать строки, добавляя «плюсики» слева от таблицы.

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


Пока ВыборкаФИО.Следующий() Цикл
    // Выводим строку-заголовок с ФИО
    ТабДок.Вывести(ОбластьШапкаГруппы);
    
    ТабДок.НачатьГруппировкуСтрок();
    Пока ВыборкаТовары.Следующий() Цикл
        // Выводим строки с товарами
        ТабДок.Вывести(ОбластьСтрокаТовар);
    КонецЦикла;
    ТабДок.ЗакончитьГруппировкуСтрок();
КонецЦикла;

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

← На главную