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