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