Программное формирование отчетов в системе «1С:Предприятие» — это стандартная задача для автоматизации рассылок или выгрузки данных во внешние системы. Однако при работе с современными конфигурациями, такими как Зарплата и Управление Персоналом 3.1, разработчики часто сталкиваются с ситуацией, когда созданный файл Excel содержит только заголовок отчета без самих данных. Рассмотрим подробнее, почему это происходит и как правильно реализовать алгоритм выгрузки.
Разберем ситуацию, когда при выполнении кода в регламентном задании формируется пустой отчет. Основная причина кроется в специфике работы Системы Компоновки Данных (СКД) и особенностях механизмов Библиотеки стандартных подсистем (БСП). В представленном в теме коде допущено несколько критических ошибок, которые мешают процессору компоновки получить данные.
Во-первых, установка параметров выполняется некорректно. Разберем этот фрагмент:
НачальнаяДата = Настройки.ПараметрыДанных.Элементы.Найти("НачалоПериода");
НачальнаяДата = (ДобавитьМесяц(ТекущаяДата(), -1));
В данном случае переменной НачальнаяДата сначала присваивается объект параметра, а затем эта же переменная просто перезаписывается датой. Значение самого параметра в объекте Настройки при этом не меняется. Процессор компоновки запускается с пустыми датами, что в 99% случаев приводит к пустому результату запроса.
Во-вторых, регламентные задания выполняются в контексте специального пользователя, у которого может не быть прав на чтение данных регистров, необходимых для отчета. Если отчет использует Rls (разграничение прав на уровне записей), данные просто не попадут в выборку.
Для того чтобы значения параметров действительно попали в запрос компоновки, необходимо использовать метод УстановитьЗначениеПараметра. Проанализируем правильный подход к работе с параметрами данных:
// Вместо прямого поиска элементов используем встроенный метод
Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;
// Устанавливаем параметры периода
ПараметрНачало = Настройки.ПараметрыДанных.Элементы.Найти("НачалоПериода");
Если ПараметрНачало <> Неопределено Тогда
ПараметрНачало.Значение = ДобавитьМесяц(ТекущаяДата(), -1);
ПараметрНачало.Использование = Истина;
КонецЕсли;
ПараметрКонец = Настройки.ПараметрыДанных.Элементы.Найти("КонецПериода");
Если ПараметрКонец <> Неопределено Тогда
ПараметрКонец.Значение = КонецДня(ТекущаяДата());
ПараметрКонец.Использование = Истина;
КонецЕсли;
Важный нюанс: В отчетах ЗУП 3.1 многие параметры вынесены в так называемые «Пользовательские настройки». Если значение параметра задано в пользовательских настройках, оно будет иметь приоритет над основными настройками. В таком случае программная установка в Настройки.ПараметрыДанных может быть проигнорирована. Выясним, как с этим бороться: нужно либо очищать пользовательские настройки, либо устанавливать значения непосредственно в них, обращаясь через ИдентификаторПользовательскойНастройки.
Поскольку формирование отчета происходит в фоновом задании, крайне важно обеспечить доступ ко всем необходимым данным (регистрам сведений о штатном расписании, плановых начислениях и т.д.). Рекомендуется оборачивать процесс формирования в привилегированный режим.
Рассмотрим, как это реализовать:
УстановитьПривилегированныйРежим(Истина);
// Далее идет код формирования макета и вывода
// ...
УстановитьПривилегированныйРежим(Ложь);
Некоторые отчеты в ЗУП используют внешние наборы данных или сложные механизмы инициализации в модуле объекта (процедура ПриКомпоновкеРезультата). Если просто взять схему из макета и попытаться ее вывести, мы пропустим всю логику, заложенную разработчиками фирмы «1С».
Проанализируем ситуацию: если отчет сложный, лучше программно создавать экземпляр объекта отчета. Это позволит платформе выполнить предопределенные действия. Посмотрим на пример кода:
ОтчетОбъект = Отчеты.ИзменениеШтатногоРасписания.Создать();
Схема = ОтчетОбъект.СхемаКомпоновкиДанных;
Настройки = ОтчетОбъект.КомпоновщикНастроек.ПолучитьНастройки();
// Установка параметров через компоновщик
ПараметрОрганизация = Настройки.ПараметрыДанных.Элементы.Найти("Организация");
Если ПараметрОрганизация <> Неопределено Тогда
ПараметрОрганизация.Значение = Справочники.Организации.НайтиПоНаименованию("Наша Компания");
ПараметрОрганизация.Использование = Истина;
КонецЕсли;
// Выполняем компоновку
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки, ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
// Здесь важно проверить, нужны ли внешние наборы данных!
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
ТабДок = Новый ТабличныйДокумент;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабДок);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Когда ТабличныйДокумент успешно заполнен данными, остается сохранить его на диск. При работе в регламентном задании (на стороне сервера) убедитесь, что у службы сервера «1С:Предприятие» есть права на запись в целевой каталог.
Рассмотрим финальную стадию записи файла:
Записать с указанием типа файла.
ПутьКФайлу = "C:\Export\StaffChanges.xlsx";
Попытка
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);
Исключение
ЗаписьЖурналаРегистрации("ОшибкаВыгрузкиОтчета", УровеньЖурналаРегистрации.Ошибка, , , КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
Если ваша конфигурация ЗУП 3.1 обновлена до актуальных версий, наиболее надежным способом будет использование программного интерфейса БСП. Вместо ручной работы с ПроцессорКомпоновкиДанных, можно обратиться к модулю ВариантыОтчетов. Это гарантирует, что все настройки (включая скрытые отборы и специфические группировки) применятся корректно, как если бы пользователь нажал кнопку «Сформировать» в интерфейсе.
Резюме: Чтобы отчет не был пустым, всегда проверяйте:
Настройки (а не просто присвоены локальным переменным).Следуя этим шагам, вы сможете организовать надежную автоматическую выгрузку любых отчетов из ЗУП в формат Excel.