Почему запрос к регистру расчета возвращает NULL и нулевые значения

Программист 1С v8.3 (Управляемые формы) Управленческий учет IT и автоматизация бизнеса
← На главную

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

Причина 1. Некорректное время в границах периода действия

Проанализируем механику работы виртуальных таблиц регистра расчета, таких как ДанныеГрафика или ФактическийПериодДействия. Эти таблицы соединяются с регистром сведений графика по периодам действия записей. Если дата начала периода действия (ПериодДействияНачало) записана в регистр со временем конца дня (например, 23:59:59 вместо 00:00:00), виртуальная таблица при подневной периодичности не захватывает расчетные дни графика или считает интервал нулевым. В итоге соединение возвращает NULL.

Разберем, как правильно формировать движения перед записью в регистр расчета. Начальную границу необходимо всегда приводить к началу дня с помощью функции НачалоДня(), а конечную — к концу дня через КонецДня():


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

Причина 2. Незаполненный график или неверная связь по измерениям

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

Для корректного соединения проверим настройки метаданных регистра расчета:

  1. В свойствах регистра расчета должно быть заполнено свойство График (ссылка на регистр сведений), Значение графика (числовой ресурс регистра сведений) и Дата графика (измерение даты).
  2. Если в регистре сведений есть дополнительные измерения (например, ГрафикРаботы), в регистре расчета должно присутствовать соответствующее измерение или реквизит, у которого в свойстве Связь с графиком указано это измерение графика.
  3. Перед расчетом убедимся, что регистр сведений графика фактически заполнен на весь расчетный период.

Причина 3. Отсутствие обработки NULL в математических выражениях запроса

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

Разберем пример запроса к виртуальной таблице ДанныеГрафика с обязательной защитой от NULL через функцию ЕСТЬNULL() и проверкой деления на ноль:


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

Чек-лист для проверки и устранения ошибки

  1. Проверяем время в периодах: поля ПериодДействияНачало и БазовыйПериодНачало должны быть строго приведены к началу дня (00:00:00).
  2. Проверяем данные графика: открываем регистр сведений графика и убеждаемся, что на весь период действия начисления есть записи с ненулевыми рабочими часами/днями.
  3. Проверяем привязку разрезов графика: сверяем свойство Связь с графиком в измерениях регистра расчета.
  4. Оборачиваем поля в ЕСТЬNULL: все числовые ресурсы и поля графика в тексте запроса защищаем от пустых значений.
← На главную