При разработке дополнительных печатных форм, обработок или интеграций в конфигурации 1С:Зарплата и Управление Персоналом (ЗУП) часто возникает задача автоматического формирования пакета документов. Например, при увольнении сотрудника, расчете заработной платы или уходе в отпуск необходимо автоматически сгенерировать расчетный листок, сохранить его в файл или отправить по электронной почте. Разберем по шагам, как правильно реализовать программное формирование отчета «Расчетный листок».
Первая сложность, с которой сталкиваются разработчики — отсутствие выделенной формы в самом объекте отчета. В типовой конфигурации ЗУП расчетный листок формируется на базе универсального отчета АнализНачисленийИУдержаний. Если мы откроем свойства этого отчета в конфигураторе, то увидим, что в поле «Форма отчета» указана общая форма ФормаОтчета.
Важно понимать, что для программного формирования отчета и получения его результата в виде табличного документа, нам вообще не требуется открывать форму. Вся логика работы должна строиться вокруг программного взаимодействия с модулем отчета и Схемой Компоновки Данных (СКД).
Рассмотрим подробнее классический подход, при котором мы программно создаем объект отчета, инициализируем его настройки, устанавливаем параметры (период, отборы по организации и сотруднику) и выводим результат в табличный документ. Проанализируем пример кода, решающий эту задачу:
// Инициализация табличного документа для результата
Таб = Новый ТабличныйДокумент;
// Флаг для определения типа листка (аванс или полный расчет)
ЭтоАванс = Ложь;
ИмяОтчета = "АнализНачисленийИУдержаний" + ?(ЭтоАванс, "Авансом","");
КлючВариантаОтчета = "РасчетныйЛисток" + ?(ЭтоАванс, "ПерваяПоловинаМесяца","");
// Создание и инициализация объекта отчета
ОтчетРЛ = Отчеты[ИмяОтчета].Создать();
ОтчетРЛ.ИнициализироватьОтчет(КлючВариантаОтчета);
ОтчетРЛ.КомпоновщикНастроек.ЗагрузитьНастройки(ОтчетРЛ.СхемаКомпоновкиДанных.ВариантыНастроек[КлючВариантаОтчета].Настройки);
// Установка дополнительных свойств для корректной компоновки
ОтчетРЛ.КомпоновщикНастроек.ПользовательскиеНастройки.ДополнительныеСвойства.Вставить("КлючВарианта", КлючВариантаОтчета);
ОтчетРЛ.КомпоновщикНастроек.ПользовательскиеНастройки.ДополнительныеСвойства.Вставить("УстанавливаетсяМакетКомпоновкиДанных", Ложь);
Настройки = ОтчетРЛ.КомпоновщикНастроек.Настройки;
// Установка параметров периода
МесяцНачисления = '20220101';
УстановитьЗначениеПараметраСКД(Настройки, "Период", Новый СтандартныйПериод(НачалоМесяца(МесяцНачисления),КонецМесяца(МесяцНачисления)));
УстановитьЗначениеПараметраСКД(Настройки, "НачалоПериода", НачалоМесяца(МесяцНачисления));
УстановитьЗначениеПараметраСКД(Настройки, "КонецПериода", КонецМесяца(МесяцНачисления));
// Установка отборов по организации и списку физических лиц
ОбщегоНазначенияКлиентСервер.ИзменитьЭлементыОтбора(Настройки.Отбор,"Организация",,Организация,ВидСравненияКомпоновкиДанных.Равно,Истина);
СписокФизЛиц = Новый СписокЗначений;
// Добавляем нужного сотрудника в список
СписокФизЛиц.Добавить(СотрудникСсылка);
ОбщегоНазначенияКлиентСервер.ИзменитьЭлементыОтбора(Настройки.Отбор,"ФизическоеЛицо",, СписокФизЛиц, ВидСравненияКомпоновкиДанных.ВСписке, Истина);
// Загрузка измененных настроек обратно в компоновщик
ОтчетРЛ.КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
// Компоновка результата в табличный документ
ОтчетРЛ.СкомпоноватьРезультат(Таб);
Для корректной работы данного фрагмента также потребуется вспомогательная процедура установки параметров СКД:
Процедура УстановитьЗначениеПараметраСКД(Настройки, Имя, Значение)
П = Настройки.ПараметрыДанных.Элементы.Найти(Имя);
Если П <> Неопределено Тогда
П.Использование = Истина;
П.Значение = Значение;
КонецЕсли;
КонецПроцедуры
Этот метод отлично подходит, если вам необходимо получить ТабличныйДокумент в фоновом режиме для дальнейшей склейки с другими документами или сложной программной обработки.
Посмотрим на более современный и безопасный подход. В актуальных версиях ЗУП 3.1 прямое использование СкомпоноватьРезультат может привести к тому, что некоторые специфические поля (например, суммы к выплате) останутся пустыми. Это связано с тем, что логика расчета таких полей скрыта в переопределенных модулях менеджера отчета.
Чтобы избежать ошибок, настоятельно рекомендуем использовать экспортные методы общих модулей подсистемы «Зарплата Кадры». Выясним, как это работает:
ВывестиОтчетВТабличныйДокумент из общего модуля ЗарплатаКадрыОтчеты.РасчетныйЛистокДляПочты, который специально оптимизирован для постраничного разбиения).ОтчетыСервер поможет получить дефолтные настройки нужного варианта отчета одной строкой.Проанализируем ситуацию: если ваша конечная цель заключается в том, чтобы сформировать расчетные листки за период и отправить их сотрудникам на электронную почту, то писать собственный код генерации и рассылки — это избыточное решение (изобретение велосипеда).
В конфигурации уже встроен мощный механизм РассылкиОтчетов. Как его использовать:
РассылкиОтчетов. В нем настраивается выборка сотрудников, формат вложения (например, PDF) и шаблон письма.Для программного запуска типовой рассылки используется следующий метод:
// Получаем ссылку на заранее настроенную рассылку
СсылкаНаРассылку = Справочники.РассылкиОтчетов.НайтиПоНаименованию("Рассылка расчетных листков");
Если ЗначениеЗаполнено(СсылкаНаРассылку) Тогда
// Запускаем штатный механизм выполнения рассылки
РассылкаОтчетов.ВыполнитьРассылку(СсылкаНаРассылку);
КонецЕсли;
Этот способ гарантирует, что система сама персонализирует отправку, архивирует вложения (если это настроено) и корректно запишет логи отправки писем, избавив вас от необходимости программировать взаимодействие с почтовыми профилями.
Если вы выбрали путь самостоятельной генерации через ТабличныйДокумент, обратите внимание на работу с периодами. В ЗУП расчетные листки строятся по реквизиту Период регистрации (месяц начисления). При передаче параметра СтандартныйПериод вы можете задать интервал в несколько месяцев. Система выведет данные за все указанные месяцы. Чтобы данные не сливались в одну таблицу, убедитесь, что в структуре настроек компоновки включена группировка по месяцам.
После получения готового результата в переменной Таб (как в Способе 1), для сохранения расчетного листка в файл формата PDF используйте стандартный метод платформы:
ИмяФайла = КаталогВременныхФайлов() + "РасчетныйЛисток_" + Строка(СотрудникСсылка) + ".pdf";
Таб.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.PDF);
Важное замечание: Чтобы при формировании отчета по списку сотрудников каждый новый расчетный листок начинался с новой страницы, проверьте пользовательские настройки варианта отчета. В группировке по полю «ФизическоеЛицо» или «Сотрудник» должен стоять флаг вывода начала области на новой странице. Это обеспечит корректное разделение страниц при сохранении в единый PDF-файл.