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