При попытке сохранения "Универсального отчета" из конфигурации 1С:Управление торговлей 10.3 как внешнего файла и последующей его работы, пользователи часто сталкиваются с ошибкой "Поле объекта не обнаружено". Эта проблема вызвана особенностями архитектуры платформы 1С:Предприятие 8, где встроенные отчеты имеют прямой доступ к метаданным конфигурации, в то время как внешние объекты работают в более изолированном контексте. Давайте разберем эту ситуацию подробнее и рассмотрим возможные пути решения для достижения нашей цели – создать отчет с закрепленными настройками и предварительными вычислениями.
Мы сталкиваемся с ситуацией, когда, казалось бы, простой шаг — "Сохранить как внешнюю обработку, отчет..." для "Универсального отчета" — приводит к неожиданной ошибке. После сохранения файла, например, под именем "УниверсальныйОтчетПросрочка", и попытки его использования или настройки, система выдает сообщение об ошибке: "Поле объекта не обнаружено (УниверсальныйОтчетПросрочка)".
В процессе отладки мы можем обнаружить, что ошибка возникает в коде, подобном следующему:
Процедура ПолеВыбораИмяРегистраПриИзменении(Элемент)
Универсальный = (Метаданные.НайтиПоТипу(ТипЗнч(ЭтотОбъект)) = ВладелецФормы.ОтчетОбъект.Метаданные);
Если Универсальный Тогда
ПереустановитьНачальныеНастройки(ВладелецФормы.ОтчетОбъект, ВладелецФормы.ОтчетОбъект, ВладелецФормы);
Иначе
ПереустановитьНачальныеНастройки(ВладелецФормы.ОтчетОбъект.УниверсальныйОтчетПросрочка, ВладелецФормы.ОтчетОбъект, ВладелецФормы);
КонецЕсли;
КонецПроцедуры
Данный фрагмент кода пытается определить, является ли текущий объект "Универсальным отчетом", сравнивая его метаданные с метаданными объекта, находящегося в свойстве ВладелецФормы.ОтчетОбъект. Проблема возникает в строке ВладелецФормы.ОтчетОбъект.УниверсальныйОтчетПросрочка, где система пытается получить доступ к свойству, которое, по ее мнению, должно быть частью метаданных объекта ВладелецФормы.ОтчетОбъект. Но для внешнего отчета это свойство оказывается недоступным.
Причина возникновения ошибки кроется в фундаментальном различии между встроенными и внешними объектами в системе 1С:Предприятие.
Особенности метаданных внешних отчетов. Когда мы сохраняем "Универсальный отчет" как внешний файл (с расширением .erf), он перестает быть непосредственной частью структуры метаданных конфигурации. Код, который изначально рассчитывал на глубокую интеграцию и прямой доступ к внутренним объектам конфигурации, теперь работает в иной среде. Метаданные внешнего отчета воспринимаются системой по-другому, что приводит к невозможности обнаружения полей или объектов, которые ожидались как встроенные.
Строка Метаданные.НайтиПоТипу(ТипЗнч(ЭтотОбъект)) = ВладелецФормы.ОтчетОбъект.Метаданные явно показывает, что отчет пытается идентифицировать себя, исходя из предположения, что он встроен в конфигурацию. Когда это условие не выполняется (поскольку отчет внешний), выполнение переходит в ветку Иначе, где и происходит попытка обращения к несуществующему полю ВладелецФормы.ОтчетОбъект.УниверсальныйОтчетПросрочка.
Отличия в доступе к контексту. Внешний отчет функционирует в более изолированном контексте по сравнению с встроенным. Часть внутренней логики "Универсального отчета" может опираться на прямые ссылки на объекты конфигурации, общие модули или другие служебные элементы, которые не всегда корректно доступны или работают, когда отчет вынесен в отдельный файл без соответствующей адаптации его кода.
Подтверждение гипотезы. Интересное наблюдение, которое подтверждает нашу гипотезу, заключается в том, что если такой внешний отчет вставить непосредственно в конфигурацию, он начинает работать без ошибок. Это однозначно указывает на то, что проблема связана именно с отсутствием правильного контекста метаданных для внешнего объекта.
Прежде чем перейти к решениям, давайте четко сформулируем нашу основную цель. Мы хотим не просто сохранить "Универсальный отчет" как внешний, а решить более широкую задачу:
Теперь, понимая как саму проблему, так и наши цели, мы можем рассмотреть наиболее эффективные и безопасные способы их достижения в 1С:УТ 10.3.
Наиболее простым и рекомендованным способом для достижения наших целей (закрепление настроек и создание вариантов отчета) без модификации кода или создания новых внешних объектов является использование встроенного функционала "Универсального отчета" по сохранению вариантов.
Преимущества данного подхода:
Как создать и использовать варианты Универсального отчета:
Откроем "Универсальный отчет". В конфигурации 1С:УТ 10.3 найдем и откроем "Универсальный отчет". Обычно он находится в меню "Отчеты" -> "Универсальный отчет" или "Универсальный журнал документов" (его форма часто содержит универсальный отчет).
Настроим отчет. Настроим отчет в соответствии с нашими требованиями:
Выполним предварительные вычисления (если требуется). Если нам необходимо реализовать предварительные вычисления (например, "сдвиг периода относительно текущей даты"), то для этого, к сожалению, стандартными средствами вариантов отчета не обойтись. Потребуется небольшая доработка кода самого "Универсального отчета" (если это допустимо) или переход к разработке отчета на СКД. Однако, для большинства задач по закреплению настроек, вариант подойдет.
Сохраним вариант отчета. После того как отчет настроен, найдем кнопку или пункт меню "Сохранить вариант" или "Сохранить настройки". В появившемся окне:
Таким образом, мы создадим "закрепленный" вариант отчета, который пользователи смогут выбирать из списка доступных вариантов, не беспокоясь о правильности настроек.
Если нам нужна полная независимость отчета, сложные предварительные вычисления, динамическое изменение логики или же мы не хотим модифицировать типовую конфигурацию, то наиболее мощным и гибким решением будет разработка нового внешнего отчета на Системе Компоновки Данных (СКД).
Преимущества СКД:
Как реализовать закрепление настроек и предварительные вычисления с помощью СКД:
Внешний отчет на СКД состоит из нескольких ключевых компонентов:
Схема Компоновки Данных. Это сердце отчета, которое определяет структуру данных, запросы, поля, параметры, группировки и отборы. Мы можем создать эту схему в конфигураторе или программно.
Пример программного создания схемы для источника данных:
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
НаборДанныхЗапрос = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
НаборДанныхЗапрос.Имя = "ОсновнойНаборДанных";
НаборДанныхЗапрос.Запрос = "ВЫБРАТЬ
| РегистрНакопления.Продажи.Период КАК Период,
| РегистрНакопления.Продажи.Номенклатура КАК Номенклатура,
| РегистрНакопления.Продажи.Количество КАК Количество,
| РегистрНакопления.Продажи.Сумма КАК Сумма
|ИЗ
| РегистрНакопления.Продажи КАК РегистрНакопленияПродажи
|ГДЕ
| РегистрНакопленияПродажи.Период МЕЖДУ &НачалоПериода И &КонецПериода";
Или используя встроенную схему из макета:
МакетСКД = ЭтотОбъект.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
СхемаКомпоновкиДанных = МакетСКД.Получить();
Настройки Компоновки Данных. Эти настройки определяют, как данные будут отображаться: какие поля выводить, как группировать, какие отборы применять. Именно здесь мы можем "закрепить" часть настроек.
Для закрепления настроек, мы можем программно установить значения параметров или отборов перед формированием отчета. Например, чтобы установить фиксированный период:
Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;
// Устанавливаем значение параметра "НачалоПериода"
ПараметрНачало = Настройки.ПараметрыДанных.Найти("НачалоПериода");
Если ПараметрНачало <> Неопределено Тогда
ПараметрНачало.Значение = НачалоМесяца(ТекущаяДата());
ПараметрНачало.Использование = Истина;
// Можно запретить пользователю изменять этот параметр
// ПараметрНачало.Редактирование = Ложь; // Если доступно в версии платформы
КонецЕсли;
// Устанавливаем значение параметра "КонецПериода"
ПараметрКонец = Настройки.ПараметрыДанных.Найти("КонецПериода");
Если ПараметрКонец <> Неопределено Тогда
ПараметрКонец.Значение = КонецМесяца(ТекущаяДата());
ПараметрКонец.Использование = Истина;
КонецЕсли;
// Добавляем фиксированный отбор
НовыйОтбор = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
НовыйОтбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Номенклатура.ВидНоменклатуры");
НовыйОтбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
НовыйОтбор.ПравоеЗначение = Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Товар");
НовыйОтбор.Использование = Истина;
НовыйОтбор.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.НеОтображать; // Скрыть от пользователя
Предварительные вычисления. Для таких задач, как "сдвиг периода относительно текущей даты", мы можем программно установить значения параметров отчета перед его формированием. Например, чтобы установить период "прошлый месяц":
Функция ПолучитьНастройкиСКДДляПрошлогоМесяца()
МакетСКД = ЭтотОбъект.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
СхемаКомпоновкиДанных = МакетСКД.Получить();
Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;
ДатаСегодня = ТекущаяДата();
НачалоПрошлогоМесяца = ДобавитьМесяц(НачалоМесяца(ДатаСегодня), -1);
КонецПрошлогоМесяца = КонецМесяца(НачалоПрошлогоМесяца);
ПараметрНачало = Настройки.ПараметрыДанных.Найти("НачалоПериода");
Если ПараметрНачало <> Неопределено Тогда
ПараметрНачало.Значение = НачалоПрошлогоМесяца;
ПараметрНачало.Использование = Истина;
КонецЕсли;
ПараметрКонец = Настройки.ПараметрыДанных.Найти("КонецПериода");
Если ПараметрКонец <> Неопределено Тогда
ПараметрКонец.Значение = КонецПрошлогоМесяца;
ПараметрКонец.Использование = Истина;
КонецЕсли;
Возврат Настройки;
КонецФункции
Форма отчета. Для внешнего отчета мы создаем обычную форму, где размещаем элемент ПолеФормы с типом ПолеКомпоновкиДанных. В коде формы мы будем вызывать СКД, передавать ей наши настройки и выводить результат. На форме мы можем добавить кнопки для сохранения вариантов или изменения параметров, которые разрешено менять пользователю.
Разработка на СКД требует большего погружения в программирование, но дает максимальный контроль и гибкость, полностью соответствуя нашим целям по закреплению данных и предварительным вычислениям.
Как мы уже выяснили, если внешний отчет вставить непосредственно в конфигурацию, он начинает работать. Это подтверждает, что проблема заключается в контексте метаданных.
Когда это применимо:
Недостатки этого подхода:
Таким образом, данный подход является наименее предпочтительным для большинства типовых задач, особенно если есть альтернативы в виде вариантов отчета или разработки на СКД.
Ошибка "Поле объекта не обнаружено" при попытке сохранить "Универсальный отчет" как внешний в 1С:УТ 10.3 вызвана его глубокой интеграцией в метаданные конфигурации. Для решения задачи по закреплению настроек и предварительных вычислений мы рекомендуем следующие пути:
Избегаем попыток прямого сохранения "Универсального отчета" как внешнего и его последующей модификации, так как это ведет к ошибкам и может потребовать нежелательной модификации типовой конфигурации.