Регистры расчета 1С — объекты метаданных для периодических расчётов: зарплаты, аренды, коммунальных платежей. Каждая запись регистра — это вид расчета (оклад, премия, командировка) с периодом регистрации, периодом действия и результатом. Главное отличие от регистров накопления — платформа сама учитывает взаимное влияние записей: одни виды расчета вытесняют другие по периоду действия, а третьи зависят от базы — результатов других видов за прошлые периоды.

В статье разберём теорию на понятных примерах, а затем соберём учебную конфигурацию: план видов расчета, график работы, документ начисления и расчёт оклада пропорционально отработанным часам через виртуальную таблицу ДанныеГрафика. Это основа, на которой построен расчёт в 1С:ЗУП, и без неё сложно дорабатывать типовые механизмы.

Как устроены регистры расчета 1С

Регистр расчета работает в паре с планом видов расчета (ПВР). ПВР хранит виды расчета и правила их взаимодействия, регистр — результаты. Один ПВР может использоваться несколькими регистрами, но у регистра расчета — только один ПВР.

ПонятиеЧто этоПример
Период регистрацииРасчётный период, в котором сделана записьАпрель
Период действияИнтервал, к которому относится начисление1–30 апреля
Фактический период действияПериод действия после вытеснения1–9 и 21–30 апреля
Базовый периодПериод, за который берётся база для зависимого видаПрошлые три месяца

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

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

Сотрудник с окладом на апрель (1–30) уехал в командировку с 10 по 20 апреля. Если в ПВР для вида «Оклад» указать «Командировку» как вытесняющий вид, платформа вырежет из периода оклада 11 дней. Фактический период действия оклада — 1–9 и 21–30 апреля, 19 дней. Оплату за эти дни и считают по окладу, а командировку — по среднему заработку.

Регистры расчета 1С: командировка вытесняет часть периода действия оклада
Регистры расчета 1С: командировка вытесняет часть периода действия оклада

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

Зависимость по базовому периоду

Премия 10% от оклада за период командировки, 10–20 апреля. Оклад 60 000 ₽, в месяце 30 дней: дневная ставка 2 000 ₽, база за 11 дней — 22 000 ₽, премия — 2 200 ₽. Здесь «Оклад» — базовый вид для «Премии», а 10–20 апреля — базовый период. Платформа умеет вернуть такую базу через виртуальную таблицу База<ИмяРегистра>.

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

Шаг 1. План видов расчета

Создаём ПВР ОсновныеНачисления. На вкладке «Расчет»:

  • ставим флаг «Использует период действия» — виды расчета получают протяжённость во времени и становится доступно вытеснение;
  • «Зависимость от базы» пока оставляем «Не зависит» — к базе вернёмся при расчёте премий.

Через «Предопределенные» добавляем вид Оклад. У предопределённого вида появляются вкладки:

  • Вытесняющие — виды того же ПВР, которые вытесняют оклад (например, Командировка);
  • Ведущие — виды, при изменении которых оклад нужно пересчитать;
  • Базовые — появится, если для ПВР включена зависимость от базы.

Премии и штрафы обычно выносят во второй ПВР без периода действия: у них нет протяжённости во времени.

Шаг 2. График работы

Для расчёта пропорционально отработанному времени нужен график — норма часов по датам:

  1. Справочник Графики (пятидневка, шестидневка, сменный) — структура по умолчанию.
  2. Регистр сведений ГрафикиРаботы: непериодический, независимый. Измерения Дата (тип Дата) и График (СправочникСсылка.Графики), ресурс КоличествоЧасов (Число).

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

Шаг 3. Документ и регистр расчета

Документ НачислениеЗарплаты с табличной частью ОсновныеНачисления: Сотрудник, ВидРасчета (ПланВидовРасчетаСсылка.ОсновныеНачисления), ДатаНачала, ДатаОкончания, График, Размер. Оперативное проведение запрещаем — периодические расчёты в реальном времени не ведутся.

Регистр расчета ОсновныеНачисления:

СвойствоЗначениеЗачем
План видов расчетаОсновныеНачисленияИсточник видов и правил
Период действияИстинаПоявляются ПериодДействия, ПериодДействияНачало, ПериодДействияКонец и вытеснение
ПериодичностьМесяцПериод регистрации приводится к месяцу
ГрафикРС ГрафикиРаботыНорма времени
Значение графикаРесурс КоличествоЧасовЧто суммировать
Дата графикаИзмерение ДатаПо какой дате связывать

