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