Почему РезультатБаза возвращает 0 при расчете премии в 1С и как это исправить?

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

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

Анализируем механизм получения расчетной базы

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

1. Проверка настроек Плана видов расчета (ПВР)

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

  1. Откроем План видов расчета «Дополнительные начисления».
  2. Перейдем к виду расчета Премия на вкладку «Расчет».
  3. В списке «Базовые виды расчета» проверим наличие вида расчета Подарок (в ПВР «Дополнительные начисления») и Оклад (в ПВР «Основные начисления»).
  4. Убедимся, что установлен флаг «Зависит от базы».

Важный нюанс: Если вы добавили «Подарок» в список базовых для «Премии», но не обновили базу данных, запрос не увидит связи.

2. Соответствие периодов регистрации и базовых периодов

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


Если Движение2.ВидРасчета = ПланыВидовРасчета.ДополнительныеНачисления.Премия Тогда
    ПрошлыйМесяц = ДобавитьМесяц(Дата, -1);
    Движение2.БазовыйПериодНачало = НачалоМесяца(ПрошлыйМесяц);
    Движение2.БазовыйПериодКонец = КонецМесяца(ПрошлыйМесяц);
КонецЕсли;

Если для Премии мы устанавливаем базовый период за прошлый месяц, то и запись Подарок должна иметь ПериодРегистрации, попадающий в этот интервал. Если «Подарок» начисляется в текущем месяце (тем же документом), а «Премия» ищет базу в прошлом — результат закономерно будет равен 0.

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

3. Использование двухпроходного алгоритма записи

Рассмотрим критическую ошибку: попытку прочитать базу записей, которые еще не были зафиксированы в базе данных с заполненным результатом. Механизм расчета в 1С требует соблюдения определенной последовательности (так называемый алгоритм «Специалиста»):

  1. Первый проход: Записываем в регистр те начисления, результат которых уже известен (фиксированные суммы, оклады). Поле Результат должно быть заполнено и Записывать = Истина.
  2. Запись набора: Вызываем метод Движения.ДополнительныеНачисления.Записать(). Только после этого данные физически попадают в таблицы базы данных, и виртуальные таблицы смогут их обработать.
  3. Второй проход: Выполняем запрос к виртуальным таблицам База. На этом этапе мы получаем суммы ранее записанных начислений.
  4. Расчет и повторная запись: Рассчитываем результат зависимых начислений (премии) и снова записываем движения.

Проанализируем фрагмент кода автора. Автор вызывает Движения.ДополнительныеНачисления.Записать() перед запросом — это верно. Однако нужно убедиться, что для записи Подарок ресурс Результат заполнен до этой записи:


Если Движение2.ВидРасчета = ПланыВидовРасчета.ДополнительныеНачисления.Подарок Тогда
    Движение2.Результат = ТекСтрокаНачисленияДоп.Размер;
КонецЕсли;

4. Анализ параметров виртуальной таблицы в запросе

Посмотрим на структуру запроса. Часто ошибка кроется в неверно переданных измерениях или фильтрах.


ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(
    &МассивИзмерений,
    &МассивИзмерений,
    ,
    ВидРасчета = &Премия И Регистратор = &Ссылка) КАК ДополнительныеНачисленияБазаДополнительныеНачисления

Разберем параметры:

5. Проверка функции ЕСТЬNULL

В запросе используется ЕСТЬNULL(..., 0). Это правильно с точки зрения программирования, чтобы избежать ошибок при расчете. Однако, если БазаДопНач всегда 0, это симптом того, что соединение с виртуальной таблицей не нашло подходящих записей.

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

Резюме для исправления

Для успешного расчета выполним следующие действия:

  1. Проверим, что Подарок указан в Базовых видах расчета для Премии.
  2. Убедимся, что ПериодРегистрации Подарка попадает в БазовыйПериод Премии.
  3. Удостоверимся, что в первом цикле (до записи) поле Результат для Подарка заполнено значением ТекСтрока.Размер.
  4. Проверим, что массив измерений содержит все ключевые разрезы (Сотрудник, ФизЛицо и т.д.), и они заполнены в обеих строках.
  5. Выполним Движения.Записать() строго перед выполнением запроса.

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

← На главную