Как программно вызвать и сформировать сохраненный вариант отчета СКД в регламентном задании

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

В практике разработки на платформе 1С:Предприятие 8 часто возникает задача автоматической рассылки отчетов. Например, каждую неделю руководству необходимо отправлять актуальные лимиты расхода денежных средств в формате Excel. Поскольку регламентные задания выполняются в фоновом режиме на сервере, у них полностью отсутствует интерфейс (клиентский контекст). Это означает, что мы не можем использовать стандартные формы отчетов и интерактивные методы работы с ними. Для администрирования списка адресатов при решении этой задачи пригодится инструмент управления получателями рассылок отчетов.

В данной статье мы подробно разберем, как программно запустить отчет на базе Системы компоновки данных (СКД), загрузить конкретный пользовательский вариант настроек, передать нужные параметры и сохранить результат в файл без открытия формы.

Почему не работают стандартные методы в фоновом режиме

Основная ошибка начинающих разработчиков при попытке запустить отчет из фонового задания — использование методов контекста формы. Например, метод УстановитьТекущийВариант() доступен только в модуле формы отчета на клиенте. Попытка вызвать его на сервере в модуле обработки или общего модуля приведет к ошибке компиляции: «Процедура или функция с указанным именем не определена».

Для выполнения отчета в фоновом режиме нам необходимо полностью воспроизвести весь цикл компоновки данных программным путем: от получения схемы до вывода готового документа. Сделать это нужно исключительно средствами серверного программного кода.

---

Шаг 1. Получение настроек сохраненного варианта отчета

По умолчанию СКД использует настройки, заданные в конфигураторе (так называемые настройки по умолчанию). Если нам нужно применить конкретный пользовательский вариант настроек (например, «Лимиты расхода денежных средств - БЕЗ ДЕПОЗИТА И ВАЛЮТЫ»), нам необходимо извлечь их из системного хранилища вариантов отчетов.

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

Рассмотрим правильный алгоритм поиска и загрузки настроек варианта по его представлению (имени):


// Полное имя отчета в метаданных обязательно указывается с префиксом "Отчет."
ИмяОтчета = "Отчет.ЛимитыРасходаДенежныхСредств"; 

// Получаем список всех доступных вариантов для данного отчета
СписокВариантов = ХранилищеВариантовОтчетов.ПолучитьСписок(ИмяОтчета);
НастройкиВарианта = Неопределено;

Для Каждого Вариант Из СписокВариантов Цикл
    Если Вариант.Представление = "Лимиты расхода денежных средств - БЕЗ ДЕПОЗИТА И ВАЛЮТЫ" Тогда
        // Загружаем настройки по уникальному ключу, который хранится в свойстве Значение
        НастройкиВарианта = ХранилищеВариантовОтчетов.Загрузить(ИмяОтчета, Вариант.Значение);
        Прервать;
    КонецЕсли;
КонецЦикла;

Если НастройкиВарианта = Неопределено Тогда
    ВызватьИсключение "Не найден указанный вариант отчета в хранилище вариантов!";
КонецЕсли;

Если ваша конфигурация построена на базе Библиотеки Стандартных Подсистем (БСП), задача упрощается. В БСП все варианты отчетов регистрируются в специальном справочнике ВариантыОтчетов. Мы можем быстро получить ключ нужного варианта с помощью простого запроса или метода поиска:


СсылкаНаВариант = Справочники.ВариантыОтчетов.НайтиПоНаименованию("Лимиты расхода денежных средств - БЕЗ ДЕПОЗИТА И ВАЛЮТЫ");

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

---

Шаг 2. Программное изменение параметров СКД (лучшая практика)

Часто разработчики пытаются изменять значения параметров непосредственно в уже сгенерированном объекте МакетКомпоновки.ЗначенияПараметров. Это архитектурно неверный подход (антипаттерн). Если изменять параметры в самом макете, система компоновки не сможет правильно оптимизировать SQL-запрос и применить параметры к виртуальным таблицам и вложенным схемам.

Правильный способ — устанавливать значения параметров в объекте Настройки (тип НастройкиКомпоновкиДанных) до момента выполнения компоновки макета. Давайте посмотрим, как это реализовать:


// Устанавливаем параметры в настройках компоновки
НастройкиВарианта.ПараметрыДанных.УстановитьЗначениеПараметра("НачалоПериода", НачалоМесяца(ТекущаяДата()));
НастройкиВарианта.ПараметрыДанных.УстановитьЗначениеПараметра("КонецПериода", КонецМесяца(ТекущаяДата()));

