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