Базовый период 1с. Свойство базовое измерения регистра расчета

Базовый период 1с. Свойство базовое измерения регистра расчета

Учимся работать с регистрами (1С:Бухгалтерия 8.3, редакция 3.0)

2016-12-08T13:50:45+00:00

Дорогие читатели, в этом уроке я хочу затронуть крайне важную тему при работе в 1С:Бухгалтерия 8.3 - Регистры .

Сразу покажу на небольшом примере почему это так важно.

Пусть у нас есть начисление заработной платы за январь:

В начале февраля мы создаём ведомость на выплату зарплаты из кассы и нажимаем кнопку "Заполнить":

И получаем следующее:

Но ведь за январь:

  • Начисление 50 000 рублей
  • НДФЛ 6 500 рублей
  • Итого к выплате 43 500 рублей

Где закралась ошибка? Что пошло не так? Неужели теперь всегда вводить сумму к выплате вручную?

Опытный бухгалтер тут же сделает оборотно-сальдовую ведомость по 70 счёту:

И будет в ещё большем недоумении, потому что по данным отчёта к выплате выходят всё те же 43 500! И откуда же взялись лишние 5 000 рублей?

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

Сегодня я попытаюсь приоткрыть завесу тайны - почему же иногда программа ведёт себя так странно. Я расскажу как в таких случаях находить и устранять ошибку. Ближе к концу статьи мы разберёмся - откуда же взялись эти самые 5 000 рублей.

Итак, поехали!

Учимся видеть регистры

При проведении документов 1С:Бухгалтерия 8 делает проводки по бухгалтерским счетам (кнопка ДтКт у любого документа):

Именно на основании этих проводок строятся все бухгалтерские отчёты: Анализ счёта, Карточка счёта, Оборотно-сальдовая ведомость...

Но есть огромный пласт данных, которые пишутся программой параллельно с проводками и используются для всего остального: заполнение КУДИР, книги покупок и продаж, регламентированной отчётности... заработной платы к выплате , наконец

Как вы уже, наверное, догадались этот пласт называется регистрами , вот он:

Я сейчас не буду вдаваться в подробности описания самих регистров, чтобы не запутать вас ещё больше.

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

Давайте присмотримся к регистру "Зарплата к выплате" - именно он имеет смысл для решения нашей проблемы с лишними 5 000:

Мы видим две записи по этому регистру, сделанные в приход, то есть в плюс. Если пролистать экран в право, то мы увидим в первой строчке сумму к выплате "-6 500", а во второй "50 000".

Остаток по этому регистру -6 500 + 50 000 равен 43 500, который и должен попасть в документ "Ведомость на выплату из кассы", когда мы нажимаем на кнопку "Заполнить".

Ещё раз повторюсь - ведомость на выплату определяет нашу задолженность по заработной плате перед сотрудником не по 70 счёту, а по регистру "Зарплата к выплате" .

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

Скорее всего мы не видим всей картины (может быть существуют другие записи по этому регистру) и напрашивается некий инструмент для анализа регистра подобный бухгалтерским отчётам.

Учимся анализировать регистры

И такой инструмент есть, он называется "Универсальный отчёт ".

Переходим в раздел "Отчеты" пункт "Универсальный отчёт":

Выбираем тип регистра "Регистр накопления", регистр "Зарплата к выплате" и нажимаем кнопку "Сформировать":

Получилось не очень информативно:

Всё потому, что требуется предварительная настройка отчёта, нажимаем кнопку "Показать настройки" и на закладке "Группировка" добавляем поле "Сотрудник":

На закладке "Отборы" делаем отбор по нашей организации:

Нажимаем кнопку "Сформировать":

Вот это уже более интересно. Видим остаток к выплате нашему сотруднику те самые 48 500 рублей!

Снова заходим в настройки отчёта и добавляем на закладку "Показатели" новое поле "Регистратор":

Снова формируем отчёт:

Вот теперь мы прекрасно видим, что 5 000 появились как результат операции (видимо ввода остатков) 31 декабря 2014 года.

