Как в ЗУП отобрать расчетные листки только по сотрудникам с определенным видом начисления?

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

В практике расчета заработной платы часто возникает потребность сформировать расчетные листки (или другие кадрово-расчетные отчеты) не по всем сотрудникам и не по конкретному подразделению, а по специфическому критерию. Например, нужно распечатать "расчетки" только для тех, кто в этом месяце получил "Доплату за разъездной характер работы" или "Сдельную оплату".

На первый взгляд задача кажется тривиальной, но стандартные настройки отчетов в 1С:Зарплата и Управление Персоналом (ЗУП 3.1) могут сбить с толку. Рассмотрим подробно, почему обычный отбор не работает так, как ожидается, и разберем эффективные способы решения этой задачи — как для уверенных пользователей, так и для программистов.

Почему стандартный отбор "ломает" отчет?

Многие пользователи пытаются решить задачу "в лоб": заходят в настройки отчета Расчетный листок, добавляют отбор по полю Вид расчета (или Начисление) и указывают нужное значение.

Давайте проанализируем, к чему это приводит. Отчеты на базе Системы Компоновки Данных (СКД) при наложении такого отбора фильтруют не сотрудников, а строки записей регистра.

Результат:

  1. В расчетном листке сотрудника пропадают все остальные начисления (Оклад, Премии) и удержания (НДФЛ).
  2. Остается только одна строка с выбранным начислением.
  3. Итоговая сумма "К выплате" и сальдо могут отображаться некорректно или не иметь смысла в контексте "обрезка".

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

Способ 1. Пользовательский (без программирования)

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

Шаг 1. Получаем список сотрудников.

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

  1. Открываем отчет "Анализ зарплаты".
  2. Заходим в Настройки -> Отборы.
  3. Устанавливаем отбор: Вид расчета Равно <Нужное начисление>.
  4. Формируем отчет.

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

Шаг 2. Копируем список.

Выделяем колонку с ФИО сотрудников в сформированном отчете и копируем их в буфер обмена (Ctrl+C).

Шаг 3. Формируем расчетные листки.

  1. Открываем отчет Расчетный листок.
  2. Заходим в Настройки.
  3. Находим поле отбора Сотрудник (или Физическое лицо).
  4. Меняем Вид сравнения на В списке.
  5. В поле Значение нажимаем "Подбор" (или открываем список значений) и вставляем скопированных людей из буфера обмена (обычно кнопка "Подбор из буфера" или просто вставка).

После нажатия кнопки "Сформировать" мы получим полноценные расчетные листки, но строго для нужной группы лиц.

Способ 2. Программный (Внешний отчет или Расширение)

Если бухгалтерия требует автоматизации этого процесса ("хотим одну кнопку"), нам потребуется вмешательство в код. Оптимальный вариант для современных конфигураций на базе БСП — создание расширения с командой или внешнего отчета-обертки.

Суть метода заключается в следующем:

  1. Мы программно выполняем запрос к базе данных, чтобы найти всех сотрудников с нужным видом расчета в заданном периоде.
  2. Полученный массив ссылок передаем в параметры стандартного отчета "Расчетный листок".
  3. Формируем отчет программно.

Получение списка сотрудников

Для начала напишем запрос, который вернет нам массив физических лиц. Лучше всего обращаться к виртуальной таблице оборотов регистра накопления НачисленияУдержанияПоСотрудникам.


&НаСервере
Функция ПолучитьМассивФизЛицСНачислением(НачалоПериода, КонецПериода, Организация, ВидРасчетаОтбор)
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ РАЗЛИЧНЫЕ
		|	НачисленияУдержания.ФизическоеЛицо КАК ФизическоеЛицо
		|ИЗ
		|	РегистрНакопления.НачисленияУдержанияПоСотрудникам.Обороты(
		|			&НачалоПериода,
		|			&КонецПериода,
		|			,
		|			НачислениеУдержание = &ВидРасчетаОтбор
		|				И Организация = &Организация) КАК НачисленияУдержания";
	
	Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);
	Запрос.УстановитьПараметр("КонецПериода", КонецПериода);
	Запрос.УстановитьПараметр("Организация", Организация);
	Запрос.УстановитьПараметр("ВидРасчетаОтбор", ВидРасчетаОтбор);
	
	Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("ФизическоеЛицо");
	
КонецФункции

Инициализация отчета "Расчетный листок"

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

Обратите внимание: в ЗУП 3.1 отчет называется Отчеты.РасчетныйЛисток. Использование Отчеты.АнализНачисленийИУдержаний (как предлагалось в некоторых старых примерах) с вариантом "РасчетныйЛисток" может привести к ошибкам, так как это разные объекты метаданных.


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

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

	ОтчетОбъект.КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);

	// 3. Устанавливаем параметры периода
	// В Расчетном листке параметры часто называются "Период" (СтандартныйПериод) или "НачалоПериода"/"КонецПериода"
	ПараметрПериод = Настройки.ПараметрыДанных.Элементы.Найти("Период");
	Если ПараметрПериод <> Неопределено Тогда
		ПараметрПериод.Значение = Новый СтандартныйПериод(
			НачалоМесяца(РеквизитыСобытия.МесяцНачисления), 
			КонецМесяца(РеквизитыСобытия.МесяцНачисления)
		);
		ПараметрПериод.Использование = Истина;
	КонецЕсли;

	// 4. Программно устанавливаем отбор
	
	// Сначала очистим старые отборы по Сотруднику/ФизЛицу, если они есть
	// (для простоты примера опустим этот шаг, предполагая чистые настройки)
	
	// Добавляем отбор по Организации
	ЭлементОтбораОрг = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ЭлементОтбораОрг.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Организация");
	ЭлементОтбораОрг.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ЭлементОтбораОрг.ПравоеЗначение = РеквизитыСобытия.Организация;
	ЭлементОтбораОрг.Использование = Истина;
	
	// Добавляем ключевой отбор по Списку ФизЛиц
	ЭлементОтбораФЛ = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	// В зависимости от настройки отчета поле может называться "Сотрудник" или "ФизическоеЛицо"
	// В типовом РЛ часто используется группировка по ФизЛицу
	ЭлементОтбораФЛ.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ФизическоеЛицо");
	ЭлементОтбораФЛ.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
	ЭлементОтбораФЛ.ПравоеЗначение = МассивФизЛиц; // Передаем наш массив
	ЭлементОтбораФЛ.Использование = Истина;
	
	// 5. Компонуем результат
	ОтчетОбъект.КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
	ОтчетОбъект.СкомпоноватьРезультат(ТабДок);
	
КонецПроцедуры

Важные нюансы реализации

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

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

← На главную