Как использовать регистры расчета в 1С 8.3
Регистры расчета 1С 8.3 — объект системы, предназначенный для хранения результатов сложных периодических расчетов заработной платы.
Регистр расчета — достаточно специфический объект системы в силу его предназначения. Порою программисты 1С с достаточно большим опытом в сфере решения бухгалтерский задач и задач оперативного учета никогда не имели опыта с решением задач сложных периодических расчетов.
Содержание
Свойства и настройка регистра расчета в 1С
Регистры расчета отличаются изобилием новых свойств, которые Вы не увидите в других объектах системы:
Прежде всего, для регистра расчета обязательно указание план видов расчета, в котором хранится информация о видах начислений/удержаний.
Период действия — флаг, который указывает поддержку периодичности регистра расчета. Отвечает за активность стандартных реквизитов ПериодДействия, ПериодДействияНачало, ПериодДействияКонец.
Если вы только начинаете программировать в 1С или просто хотите систематизировать свои знания - попробуйте Школу программирования 1С нашего друга Владимира Милькина. Пошаговые и понятные уроки даже для новичка с поддержкой учителя.
Попробуйте бесплатно по ссылке >>
Базовой период — флаг, отвечающий за использование механизма расчета на основе базовых периодов. База для расчета — расчет другого вида, на основе которого рассчитывается текущая запись. Отвечает за активность стандартных реквизитов БазовыйПериодКонец и БазовыйПериодНачало.
Периодичность — реквизит, отображающий периодичность расчетов. В зависимости от этого реквизита устанавливается значение реквизита ПериодРегистрации на начало расчетного периода.
График регистра расчета 1С 8
График — ссылка на регистр сведений, хранящий в себе информацию графика. Значение графика — поле числового типа, где хранится значение для даты. Дата графика — измерение регистра сведений с типом дата, в котором отображается дата для значения графика.
Пример графика, хранящего в себе информацию в часах:
- Дата — 04.05.2013 Значение — 0
- Дата — 05.05.2013 Значение — 0
- Дата — 06.05.2013 Значение — 8
- Дата — 07.05.2013 Значение — 8
- Дата — 08.05.2013 Значение — 8
- Дата — 09.05.2013 Значение — 0
Из графика ясно, что 4, 5, 9 число — выходной, а 6, 7, 8 — восьмичасовые рабочие дни.
Заполнение графика в системе производится обычно произвольно обработкой. Пример программного кода процедуры заполнения графика:
Процедура ЗаполнитьГрафик(ДатаНачала, ДатаОкончания) Экспорт Набор = РегистрыСведений.ГрафикиРаботы.СоздатьНаборЗаписей(); Набор.Прочитать(); Набор.Очистить(); ЧислоСекундВСутках = 86400; ТекДата = ДатаНачала; Пока ТекДата <= ДатаОкончания Цикл Запись = Набор.Добавить(); Запись.Дата = ТекДата; Если ДеньНедели(ТекДата) = 7 ИЛИ ДеньНедели(ТекДата) = 6 Тогда Запись.Значение = 0; Иначе Запись.Значение = 8; КонецЕсли; ТекДата = ТекДата + ЧислоСекундВСутках; КонецЦикла; Набор.Записать(); КонецПроцедуры
Такая процедура заполнит рабочие дни значением 8, а выходные — 0.
Измерение и реквизит регистра расчета можно связать со значением графика. Это необходимо для получения данных в нужных разрезах. Например, в графике работы значения могут быть указаны в разрезе сотрудников. Т.е. сколько сотрудников, столько и графиков. Для правильного расчета необходимо будет указать связь с графиком в палитре свойств регистра расчета:
Пример создания записей в регистр расчета 1С
Настоятельно рекомендуется все сложные периодические расчеты разбивать на 2 этапа: подготовка таблиц на основе документа и расчет данных на основе этой таблицы, выполняемый на сервере.
Рассмотрим типичный способ создания записей регистра расчета.
Первый этап — формирование предварительных записей:
Процедура ОбработкаПроведения(Отказ, РежимПроведения) Движения.ОсновныеНачисления.Записывать = Истина; Движения.ДополнительныеНачисления.Записывать = Истина; Запрос = Новый Запрос; Запрос.Текст = ".... // запрос к ТЧ основных начислений"; Запрос.УстановитьПараметр("Ссылка", Ссылка); Запрос.УстановитьПараметр("ПериодРегистрации" , ПериодРегистрации); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл Движение = Движения.ОсновныеНачисления.Добавить(); ЗаполнитьЗначенияСвойств(Движение, Выборка); Движение.ПериодРегистрации = ПериодРегистрации; Если Выборка.ВидРасчета = ПланыВидовРасчета.ОсновныеНачисления.Больничный Тогда Движение.БазовыйПериодКонец = ПериодРегистрации - 1; Движение.БазовыйПериодНачало = ДобавитьМесяц(ПериодРегистрации, -1); ИначеЕсли Выборка.ВидРасчета = ПланыВидовРасчета.ОсновныеНачисления.Оклад Тогда Движение.Параметр = Выборка.Оклад; КонецЕсли; КонецЦикла; Запрос = Новый Запрос; Запрос.Текст = "".... // запрос к ТЧ дополнительных начислений"; Запрос.УстановитьПараметр("Ссылка", Ссылка); Запрос.УстановитьПараметр("ПериодРегистрации" , ПериодРегистрации); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл Движение = Движения.ДополнительныеНачисления.Добавить(); ЗаполнитьЗначенияСвойств(Движение, Выборка); Движение.ПериодРегистрации = ПериодРегистрации; Если Выборка.ВидРасчета = ПланыВидовРасчета.ДополнительныеНачисления.ПремияПроцентом Тогда Движение.БазовыйПериодКонец = КонецМесяца(ПериодРегистрации); Движение.БазовыйПериодНачало = ПериодРегистрации; ИначеЕсли Выборка.ВидРасчета = ПланыВидовРасчета.ДополнительныеНачисления.Компенсация Тогда Движение.Параметр = Выборка.Компенсация; КонецЕсли; КонецЦикла; Движения.ОсновныеНачисления.Записать(); Движения.ДополнительныеНачисления.Записать(); РасчетЗП.Расчитать(Ссылка,Движения.ОсновныеНачисления,Движения.ДополнительныеНачисления); КонецПроцедуры
В этой обработке проведения мы подготовили предварительные записи для будущей обработки, записали их и передали для расчета в процедуру общего модуля «РасчетЗП» с директивой выполнения на сервере.
Второй этап — сам расчет:
Процедура Расчитать(Ссылка, Основные, Дополнительные) ЭКСПОРТ МассивОсновныхВР = Ссылка.ОсновныеНачисления.ВыгрузитьКолонку("ВидРасчета"); МассивДополнительныхВР = Ссылка.ДополнительныеНачисления.ВыгрузитьКолонку("ВидРасчета"); Измерения = Новый Массив; Измерения.Добавить("Подразделение"); Измерения.Добавить("Сотрудник"); Если МассивОсновныхВР.Найти(ПланыВидовРасчета.ОсновныеНачисления.Оклад) <> Неопределено Тогда Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ОсновныеНачисленияДанныеГрафика.ЧасыФактическийПериодДействия, | ОсновныеНачисленияДанныеГрафика.ЧасыБазовыйПериод, | ОсновныеНачисленияДанныеГрафика.НомерСтроки, | ОсновныеНачисленияДанныеГрафика.Параметр, | ОсновныеНачисленияДанныеГрафика.ЧасыПериодДействия, | ОсновныеНачисленияДанныеГрафика.ЧасыПериодРегистрации |ИЗ | РегистрРасчета.ОсновныеНачисления.ДанныеГрафика( | Регистратор = &Ссылка | И ВидРасчета = ЗНАЧЕНИЕ(ПланВидовРасчета.ОсновныеНачисления.Оклад)) КАК ОсновныеНачисленияДанныеГрафика"; Запрос.УстановитьПараметр("Ссылка", Ссылка); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл Запись = Основные[Выборка.НомерСтроки - 1]; Запись.Сумма = Выборка.ЧасыФактическийПериодДействия / Выборка.ЧасыПериодДействия * Выборка.Параметр; КонецЦикла; Основные.Записать(, Истина); КонецЕсли; Если МассивОсновныхВР.Найти(ПланыВидовРасчета.ОсновныеНачисления.Больничный) <> Неопределено Тогда Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ОсновныеНачисленияДанныеГрафика.НомерСтроки, | ОсновныеНачисленияБазаОсновныеНачисления.СуммаБаза, | ОсновныеНачисленияДанныеГрафика.ЧасыБазовыйПериод, | ОсновныеНачисленияДанныеГрафика.ЧасыБолезниФактическийПериодДействия |ИЗ | РегистрРасчета.ОсновныеНачисления.ДанныеГрафика( | Регистратор = &Ссылка | И ВидРасчета = ЗНАЧЕНИЕ(ПланВидовРасчета.ОсновныеНачисления.Больничный)) КАК ОсновныеНачисленияДанныеГрафика | ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаОсновныеНачисления(&Измерения, &Измерения, , Регистратор = &Ссылка) КАК ОсновныеНачисленияБазаОсновныеНачисления | ПО ОсновныеНачисленияДанныеГрафика.НомерСтроки = ОсновныеНачисленияБазаОсновныеНачисления.НомерСтроки"; Запрос.УстановитьПараметр("Ссылка", Ссылка); Запрос.УстановитьПараметр("Измерения", Измерения); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл Запись = Основные[Выборка.НомерСтроки - 1]; Запись.Сумма = Выборка.ЧасыБолезниФактическийПериодДействия / Выборка.ЧасыБазовыйПериод * Выборка.СуммаБаза; КонецЦикла; Основные.Записать(, Истина); КонецЕсли; Если МассивДополнительныхВР.Найти(ПланыВидовРасчета.ДополнительныеНачисления.Компенсация) <> Неопределено Тогда Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ДополнительныеНачисления.НомерСтроки, | ДополнительныеНачисления.ВидРасчета, | ДополнительныеНачисления.БазовыйПериодНачало, | ДополнительныеНачисления.БазовыйПериодКонец, | ДополнительныеНачисления.Активность, | ДополнительныеНачисления.Сторно, | ДополнительныеНачисления.Подразделение, | ДополнительныеНачисления.Сотрудник, | ДополнительныеНачисления.Сумма, | ДополнительныеНачисления.Параметр |ИЗ | РегистрРасчета.ДополнительныеНачисления КАК ДополнительныеНачисления |ГДЕ | ДополнительныеНачисления.Регистратор = &Ссылка | И ДополнительныеНачисления.ВидРасчета = ЗНАЧЕНИЕ(ПланВидовРасчета.ДополнительныеНачисления.Компенсация)"; Запрос.УстановитьПараметр("Ссылка", Ссылка); Запрос.УстановитьПараметр("Измерения", Измерения); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл Запись = Дополнительные[Выборка.НомерСтроки - 1]; Запись.Сумма = Выборка.Параметр; КонецЦикла; Дополнительные.Записать(, Истина); КонецЕсли; Если МассивДополнительныхВР.Найти(ПланыВидовРасчета.ДополнительныеНачисления.ПремияПроцентом) <> Неопределено Тогда Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ДополнительныеНачисления.НомерСтроки, | (ЕСТЬNULL(ДополнительныеНачисленияБазаОсновныеНачисления.СуммаБаза, 0) + ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисления.СуммаБаза, 0)) * ДополнительныеНачисления.Параметр / 100 КАК Сумма, | ДополнительныеНачисления.БазовыйПериодНачало, | ДополнительныеНачисления.БазовыйПериодКонец |ИЗ | РегистрРасчета.ДополнительныеНачисления КАК ДополнительныеНачисления | ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаОсновныеНачисления(&Измерения, &Измерения, , Регистратор = &Ссылка) КАК ДополнительныеНачисленияБазаОсновныеНачисления | ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаОсновныеНачисления.НомерСтроки | ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(&Измерения, &Измерения, , Регистратор = &Ссылка) КАК ДополнительныеНачисленияБазаДополнительныеНачисления | ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаДополнительныеНачисления.НомерСтроки |ГДЕ | ДополнительныеНачисления.Регистратор = &Ссылка | И ДополнительныеНачисления.ВидРасчета = ЗНАЧЕНИЕ(ПланВидовРасчета.ДополнительныеНачисления.ПремияПроцентом)"; Запрос.УстановитьПараметр("Ссылка", Ссылка); Запрос.УстановитьПараметр("Измерения", Измерения); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл Запись = Дополнительные[Выборка.НомерСтроки - 1]; Запись.Сумма = Выборка.Сумма; КонецЦикла; Дополнительные.Записать(, Истина); КонецЕсли; КонецПроцедуры
Обратите внимание на параметры конструкции Дополнительные.Записать(, Истина). Установленный параметр номер 2 -ТолькоЗапись позволяет оптимизировать запись набора записей путём отключения пересчета итогов при повторной записи в общем модуле.
Если Вы начинаете изучать 1С программирование, рекомендуем наш бесплатный курс (не забудьте подписаться на YouTube — регулярно выходят новые видео):
К сожалению, мы физически не можем проконсультировать бесплатно всех желающих, но наша команда будет рада оказать услуги по внедрению и обслуживанию 1С. Более подробно о наших услугах можно узнать на странице Услуги 1С или просто позвоните по телефону +7 (499) 350 29 00. Мы работаем в Москве и области.
СПРОСИТЕ в комментариях!
Jes:
Простите за вопрос, но почему нельзя при предварительной записи наборов в обработке проведения просто пройтись циклами по табличным частям ОН и ДН и записать наборы, а вместо этого идут запросы к табличным частям и потом опять же обход выборки в цикле?
Кирилл:
Честно говоря сейчас уже не помню почему так сделал 🙂
Сейчас смотрю и думаю — вроде бы действительно мог бы сделать просто построчную запись. Возможно, в запросе я что то проверял еще дополнительно, какие то отборы накладывал.
Аноним:
Вопрос: когда в рег.расчета по измерению Сотрудник ставится галка Базовое? это нужно только для перерасчетов? или эта галка нужна, если по этому измер.Сотрудник — будет потом расчет Базы?
Спасибо.
Dmtry:
Текст запросов по основным и дополнительным начисления можно показать?