И нам нужно либо изменить эту операцию, либо вручную откорректировать регистр "Зарплата к выплате" и закрыть эти 5 000 рублей, например, 31 декабря 2015 года.

Давайте пойдём вторым путём. Итак, наша задача - сделать так, чтобы на начало 2016 года по регистру "Зарплата к выплате" не было нашей задолженности перед сотрудником.

Это делается ручной операцией.

Учимся корректировать регистры

Заходим в раздел "Операции" пункт "Операции, введенные вручную":

Создаём новую операцию концом 2015 года:

Из меню "Ещё" выбираем пункт "Выбор регистров...":

Указываем регистр "Зарплата к выплате" и нажимаем ОК:

Переходим на появившуюся закладку регистра и делаем расход на 5 000 рублей:

Этим самым мы как бы отнимаем от регистра 5 000 рублей по сотруднику, чтобы выйти на ноль к началу 2016 года.

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

Всё получилось! Видим, что наша ручная операция от 31.12.2015 вывела остаток в ноль и зарплата к выплате после начисления равна ожидаемым 43 500.

Замечательно. И сейчас мы проверим это в ведомости на выплату.

Но прежде я хочу обратить ваше внимание на ещё один важный момент:

Обратите внимание, что остатки на начало и на конец по группировке "Сотрудник" показывают ерунду. Это никакая не ошибка, это нюанс, который нужно учитывать, связанный с архитектурными особенностями 1с.

Запомните. В том случае, если универсальный отчёт выводится с детализацией до документа (регистратора) - остатки по группировкам будут показывать ерунду.

Если нам требуются остатки по группировке сотрудник - нужно сначала удалить из настроек добавленный нами показатель "Регистратор".

регистр сведений , который будет содержать график , используемый при расчете. В нашем случае это регистр РабочиеДниПоГрафику . В поле Значение графика выберем РабочийДень - именно в этом ресурсе регистра сведений будет храниться 1, если день является рабочим. В поле Дата графика выберем измерение регистра Дата .

Установим флаг Базовый период .

Зададим в группе параметров Периодичность параметр Месяц .

Перейдем на вкладку Данные . Зададим здесь следующие параметры, рис. 1.11 :


Рис. 1.11.

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

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

Реквизит ИсходныеДанные - тип число, длина 10, точность 2. В этот реквизит мы будем записывать исходные данные для расчета. Например, для вида расчета Оклад мы запишем сюда исходный размер оклада, для вида расчета Премия - процент , который должен браться от расчетной базы, для вида расчета Удержание - размер удержания в рублях.

Реквизит График - тип СправочникСсылка.ГрафикиРаботы . В этом реквизите будем хранить график , который соответствует сотруднику, для которого мы начисляем заработную плату. В свойстве этого реквизита Связь с графиком установим измерение График регистра сведений Графики работы . Именно благодаря этой настройке мы сможем использовать различные графики работы для разных сотрудников (пятидневка, шестидневка) и при расчете получать правильное количество рабочих дней по каждому графику.

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

1.6. Документ Начисление зарплаты

Создадим новый документ, дадим ему имя НачислениеЗарплаты . Этот документ должен иметь следующую функциональность:

  1. Возможность ручного ввода начислений;
  2. Формирование движений по регистру расчета ;

Перейдем на вкладку Данные окна настройки свойств документа НачислениеЗарплаты , рис. 1.12 . Создадим реквизит документа ПериодРегистрации - тип Дата , состав даты - Дата .


Рис. 1.12.

Создадим табличную часть НачисленияИУдержания . Создадим в ней следующие реквизиты:

Теперь перейдем на вкладку Движения . Запретим оперативное проведение документа , добавим в состав регистров, по которым документ формирует движения, регистр НачисленияИУдержания .

Нажмем на кнопку Конструктор движений . Откроется окно конструктора, рис. 1.13 .


Рис. 1.13.

При заполнении полей, задающих правила формирования движений мы заполним их следующим образом:

