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