Как реализовать автоматический отбор во внешнем отчете СКД по текущему объекту

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке внешних отчетов на базе Схемы компоновки данных (СКД) часто возникает задача: сделать так, чтобы при запуске отчета из конкретной формы (например, из карточки «Основного средства» или «Номенклатуры») он автоматически открывался с установленным фильтром по этому объекту. В типовых конфигурациях 1С, построенных на Библиотеке Стандартных Подсистем (БСП), механизм работы внешних отчетов отличается от обычных печатных форм, но он также позволяет элегантно передавать контекст вызова.

В этой статье мы подробно разберем, как прописать логику во внешнем отчете, чтобы он «понимал», из какого объекта был вызван, и автоматически подставлял нужные значения в настройки компоновки данных. Мы проанализируем регистрацию отчета в системе и использование специальных экспортных процедур в модуле объекта.

Регистрация внешнего отчета в системе

Для начала разберем, как отчет должен быть «представлен» системе через механизм «Дополнительных отчетов и обработок». Чтобы отчет появился в меню «Отчеты» конкретного справочника, нам необходимо правильно заполнить функцию СведенияОВнешнейОбработке() в модуле объекта нашего отчета.

Рассмотрим структуру кода регистрации. Нам важно указать вид обработки как «Отчет» и назначить его конкретному метаданному (например, справочнику «Основные средства»). Также критически важным является использование типа команды ОткрытиеФормы.


Функция СведенияОВнешнейОбработке() Экспорт
    ИмяОтчета = ЭтотОбъект.Метаданные().Имя; 
    Синоним = ЭтотОбъект.Метаданные().Синоним; 
    Синоним = ?(ЗначениеЗаполнено(Синоним), Синоним, ИмяОтчета);        
    
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке();
    
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиОтчет();     
    ПараметрыРегистрации.Версия = "1.0";
    ПараметрыРегистрации.БезопасныйРежим = Ложь;
    ПараметрыРегистрации.Наименование = Синоним;
    ПараметрыРегистрации.Информация = "Отчет по текущему объекту: " + Синоним;
    
    // Указываем, к какому справочнику привязываем отчет
    ПараметрыРегистрации.Назначение.Добавить("Справочник.ОсновныеСредства");
    
    СтрКоманды = ПараметрыРегистрации.Команды.Добавить();
    СтрКоманды.Идентификатор = ИмяОтчета + "_КомандаОткрытиеФормы";
    СтрКоманды.Представление = Синоним;
    СтрКоманды.ПоказыватьОповещение = Истина;
    
    // Важно: выбираем именно открытие формы, чтобы передать параметры
    СтрКоманды.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы(); 
    
    Возврат ПараметрыРегистрации;
КонецФункции

Именно использование ВидОбработкиОтчет() позволяет БСП автоматически добавить команду в нужный справочник, а при ее нажатии передать в форму отчета массив ссылок на выбранные объекты в параметре ОбъектыНазначения.

Настройка взаимодействия с формой через модуль объекта

В современных версиях БСП внешние отчеты могут взаимодействовать со своей формой через специальные «точки входа» прямо в модуле объекта. Это очень удобно, так как нам не нужно создавать собственную форму отчета — достаточно использовать стандартную, предоставляемую платформой или конфигурацией, и управлять ею программно.

Для решения нашей задачи нам понадобятся две экспортные процедуры: ОпределитьНастройкиФормы и ПриСозданииНаСервере. Разберем их назначение подробнее.

Процедура ОпределитьНастройкиФормы позволяет нам управлять поведением формы до ее открытия. Здесь мы можем указать системе, что отчет должен сформироваться сразу при открытии (чтобы пользователю не пришлось лишний раз нажимать кнопку «Сформировать»), а также включить обработку события создания формы на сервере.


Процедура ОпределитьНастройкиФормы(Форма, КлючВарианта, Настройки) Экспорт
    // Указываем, что отчет должен быть сформирован автоматически при открытии
    Настройки.ФормироватьСразу = Истина;
    // Разрешаем выполнение кода в процедуре ПриСозданииНаСервере в модуле объекта
    Настройки.События.ПриСозданииНаСервере = Истина;
КонецПроцедуры

Обработка параметра «ОбъектыНазначения»

Теперь перейдем к самому главному — получению ссылки на объект, из которого вызван отчет, и установке отбора в СКД. Когда мы запускаем внешний отчет из формы элемента, БСП передает в параметры формы структуру, содержащую ключ ОбъектыНазначения. Это всегда массив ссылок, даже если отчет вызван для одного объекта.