// Если параметр может отсутствовать в схеме, желательно сделать проверку его существования
ПараметрХозОперация = НастройкиВарианта.ПараметрыДанных.Элементы.Найти("ХозяйственнаяОперация");
Если ПараметрХозОперация <> Неопределено Тогда
    ПараметрХозОперация.Значение = Перечисления.ХозяйственныеОперации.ПустаяСсылка;
    ПараметрХозОперация.Использование = Истина;
КонецЕсли;

---

Шаг 3. Установка программных отборов и исправление ошибки поиска полей

При попытке программно наложить отборы на компоновку часто возникает ошибка: «Ошибка компоновки макета. Поле не найдено "[Имя Поля]"». Выясним причину этой проблемы.

В СКД у каждого поля есть системное имя (путь к данным) и синоним (заголовок, который видит пользователь в режиме предприятия). Например, в интерфейсе поле может называться "Статья ДДС" (с пробелом), но его реальный путь к данным в схеме компоновки — "СтатьяДвиженияДенежныхСредств". При программной установке левого значения отбора мы всегда обязаны указывать только системный путь к данным (без пробелов, спецсимволов и в строгом соответствии с регистром).

Давайте разберем правильный код добавления программного отбора по списку значений:


// Очищаем существующие отборы, если это необходимо
НастройкиВарианта.Отбор.Элементы.Очистить();

// Добавляем новый элемент отбора
НовыйОтбор = НастройкиВарианта.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));

// Важно: передаем точный путь к данным поля из схемы компоновки (без пробелов!)
НовыйОтбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("СтатьяДвиженияДенежныхСредств");
НовыйОтбор.Использование = Истина;
НовыйОтбор.ВидСравнения  = ВидСравненияКомпоновкиДанных.НеВСписке;

// Формируем список исключаемых статей
СписокИсключений = Новый СписокЗначений;
СписокИсключений.Добавить(Справочники.СтатьиДвиженияДенежныхСредств.НайтиПоНаименованию("Покупка валюты"));
СписокИсключений.Добавить(Справочники.СтатьиДвиженияДенежныхСредств.НайтиПоНаименованию("Выплата депозита"));

НовыйОтбор.ПравоеЗначение = СписокИсключений;

---

Шаг 4. Полный цикл компоновки и вывода отчета в файл

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


Процедура ВыполнитьРассылкуОтчетаЛимиты() Экспорт

    // 1. Получаем основную схему компоновки из макета отчета
    СхемаКомпоновкиДанных = Отчеты.ЛимитыРасходаДенежныхСредств.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
    
    // 2. Пытаемся загрузить настройки конкретного пользовательского варианта
    ИмяОтчета = "Отчет.ЛимитыРасходаДенежныхСредств";
    ИмяНужногоВарианта = "Лимиты расхода денежных средств - БЕЗ ДЕПОЗИТА И ВАЛЮТЫ";
    Настройки = Неопределено;
    
    СписокВариантов = ХранилищеВариантовОтчетов.ПолучитьСписок(ИмяОтчета);
    Для Каждого Вариант Из СписокВариантов Цикл
        Если Вариант.Представление = ИмяНужногоВарианта Тогда
            Настройки = ХранилищеВариантовОтчетов.Загрузить(ИмяОтчета, Вариант.Значение);
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
    // Если вариант не найден в хранилище, берем настройки по умолчанию
    Если Настройки = Неопределено Тогда
        Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;
    КонецЕсли;
    
    // 3. Заполняем параметры периода
    Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("НачалоПериода", НачалоМесяца(ТекущаяДата()));
    Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("КонецПериода", КонецМесяца(ТекущаяДата()));
    
    // 4. Подготавливаем объекты для компоновки макета
    ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    
    // Выполняем компоновку схемы на основе подготовленных настроек
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    // 5. Инициализируем процессор компоновки данных
    ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
    
    // 6. Выводим результат компоновки в новый табличный документ
    РезультатТД = Новый ТабличныйДокумент;
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(РезультатТД);
    ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
    
    // 7. Сохраняем итоговый отчет в файл на диске сервера
    ПутьКФайлу = "C:\Reports\LimitsReport.xls";
    РезультатТД.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLS);
    
    // Здесь можно вызвать функцию отправки полученного файла по электронной почте
    // ОтправитьПисьмоСОтчетом(ПутьКФайлу);

КонецПроцедуры

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

← На главную