Как исправить ошибку «Значение не является значением объектного типа (Порядок оплаты)» при согласовании заявки в 1С:ERP

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием Управленческий учет
← На главную

В процессе работы с конфигурациями на базе платформы 1С:Предприятие 8.3, такими как 1С:ERP Управление предприятием или Комплексная автоматизация 2, пользователи часто сталкиваются с ошибкой при изменении статусов документов. Одной из наиболее типичных является ситуация, когда при попытке согласовать «Заявку на расходование денежных средств» система выдает критическое оповещение: «Значение не является значением объектного типа (Порядок оплаты)». В этой статье мы подробно разберем причины возникновения этой проблемы и рассмотрим способы её решения как на уровне пользователя, так и на уровне программного кода.

Анализ ситуации и поиск причины возникновения ошибки

Для начала проанализируем условия, при которых возникает данная ошибка. Как правило, проблема проявляется не постоянно, а при определенной последовательности действий. Рассмотрим сценарий, описанный пользователями:

  1. Если при создании документа сразу установить статус «К оплате» и провести его, ошибка не возникает.
  2. Если же документ сначала проводится в статусе «Не согласована», а затем пользователь пытается перевести его в статус «Согласована», система прерывает выполнение операции с ошибкой.

Разберем, почему так происходит. В системе 1С:ERP механизмы проведения документов часто зависят от их текущего и нового статуса. При установке статуса «Согласована» или переходе между этапами согласования, программа инициирует дополнительные проверки. Эти проверки могут касаться лимитов расходования денежных средств, условий договоров или параметров взаиморасчетов. Ошибка «Значение не является значением объектного типа» означает, что код пытается обратиться к свойству (в данном случае ПорядокОплаты) через точку от переменной, которая не является ссылкой на объект (например, имеет значение Неопределено или NULL).

Выявление проблемного участка кода

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


ИначеЕсли Договор.ПорядокОплаты = Перечисления.ПорядокОплатыПоСоглашениям.РасчетыВВалютеОплатаВРублях 
    И Подразделение <> ПодразделениеИсключение Тогда
    // Логика обработки...
КонецЕсли;

В этом фрагменте переменная Договор в момент выполнения может быть пустой. Если в «Заявке на расходование денежных средств» реквизит Договор не заполнен (что допустимо для некоторых хозяйственных операций, например, «Прочий расход»), то при обращении к Договор.ПорядокОплаты система падает, так как у пустого значения нет свойства ПорядокОплаты.

Выясним, почему ошибка не проявляется при статусе «К оплате». Дело в том, что при прямой установке финального статуса система может пропускать цепочку промежуточных проверок согласования. Когда же документ идет по маршруту «Не согласован -> Согласован», включается логика модуля СогласованиеЗаявок или проверки бюджетных лимитов, где программистами не была предусмотрена проверка на заполненность договора.

Вариант решения №1: Исправление на уровне программного кода (Безопасный вызов)

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

Вместо прямого обращения через точку, рекомендуется использовать метод ЗначениеЗаполнено() или функции общего назначения. Рассмотрим пример исправленного кода:


Если ЗначениеЗаполнено(Договор) Тогда
    Если Договор.ПорядокОплаты = Перечисления.ПорядокОплатыПоСоглашениям.РасчетыВВалютеОплатаВРублях 
        И Подразделение <> ПодразделениеИсключение Тогда
        // Безопасная логика
    КонецЕсли;
КонецЕсли;

Однако более профессиональным и отказоустойчивым методом в типовых конфигурациях является использование функции ОбщегоНазначения.ЗначениеРеквизитаОбъекта(). Этот метод позволяет получить значение реквизита даже от пустой ссылки, не вызывая исключения. Разберем этот пример:


ПорядокОплаты = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Договор, "ПорядокОплаты");

Если ПорядокОплаты = Перечисления.ПорядокОплатыПоСоглашениям.РасчетыВВалютеОплатаВРублях 
    И Подразделение <> ПодразделениеИсключение Тогда
    // Обработка...
КонецЕсли;

В данном случае, если Договор будет пуст, переменная ПорядокОплаты примет значение Неопределено, и последующее сравнение в условии Если пройдет корректно, просто вернув Ложь, вместо остановки работы всей системы.

Вариант решения №2: Проверка данных на стороне пользователя

Если у вас нет возможности немедленно внести изменения в программный код (например, вы работаете в облачном сервисе без прав программиста), проанализируем ситуацию с точки зрения данных. Ошибка сигнализирует о том, что для выполнения бизнес-логики системе необходимы данные о договоре, которые отсутствуют.

Рассмотрим шаги для пользователя:

  1. Проверьте Тип операции в Заявке. Если выбран тип, подразумевающий расчеты с контрагентами, убедитесь, что поле «Договор» заполнено.
  2. Если вы используете Объекты расчетов, убедитесь, что в качестве объекта расчетов выбран именно договор, а не просто первичный документ (если настройки системы требуют наличия договора).
  3. Проверьте Соглашение. В некоторых случаях порядок оплаты может наследоваться из соглашения, и если оно не указано, это косвенно влияет на формирование переменных в коде.

Почему это происходит именно в ERP?

Проанализируем архитектурную особенность. В 1С:ERP и КА 2 существует сложная система «Лимитов расходования денежных средств». Когда заявка переходит в статус «Согласована», система пытается зарезервировать сумму под этот лимит. Если в правилах лимитирования указано, что контроль ведется в разрезе договоров, программный код будет искать этот договор в документе. Отсутствие проверки на наличие договора в процедурах контроля лимитов — это типичное место возникновения подобных ошибок.

Также стоит обратить внимание на функциональные опции. Если в настройках системы отключена опция «Использовать договоры с контрагентами», но при этом в коде остались кастомные (доработанные) проверки, обращающиеся к договорам, система также будет выдавать ошибку «Значение не является значением объектного типа».

Резюме

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

Рассмотренные методы позволяют не только устранить текущую ошибку, но и повысить общую стабильность системы, предотвращая аналогичные сбои в будущем при работе с любыми ссылочными реквизитами.

← На главную