При разработке подсистем начисления заработной платы и сложных периодических расчетов на платформе 1С разработчики часто сталкиваются с ситуацией, когда алгоритм расчета в общем модуле падает с ошибкой несовпадения типов или возвращает нулевые результаты. Выясним причину такого поведения и разберем по шагам, как правильно настроить движения регистра расчета и запросы для получения данных графика.
Проанализируем механику работы виртуальных таблиц регистра расчета, таких как ДанныеГрафика или ФактическийПериодДействия. Эти таблицы соединяются с регистром сведений графика по периодам действия записей. Если дата начала периода действия (ПериодДействияНачало) записана в регистр со временем конца дня (например, 23:59:59 вместо 00:00:00), виртуальная таблица при подневной периодичности не захватывает расчетные дни графика или считает интервал нулевым. В итоге соединение возвращает NULL.
Разберем, как правильно формировать движения перед записью в регистр расчета. Начальную границу необходимо всегда приводить к началу дня с помощью функции НачалоДня(), а конечную — к концу дня через КонецДня():
Движение = Движения.ОсновныеНачисления.Добавить();
Движение.ВидРасчета = СтрокаТабличнойЧасти.ВидРасчета;
Движение.ПериодРегистрации = НачалоМесяца(Дата);
Движение.ПериодДействияНачало = НачалоДня(СтрокаТабличнойЧасти.ДатаНачала);
Движение.ПериодДействияКонец = КонецДня(СтрокаТабличнойЧасти.ДатаОкончания);
Движение.БазовыйПериодНачало = НачалоДня(СтрокаТабличнойЧасти.ДатаНачала);
Движение.БазовыйПериодКонец = КонецДня(СтрокаТабличнойЧасти.ДатаОкончания);
Движение.График = СтрокаТабличнойЧасти.ГрафикРаботы;
Посмотрим на структуру регистра сведений, который выступает графиком для регистра расчета. Виртуальная таблица выполняет левое соединение с записями регистра сведений. Если для указанного периода или значения разреза (например, графика работы, подразделения или кружка) в регистре сведений нет строк с датами, поля нормы и факта вернут значение NULL.
Для корректного соединения проверим настройки метаданных регистра расчета:
ГрафикРаботы), в регистре расчета должно присутствовать соответствующее измерение или реквизит, у которого в свойстве Связь с графиком указано это измерение графика.Рассмотрим поведение языка запросов 1С при арифметических операциях. Если к значению NULL прибавить, вычесть или умножить число, результатом выражения всегда будет NULL. При попытке передать такое нечисловое значение во встроенный язык для дальнейших вычислений платформа выдает ошибку.
Разберем пример запроса к виртуальной таблице ДанныеГрафика с обязательной защитой от NULL через функцию ЕСТЬNULL() и проверкой деления на ноль:
ВЫБРАТЬ
Рег.Сотрудник КАК Сотрудник,
Рег.ВидРасчета КАК ВидРасчета,
ЕСТЬNULL(Рег.ДанныеГрафикаПериодДействия, 0) КАК ОтработаноДней,
ЕСТЬNULL(Рег.ДанныеГрафикаБазовыйПериод, 0) КАК НормаДней,
ЕСТЬNULL(Рег.Размер, 0) КАК Оклад,
ВЫБОР
КОГДА ЕСТЬNULL(Рег.ДанныеГрафикаБазовыйПериод, 0) = 0
ТОГДА 0
ИНАЧЕ ЕСТЬNULL(Рег.Размер, 0) * ЕСТЬNULL(Рег.ДанныеГрафикаПериодДействия, 0) / Рег.ДанныеГрафикаБазовыйПериод
КОНЕЦ КАК Результат
ИЗ
РегистрРасчета.ОсновныеНачисления.ДанныеГрафика(
&УсловиеРегистратор,
ВЫРАЗИТЬ(График КАК Справочник.ГрафикиРаботы)
) КАК Рег
ПериодДействияНачало и БазовыйПериодНачало должны быть строго приведены к началу дня (00:00:00).