Структура:

  • измерение Сотрудник — по нему работают вытеснение и база; флаг «Базовое» нужен, если регистр будет базой для других;
  • ресурс Сумма — результат;
  • реквизит График с заполненным свойством «Связь с графиком» = измерение График регистра ГрафикиРаботы. Без этой связи платформа не поймёт, какой график брать, и данные графика будут пустыми;
  • реквизит Параметр — размер оклада.

Регистратор — документ НачислениеЗарплаты.

Важно: если указать ПВР с периодом действия, а у регистра флаг «Период действия» снять, виды расчета будут работать как непротяжённые.

Шаг 4. Проведение: записать, потом рассчитать

1С
Процедура ОбработкаПроведения(Отказ, РежимПроведения)

	Движения.ОсновныеНачисления.Записывать = Истина;
	ПериодРегистрации = НачалоМесяца(Дата);

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

	// Сначала записываем: виртуальные таблицы видят только записанные данные.
	Движения.ОсновныеНачисления.Записать();

	РасчетЗарплаты.РассчитатьОклад(Ссылка, Движения.ОсновныеНачисления);

КонецПроцедуры

Шаг 5. Расчёт оклада через ДанныеГрафика

Поскольку у регистра заданы график, значение и дата графика, появляется виртуальная таблица ДанныеГрафика. Её поля строятся из имени ресурса графика: КоличествоЧасовПериодДействия — норма за период действия, КоличествоЧасовФактическийПериодДействия — норма за фактический период после вытеснения.

Код — в серверном общем модуле РасчетЗарплаты. Вместо поиска по выборке с постоянным сбросом я кладу результат запроса в соответствие по номеру строки — так быстрее и нагляднее.

1С
// Рассчитывает оклад пропорционально отработанным по графику часам.
Процедура РассчитатьОклад(Регистратор, НаборЗаписей) Экспорт

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

	ДанныеПоСтрокам = Новый Соответствие;
	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		ДанныеПоСтрокам.Вставить(Выборка.НомерСтроки,
			Новый Структура("Оклад, ЧасовНорма, ЧасовФакт", Выборка.Оклад, Выборка.ЧасовНорма, Выборка.ЧасовФакт));
	КонецЦикла;

	Для Каждого Запись Из НаборЗаписей Цикл
		Данные = ДанныеПоСтрокам[Запись.НомерСтроки];
		Если Данные = Неопределено Или Данные.ЧасовНорма = 0 Тогда
			Продолжить;
		КонецЕсли;
		Запись.Сумма = Окр(Данные.Оклад * Данные.ЧасовФакт / Данные.ЧасовНорма, 2);
	КонецЦикла;

	НаборЗаписей.Записать(Истина);

КонецПроцедуры
Регистры расчета 1С: расчёт суммы по норме и факту часов из графика работы
Регистры расчета 1С: расчёт суммы по норме и факту часов из графика работы

Проверка: заполните график пятидневкой по 8 часов, проведите документ с окладом на весь месяц — сумма равна окладу. Добавьте командировку с вытеснением — фактические часы уменьшатся, и оклад пересчитается пропорционально.

Типичные ошибки

  • Расчёт до записи. ДанныеГрафика возвращает пусто, если набор ещё не записан. Записывайте, потом считайте.
  • Не заполнена «Связь с графиком». Норма и факт часов — NULL, сумма нулевая. Отсюда и ЕСТЬNULL в запросе.
  • Пустые дни графика. Если в графике нет записей за месяц, норма 0 — проверяйте деление.
  • Конец периода без времени. ПериодДействияКонец должен быть концом дня, иначе последний день выпадет из расчёта.
  • Вытесняющий вид из другого ПВР. Вытеснение работает только в пределах одного ПВР; ведущие виды — между ПВР.
Регистр расчета не считает за вас зарплату. Он даёт периоды, вытеснение и базу, а сумму вы рассчитываете кодом — после того как движения записаны.

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

Коротко

  • Регистры расчета 1С хранят результаты периодических расчётов, а правила — в плане видов расчета.
  • Вытеснение по периоду действия формирует фактический период, зависимость по базе — расчёт от результатов других видов.
  • Для расчёта по времени свяжите регистр с графиком и заполните «Связь с графиком» у реквизита.
  • Сначала записывайте движения, затем читайте ДанныеГрафика и записывайте рассчитанные суммы.