Регистры расчета в 1с8
для чайников
Многие программисты 1С никогда не сталкивались в своей практике с компонентой «Расчет», поэтому, когда им приходится сдавать экзамены на Специалиста по Платформе 8.0, где в каждом задании есть задача по сложным периодическим расчетам, возникают сложности, прежде всего сложности понимания.
Попробуем разобраться с этой компонентой в 8.0. Вместо того чтобы решать различные задачи на расчет попробуем разобраться с этой компонентой так, чтобы можно было решить любую задачу по расчету. Изучив это пособие, вы поймете, как устроены и работают регистры расчета.
Для примера будем использовать каркасную конфигурацию, устанавливаемую на экзаменах.
Честно говоря, я долго пытался придумать, для чего еще нужны расчеты, но не придумал, поэтому будем рассматривать задачу расчета зарплаты.
В принципе, конечный продукт расчета зарплаты – это набор записей регистра расчета вида:
Сотрудник |
Период |
Вид расчета |
Результат |
Данные |
Комментарий |
Измерение |
Служебный |
Служебный |
Ресурс |
Ресурс |
Реквизит |
Иванов |
1 января – 31 января |
Оклад |
1000 |
1000 |
|
Петров |
1 январь – 31 января |
Оклад |
600 |
1000 |
|
Петров |
1 января – 10 февраля |
Невыход |
|
|
Болезнь |
Значение в колонке «Данные» отражают базовый оклад работника (согласно трудового договора), но эта сумма может быть увеличена премиями, уменьшена штрафами и невыходами и т.п., поэтому реальная сумма к выплате заносится после выполнения расчета в колонку «Результат». В этом и заключается расчет. Сумма по колонке «Ресурс» для данного сотрудника – причитающаяся ему зарплата.
Таким образом регистр расчета – по сути набор записей, по структуре похож на оборотный регистр накопления. Просто для выполнения сложных расчетов для него указываются дополнительные настройки, которые позволяют затем строить много виртуальных таблиц для регистра расчета, хотя, по сути этот регистр – просто набор записей, указанных на рисунке.
Каждая запись регистра расчетов относится к определенному виду расчета и периоду времени.
Каждая запись видов расчета имеет служебный реквизит – вид расчетов.
Вид расчетов можно представлять себе как элемент особого справочника типа «План видов расчетов» - он также имеет реквизиты, табличные части, предопределенные и заведенные пользователем элементы. В системе может быть несколько таких «справочников».
Для примера заведем план видов расчета Основной и в нем предопределенные виды расчета оклад, премия, невыход, командировка.
Виды расчета используются функционально для того, чтобы отразить влияние записей регистра расчета друг на друга. Но сокращенно говорят о влиянии видов расчета друг на друга:
Вид расчета |
Описание |
Пример |
По базовому периоду |
Результат расчета зависимого периода зависит от результата базового периода. Если результат базового периода изменится, то результат зависимого периода нужно пересчитать. |
Премия зависит по базовому периоду от оклада. |
Вытеснение по периоду |
Период действия зависимого периода вытесняет период действия базового периода, таким образом у базового периода появляется фактический |
Невыход влияет на фактический период действия оклада. |
Ведущие расчеты |
Расчет зависит от ведущего расчета, но не прямо а косвенно, т.е. расчет А зависит от базового расчета Б, а расчет Б зависит от базового расчета В, следовательно А косвенно зависит от В, т.е. А зависит от ведущего расчета В. В самом деле, при изменении расчета В может измениться Б и следовательно может измениться А. Система автоматически не отслеживает такие сложные зависимости, поэтому нужно указывать какие расчеты являются ведущими. |
Премия зависит по базе от оклада, но также косвенно зависит и от невыхода. |
В силу подобного влияния, период действия записи регистра расчетов делится на четыре периода:
Период |
Описание |
Период регистрации |
В каком периоде зарегистрировано событие, т.е. обычно когда введен документ. |
Период действия |
В каком периоде действует событие, т.е. к какому периоду относится событие. |
Базовый период |
Имеет смысл только для периодов, имеющих базовый период – описывает интервал базового периода. |
Фактический период действия |
Если период действия вытесняется другими видами расчетов, то фактический период действия состоит из нескольких периодов, когда этот вид расчета фактически действует. |
Период регистрации задается одним числом – началом периода, соответствующим периодичности регистра расчета. Даже если мы установим в это служебное поле другую дату, он все равно заменится на начало периода. Остальные периоды задаются двумя полями – началом и концом периода. Фактический период действия – это набор периодов, т.к. он может состоять из нескольких интервалов дат.
В системе имеется возможность связывать данные из регистров расчета с графиками времени, чтобы по любому периоду можно было получить количество рабочих часов.
График времени – это простой регистр сведений, одно измерение которого хранит дату, другое связывается с измерением регистром расчета, а один из ресурсов используется для учета времени.
Измерение, которое связывается с регистром расчета обычно носит смысл «вид графика».
Дата |
Вид графика |
Значение |
11.01.05 пт |
Пятидневка |
8 |
11.01.05 пт |
Шестидневка |
8 |
12.01.05 сб |
Пятидневка |
0 |
12.01.05 сб |
Шестидневка |
8 |
Почему используется измерение дата, а не периодический регистр сведений? Все очень просто – если 11 января в пятницу по пятидневке у нас 8 рабочих часов, то это еще не значит, что на следующий день у нас будет опять же 8 рабочих часов. А ведь если бы мы использовали периодический регистр, значение на следующий день бралось бы из предыдущего дня при отсутствии записей.
Таким образом, имея определенный период (фактического действия, регистрации, базовый период и т.п.) мы можем автоматически получить количество часов за этот период по графику.
Перерасчет чем-то напоминает границу последовательности. Так как у нас есть зависимые расчеты, то при изменении их базовых и ведущих расчетов система должна как-то отметить, что мы должны пересчитать зависимые расчеты.
Для этого и служат перерасчеты.
Если мы рассчитаем базовые записи, то система отметит в перерасчетах, что нам нужно рассчитать зависимые записи. Как только мы рассчитаем зависимые записи, перерасчеты очистятся.
По сути перерасчеты – это список записей регистра расчета, которые нужно перерасчитать.
Если в перерасчетах не заводить ни одного измерения, то при изменении базовых расчетов в список перерасчета занесутся все зависимые записи.
Если мы заведем измерение «Сотрудник» в перерасчете, то при изменении базового расчета по сотруднику в перерасчеты добавятся зависимые записи только по этому сотруднику.
Достаточно теории. Попробуем изучить детали на практике. За основу возьмем каркасную конфигурацию.
Пусть премия задается фиксированным процентом к окладу (за вычетом невыходов и командировочных).
Командировочные пусть оплачиваются в двойном окладе + фиксированная сумма выплат за каждый день командировки.
Пусть за невыходы с сотрудника взымается штраф в размере половины оклада за период невыхода.
Начальная подготовка
Создадим новый план видов расчета «Основной».
Определим виды расчета и зависимости между ними:
|
Базовые |
Вытесняющие |
Ведущие |
Оклад |
|
Невыход, Командировка |
|
Премия |
Оклад |
Невыход, Командировка |
Оклад, Невыход, Командировка |
Командировка |
Оклад |
|
|
Невыход |
Оклад |
|
|
Занесем эти виды расчета в план видов расчета «Основной» и в свойствах видов расчета поставим зависимости согласно таблице.
В регистре расчета зарплаты сделаем измерение «Сотрудник» типа «ФизическиеЛица» - чтобы в регистре был разрез аналитики по сотрудникам.
В конфигурации уже имеется документ «Начисление зарплаты».
В нем две даты в шапке – «дата» и «период регистрации», а также по две даты «дата начала» и «датаконца» в каждой строчке.
Подразумевается что дата – это просто дата оформления документа, период регистрации указывает, за какой месяц мы считаем зарплату, а даты в каждой строке описывают период действия каждого вида расчета.
Добавим в модуль документа первоначальную установку реквизита «Данные» - в него будем заносить начальный оклад, установку периода регистрации, периода действия и базового периода.
Модуль документа будет выглядеть примерно так:
Для Каждого
ТекСтрокаСписок Из Список Цикл
// регистр
Расчеты
Движение = Движения.Расчеты.Добавить();
Движение.Сторно = Ложь;
Движение.ВидРасчета = ТекСтрокаСписок.ВидРасчета;
Движение.ПериодДействияНачало = НачалоДня(ТекСтрокаСписок.ДатаНачала);
Движение.ПериодДействияКонец = КонецДня(ТекСтрокаСписок.ДатаОкончания);
Движение.ПериодРегистрации = ПериодРегистрации;
Движение.БазовыйПериодНачало = НачалоДня(ТекСтрокаСписок.ДатаНачала);
Движение.БазовыйПериодКонец = КонецДня(ТекСтрокаСписок.ДатаОкончания);
Движение.Сотрудник = ТекСтрокаСписок.Сотрудник;
Движение.ГрафикРаботы = ТекСтрокаСписок.График;
Движение.Результат = 0;
Движение.Данные = ТекСтрокаСписок.Размер;
КонецЦикла;
Реквизит Сторно нужен чтобы сторнировать записи (аналог минуса).
Проставляем вид расчета, даты приводим к началу и концу дня. Конечно базовый период можно проставлять только у зависимых по базе видов расчета, а Данные можно проставлять только у оклада, но и так все работает.
Все документы датировать будем 20.01.2003, период регистрации будем ставить 02.01.2003 (специально указываю не начальные и конечные данные, здесь это неважно, все равно при записи в ПериодРегистрации преобразуется в начало периода 01.01.2003). Январь 2003 года используем, потому что за этот период заполнены графики работ.
Заведем перерасчет «Перерасчет», добавим в него измерение «Сотрудник», связанное с измерением «Сотрудник».
Играем с
Перерасчетами.
Для игры откроем консоль запроса – обработка «ПроизовльныйЗапрос» в каркасной конфигурации. Создадим новый запрос конструктором запроса, добавим туда виртуальную таблицу Перерасчеты.Расчеты.Перерасчет, текст запроса будет таким:
ВЫБРАТЬ
РасчетыПерерасчет.ОбъектПерерасчета,
РасчетыПерерасчет.ВидРасчета,
РасчетыПерерасчет.Сотрудник
ИЗ
РегистрРасчета.Расчеты.Перерасчет КАК РасчетыПерерасчет
Сформируем три документа – первым начислим оклад сотрудникам А и Б. Сотрудник А работает с 1 по 31 января, Б работает с 1 по 20 января. Вторым начислим премию сотруднику Б за период с 1 по 31 января, третьим назначим невыход сотруднику А с 20 по 25 января.
Играем с Фактическим
периодом действия.
Создадим новый запрос – на этот раз в него добавим данные таблицы РегистрыРасчета.Расчеты.ФактическийПериодДействия.
Сформируем запрос и увидим, что сотруднику А период действия оклада разбит на два периода – с 1 по 19 и с 26 по 31 января. Надеюсь вам понятно, что период был разбит на два, т.к. невыход вытеснил оклад.
Думаю, механизмы работы регистра расчета проясняются на глазах.
Изучаем графики.
Теперь попробуем начислить зарплату по окладу сотрудника.
Создадим новый запрос по регистру расчета используя виртуальную таблицу РегистрыРасчета.Расчеты.ДанныеГрафика. У этой виртуальной таблицы можно задать параметр - условие отбора записей, например Сотрудник=&ВыбСотрудник и ВидРасчета=&ВидРасчета и График=&ВидГрафика.
Зададим в параметрах запроса конкретных сотрудников, виды расчета и графиков и посмотрим, сколько часов получается в результате.
Колонка результата |
Значение |
ЗначениеПериодДействия |
На какой период действия в часах была запись в регистре. |
ЗначениеФактическийПериодДействия |
Сколько сотрудник фактически проработал в часах |
ЗначениеБазовыйПериод |
Для оклада смысла не имеет, для премии – количество рабочих часов в базовом периоде. |
ЗначениеПериодРегистрации |
Сколько рабочих часов в периоде регистрации (месяц январь) |