БазовыйПериодНачало и БазовыйПериодКонец в конструкторе мы заполнять не будем. Эти поля нужны нам для вида расчета Премия , поэтому мы заполним их в коде процедуры обработки проведения для данного вида расчета .

Нажмем на кнопку ОК в окне конструктора движений и посмотрим, какой код он сформировал:

Процедура ОбработкаПроведения(Отказ, Режим) //{{__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ // Данный фрагмент построен конструктором. // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!! Для Каждого ТекСтрокаНачисленияИУдержания Из НачисленияИУдержания Цикл // регистр НачисленияИУдержания Движение = Движения.НачисленияИУдержания.Добавить(); Движение.Сторно = Ложь; Движение.ВидРасчета = ТекСтрокаНачисленияИУдержания.ВидРасчета; Движение.ПериодДействияНачало = ТекСтрокаНачисленияИУдержания.ДатаНачала; Движение.ПериодДействияКонец = ТекСтрокаНачисленияИУдержания.ДатаОкончания; Движение.ПериодРегистрации = ПериодРегистрации; Движение.Сотрудник = ТекСтрокаНачисленияИУдержания.Сотрудник; Движение.ИсходныеДанные = ТекСтрокаНачисленияИУдержания.ИсходныеДанные; Движение.График = ТекСтрокаНачисленияИУдержания.График; КонецЦикла; //}}__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ КонецПроцедуры

Очевидно, что для каждой строки табличной части создается новый элемент коллекции документа Движения.НачисленияИУдержания , после чего заполняются свойства нового элемента.

Модифицируем этот код таким образом, чтобы задать параметры базового периода для вида начисления Премия . Для этого будем проверять вид расчета , присутствующий в обрабатываемой строке, если это - Премия - задаем параметры базового периода . Поместим в цикл обработки строк табличной части такой код:

Если ТекСтрокаНачисленияИУдержания.ВидРасчета= ПланыВидовРасчета.Основной.Премия Тогда Движение.БазовыйПериодНачало=НачалоМесяца(ПериодРегистрации); Движение.БазовыйПериодКонец=КонецМесяца(ПериодРегистрации); КонецЕсли;

Теперь немного изменим ту часть кода, которая задает начало и конец периода действия начисления. В нашем случае лишь один вид начисления нужно "оснастить" периодом действия , который в явном виде будет задавать пользователь . Это - Прогул . У всех остальных период действия будет равняться одному месяцу - начало периода будет совпадать с началом месяца, за который производится начисление заработной платы, конец периода действия будет совпадать с концом месяца. Поэтому мы, для того, чтобы избавить пользователя документа НачислениеЗарплаты от ввода ненужных значений, добавим в наш модуль следующий код, поместив его в цикл обработки строк табличной части:

Если Движение.ВидРасчета=ПланыВидовРасчета.Основной.Прогул Тогда Движение.ПериодДействияНачало = ТекСтрокаНачисленияИУдержания.ДатаНачала; Движение.ПериодДействияКонец = ТекСтрокаНачисленияИУдержания.ДатаОкончания; Иначе Движение.ПериодДействияНачало = НачалоМесяца(ПериодРегистрации); Движение.ПериодДействияКонец = КонецМесяца(ПериодРегистрации); КонецЕсли;

Этот код заменит строки

Движение.ПериодДействияНачало = ТекСтрокаНачисленияИУдержания.ДатаНачала; Движение.ПериодДействияКонец = ТекСтрокаНачисленияИУдержания.ДатаОкончания;

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

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

На рис. 1.14 вы можете видеть документ, который мы заполнили, и движения в регистре расчета , которые он произвел после проведения, после отработки кода, который мы написали выше.

Если все перенесено верно, а в нашем случае это именно так, мы можем приступать к реализации процедуры расчета. Сделаем это в том же модуле, в котором осуществляется формирование движений.

