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