Введение
Что я подразумеваю под сложными расчетами? Это расчеты начислений, которые сложно/неудобно выполнять в подсистеме начисления зарплаты. Хорошим примером будет расчет премии работников, зависящей от разнообразных данных учета: фактической выработки по сдельным нарядам, отработанного времени, продаж, периодических коэффициентов и т.п.
Типовой реализацией таких расчетов будет создание начисления с произвольной формулой и использование системы KPI – показателей схем мотивации. Значения показателей можно заносить вручную или автоматизировать этот процесс, например, в этой статье //infostart.ru/public/143181/ описано как затолкать данные других подсистем в значения показателей. Однако у такого подхода есть пара существенных недостатков:
- Количество показателей в формуле произвольного расчета ограничено 6-ю, если исхитрится, можно использовать 7 J. На мой взгляд, это просчет архитектуры подсистемы расчета ЗП, для простеньких расчетов регистры хранят лишние пустые колонки, а для сложных расчетов быстро упираешься в это ограничение. К тому же увеличить количество показателей редактированием конфигурации не удастся, слишком сильно она завязана на нем. В принципе этот недостаток можно обойти, введя агрегированные показатели — несколько показателей объединяются в один и он используется в формуле. Другой вариант решения – создать один или несколько промежуточных начислений, а результирующее начисление выразить через расчетную базу от промежуточных. При использовании второго варианта, возникнет вопрос, как исключить промежуточные начисления из результатов расчета (самое простое – удалять руками или обработкой ненужные начисления из документа начисления зарплаты после расчета).
- При появлении новых показателей, данные которых должны заполняться автоматически, программисту каждый раз придется дописывать код и пользователям эту работу делегировать не получится.
- Для ввода показателей используется обработка «Значения показателей схем мотивации», обработка конечно хорошая, но она подразумевает довольно высокий уровень компетенции и ответственности пользователя. Она работает напрямую с регистрами сведений и «не оставляет следов», если кто-то что-то изменил.
Бюджетирование это подсистема планирования, контроля и анализа денежных потоков, существующая в УПП (и в некоторых других конфигурациях). Подсистма бюджетирования в УПП позволяет планировать не только денежные потоки (БДДС), но также и доходы-расходы (БДР), и балансовые статьи (ББ).
В этой статье неплохо описана подготовка управленческой отчетности с использованием бюджетирования.
Каким образом можно использовать эту чрезвычайно мощную, но не лишенную багов (куда без этого) подсистему?
Идея состоит в том, чтобы использовать измерение «Контрагенты» для представления сотрудников, а измерение «Статьи оборотов по бюджетам» для представления отдельных показателей. Откуда брать данные, поможет указать справочник «Источники данных для расчета бюджетирования». Непосредственным расчетом и формированием движений с результатами расчетов занимается документ «Расчет по модели бюджетирования», интересующие нас движения создаются в регистре накопления «Обороты бюджетов». Для быстрого перерасчета пригодится обработка «Регламентный пересчет по моделям», для вывода результатов подойдет отчет «Обороты по статьям бюджетов». Наконец, для ввода первичных данных можно использовать документ «Бюджетная операция» либо обработку «Пакетный ввод бюджетных операций».
Разбор примера
Как известно, лучше всего изучать предмет на практике, поэтому разберем реализацию расчета начисления на следующем примере. Пусть премия работников определяется формулой
Кподр — коэффициент общий для всего подразделения, утверждается ежемесячно, откуда-то сверху,
Si — сумма сдельной выработки i-го работника,
Sподр — сумма сдельной выработки по всему подразделению,
Ккач — коэффициент качества работы в течение месяца, вводится ежемесячно для каждого работника, по умолчанию равен 1,
Vфакт дек j — сдельная выработка в нормочасах за j-ю декаду,
Тфакт дек j — отработанное по табелю время за j-ю декаду, в часах,
Vфакт — сдельная выработка в нормочасах за месяц,
Ттаб — отработанное по табелю время за месяц, в часах.
Разберемся сначала с показателями, являющимися входными для расчета.
Кподр заведем как обычный показатель схем мотивации, который будет заполняться руками через соответствующую обработку (она называется «Значения показателей схем мотивации» хотя в заголовке формы написано другое).
Ккач можно завести либо как элемент справочника «Статьи оборотов по бюджетам» и вводить потом значения с помощью документа «Бюджетная операция» или обработки «Пакетный ввод бюджетных операций», либо, как и в предыдущем случае, воспользоваться показателями схем мотивации. Я выбрал второй вариант, так как с ним немного меньше возни, но недостатком будет ввод непосредственно в регистр сведений. Поэтому если коэффициенты будут вводить пользователи с ограниченными правами, подумайте о втором варианте (там будут документы с полем «Ответственный»).
Все остальные показатели являются производными или получаются запросом к соответствующим регистрам и документам.
Следующим шагом будет создание статей оборотов по бюджетам. Статьи нужно создавать для тех данных, которые вы хотите видеть потом в отчетах и документах. Для моего примера я создал следующие статьи:
Настройки статей ничем не отличаются друг от друга
Задействован учет по количеству, так как я собираюсь использовать поле количество для хранения рассчитанных данных, у этого поля 3 знака после запятой, в отличие от поля суммы. Учет по сумме тоже включен, так как документ расчета ругается на пустую валюту без него; пусть будет.
Создадим теперь элемент справочника «Источники данных для расчетов бюджетирования». Этот этап очень важен, так как источник это сердце будущего расчета. В теории можно создать на каждый показатель по источнику данных и прописать в нем простенький запрос, который будет добывать нужные данные, однако документ расчета не поддерживает расчет из нескольких источников данных и выбросит забавную ошибку, если вы в документе попытаетесь задать несколько дополнительных источников, не указав основного источника.
Начнем сразу со вкладки «Настройка», нажав перед этим кнопку произвольный запрос. При редактировании запроса не забывайте нажимать кнопку «Закончить редактирование», иначе изменения не применятся (каждый раз вспоминаю разработчиков УПП, нажимая на эту кнопку).
Текст запроса:
ВЫБРАТЬ
СдельныйНарядИсполнители.Сотрудник,
ВЫБОР
КОГДА СдельныйНарядИсполнители.Ссылка.СуммаДокумента = 0
ТОГДА 0
ИНАЧЕ СдельныйНарядИсполнители.СуммаКНачислениюРегл / СдельныйНарядИсполнители.Ссылка.СуммаДокумента
КОНЕЦ КАК ДоляВаловки,
СдельныйНарядИсполнители.Ссылка КАК Документ
ПОМЕСТИТЬ втИсполнители
ИЗ
Документ.СдельныйНаряд.Исполнители КАК СдельныйНарядИсполнители
ГДЕ
СдельныйНарядИсполнители.Ссылка.Проведен = ИСТИНА
И СдельныйНарядИсполнители.Ссылка.ДатаНачалаПериода МЕЖДУ &НачалоПериода И &КонецПериода
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗРЕШЕННЫЕ
ВТ_Исполнители.Сотрудник,
СУММА(СдельныйНарядВыработка.ТехнологическаяОперация.НормаВремени * СдельныйНарядВыработка.Количество * ВТ_Исполнители.ДоляВаловки / 60) КАК Vфакт,
НАЧАЛОПЕРИОДА(СдельныйНарядВыработка.Ссылка.ДатаНачалаПериода, ДЕКАДА) КАК Декада,
СУММА(СдельныйНарядВыработка.СуммаРегл * ВТ_Исполнители.ДоляВаловки) КАК Сумма
ПОМЕСТИТЬ втВыработкаПоДекадам
ИЗ
втИсполнители КАК ВТ_Исполнители
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.СдельныйНаряд.Выработка КАК СдельныйНарядВыработка
ПО ВТ_Исполнители.Документ = СдельныйНарядВыработка.Ссылка
СГРУППИРОВАТЬ ПО
ВТ_Исполнители.Сотрудник,
НАЧАЛОПЕРИОДА(СдельныйНарядВыработка.Ссылка.ДатаНачалаПериода, ДЕКАДА)
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
втВыработкаПоДекадам.Сотрудник,
втВыработкаПоДекадам.Vфакт,
втВыработкаПоДекадам.Декада,
ЕСТЬNULL(РабочееВремяРаботниковОрганизацийОбороты.ЧасовОборот, 0) КАК Ттаб,
ВЫБОР
КОГДА ЕСТЬNULL(РабочееВремяРаботниковОрганизацийОбороты.ЧасовОборот, 0) = 0
ТОГДА 0
КОГДА втВыработкаПоДекадам.Vфакт / ЕСТЬNULL(РабочееВремяРаботниковОрганизацийОбороты.ЧасовОборот, 0) > 1
ТОГДА 1
ИНАЧЕ втВыработкаПоДекадам.Vфакт / ЕСТЬNULL(РабочееВремяРаботниковОрганизацийОбороты.ЧасовОборот, 0)
КОНЕЦ КАК Критм,
втВыработкаПоДекадам.Сумма
ПОМЕСТИТЬ втТабельноеВремя
ИЗ
втВыработкаПоДекадам КАК втВыработкаПоДекадам
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.РабочееВремяРаботниковОрганизаций.Обороты(&НачалоПериода, &КонецПериода, Декада, ВидИспользованияРабочегоВремени = ЗНАЧЕНИЕ(Справочник.КлассификаторИспользованияРабочегоВремени.Работа)) КАК РабочееВремяРаботниковОрганизацийОбороты
ПО втВыработкаПоДекадам.Сотрудник = РабочееВремяРаботниковОрганизацийОбороты.Сотрудник
И втВыработкаПоДекадам.Декада = РабочееВремяРаботниковОрганизацийОбороты.Период
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
втТабельноеВремя.Сотрудник,
СУММА(втТабельноеВремя.Vфакт) КАК Vфакт,
СУММА(втТабельноеВремя.Ттаб) КАК Ттаб,
СРЕДНЕЕ(втТабельноеВремя.Критм) КАК Критм,
втТабельноеВремя.Сумма
ПОМЕСТИТЬ втКритмМес
ИЗ
втТабельноеВремя КАК втТабельноеВремя
СГРУППИРОВАТЬ ПО
втТабельноеВремя.Сотрудник,
втТабельноеВремя.Сумма
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
РаботникиОрганизацийСрезПоследних.Сотрудник,
ВЫБОР
КОГДА РаботникиОрганизацийСрезПоследних.ПериодЗавершения <> ДАТАВРЕМЯ(1, 1, 1)
И РаботникиОрганизацийСрезПоследних.ПериодЗавершения <= &КонецПериода
ТОГДА РаботникиОрганизацийСрезПоследних.ПодразделениеОрганизацииЗавершения
ИНАЧЕ РаботникиОрганизацийСрезПоследних.ПодразделениеОрганизации
КОНЕЦ КАК Подразделение,
втКритмМес.Vфакт,
втКритмМес.Ттаб,
втКритмМес.Критм,
ВЫБОР
КОГДА втКритмМес.Ттаб = 0
ТОГДА 0
КОГДА втКритмМес.Vфакт / втКритмМес.Ттаб < 1
ТОГДА 1
КОГДА втКритмМес.Vфакт / втКритмМес.Ттаб > 1.25
ТОГДА 1.25
ИНАЧЕ втКритмМес.Vфакт / втКритмМес.Ттаб
КОНЕЦ КАК Квып,
ЕСТЬNULL(ЗначенияПоказателейСхемМотивации.Значение, 1) КАК Ккач,
втКритмМес.Сумма
ПОМЕСТИТЬ втКвыпКкач
ИЗ
втКритмМес КАК втКритмМес
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций.СрезПоследних(&КонецПериода, ) КАК РаботникиОрганизацийСрезПоследних
ПО втКритмМес.Сотрудник = РаботникиОрганизацийСрезПоследних.Сотрудник
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияПоказателейСхемМотивации КАК ЗначенияПоказателейСхемМотивации
ПО втКритмМес.Сотрудник = ЗначенияПоказателейСхемМотивации.Сотрудник
И (ЗначенияПоказателейСхемМотивации.Показатель = &ПоказательККач)
И (ЗначенияПоказателейСхемМотивации.ПериодДействия = &НачалоПериода)
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
СУММА(ВЫБОР
КОГДА взСуммаПоПодр.СуммаПоПодр = 0
ТОГДА 0
ИНАЧЕ втКвыпКкач.Сумма / взСуммаПоПодр.СуммаПоПодр * втКвыпКкач.Квып * втКвыпКкач.Критм * втКвыпКкач.Ккач
КОНЕЦ) КАК Кобщ,
взСуммаПоПодр.Подразделение
ПОМЕСТИТЬ втСуммаПоПодр
ИЗ
втКвыпКкач КАК втКвыпКкач
ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
втКвыпКкач.Подразделение КАК Подразделение,
СУММА(втКвыпКкач.Сумма) КАК СуммаПоПодр
ИЗ
втКвыпКкач КАК втКвыпКкач
СГРУППИРОВАТЬ ПО
втКвыпКкач.Подразделение) КАК взСуммаПоПодр
ПО втКвыпКкач.Подразделение = взСуммаПоПодр.Подразделение
СГРУППИРОВАТЬ ПО
взСуммаПоПодр.Подразделение
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
втКвыпКкач.Сотрудник,
втКвыпКкач.Подразделение,
втКвыпКкач.Vфакт,
втКвыпКкач.Ттаб,
втКвыпКкач.Критм,
втКвыпКкач.Квып,
втКвыпКкач.Ккач,
втКвыпКкач.Сумма,
ВЫБОР
КОГДА втСуммаПоПодр.Кобщ = 0
ТОГДА 0
ИНАЧЕ ЕСТЬNULL(ЗначениеКПодр.Значение, 0) * втКвыпКкач.Квып * втКвыпКкач.Критм * втКвыпКкач.Ккач / втСуммаПоПодр.Кобщ
КОНЕЦ КАК Крез,
ЕСТЬNULL(ЗначениеКПодр.Значение, 0) КАК Кподр
ПОМЕСТИТЬ втРезультат
ИЗ
втКвыпКкач КАК втКвыпКкач
ВНУТРЕННЕЕ СОЕДИНЕНИЕ втСуммаПоПодр КАК втСуммаПоПодр
ПО втКвыпКкач.Подразделение = втСуммаПоПодр.Подразделение
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияПоказателейСхемМотивации КАК ЗначениеКПодр
ПО втКвыпКкач.Подразделение = ЗначениеКПодр.Подразделение
И (ЗначениеКПодр.Показатель = &ПоказательКподр)
И (ЗначениеКПодр.ПериодДействия = &НачалоПериода)
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
втРезультат.Подразделение,
втРезультат.Vфакт,
втРезультат.Ттаб,
втРезультат.Критм,
втРезультат.Квып,
втРезультат.Ккач,
втРезультат.Сумма,
втРезультат.Крез,
втРезультат.Кподр,
ЗначенияСвойствОбъектов.Значение КАК Контрагент
ИЗ
втРезультат КАК втРезультат
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
ПО втРезультат.Сотрудник = ЗначенияСвойствОбъектов.Объект
И (ЗначенияСвойствОбъектов.Свойство = &СвойствоКонтрагент)
На вкладке «Параметры» задайте используемые в запросе параметры. В примере это элементы справочника «Показатели схем мотивации» для параметров «Коэффициент качества» и «К подразделения», и значение «Контрагент» плана видов характеристик «Свойства объектов» для параметра «Контрагент». Параметры, производные от месяца расчета здесь задавать не нужно.
Перейдем на вкладку «Данные». Здесь как раз можно задать параметры начала и конца периода расчета, причем можно дополнительно настроить смещение относительно рассчитываемого периода, если вдруг такое понадобится. В поле «Имя» просто вписывается имя параметра из вашего запроса, нужные данные будут подставлены в соответствии с тем, что было указано в поле «Начальная граница».
Важный штрих – задать связь с измерениями бюджетирования, в нашем случае связь будет одна, по измерению «Контрагент». В «Поле источника» выбирается одно из полей запроса, в данном случае «Контрагент».
Последним действием будет указание показателей, которые источник данных будет предоставлять при расчете, можно снять галочки, если вам нужны не все. В данном примере используется все поля запроса. На этом настройку источника данных можно считать завершенной.
Для выполнения самого расчета и записи полученных данных служит документ «Расчет по модели бюджетирования». Создадим новый документ. Общий вид созданного и частично заполненного документа представлен на скриншоте.
Указываем поле «Дата расчета» как первый день расчетного месяца. Если указать галочку «Регламентированный расчет», то потом можно будет быстро пересчитывать документы через обработку «Регламентный пересчет по моделям». Значение поля «Сценарий» большой роли не играет, главное, чтобы периодичность у этого сценария была месяц. В принципе, можно сделать расчет по нескольким сценариям, а потом сравнивать сценарии в отчете, чтобы прикинуть, насколько изменится премия, если изменить формулу. В поле «Основной источник данных» подставляем свежесозданный источник данных.
После подстановки источника данных автоматически заполняется вкладка «Показатели для расчета»
После того как задан «Основной источник данных», дополнительные источники данных задать уже нельзя, на соответствующей вкладке редактирование таблицы недоступно. Было бы неплохо иметь возможность задавать любое количество источников, а потом задавать связи по измерениям между ними, но такая возможность отсутствует (если кто знает, как это сделать, поделитесь в комментариях). Если попытаться, не указывая основного источника, задать набор дополнительных источников, то при расчете вылетит ошибка, и ничего не рассчитается.
Дальше нужно заполнить таблицу «Параметры расчета» , причем она имеет забавный интерфейс: на вкладке «Параметры расчета (таблица)» представлена сама таблица, а на вкладке «Параметры расчета (по строке таблицы)» находится что-то вроде окна редактирования текущей строки таблицы.
Заполняем выделенные поля, в поле «Статья оборотов» указывается соответствующая статья оборотов по бюджетам, по которой будут сформированы движения на основе рассчитанных данных. В поле «Расчет количества» заносится формула расчета с помощью конструктора.
Конструктор неплох, но напрягает то, что с клавиатуры можно вводить только цифры и символы, остальное делается мышью.
Аналогичным образом вводятся строки для остальных показателей, меняется только статья оборотов и формула расчета количества.
Теперь можно запустить расчет, кнопкой «Выполнить расчет» и посмотреть результат, нажав на «Просмотр результата».
При проведении документа эти данные попадут в регистр накопления «Обороты бюджетов», которые можно использовать для построения отчетов или выгрузить в регистры подсистемы зарплаты.
Полученные данные можно проанализировать с помощью отчета «Обороты по статьям», не забудьте переключить показатель на «Количество» в настройках отчета.
Для перерасчета уже созданных документов удобно воспользоваться обработкой «Регламентный пересчет по моделям бюджетирования». В ней можно пересчитать либо все документы за указанный период, либо отредактировать вручную список документов для пересчета.
Когда все показатели посчитаны, встает вопрос, как перенести их значения в подсистему зарплаты, ведь планы видов расчета ничего не знают о статьях оборотов по бюджетам. Здесь следующие варианты: дописать код, который будет создавать записи регистра сведений «Значения показателей схем мотивации» по данным оборотов по статьям в обработку «Значения показателей схем мотивации», либо вынести этот же код в отдельную обработку. Для второго варианта я написал простенькую обработку, которая и находится в публикации.
Работа с ней упрощена до предела. Указываете месяц переноса данных и заполняете таблицу соответствий, по которой данные оборотов по статьям будут сопоставлены со значениями показателей схем мотивации. При нажатии на кнопку «Заполнить» будут выбраны показатели и статьи, совпадающие по наименованию. Соответствие показателей и статей можно сохранять и загружать. Нажатием кнопки «Выполнить» запускается процесс формирования записей в регистре сведений «Значения показателей схем мотивации». В регистре заполняются поля сотрудник, организация, значение и период действия. Так как запись выполняется с помощью набора записей, все данные по этим показателям (указанным в таблице соответствий) за выбранный период будут очищены перед заполнением.
Сформированные данные по показателям можно проверить стандартной обработкой.
И использовать в произвольной формуле плана видов расчета.
В качестве бонуса предлагаю свой вариант отчета для анализа рассчитанных показателей. Он довольно прост, но как мне кажется, более удобен для этой цели, так как позволяет использовать в качестве измерения сотрудников, а не контрагентов, к тому же сделан на СКД, что дает определенную гибкость.
Выводы
Стоит ли использовать данный подход в реальной базе? Если у вас есть громоздкие формулы для расчета начислений, которые не удобны или просто не помещаются в стандартную произвольную формулу, то вполне можно взять этот метод на вооружение и считать с помощью него. Главный плюс — это отсутствие необходимости редактировать конфигурацию поставщика: все решается штатными механизмами. Еще один плюс в том, что для добавления новых показателей или редактирования существующих не нужно запускать конфигуратор, так как все настраивается в режиме предприятия. Сам расчет по модели бюджетирования происходит довольно быстро, особенно если сравнивать с расчетом в документе «Начисление зарплаты работникам организаций».
Для скачивания прикреплен архив, в котором:
1) обработка для переноса рассчитанных значений показателей из подсистемы бюджетирования (из РН обороты по статьям) в подсистему зарплаты (в РС значения показателей схем мотивации).
2) простой отчет на СКД для анализа расчитанных показателей в подсистеме бюджетирования (данные берутся из РН обороты по статьям)
3) файл консоли запросов с текстом запроса, расмотренного в примере.
P.S. текст запроса раскрашен обработкой «Разукрашка«: //infostart.ru/public/19856/
Сильно. Пару месяцев назад как раз занимались настройкой расчета заработной платы через штатные механизмы — через показатели схем мотивации — а коэффициентов премирования в новом положении о расчете заработной платы было немало. Относящихся и к работнику, и к подразделению, и к дереву подразделений.
Если фантазия руководства еще разок масштабные изменения алгоритма выдаст — возможно, попробуем, как изложено здесь.
Попробуйте :), если будут вопросы или темы для обсуждения, всегда готов к дискуссии.
Весьма нетривиальный подход: давно такого мозголомного проекта у коллег не видел — всё больше самому приходится мозги ломать. Слава богу, что не на этой стезе, а то б точно сломался. :)))
Думаю, у метода есть неплохой рынок. Надо только грамотно этот метод позиционировать.
И, наверное, имеет смысл выступить с докладом на конференции Infostart: страна должна знать своих героев! 🙂