При разработке отчетов и обработок в 1С:Предприятие часто возникает задача формирования сложных печатных форм, таких как расписания, графики или «шахматки». Основная трудность заключается в том, что стандартная сетка табличного документа не всегда позволяет легко состыковать области разной высоты и ширины в одной логической строке. Например, когда заголовок должен объединять несколько колонок данных, а сами данные под ним имеют сложную структуру. Рассмотрим подробно, как эффективно решать такие задачи, используя встроенные механизмы 1С.
Представим ситуацию: нам необходимо вывести строку расписания. Слева находится номер строки (высотой в три ячейки), затем идет общее название интервала (шириной в две ячейки, но высотой в одну), а под этим названием должны располагаться конкретные временные отрезки (интервалы), каждый из которых занимает свою ячейку. Проблема в том, что при обычном использовании метода Вывести() каждая новая область начинается с новой строки, а метод Присоединить() работает только в пределах текущей активной строки. Чтобы добиться желаемого результата, нам нужно научиться «собирать» сложные блоки и правильно позиционировать их в конечном документе.
Один из самых надежных и понятных способов — это создание временного табличного документа, который выступает в роли «сборочного цеха». Мы формируем в нем нужный нам сложный блок (например, шапку с подписями интервалов), а затем целиком присоединяем этот буфер к основному документу. Рассмотрим пример кода, который реализует этот подход:
// Создаем основной документ и временный буфер
ТабДок = Новый ТабличныйДокумент;
ТабДок2 = Новый ТабличныйДокумент;
// Получаем область с номером строки из макета
СтрокаТаблицы = Макет.ПолучитьОбласть("Строка|Номер");
СтрокаТаблицы.Параметры.Номер = 1;
// Выводим номер в основной документ
ТабДок.Присоединить(СтрокаТаблицы);
// Теперь собираем сложную правую часть во временном документе ТабДок2
Название = Макет.ПолучитьОбласть("Название|Интервалы");
Название.Параметры.Имя = "Рейс №101";
ТабДок2.Вывести(Название); // Название выводится сверху
// Добавляем детализацию под названием
Ин1 = Макет.ПолучитьОбласть("Времена|Интервал2");
Ин1.Параметры.Инт2 = "08:00-10:00";
ТабДок2.Вывести(Ин1); // Выводится под названием
// Присоединяем второй интервал рядом в том же временном документе
Ин2 = Макет.ПолучитьОбласть("Времена|Интервал1");
Ин2.Параметры.Инт1 = "10:00-12:00";
ТабДок2.Присоединить(Ин2);
// Наконец, присоединяем весь собранный блок ТабДок2 к основному документу
ТабДок.Присоединить(ТабДок2);
Проанализируем этот код: использование метода Присоединить(ТабДок2) позволяет вставить сразу весь массив ячеек, при этом 1С автоматически рассчитает необходимые координаты. Это избавляет разработчика от ручного вычисления индексов строк и колонок.
Если структура документа крайне нерегулярна, можно использовать метод ВставитьОбласть(). Этот метод позволяет буквально «вклеить» фрагмент макета в любое место итоговой таблицы по заданному адресу. Однако здесь важно учитывать производительность: при большом объеме данных (сотни и тысячи строк) этот метод работает медленнее, чем Вывести() или Присоединить(), так как системе приходится каждый раз пересчитывать структуру стилей и границ документа.
Рассмотрим, как это выглядит на практике:
// Определяем границы вставки
нВерх = пНомер.Верх;
нЛево = пНомер.Право + 1;
нПраво = нЛево + Название.ШиринаТаблицы - 1;
нНиз = нВерх + Название.ВысотаТаблицы - 1;
// Получаем область из макета и вставляем ее в основной документ
тВставка = Название.Область(1, 1, Название.ВысотаТаблицы, Название.ШиринаТаблицы);
ТабДок.ВставитьОбласть(тВставка, ТабДок.Область(нВерх, нЛево, нНиз, нПраво));
Обратите внимание, что вместо формата адресации RC (например, "R1C1"), лучше использовать числовые координаты метода Область(НомерСтроки, НомерКолонки). Это делает код более читаемым и менее подверженным ошибкам при динамическом расчете координат.
В некоторых случаях проще сначала вывести данные в «плоском» виде, а затем программно объединить ячейки. Это особенно удобно для динамических расписаний, где количество колонок заранее неизвестно.
Рассмотрим алгоритм действий:
Вывести() и Присоединить(), заполняя ячейки информацией.Область().Объединить() для создания визуальных блоков.Пример кода для объединения ячеек:
// Объединяем ячейки в первой колонке для создания эффекта высокой ячейки номера
ОбластьНомера = ТабДок.Область(ТекущаяСтрока, 1, ТекущаяСтрока + 2, 1);
ОбластьНомера.Объединить();
ОбластьНомера.ВертикальноеПоложение = ВертикальноеПоложение.Центр;
При работе со сложными областями часто возникают проблемы с форматированием. Разберем основные моменты, на которые стоит обратить внимание:
ОбластьМакета.Параметры.Значение = ... до того, как область будет добавлена в основной документ. Если пытаться заполнять параметры в уже сформированном ТабличномДокументе по имени, 1С заполнит все одноименные параметры во всем документе или строке одинаковыми значениями.Присоединить() убедитесь, что ширина колонок в макете настроена корректно. Часто бывает полезно сначала вывести «эталонную» строку (шапку), в которой заданы ширины всех колонок, а затем выводить данные.ТабДок.ФиксацияСверху = НомерСтрокиШапки и ТабДок.ФиксацияСлева = НомерКолонкиНомера.ВставитьОбласть. Попробуйте заменить его на комбинацию Вывести и Присоединить с использованием буферного документа.Таким образом, комбинируя методы работы с областями и используя вспомогательные табличные документы, мы можем создавать отчеты практически любой сложности. Главное — четко представлять структуру итоговой таблицы и выбирать метод вывода, исходя из требований к производительности и гибкости макета.