Разработка регламентированных форм, таких как 0504402 (Расчетная ведомость), в конфигурации «1С:Зарплата и управление персоналом 3.1» часто ставит перед начинающим программистом сложную задачу: как вывести переменное количество начислений и удержаний в одну строку? В отличие от простых печатных форм, где состав колонок статичен, здесь нам необходимо подстраиваться под данные каждого конкретного сотрудника. Рассмотрим подробнее, как решить эту задачу правильно, используя механизмы платформы 1С.
Для начала нам необходимо определиться, откуда брать данные. В ЗУП 3.1 основным источником информации о начислениях и удержаниях является регистр накопления НачисленияУдержанияПоСотрудникам. Однако, простого запроса к регистру недостаточно, так как данные там хранятся «в столбик» (каждая запись — это отдельное начисление или удержание).
Проанализируем типичную ошибку при написании запроса. Часто разработчики пытаются фильтровать НДФЛ или конкретные начисления по строковому наименованию, например: Если Выборка.НачислениеУдержание = "НДФЛ". Это некорректно, так как поле НачислениеУдержание имеет ссылочный тип. Правильнее сравнивать его с предопределенными данными или проверять категорию начисления через свойства объекта.
Рассмотрим пример правильного подхода к получению данных через запрос:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| НачисленияУдержания.Сотрудник КАК Сотрудник,
| НачисленияУдержания.НачислениеУдержание КАК ВидРасчета,
| СУММА(НачисленияУдержания.Сумма) КАК Сумма,
| НачисленияУдержания.ГруппаНачисленияУдержаниеВыплаты КАК Группа
|ИЗ
| РегистрНакопления.НачисленияУдержанияПоСотрудникам КАК НачисленияУдержания
|ГДЕ
| НачисленияУдержания.Период МЕЖДУ &ДатаНач И &ДатаКон
| И НачисленияУдержания.Сотрудник В (&МассивСотрудников)
|СГРУППИРОВАТЬ ПО
| НачисленияУдержания.Сотрудник,
| НачисленияУдержания.НачислениеУдержание,
| НачисленияУдержания.ГруппаНачисленияУдержаниеВыплаты";
Запрос.УстановитьПараметр("ДатаНач", НачалоМесяца(ДатаОтчета));
Запрос.УстановитьПараметр("ДатаКон", КонецМесяца(ДатаОтчета));
Запрос.УстановитьПараметр("МассивСотрудников", СписокСотрудниковИзДокумента);
РезультатЗапроса = Запрос.Выполнить();
Чтобы колонки выводились «в строчку», нам нужно изменить подход к созданию макета. Вместо одной широкой области «Строка», мы разделим макет на вертикальные секции. Выясним, какие секции нам понадобятся:
НазваниеНачисления в шапке и СуммаНачисления в строке данных.Такой подход позволит нам сначала вывести левую часть, затем в цикле «присоединить» столько колонок начислений, сколько потребуется, и в конце закрыть строку правой частью.
Разберем по шагам процесс вывода данных в табличный документ. Главный секрет заключается в использовании метода ТабДок.Присоединить() вместо привычного ТабДок.Вывести() для всех областей, кроме самой первой в строке.
Посмотрим на пример программной реализации вывода:
// 1. Сначала формируем шапку
ОбластьШапкаЛево = Макет.ПолучитьОбласть("Шапка|Область_Сотрудник");
ТабДок.Вывести(ОбластьШапкаЛево);
// Собираем все уникальные виды начислений для шапки
СписокВидовРасчета = ПолучитьСписокВидовРасчета(РезультатЗапроса);
Для Каждого ВидИзСписка Из СписокВидовРасчета Цикл
ОбластьШапкаКолонка = Макет.ПолучитьОбласть("Шапка|Область_Начисление");
ОбластьШапкаКолонка.Параметры.Заполнить(ВидИзСписка);
ТабДок.Присоединить(ОбластьШапкаКолонка);
КонецЦикла;
ОбластьШапкаПраво = Макет.ПолучитьОбласть("Шапка|Область_Итого");
ТабДок.Присоединить(ОбластьШапкаПраво);
// 2. Выводим строки по сотрудникам
Для Каждого СотрудникИзСписка Из МассивСотрудников Цикл
// Выводим левую часть строки
ОбластьСтрокаЛево = Макет.ПолучитьОбласть("Строка|Область_Сотрудник");
ОбластьСтрокаЛево.Параметры.ФИО = СотрудникИзСписка.Наименование;
ТабДок.Вывести(ОбластьСтрокаЛево);
// Выводим динамические колонки начислений
Для Каждого ВидИзСписка Из СписокВидовРасчета Цикл
ОбластьКолонка = Макет.ПолучитьОбласть("Строка|Область_Начисление");
// Ищем сумму конкретного начисления для этого сотрудника
Сумма = НайтиСуммуПоСотрудникуИВиду(РезультатЗапроса, СотрудникИзСписка, ВидИзСписка);
ОбластьКолонка.Параметры.СуммаНачисления = Сумма;
ТабДок.Присоединить(ОбластьКолонка);
КонецЦикла;
// Выводим правую часть строки
ОбластьСтрокаПраво = Макет.ПолучитьОбласть("Строка|Область_Итого");
// Заполняем НДФЛ и Итого
ТабДок.Присоединить(ОбластьСтрокаПраво);
КонецЦикла;
Проанализируем ситуацию с НДФЛ. В форме 0504402 налог должен отображаться отдельно от прочих удержаний. Поскольку в регистре начислений он может присутствовать в общей массе, при обходе выборки используйте условие для выделения его суммы в отдельную переменную. Помните, что сравнивать ВидРасчета лучше всего с результатом функции Справочники.ВидыУдержаний.НДФЛ или проверять ГруппаНачисленияУдержаниеВыплаты.
Если ваша задача требует вывода страховых взносов (ПФР, ФСС, ФОМС), имейте в виду, что в регистре НачисленияУдержанияПоСотрудникам их нет. Эти данные хранятся в регистре накопления ИсчисленныеСтраховыеВзносы. Вам потребуется либо объединять два запроса, либо использовать типовой программный интерфейс ЗУП 3.1.
Рекомендация: Для серьезных разработок в ЗУП 3.1 рекомендуется изучить функцию УчетЗарплаты.ПодготовитьДанныеДляПечатиРасчетнойВедомости0504402. Типовой механизм уже учитывает все тонкости бюджетного учета (КФО, ИФО, КОСГУ) и позволяет получить готовую структуру данных для вывода, что избавит вас от необходимости писать сложные запросы к регистрам вручную.
Использование метода Присоединить() совместно с грамотно спроектированным макетом и предварительной подготовкой списка начислений позволяет создавать гибкие и профессиональные отчеты, отвечающие любым требованиям законодательства и заказчика.