Сразу хотелось бы отметить, что в существующих конфигурациях обычно применяются несколько другие методы реализации расчетных процедур. В частности, для них характерна следующая последовательность действий. После того, как документ сформировал движения по регистру, происходит запись данных в регистр , после чего управление передается в расчетную процедуру общего модуля с установленным свойством Сервер , что актуально в том случае, если система работает в клиент-серверном режиме. В процедуре, с помощью запроса к таблицам регистра расчета , получают записанные данные и проводят манипуляции с ними. Все эти действия, в итоге, приводят к повышению быстродействия прикладных решений , которые могут использоваться в различных режимах, работать с большими объемами данных. Сущность действия такая же, как в нашем примере, но реализация отличается. Главная цель нашего учебного примера - показать принципы, по которым осуществляется решение расчетных задач, поэтому здесь мы концентрируемся именно на основных принципах, не обращая внимание на оптимальность кода или его быстродействие .

Добавим в процедуру проведения документа команду записи сформированных движений:

Движения.НачисленияИУдержания.Записать();

Эта команда должна следовать за командой закрытия цикла формирования движений.

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

Для Каждого Движение из Движения.НачисленияИУдержания Цикл Если Движение.ВидРасчета=ПланыВидовРасчета.Основной.Удержание Тогда Движение.Результат=Движение.ИсходныеДанные; КонецЕсли; КонецЦикла; Движения.НачисленияИУдержания.Записать();

Теперь займемся расчетом оклада.

Для Каждого Движение из Движения.НачисленияИУдержания Цикл Если Движение.ВидРасчета=ПланыВидовРасчета.Основной.Оклад Тогда План = Движение.ПолучитьДанныеГрафика(ВидПериодаРегистраРасчета.ПериодДействия); Факт= Движение.ПолучитьДанныеГрафика(ВидПериодаРегистраРасчета.ФактическийПериодДействия); Движение.Результат= Движение.ИсходныеДанные*Факт.РабочийДень/План.РабочийДень; КонецЕсли; КонецЦикла; Движения.НачисленияИУдержания.Записать();

Метод ПолучитьДанныеГрафика записи регистра расчета возвращает данные графика в виде таблицы значений, причем, этот метод вызывается с параметром типа ВидПериодаРегистраРасчета . Если вызвать его с видом периода ПериодДействия - будут возвращены данные по графику, отражающие, в нашем случае, полное количество рабочих дней. Вызов метода с видом периода ФактическийПериодДействия возвращает данные с учетом вытесняющих видов расчета .

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

В итоге, получив нужные данные, мы проводим следующие манипуляции: делим фактическое количество отработанных дней на плановое и умножаем на размер оклада.

И, наконец, последним этапом нашей расчетной задачи является расчет премии. Его мы реализуем с помощью следующего кода:

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

Для начала мы подготовим параметры для передачи в метод ПолучитьБазу . Это будет массив Ресурсы , который в нашем случае содержит имя ресурса базового регистра расчета в формате "ИмяРегистра.ИмяРесурса" . Так же мы готовим структуру Измерения . В структуру мы добавляем новый элемент, имя которого совпадает с именем измерения регистра расчета ("Сотрудник" ), а значение содержит список измерений (в формате "ИмяРегистра.ИмяИзмерения" ), в нашем случае это одно измерение. Эти данные будут использованы при получении расчетной базы при расчете премии.

В цикле мы записываем в переменную ДанныеБазы результаты выполнения метода ПолучитьБазу для текущей записи регистра расчета (то есть - для вида расчета Премия ). Метод ПолучитьБазу возвращает таблицу значений, строки которой хранят запрошенные при вызове метода данные.

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

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

После того, как все вышеперечисленные действия выполнены, мы можем испытать наше решение на практике. Если все выполнено верно - в

Многие программисты 1С никогда не сталкивались в своей практике с компонентой «Расчет»,поэтому, когда им приходится сдавать экзамены на Специалиста по Платформе 8.0, где в каждомзадании есть задача по сложным периодическим расчетам, возникают сложности, прежде всего сложности понимания.

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