Проанализируем процедуру ПриСозданииНаСервере, которую мы размещаем в модуле объекта отчета. Обратите внимание, что первым параметром она принимает объект самой Форма.


Процедура ПриСозданииНаСервере(Форма, Отказ, СтандартнаяОбработка) Экспорт
    // Извлекаем массив объектов назначения из параметров формы
    ОбъектыНазначения = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Форма.Параметры, "ОбъектыНазначения");
    
    Если ОбъектыНазначения <> Неопределено И ОбъектыНазначения.Количество() > 0 Тогда
        // Способ 1: Прямая вставка в структуру отборов параметров формы
        // Система попытается автоматически применить этот отбор к СКД
        Форма.ФормаПараметры.Отбор.Вставить("Ссылка", ОбъектыНазначения);
        
        // Способ 2 (более надежный): Программная установка отбора в компоновщике настроек
        УстановитьОтборВКомпоновщике(Форма.Отчет.КомпоновщикНастроек, "Ссылка", ОбъектыНазначения);
    КонецЕсли;
КонецПроцедуры

Выясним причину, почему второй способ часто предпочтительнее. Если в вашей схеме компоновки данных поле называется не Ссылка, а, например, ОсновноеСредство или Объект, автоматический механизм платформы может не сработать. В таком случае нам нужно явно найти элемент отбора в компоновщике настроек.

Универсальный метод установки отбора в СКД

Разберем по шагам, как правильно реализовать процедуру установки отбора, чтобы она корректно работала с массивом значений (так как ОбъектыНазначения — это массив).


Процедура УстановитьОтборВКомпоновщике(КомпоновщикНастроек, ИмяПоля, Значение)
    ПолеКомпоновки = Новый ПолеКомпоновкиДанных(ИмяПоля);
    
    // Ищем существующий отбор по этому полю, чтобы не дублировать
    ЭлементОтбора = Неопределено;
    Для Каждого Элемент Из КомпоновщикНастроек.Настройки.Отбор.Элементы Цикл
        Если ТипЗнч(Элемент) = Тип("ЭлементОтбораКомпоновкиДанных") 
            И Элемент.ЛевоеЗначение = ПолеКомпоновки Тогда
            ЭлементОтбора = Элемент;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
    // Если не нашли, создаем новый
    Если ЭлементОтбора = Неопределено Тогда
        ЭлементОтбора = КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
        ЭлементОтбора.ЛевоеЗначение = ПолеКомпоновки;
    КонецЕсли;
    
    // Настраиваем вид сравнения и значение
    Если ТипЗнч(Значение) = Тип("Массив") Тогда
        ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
        ЭлементОтбора.ПравоеЗначение.Очистить();
        ЭлементОтбора.ПравоеЗначение.ЗагрузитьЗначения(Значение);
    Иначе
        ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
        ЭлементОтбора.ПравоеЗначение = Значение;
    КонецЕсли;
    
    ЭлементОтбора.Использование = Истина;
КонецПроцедуры

Важные технические нюансы

Рассмотрим несколько моментов, которые могут повлиять на результат работы:

  1. Доступность полей в СКД: Проверьте, чтобы поле, по которому вы устанавливаете отбор (например, Ссылка), не было отмечено флагом «Ограничение настройки» на закладке «Настройки» или «Наборы данных» в схеме компоновки. Если поле ограничено для пользователя, программная установка отбора в стандартные настройки может не сработать.
  2. Фиксированные настройки: Если вы хотите, чтобы пользователь не мог изменить или удалить этот автоматический отбор, его следует устанавливать не в КомпоновщикНастроек.Настройки, а в КомпоновщикНастроек.ФиксированныеНастройки.
  3. Безопасный режим: Если в СведенияОВнешнейОбработке указано БезопасныйРежим = Истина, убедитесь, что ваш код не использует методы, запрещенные в этом режиме. В большинстве случаев для работы с отборами это не является проблемой.
  4. Тип команды: Еще раз подчеркнем — используйте ТипКомандыОткрытиеФормы(). Если использовать ВызовСерверногоМетода, отчет попытается выполниться в фоне, и механизм работы с параметрами формы будет совершенно иным.

Проанализировав ситуацию, можно сделать вывод: механизм БСП предоставляет достаточно гибкие инструменты для интеграции внешних отчетов в интерфейс системы. Используя процедуры модуля объекта ОпределитьНастройкиФормы и ПриСозданииНаСервере, мы можем добиться того, что отчет будет выглядеть и вести себя как встроенный, обеспечивая пользователю максимальное удобство при работе с данными конкретных объектов.

← На главную