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