Для примера будем использовать каркасную конфигурацию, устанавливаемую на экзаменах.

Честно говоря, я долго пытался придумать, для чего еще нужны расчеты, но не придумал, поэтому будем рассматривать задачу расчета зарплаты.

Что такое расчеты

В принципе, конечный продукт расчета зарплаты - это набор записей регистра расчета вида:

Сотрудник

Период

Вид расчета

Результат

Данные

Комментарий

Измерение

Служебный

Служебный

Реквизит

Значение в колонке «Данные» отражают базовый оклад работника (согласно трудового договора), но эта сумма может быть увеличена премиями, уменьшена штрафами и невыходами и т.п., поэтому реальная сумма к выплате заносится после выполнения расчета в колонку «Результат». В этом и заключается расчет. Сумма по колонке «Ресурс» для данного сотрудника - причитающаяся ему зарплата.

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

Каждая запись регистра расчетов относится к определенному виду расчета и периоду времени.

Виды расчетов

Каждая запись видов расчета имеет служебный реквизит - вид расчетов.

Вид расчетов можно представлять себе как элемент особого справочника типа «План видов расчетов» - он также имеет реквизиты, табличные части, предопределенные и заведенные пользователем элементы. В системе может быть несколько таких «справочников».

Для примера заведем план видов расчета Основной и в нем предопределенные виды расчета оклад , премия , невыход , командировка .

Виды расчета используются функционально для того, чтобы отразить влияние записей регистра расчета друг на друга. Но сокращенно говорят о влиянии видов расчета друг на друга:

Вид расчета

Описание

Пример

По базовому периоду

Результат расчета зависимого периода зависит от результата базового периода. Если результат базового периода изменится, то результат зависимого периода нужно пересчитать.

Премия зависит по базовому периоду от оклада.

Вытеснение по периоду

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

Невыход влияет на фактический период действия оклада.

Ведущие расчеты

Расчет зависит от ведущего расчета, но не прямо а косвенно, т.е. расчет А зависит от базового расчета Б, а расчет Б зависит от базового расчета В, следовательно А косвенно зависит от В, т.е. А зависит от ведущего расчета В. В самом деле, при изменении расчета В может измениться Б и следовательно может измениться А. Система автоматически не отслеживает такие сложные зависимости, поэтому нужно указывать какие расчеты являются ведущими.

Премия зависит по базе от оклада, но также косвенно зависит и от невыхода.

В силу подобного влияния, период действия записи регистра расчетов делится на четыре периода:

Период

Описание

Период регистрации

В каком периоде зарегистрировано событие, т.е. обычно когда введен документ.

Период действия

В каком периоде действует событие, т.е. к какому периоду относится событие.

Базовый период

Имеет смысл только для периодов, имеющих базовый период - описывает интервал базового периода.

Фактический период действия

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

Период регистрации задается одним числом - началом периода, соответствующим периодичности регистра расчета. Даже если мы установим в это служебное поле другую дату, он все равно заменится на начало периода. Остальные периоды задаются двумя полями - началом и концом периода.Фактический период действия - это набор периодов, т.к. он может состоять из нескольких интервалов дат.

Графики времени

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

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

Измерение, которое связывается с регистром расчета обычно носит смысл «вид графика».

Дата

Вид графика

Значение

11.01.05 пт

Пятидневка

11.01.05 пт

Шестидневка

12.01.05 сб

Пятидневка

12.01.05 сб

Шестидневка

Почему используется измерение дата, а не периодический регистр сведений? Все очень просто - если 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 января. Надеюсь вам понятно, что период был разбит на два, т.к. невыход вытеснил оклад.

Думаю, механизмы работы регистра расчета проясняются на глазах.

Изучаем графики.

Теперь попробуем начислить зарплату по окладу сотрудника.

Создадим новый запрос по регистру расчета используя виртуальную таблицу РегистрыРасчета.Р асчеты.ДанныеГрафика . У этой виртуальной таблицы можно задать параметр - условие отбора записей, например Сотрудник=&ВыбСотрудник и ВидРасчета=&ВидРасчета и График=&ВидГрафика .

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

