Как программно сформировать отчет «Анализ начислений и удержаний» в 1С:ЗУП 3.1?

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

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

В этой статье мы подробно разберем, как победить проблему пустого табличного документа и правильно вызвать формирование этого отчета из внешней обработки или другого программного модуля.

Почему стандартный подход с СКД не всегда работает?

Обычно для формирования отчета достаточно создать объект, загрузить настройки и вызвать СкомпоноватьРезультат(). Однако в случае с «Анализом начислений и удержаний» мы сталкиваемся с рядом особенностей:

  1. Динамическая схема: Отчет подменяет основную схему компоновки в зависимости от выбранного варианта.
  2. Внешние наборы данных: Часть данных (например, отработанное время или расчеты с сотрудниками) подготавливается программно и передается в процессор компоновки как внешние таблицы.
  3. Пользовательские настройки: В современных версиях 1С значения параметров, установленные в КомпоновщикНастроек.Настройки, могут игнорироваться, если они перекрыты в ПользовательскиеНастройки.

Рассмотрим два проверенных способа решения этой задачи.

Способ 1: Упрощенный метод (через объект отчета)

Этот метод подходит, если вам нужно быстро получить результат, не углубляясь в ручное управление внешними наборами данных. Проанализируем пример кода, который позволяет задействовать встроенные механизмы отчета:


ОтчетРасчетныйЛист = Отчеты.АнализНачисленийИУдержаний.Создать();
СхемаКомпоновки = ОтчетРасчетныйЛист.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");

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

Если ВариантОтчета = Неопределено Тогда
    Возврат; // Вариант не найден
КонецЕсли;

// Критически важный шаг — инициализация отчета для конкретного варианта
ОтчетРасчетныйЛист.ИнициализироватьОтчет(ИмяВарианта);

// Загружаем настройки варианта в компоновщик
ОтчетРасчетныйЛист.КомпоновщикНастроек.ЗагрузитьНастройки(ВариантОтчета.Настройки);

// Здесь можно программно установить период или отборы
// Например: ОтчетРасчетныйЛист.КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Период", Новый СтандартныйПериод(...));

ТабДок = Новый ТабличныйДокумент;
ОтчетРасчетныйЛист.СкомпоноватьРезультат(ТабДок);
ТабДок.Показать();

Важный нюанс: Вызов метода ИнициализироватьОтчет обязателен. Именно внутри него происходит магия подмены схем и подготовки структуры данных, специфичной для «Полного свода».

Способ 2: Полный программный контроль (через общие модули)

Если упрощенный метод выдает пустой результат или данные отображаются «не как в типовом отчете», необходимо выполнить последовательность действий, которую делает форма отчета при нажатии кнопки «Сформировать». Разберем ситуацию, когда мы работаем через внешнюю обработку.

Выясним причину возможной неудачи: зачастую внешние наборы данных не заполняются сами по себе. Нам нужно вызвать процедуры из общих модулей ЗарплатаКадрыОтчеты и УчетНачисленнойЗарплаты.

Проанализируем алгоритм действий:

  1. Создаем объект отчета и инициализируем его.
  2. Устанавливаем параметры (обязательно проверяя пользовательские настройки).
  3. Вызываем подготовку внешних наборов данных.
  4. Инициализируем процессор компоновки.

Пример реализации:


ОтчетОбъект = Отчеты.АнализНачисленийИУдержаний.Создать();
ОтчетОбъект.ИнициализироватьОтчет();
КомпоновщикНастроек = ОтчетОбъект.КомпоновщикНастроек;
СхемаКомпоновкиДанных = ОтчетОбъект.СхемаКомпоновкиДанных;

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

// Установка периода в ПОЛЬЗОВАТЕЛЬСКИХ настройках (это важно!)
ПериодОтчета = Новый СтандартныйПериод;
ПериодОтчета.ДатаНачала = НачалоМесяца(ТекущаяДата());
ПериодОтчета.ДатаОкончания = КонецМесяца(ТекущаяДата());

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

// Вызываем типовые процедуры подготовки
ЗарплатаКадрыОтчеты.ПередНачаломКомпоновкиРезультата(ОтчетОбъект);

// Инициализация внешних данных
ТабДок = Новый ТабличныйДокумент;
ДанныеРасшифровки = Неопределено;
УчетНачисленнойЗарплаты.ПриКомпоновкеОтчетаАнализНачисленийИУдержаний(ОтчетОбъект, ТабДок, ДанныеРасшифровки, Истина);

// Получаем макет и наборы данных
НовыеНастройкиКД = КомпоновщикНастроек.ПолучитьНастройки();
МакетКомпоновкиДанных = ЗарплатаКадрыОтчеты.МакетКомпоновкиДанных(СхемаКомпоновкиДанных, НовыеНастройкиКД, ДанныеРасшифровки);

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

// Финальный вывод
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных, НаборыВнешнихДанных, ДанныеРасшифровки, Истина);

ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабДок);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);

ТабДок.Показать();

Разберем типичные ошибки

Если после выполнения кода вы все равно получаете пустой лист, следует проверить несколько моментов:

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

Используя приведенные выше методики, вы сможете добиться идентичности программно сформированного отчета с тем, который пользователь видит в интерфейсе программы 1С:ЗУП. Если же требуется готовое решение для сопоставления начислений между периодами, можно использовать внешний отчет для анализа зарплаты в динамике.

← На главную