Как перехватить список сотрудников в отчете «Расчетные листки» в ЗУП 2.5?

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

При работе с отчетом «Расчетные листки» в конфигурации «Зарплата и Управление Персоналом, редакция 2.5» (ЗУП 2.5) разработчики часто сталкиваются с необходимостью получить итоговый список сотрудников, для которых были сформированы листки. Это может потребоваться для ведения логов, автоматической рассылки расчетных листков по электронной почте или интеграции с другими системами.

Попытка использовать для этой цели стандартное событие модуля объекта отчета ПриКомпоновкеРезультата обычно заканчивается неудачей — процедура просто не вызывается платформой. В этой статье мы подробно разберем, почему так происходит, и рассмотрим три надежных способа программного перехвата данных.

Выясняем причину: почему не работает ПриКомпоновкеРезультата?

Событие ПриКомпоновкеРезультата вызывается платформой автоматически только в том случае, если отчет формируется стандартным (штатным) механизмом компоновки данных. Однако в отчете «Расчетные листки» в ЗУП 2.5 разработчики фирмы «1С» применили полностью ручной вывод.

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

  1. Создает и инициализирует объект КомпоновщикМакетаКомпоновкиДанных.
  2. Генерирует макет компоновки с помощью метода Выполнить().
  3. Инициализирует ПроцессорКомпоновкиДанных, передавая туда внешний набор данных (таблицу значений).
  4. В цикле последовательно получает элементы результата через метод Следующий() и выводит их с помощью процессора вывода в ТабличныйДокумент.

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

Способ 1. Перехват внешнего набора данных (Рекомендуемый)

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

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

Рассмотрим пример реализации этого способа в процедуре формирования отчета:


// В процедуре, где подготавливается таблица "НачисленияУдержания"
// (обычно это процедура "СформироватьОтчет" или "ВывестиРезультатВТабличныйДокумент")

ВнешниеНаборыДанных = Новый Структура;
ВнешниеНаборыДанных.Вставить("НачисленияУдержания", НачисленияУдержания);

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

Для Каждого СтрокаСотрудник Из ТаблицаСотрудников Цикл
    // Здесь мы можем зафиксировать сотрудника, отправить на почту или записать в лог
    Сообщить("Расчетный листок сформирован для: " + СтрокаСотрудник.Сотрудник);
КонецЦикла;

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

Способ 2. Анализ элементов результата СКД в цикле вывода

Если вам необходимо отслеживать сотрудников непосредственно в процессе формирования графической формы отчета (например, чтобы сопоставить сотрудника с конкретной страницей или областью табличного документа), можно перехватить данные в цикле вывода процессора компоновки.

Разберем по шагам, как модифицировать процедуру вывода. Нам потребуется анализировать свойство ТипЭлемента у объекта ЭлементРезультатаКомпоновкиДанных. Нас интересует начало вывода группировки по сотруднику.

Пример модификации процедуры ВывестиРезультатВТабличныйДокумент:


Процедура ВывестиРезультатВТабличныйДокумент(ПроцессорКомпоновкиДанных, ТабличныйДокумент, ВыводитьПоСтраницам) Экспорт
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ТабличныйДокумент);
    ПроцессорВывода.НачатьВывод();
    
    Пока Истина Цикл
        
        ЭлементРезультата = ПроцессорКомпоновкиДанных.Следующий();
        
        Если ЭлементРезультата = Неопределено Тогда
            Прервать;
        Иначе
            
            // Наш перехват: проверяем тип элемента компоновки
            Если ЭлементРезультата.ТипЭлемента = ТипЭлементаРезультатаКомпоновкиДанных.НачалоГруппировки Тогда
                
                // Проанализируем значения параметров или поля группировки
                Для Каждого ЗначениеПараметра Из ЭлементРезультата.ЗначенияПараметров Цикл
                    // "П1" или другое имя параметра, отвечающее за группировку по сотруднику в СКД
                    Если ЗначениеПараметра.Имя = "П1" И ЗначениеЗаполнено(ЗначениеПараметра.Значение) Тогда
                        ТекущийСотрудник = ЗначениеПараметра.Значение;
                        Сообщить("Выводится группировка по сотруднику: " + ТекущийСотрудник);
                    КонецЕсли;
                КонецЦикла;
                
            КонецЕсли;
            
            // Выводим элемент в результирующий документ
            ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
            
        КонецЕсли;
        
    КонецЦикла;
    
    ПроцессорВывода.ЗакончитьВывод();
    
КонецПроцедуры

Преимущества метода: Позволяет точно определить момент начала вывода каждого сотрудника на форму и связать этот момент с заполнением макета табличного документа.

Способ 3. Обход расшифровки готового Табличного Документа

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

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


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

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

Резюме

Мы проанализировали особенности работы программной компоновки результатов в ЗУП 2.5 и нашли причины неработоспособности события ПриКомпоновкеРезультата. Выбор конкретного метода перехвата зависит от архитектурной задачи:

← На главную