Колонка результата

Значение

ЗначениеПериодДействия

На какой период действия в часах была запись в регистре.

ЗначениеФактическийПериодДействия

Сколько сотрудник фактически проработал в часах

ЗначениеБазовыйПериод

Для оклада смысла не имеет, для премии - количество рабочих часов в базовом периоде.

ЗначениеПериодРегистрации

Сколько рабочих часов в периоде регистрации (месяц январь)

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

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

Мы не будем рассматривать эти способы подробно, рассмотрим только их отличия и область применения.

Метод ПолучитьБазу()

Метод ПолучитьБазу() определен для объектов РегистрРасчетаМенеджер.<Имя регистра расчета> и РегистрРасчетаЗапись.<Имя регистра расчета> . Метод позволяет задать ресурсы базовых регистров, по которым необходимо получить обороты, задать поля, в разрезе которых нужно получить обороты и задать правила сопоставления измерений основного и базовых регистров расчета.

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

Имена измерений и ресурсов базовых регистров задаются в формате <ИмяРегистраРасчета>.<ИмяПоля>.

Пример использования метода:
Код 1C v 8.х Ресурсы = Новый Массив(1);
Ресурсы = "ОсновныеНачисления.Результат,ДополнительныеНачисления.Результат";

Измерения = Новый Структура("ФизЛицо,Организация");
Измерения.ФизЛицо = "ОсновныеНачисления.Физлицо,ДополнительныеНачисления.Работник";
Измерения.Организация = "ОсновныеНачисления.Организация,ДополнительныеНачисления.Организация";

Разрезы = Новый Массив(1);
Разрезы = "ОсновныеНачисления.Способ,ДополнительныеНачисления.Способ";
// Рассчитываем базуТаблицаБазовыхДанных = РегистрРасчета.Удержания.ПолучитьБазу(Отбор,
// Ресурсы, Измерения, Разрезы);

В приведенном выше примере измерение "Физлицо" основного регистра при получении оборотов будет сопоставляться с измерением "Физлицо" базового регистра "ОсновныеНачисления" и измерением "Работник" базового регистра "ДополнительныеНачисления".

Таблица языка запросов для получения базовых данных
Для получения базовых данных в языке запросов определены виртуальные таблицы "РегистрРасчета.<Имя регистра расчета>.База<Имя базового регистра расчета>" . В качестве параметров виртуальной таблицы задаются измерения основного регистра, измерения базового регистра и поля, в разрезе которых нужно получить базовые данные. Измерения и разрезы задаются как массив (или список значений) строк с именами измерений.

Пример написания запроса с использованием виртуальных таблиц базовых данных:
Код 1C v 8.х
Измерения1 = Массив(2);
Измерения1 = "Физлицо";
Измерения1 = "Организация";

Измерения2 = Массив(2);
Измерения2 = "Работник";
Измерения2 = "Организация";

Разрезы = Новый Массив(1);
Разрезы = "Способ";

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

Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("Измерения1", Измерения1);
Запрос.УстановитьПараметр("Измерения2", Измерения2);
Запрос.УстановитьПараметр("Разрезы", Разрезы);

// ...установка дополнительных параметров запроса, применяемых в условиях в операторе ГДЕ// ,..
// получим выборку результата запросаВыборка = Запрос.Выполнить().Выбрать();

Приведенный пример предполагает ту же структуру данных и ту же решаемую задачу, что и пример для метода ПолучитьБазу(). При этом мы видим заметное увеличение исходного кода и кажущуюся его сложность.

Сравнение
Заметным отличием функционального метода получения базовых данных и получения при помощи запроса является то, что в функциональном методе одним вызовом метода можно получить базовые данные по всем базовым регистрам, а при использовании запросов получение базовых данных делается запросом к нескольким таблицам - по числу базовых регистров. Тем не менее, рекомендуемым способом получения данных является получение данных запросом. Это позволит, например, получить не только данные базовых видов расчета, но и дополнительную информацию, необходимую для расчета.

