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