При разработке механизмов расчета заработной платы в 1С:Предприятии 8.3 программисты часто сталкиваются с ситуацией, когда виртуальная таблица БазаДополнительныеНачисления или БазаОсновныеНачисления возвращает нулевые значения в поле РезультатБаза. Особенно это актуально при попытке рассчитать премию, база которой складывается из начислений, введенных в этом же документе (например, фиксированной суммы подарка). Разберем по шагам, почему это происходит и как правильно настроить систему для корректного расчета.
Для того чтобы система смогла рассчитать базу, недостаточно просто написать запрос к виртуальной таблице регистра расчета. Виртуальная таблица — это сложный механизм, который опирается на настройки метаданных и физически записанные данные в регистре. Рассмотрим основные причины, по которым база может быть пустой.
Первым делом проанализируем настройки метаданных. Если вид расчета Премия не знает, что он зависит от вида расчета Подарок, виртуальная таблица базы всегда будет возвращать 0. Выполним следующие действия:
Премия на вкладку «Расчет».Подарок (в ПВР «Дополнительные начисления») и Оклад (в ПВР «Основные начисления»).Важный нюанс: Если вы добавили «Подарок» в список базовых для «Премии», но не обновили базу данных, запрос не увидит связи.
Разберем логику периодов. Чтобы запись Подарок попала в базу записи Премия, должны соблюдаться условия пересечения периодов. Проанализируем программный код формирования движений:
Если Движение2.ВидРасчета = ПланыВидовРасчета.ДополнительныеНачисления.Премия Тогда
ПрошлыйМесяц = ДобавитьМесяц(Дата, -1);
Движение2.БазовыйПериодНачало = НачалоМесяца(ПрошлыйМесяц);
Движение2.БазовыйПериодКонец = КонецМесяца(ПрошлыйМесяц);
КонецЕсли;
Если для Премии мы устанавливаем базовый период за прошлый месяц, то и запись Подарок должна иметь ПериодРегистрации, попадающий в этот интервал. Если «Подарок» начисляется в текущем месяце (тем же документом), а «Премия» ищет базу в прошлом — результат закономерно будет равен 0.
Для решения задачи, когда и подарок, и премия вводятся одновременно за текущий период, убедимся, что ПериодРегистрации у обоих начислений совпадает, а базовый период премии включает этот период регистрации.
Рассмотрим критическую ошибку: попытку прочитать базу записей, которые еще не были зафиксированы в базе данных с заполненным результатом. Механизм расчета в 1С требует соблюдения определенной последовательности (так называемый алгоритм «Специалиста»):
Результат должно быть заполнено и Записывать = Истина.Движения.ДополнительныеНачисления.Записать(). Только после этого данные физически попадают в таблицы базы данных, и виртуальные таблицы смогут их обработать.База. На этом этапе мы получаем суммы ранее записанных начислений.Проанализируем фрагмент кода автора. Автор вызывает Движения.ДополнительныеНачисления.Записать() перед запросом — это верно. Однако нужно убедиться, что для записи Подарок ресурс Результат заполнен до этой записи:
Если Движение2.ВидРасчета = ПланыВидовРасчета.ДополнительныеНачисления.Подарок Тогда
Движение2.Результат = ТекСтрокаНачисленияДоп.Размер;
КонецЕсли;
Посмотрим на структуру запроса. Часто ошибка кроется в неверно переданных измерениях или фильтрах.
ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(
&МассивИзмерений,
&МассивИзмерений,
,
ВидРасчета = &Премия И Регистратор = &Ссылка) КАК ДополнительныеНачисленияБазаДополнительныеНачисления
Разберем параметры:
&МассивИзмерений — должен содержать строку "Сотрудник". Убедимся, что измерение «Сотрудник» в регистре расчета заполнено идентично для обеих записей. Если в одной записи сотрудник указан, а в другой нет — база не соберется.Регистратор = &Ссылка в условии — это означает, что премия будет искать базу только внутри этого же документа. Если подарок был начислен другим документом в прошлом месяце, этот фильтр отсечет его.В запросе используется ЕСТЬNULL(..., 0). Это правильно с точки зрения программирования, чтобы избежать ошибок при расчете. Однако, если БазаДопНач всегда 0, это симптом того, что соединение с виртуальной таблицей не нашло подходящих записей.
Выясним причину, временно изменив запрос. Попробуем убрать фильтр по регистратору в параметрах виртуальной таблицы. Если после этого база появится — значит, проблема в том, что базовые записи были сделаны другими документами или имеют другой период регистрации.
Для успешного расчета выполним следующие действия:
Подарок указан в Базовых видах расчета для Премии.ПериодРегистрации Подарка попадает в БазовыйПериод Премии.Результат для Подарка заполнено значением ТекСтрока.Размер.Движения.Записать() строго перед выполнением запроса.Соблюдение этой методологии гарантирует, что РезультатБаза будет содержать корректную сумму для вычисления премии.