Отметим, что производительность получения данных при помощи функционального метода и при помощи запроса одинакова несмотря на кажущееся усложнение исполняемого кода в случае с запросами.

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

Еще одно соображение касается условий отбора базовых данных. Для метода ПолучитьБазу(), фактически, нет возможности получить базовые данные иначе, чем по одной записи или по конкретному регистратору (с отбором по тем или иным измерениям). В случае же запроса в распоряжении у разработчика все возможности языка запросов по отбору записей.

Для того чтобы можно было рассчитывать зарплату в конфигурации, работающей на платформе 1С Предприятие 8, необходимо умение работать с объектами конфигурации которые для этого и предназначены. Для реализации возможности расчета заработной платы, в конфигурации необходимо использовать такие объекты как планы видов расчета и регистры расчета. Без этих объектов реализовать расчет достаточно проблематично, если совсем не возможно. В этой статье хочу поведать какие объекты предназначены для расчета зарплаты и как с ними работать.
Основные используемые понятия:
Вид расчета – начисление или удержание, которое может быть применено к сотруднику.
План видов расчета – объект конфигурации, предназначенный для хранения однотипных видов расчета.
База – совокупность видов расчета, которые и являются основой для расчета конкретного вида расчета.
Период регистрации – это дата, когда документ зарегистрирован в системе. И если периодичность регистра расчета месяц, то период регистрации системой автоматически приводится к началу месяца.
Период действия – это интервал, в котором действует вид расчета. Например, зарегистрировать документ можно в одном месяце, а период действия будет находиться в другом месяце.
Сокращения, встречающиеся в тексте:
ПВР – план видов расчета;

Итак, начнем с настройки ПВР. В основном настройки ПВР схожи с настройками справочников, но настройки, характерные именно для ПВР находятся на закладке «Расчет» окна редактирования объекта. ПВР содержит однотипные виды расчета. В системе может быть несколько ПВР. Обычно, ПВР создают для основных начислений, для дополнительных начислений и для удержаний. Пример настройки ПВР приведен на рисунке 1.

Рисунок 1

Свойство «Использует период действия» - устанавливаем флаг в том случае, если виды расчета в этом ПВР будут иметь протяженность во времени (Например, Оклад). В этом случае можно будет например с 15 по 20 число месяца начислить оплату по окладу. Если этот флаг не устанавливать, то такой возможности не будет.
Свойство «Зависимость от базы» – указываем, могут ли виды расчета зависеть от базы. Зависимость от базы бывает двух видов: а) Зависимость от базы по периоду действия – это означает, что наши виды расчета, которые находятся в этом ПВР будут зависеть от периода действия. б) Зависимость от базы по периоду регистрации – виды расчета будут зависеть от базы за тот месяц, в котором была введена запись. Если есть та или другая зависимости от базы, то необходимо выбрать базовые планы видов расчета. То есть это те ПВР виды расчета которых смогут использоваться как базовые.

После этого, в план видов расчета можно добавлять виды расчета и настраивать их. При настройке вида расчета нужно настроить Базовые, Ведущие, Вытесняющие виды расчета. Пример настройки вида расчета приведен на рисунке 2.

Рисунок 2

На закладке «Базовые виды расчетов» настраивается список видов расчета, которые будут включаться в базу при расчете текущего вида расчета. Соответственно, виды расчета, не вошедшие в базу при расчете данного вида расчета учитываться не будут. В списке ведущих видов расчета указывается список тех видов расчета, при изменении которых будет требоваться перерасчет данного вида расчета. Ну и в списке вытесняющих видов указываются те виды расчета, которые будут вытеснять данный вид расчета, если будет конкуренция по периоду действия у видов расчета.
Далее необходимо настроить регистры расчета. Здесь каждому регистру расчета должен соответствовать один план видов расчета, но один ПВР может соответствовать нескольким регистрам расчета. Основные настройки регистров расчета выполняются на закладке Основные диалога редактирования объекта. Пример настроек приведен на рисунке 3

