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

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

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

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

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

В чем сложность стандартного вывода?

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

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

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

Давайте подробно рассмотрим, как решить эту проблему несколькими профессиональными способами.

Способ 1. Заполнение параметров и расшифровок во временной области (Рекомендуемый способ)

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

Давайте разберем этот процесс по шагам на практическом примере:


// Шаг 1. Инициализируем итоговый табличный документ
ТабДок = Новый ТабличныйДокумент;
ТабДок.ТолькоПросмотр = Истина; // Обязательно для работы расшифровок

// Шаг 2. Выводим левую объединенную часть (Сотрудник)
ОбластьСотрудник = Макет.ПолучитьОбласть("Строка|Сотрудник");
ОбластьСотрудник.Параметры.ФИО = "Иванов Иван Иванович";
ТабДок.Вывести(ОбластьСотрудник);

// Начинаем цикл по дням периода (например, 31 день)
Для День = 1 По 31 Цикл
    
    // Шаг 3. Получаем из макета двухстрочную область (высота - 2 строки, ширина - 1 колонка)
    // В макете эта область может называться, например, "Строка|Часы"
    ОбластьЧасы = Макет.ПолучитьОбласть("Строка|Часы");
    
    // Шаг 4. Заполняем параметры ячеек
    ОбластьЧасы.Параметры.Явка = ПолучитьЗначениеЯвки(День);
    ОбластьЧасы.Параметры.Ночные = ПолучитьЗначениеНочных(День);
    
    // Шаг 5. Обращаемся к конкретным ячейкам временной области по локальным координатам (R1C1)
    // "R1C1" — это первая строка, первая колонка полученной локальной области
    // "R2C1" — это вторая строка, первая колонка локальной области
    
    // Задаем расшифровку для верхней ячейки (Дневные часы)
    ЯчейкаЯвки = ОбластьЧасы.Область("R1C1");
    ЯчейкаЯвки.Расшифровка = ПолучитьДокументОснованиеЯвки(День);
    
    // Задаем расшифровку для нижней ячейки (Ночные часы)
    ЯчейкаНочных = ОбластьЧасы.Область("R2C1");
    ЯчейкаНочных.Расшифровка = ПолучитьДокументОснованиеНочных(День);
    
    // Шаг 6. Присоединяем полностью подготовленную область к итоговому документу
    // Метод Присоединить() добавит двухстрочную колонку ровно справа от предыдущей
    ТабДок.Присоединить(ОбластьЧасы);
    
КонецЦикла;

Этот метод исключает необходимость сложных расчетов координат в результирующем документе. Мы работаем с локальной системой координат "R1C1" и "R2C1", что гарантирует точное попадание данных в нужные ячейки независимо от того, в какую именно позицию итогового отчета выводится данная область.

Способ 2. Построчный вывод данных с последующим программным объединением

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

Мы выводим данные строго построчно, а объединение ячеек сотрудника выполняем программно в самом конце формирования блока данных.

Рассмотрим алгоритм реализации этого метода:


// Шаг 1. Получаем высоту таблицы до вывода сотрудника
СтартоваяСтрока = ТабДок.ВысотаТаблицы + 1;

// Шаг 2. Выводим первую (верхнюю) строку сотрудника
ОбластьСтрока1_Основная = Макет.ПолучитьОбласть("Строка1|Основная");
ОбластьСтрока1_Основная.Параметры.ФИО = "Петров Петр Петрович";
ТабДок.Вывести(ОбластьСтрока1_Основная);

// В цикле присоединяем верхние ячейки (например, дневные показатели)
Для День = 1 По 31 Цикл
    ОбластьЧасы1 = Макет.ПолучитьОбласть("Строка1|Часы");
    ОбластьЧасы1.Параметры.Значение = ПолучитьЗначениеЯвки(День);
    ОбластьЧасы1.Область("R1C1").Расшифровка = ПолучитьДокументЯвки(День);
    ТабДок.Присоединить(ОбластьЧасы1);
КонецЦикла;

// Шаг 3. Выводим вторую (нижнюю) строку сотрудника
// Обратите внимание: метод Вывести() автоматически переведет курсор на новую строку вниз
ОбластьСтрока2_Основная = Макет.ПолучитьОбласть("Строка2|Основная");
// Параметр ФИО здесь можно оставить пустым или продублировать
ОбластьСтрока2_Основная.Параметры.ФИО = "Петров Петр Петрович"; 
ТабДок.Вывести(ОбластьСтрока2_Основная);

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

// Шаг 4. Программное объединение ячеек сотрудника по вертикали
КонечнаяСтрока = ТабДок.ВысотаТаблицы;

// Предположим, что колонка с ФИО сотрудника имеет индекс 1
ОбластьСотрудника = ТабДок.Область(СтартоваяСтрока, 1, КонечнаяСтрока, 1);
ОбластьСотрудника.Объединить();

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

Способ 3. Пост-обработка координат в итоговом документе

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

Каждое успешное выполнение метода Присоединить() увеличивает ширину результирующего табличного документа. Это дает нам возможность рассчитать точные координаты только что добавленных ячеек:


// Присоединяем двухстрочный блок из макета
ТабДок.Присоединить(ОбластьЧасы);

// Определяем текущие границы табличного документа
ТекущаяКолонка = ТабДок.ШиринаТаблицы;
НижняяСтрока   = ТабДок.ВысотаТаблицы;
ВерхняяСтрока  = НижняяСтрока - 1;

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

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

Важные настройки для корректной работы расшифровок

Каким бы из вышеперечисленных способов вы ни воспользовались, расшифровка в итоговом отчете не заработает должным образом, если не выполнить две важные системные настройки:

  1. Свойство ячейки «Использование расшифровки»: По умолчанию в макетах 1С свойство ячейки ИспользованиеРасшифровки может быть настроено на уровень всей строки. Чтобы при двойном клике открывалась расшифровка именно конкретной ячейки, необходимо в свойствах ячеек макета (или программно) установить это значение в ИспользованиеРасшифровкиТабличногоДокумента.Ячейка. Это разграничит поведение соседних показателей по вертикали и горизонтали.
  2. Режим «Только просмотр»: Интерактивный клик по расшифровке срабатывает только в том случае, если табличный документ защищен от редактирования пользователем. Обязательно добавляйте в конец процедуры формирования отчета строку кода: ТабДок.ТолькоПросмотр = Истина;

Мы подробно разобрали все доступные и наиболее эффективные варианты работы с многострочными присоединенными областями. Выбор конкретного метода зависит от архитектуры вашего отчета и личных предпочтений в проектировании макетов.

← На главную