При работе с конфигурациями на базе 1С:Зарплата и управление персоналом 3.1 (включая специализированные решения, такие как Зарплата и кадры образовательной организации) пользователи и программисты могут столкнуться с критической ошибкой при проведении документа «Начисление зарплаты и взносов». Текст ошибки обычно выглядит так: {ОбщийМодуль.РасчетЗарплатыРасширенный.Модуль(275)}: Значение не является значением объектного типа (ИспользованиеПериода). В этой статье мы подробно разберем, почему возникает эта проблема, как ее диагностировать с помощью отладчика и как исправить данные в информационной базе.
Рассмотрим ситуацию, когда конфигурация не обновлялась, но за определенный месяц (например, июнь) расчет перестал работать. Ошибка «Значение не является значением объектного типа» в языке 1С означает, что программа пытается обратиться к свойству (в данном случае ИспользованиеПериода) переменной, которая на самом деле является Неопределено или имеет примитивный тип.
Проанализируем фрагмент кода, где происходит сбой. Как правило, это процедура СформироватьДвиженияНачислений в общем модуле РасчетЗарплатыРасширенный. Программа выполняет следующие действия:
Соответствие, где ключом выступает ссылка на начисление.Ошибка возникает на следующем участке кода:
Если РеквизитыНачислений[Строка.Начисление].ИспользованиеПериода <> Перечисления.ВариантыИспользованияПериодаНачисления.ПериодДействия Тогда
// Логика обработки дат
КонецЕсли;
Если в таблице документа есть строка, в которой поле Начисление пустое или содержит некорректную (битую) ссылку, то попытка получить данные по этому ключу РеквизитыНачислений[Строка.Начисление] вернет Неопределено. Соответственно, обращение к свойству .ИспользованиеПериода у значения Неопределено вызывает исключение.
Выясним причину появления такой строки. Чаще всего это происходит из-за некорректного ручного ввода или использования механизма копирования документов из прошлых периодов. Разберем шаги по поиску виновника:
<Объект не найден>.Документ.НачислениеЗарплатыИВзносов.Начисления с фильтром по конкретной ссылке на ваш документ и условием Начисление = ЗНАЧЕНИЕ(ПланВидовРасчета.Начисления.ПустаяСсылка).Многие разработчики сталкиваются с тем, что точка останова в коде не срабатывает. Посмотрим на причину: современные версии 1С:ЗУП 3.1 выполняют расчет зарплаты в фоновом задании через механизм длительных операций. Отладчик основного сеанса не «видит» выполнение кода в фоне.
Рассмотрим два способа, как обойти это ограничение:
Для более глубокого понимания ситуации проанализируем структуру процедуры СформироватьДвиженияНачислений, которую привел автор темы. Это поможет нам понять, какие именно данные подготавливает система перед падением.
// Фрагмент кода подготовки данных
МассивНачислений = Новый Массив;
Для Каждого Строка Из Начисления Цикл
МассивНачислений.Добавить(Строка.Начисление);
КонецЦикла;
// Получаем реквизиты видов расчета одним махом для оптимизации
ИменаРеквизитов = "ИспользованиеПериода, |ПериодРасчетаБазовыхНачислений, |КоличествоМесяцевБазовогоПериода, |СдвигБазовогоПериода";
РеквизитыНачислений = ОбщегоНазначения.ЗначенияРеквизитовОбъектов(МассивНачислений, ИменаРеквизитов);
Функция ОбщегоНазначения.ЗначенияРеквизитовОбъектов возвращает Соответствие. Если в МассивНачислений попало пустое значение или ссылка на несуществующий объект, она просто не попадет в результат. Далее по коду идет основной цикл по таблице начислений:
Для Каждого Строка Из Начисления Цикл
// ... заполнение свойств ...
// Вот здесь происходит ошибка, если Строка.Начисление отсутствует в РеквизитыНачислений
Если РеквизитыНачислений[Строка.Начисление].ИспользованиеПериода <> Перечисления.ВариантыИспользованияПериодаНачисления.ПериодДействия Тогда
// ...
КонецЕсли;
КонецЦикла;
Если вы имеете возможность вносить изменения в конфигурацию (или создаете расширение), рекомендуется добавить проверку на существование ключа в соответствии. Это сделает код более устойчивым к ошибкам данных.
Рассмотрим пример безопасного обращения к реквизитам:
Для Каждого Строка Из Начисления Цикл
// Получаем структуру реквизитов для текущей строки
ТекущиеРеквизиты = Неопределено;
РеквизитыНачислений.Свойство(Строка.Начисление, ТекущиеРеквизиты);
Если ТекущиеРеквизиты = Неопределено Тогда
// Если реквизиты не найдены, значит данные в строке некорректны.
// Можно либо пропустить строку, либо выдать осмысленное сообщение.
Продолжить;
КонецЕсли;
Если ТекущиеРеквизиты.ИспользованиеПериода <> Перечисления.ВариантыИспользованияПериодаНачисления.ПериодДействия Тогда
// Безопасное выполнение логики
КонецЕсли;
КонецЦикла;
Выясним краткий алгоритм действий при возникновении данной ошибки:
Используя комплексный подход — от анализа кода до проверки чистоты данных в табличных частях — вы сможете быстро локализовать и устранить ошибку Значение не является значением объектного типа (ИспользованиеПериода).