Рисунок 3

Свойство «План видов расчета» - здесь указывается то, какой ПВР будет соответствовать нашему регистру расчета.
Свойство «Период действия» - указывается флаг, если регистр расчета будет поддерживать период действия видов расчета, то есть те виды расчета, которые являются периодическими. При установленном флаге, у записи регистра расчета добавляются свойства «Период действия начало» и «Период действия конец».
Свойство «График работы» - если стоит флаг периода действия, то становится доступным это свойство. Указываем регистр сведений (непериодический), в котором будет регистрироваться норма времени за конкретный день календаря.
Свойство «Значение графика» - указывается ресурс регистра сведений Графики работы. По этому значению система сможет вычислить данные базы. То есть система сможет вычислить, сколько сотрудник должен отработать в тот или иной день.
Свойство «Дата графика» - указывается измерение с типом Дата. По этому измерению система сможет понять к какой дате относится рабочий/не рабочий день.
Свойство «Базовый период» - указывается, если регистр расчета будет поддерживать базовый период видов расчета. Если флаг установлен, то у записи регистра расчета появляются дополнительные свойства «Базовый период начало» и «Базовый период конец».
Свойство «Периодичность» - указывается периодичность регистра расчета.
На вкладке Данные настраиваются измерения, ресурсы и реквизиты регистра расчета. Пример настройки приведен на рисунке 4

Рисунок 4

Измерениями задаются разрезы, в которых будут храниться записи в регистре расчета. Ресурсы – это вычисляемые значения, фактический результат расчета вида расчета. Реквизиты – здесь указываются дополнительные сведения о записи регистра расчета. Например, в реквизите можно хранить плановые значения видов расчета.
Кроме этого, необходимо указать документы-регистраторы для регистра расчета иначе система не даст сохранить конфигурацию базы данных. Регистраторы задаются на одноименной закладке диалога редактирования объекта конфигурации.
После выполненных настроек, необходимо в обработчике проведения документа-регистратора описать алгоритм формирования движений по регистрам расчета. Пример алгоритма формирования движений может быть такой:

Процедура ОбработкаПроведения(Отказ, Режим) Движения.ОсновныеНачисления.Записывать = Истина; Для Каждого ТекСтрокаНачисления Из Начисления Цикл Движение = Движения.ОсновныеНачисления.Добавить(); Движение.Сторно = ТекСтрокаНачисления.Сторно; Движение.ВидРасчета = ТекСтрокаНачисления.ВидРасчета; Движение.ПериодДействияНачало = ТекСтрокаНачисления.ДатаНачала; Движение.ПериодДействияКонец = КонецДня(ТекСтрокаНачисления.ДатаОкончания); Движение.ПериодРегистрации = ПериодРегистрации; Движение.Сотрудник = ТекСтрокаНачисления.Сотрудник; Движение.Подразделение = ТекСтрокаНачисления.Подразделение; Движение.ТипГрафика = ТекСтрокаНачисления.ТипГрафика; Движение.Размер = ТекСтрокаНачисления.Размер; КонецЦикла; Движения.Записать();//записываем рабочий набор записей РассчитатьНачисления(Отказ); КонецПроцедуры

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

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

В данном примере будут рассчитываться начисления ОкладПоДням, а для того, чтобы рассчитывались и другие виды расчета, необходимо дописать соответствующее условие и формулу. Пример заполненного и рассчитанного документа начисления зарплаты приведен на рисунке 5.

Рисунок 5

Таким образом и происходит расчет зарплаты на платформе 1С:Предприятие 8. Здесь приведен самый простой случай, без всяких наворотов. Понятное дело, что в типовых решениях алгоритмы более объемные, развесистые и универсальные. В этой статье я показал основу работы с объектами платформы для возможности расчета зарплаты.

Спасибо за внимание! Если есть вопросы, постараюсь на них ответить.​