При разработке и модификации отчетов в платформе 1С:Предприятие 7.7 программисты часто сталкиваются с необходимостью вывода дополнительных данных в существующие печатные формы. Типичный пример — интеграция парсинга журнала регистрации для вывода реальной даты создания документов прямо в табличный документ отчета. Однако при попытке программно заполнить добавленную колонку в секции макета нередко возникает критическая ошибка: «Значение не представляет агрегатный объект». Либо, при использовании механизмов выражений, добавленное поле просто остается пустым.
В этой статье мы подробно разберем природу этих ошибок, выясним причины их возникновения на уровне ядра платформы 1С 7.7 и рассмотрим пошаговые сценарии правильной работы с областями табличного документа.
Рассмотрим исходную ситуацию. При попытке заполнить ячейку с именем Создан внутри полученной секции СекСоздан разработчик использует следующий код:
СекСоздан = пТаб.ПолучитьСекцию("Строка|Секция_8");
СекСоздан.Создан.Текст = ДатаСоздания;
Система на это выдает ошибку агрегатного объекта. Проанализируем причину такого поведения. В платформе 1С 7.7 обращение к элементам таблицы имеет свои синтаксические особенности:
СекСоздан.Создан возвращает не объект типа ОбластьТаблицы, а пустое строковое значение "" или число 0. Попытка обратиться к свойству .Текст у примитивного типа данных и вызывает ошибку среды исполнения.ПолучитьСекцию() не находит указанное пересечение горизонтальной и вертикальной секций (например, из-за опечатки в названии "Строка|Секция_8"), переменная СекСоздан принимает значение 0. Соответственно, любое дальнейшее обращение к ней приводит к падению программы.Чтобы гарантированно избежать этой ошибки, необходимо использовать явный метод получения области ячейки табличного документа — Область(). Этот метод всегда возвращает объект типа ОбластьТаблицы, у которого можно безопасно изменять свойства.
Рассмотрим подробнее первый вариант решения проблемы, основанный на прямом заполнении текста ячейки. Для этого нам потребуется правильно настроить макет и скорректировать код.
Шаг 1. Именование ячейки в макете. Откройте макет вашего отчета в конфигураторе. Найдите пересечение горизонтальной секции Строка и вертикальной секции Секция_8. Выделите целевую ячейку. Обратите внимание на левый верхний угол под панелью инструментов — там отображается текущий адрес ячейки (например, R10C8). Щелкните в это поле ввода и впишите туда уникальное имя переменной, например Создан, после чего нажмите Enter. Теперь данная ячейка стала именованной областью.
Шаг 2. Корректировка кода вывода. Теперь мы можем безопасно обратиться к этой ячейке по ее имени, используя встроенный метод Область(). Перепишем фрагмент кода процедуры:
Если СДатДок = 1 Тогда
// Получаем область пересечения горизонтальной и вертикальной секций
СекСоздан = пТаб.ПолучитьСекцию("Строка|Секция_8");
// Безопасное обращение к именованной ячейке
СекСоздан.Область("Создан").Текст = ДатаСоздания;
// Присоединяем заполненную секцию к текущей строке отчета
пТаб.ПрисоединитьСекцию(СекСоздан);
КонецЕсли;
Использование конструкции СекСоздан.Область("Создан").Текст полностью решает проблему возникновения ошибки агрегатного объекта.
В платформе 1С 7.7 существует альтернативный, более декларативный способ вывода данных, который не требует ручного обращения к свойствам ячеек через программный код. Это механизм автоматического вычисления выражений в момент формирования отчета.
Выясним причину, почему у автора темы во втором варианте ячейка оставалась пустой:
Если СДатДок = 1 Тогда
СекСоздан = пТаб.ПолучитьСекцию("Строка|Секция_8");
Создан = ДатаСоздания;
КонецЕсли;
Здесь допущены две ключевые ошибки. Во-первых, отсутствует сам вызов вывода секции в результирующий табличный документ (метод ПрисоединитьСекцию). Во-вторых, локальная переменная Создан должна быть доступна в контексте вычисления макета в момент вывода.
Разберем по шагам, как правильно настроить вывод через выражение:
Создан.Создан в начале процедуры вывода, чтобы обеспечить ее видимость.При таком подходе код процедуры печати значительно упрощается и выглядит следующим образом:
Процедура ПечатьРеквизитовШапки(пТаб, пДок, пРеквизиты, СекСостояние, СекОбязательные, ДатаСоздания)
// Объявляем переменную, привязанную к выражению в макете
Перем Создан;
// Печатаем метку состояния
Если пДок.Проведен() = 1 Тогда
СекСостояние.Флаг.Текст = "V";
ИначеЕсли пДок.ПометкаУдаления() = 1 Тогда
СекСостояние.Флаг.Текст = "X";
Иначе
СекСостояние.Флаг.Текст = " ";
КонецЕсли;
пТаб.ВывестиСекцию(СекСостояние);
// Печатаем обязательные реквизиты
СекОбязательные.Номер.Текст = пДок.НомерДок;
СекОбязательные.Дата.Текст = пДок.ДатаДок;
СекОбязательные.Время.Текст = пДок.ПолучитьВремя();
СекОбязательные.Номер.Расшифровка(пДок.ТекущийДокумент(), 1);
пТаб.ПрисоединитьСекцию(СекОбязательные);
// Вывод дополнительной колонки с датой создания
Если СДатДок = 1 Тогда
Создан = ДатаСоздания; // Заполняем переменную значения
пТаб.ПрисоединитьСекцию("Строка|Секция_8"); // Платформа сама вычислит "Создан"
КонецЕсли;
КонецПроцедуры
При вызове метода пТаб.ПрисоединитьСекцию("Строка|Секция_8") платформа автоматически обратится к контексту процедуры, найдет переменную Создан, вычислит ее текущее значение и подставит в ячейку табличного документа.
Автор темы столкнулся с еще одной классической проблемой верстки в 1С 7.7: при добавлении вызова ПрисоединитьСекцию() структура отчета визуально нарушилась («поехал весь отчет»).
Проанализируем ситуацию. Метод ПрисоединитьСекцию() осуществляет горизонтальное позиционирование колонок, пристыковывая указанную вертикальную секцию к последней выведенной строке справа. Если нарушается структура вызовов, это неизбежно ведет к сдвигу сетки табличного документа. Основные правила бесконфликтной верстки:
"Строка|Секция_8"), то эту же колонку необходимо присоединить и в шапке отчета ("Шапка|Секция_8"), и в подвале. В противном случае правая часть таблицы сместится, а границы колонок перестанут совпадать.Секция_8 высота строк совпадает с высотой строк основной секции. Различие в высоте приведет к тому, что 1С автоматически растянет всю строку результирующей таблицы по максимальному значению, нарушив вертикальное форматирование соседних ячеек.Рекомендуется всегда проверять соответствие структуры выводимых областей. Например, если в шапке документа колонка выводится условно, то и в строках данных условие Если СДатДок = 1 Тогда должно отрабатывать абсолютно идентично.