Как исправить ошибку «Поле объекта не обнаружено (СпособОтражения)» при проведении начисления отпуска с материальной помощью в 1С?

Программист 1С v8.3 (Обычные формы) 1С:Зарплата и Управление Персоналом Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При доработке типовых или старых кастомных конфигураций «1С:Предприятие» (например, на базе решений «Зарплата и Управление Персоналом 2.5» или «Управление производственным предприятием 1.3») разработчики часто сталкиваются с необходимостью изменить логику распределения затрат. Одной из классических задач является распределение сумм начисленного отпуска по разным счетам бухгалтерского учета непосредственно из табличной части документа, в то время как ранее учет велся по единому счету из шапки.

В процессе реализации этой задачи часто возникает неприятная ошибка при проведении документа:

«Ошибка при выполнении обработчика - '{Документ.дНачислениеОтпускаРаботникамОрганизаций(1309)}: Поле объекта не обнаружено (СпособОтражения)'»

В этой статье мы подробно разберем, почему возникает данная ошибка, проанализируем поведение системы при обработке основных начислений и материальной помощи, а также рассмотрим несколько эффективных способов решения проблемы — от быстрого «обхода» до архитектурно правильного и безопасного кода.

---

Почему возникает ошибка: анализируем исходный код

Рассмотрим ситуацию детальнее. Бухгалтерия ставит задачу: распределять отпускные по разным счетам затрат. Для этого в табличную часть документа начисления добавляется реквизит СпособОтражения (ссылка на справочник способов отражения зарплаты в регламентированном учете). Программист успешно реализует эту логику в процедуре проведения.

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

Давайте проанализируем стандартную процедуру, отвечающую за формирование движений:


Процедура ДобавитьСтрокуОсновныхНачислений(ВыборкаПоШапкеДокумента, ВыборкаПоСтрокамДокумента, УчетнаяПолитикаПоПерсоналуОрганизации)
    
    Движение = Движения.ОсновныеНачисленияРаботниковОрганизаций.Добавить();
    
    // Заполнение стандартных реквизитов движения
    Движение.ПериодРегистрации = ВыборкаПоШапкеДокумента.ПериодРегистрации;
    Движение.ПериодДействияНачало = ВыборкаПоСтрокамДокумента.ДатаНачала;
    Движение.ПериодДействияКонец = ВыборкаПоСтрокамДокумента.ДатаОкончания;
    Движение.ВидРасчета = ВыборкаПоСтрокамДокумента.ВидРасчета;
    // ... [пропущен код заполнения других измерений и ресурсов] ...

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

    Движение.ДатаНачалаСобытия = ПолучитьДатуНачалаСобытия;
    Движение.Авторасчет = Истина;
КонецПроцедуры

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

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

При попытке выполнить проверку Если ЗначениеЗаполнено(ВыборкаПоСтрокамДокумента.СпособОтражения) на четвертом шаге система выбрасывает исключение, так как у переданного объекта (структуры) нет такого свойства.

---

Решение 1. Быстрое исправление (добавление заглушки в структуру)

Самый быстрый способ обойти ошибку, к которому часто прибегают разработчики в условиях жестких временных рамок, — это найти место в модуле проведения, где формируется структура данных для начисления материальной помощи, и принудительно добавить туда пустое свойство-заглушку.

Для этого в код формирования параметров (где заполняется структура проведения для материальной помощи) необходимо добавить следующую строку:

СтруктураПроведения.Вставить("СпособОтражения", Неопределено);

Это решает проблему «в лоб»: теперь при вызове процедуры ДобавитьСтрокуОсновныхНачислений обращение к свойству ВыборкаПоСтрокамДокумента.СпособОтражения не вызовет ошибку, так как свойство существует, хотя и содержит значение Неопределено.

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

---

Решение 2. Безопасный и устойчивый к ошибкам код (Рекомендуется)

Более профессиональным решением является доработка самой процедуры ДобавитьСтрокуОсновныхНачислений. Мы сделаем ее устойчивой к передаче объектов различной структуры, чтобы отсутствие поля СпособОтражения обрабатывалось платформой корректно и без падений.

Рассмотрим, как переписать блок определения способа отражения:


// Безопасное определение способа отражения в бухучете
СпособОтраженияСтроки = Неопределено;

Если ТипЗнч(ВыборкаПоСтрокамДокумента) = Тип("Структура") Тогда
    // Если передана структура, используем безопасный метод Свойство()
    ВыборкаПоСтрокамДокумента.Свойство("СпособОтражения", СпособОтраженияСтроки);
Иначе
    // Если передана выборка из запроса или строка таблицы значений
    Попытка
        СпособОтраженияСтроки = ВыборкаПоСтрокамДокумента.СпособОтражения;
    Исключение
        // Поля нет в выборке, оставляем значение Неопределено
        СпособОтраженияСтроки = Неопределено;
    КонецПопытки;
КонецЕсли;

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

Этот код гарантирует, что даже если структура параметров материальной помощи изменится или будет передана неполной, система не завершит работу аварийно. Переменная СпособОтраженияСтроки просто примет пустое значение.

---

Решение 3. Корректировка исходного запроса проведения

Если данные по материальной помощи собираются в общую временную таблицу или выборку с помощью SQL-запроса в модуле проведения, правильнее всего будет добавить недостающее поле непосредственно в текст этого запроса.

В той ветке пакета запросов (или объединения), которая отвечает за выборку данных по материальной помощи, необходимо явно инициализировать пустое поле нужного типа:


ВЫБРАТЬ
    СсылкаНаДокумент.Сотрудник КАК Сотрудник,
    СсылкаНаДокумент.МатериальнаяПомощьСумма КАК Результат,
    // Принудительно создаем пустое поле нужного типа справочника
    ВЫРАЗИТЬ(НЕОПРЕДЕЛЕНО КАК Справочник.СпособыОтраженияЗарплатыВБухучете) КАК СпособОтражения
ИЗ
    Документ.НачислениеОтпускаРаботникамОрганизаций КАК СсылкаНаДокумент

Это исключит возникновение ошибки на уровне чтения выборки данных, сохранив типизацию метаданных.

---

Методологические нюансы: почему нельзя просто скопировать счет отпуска?

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

Проанализируем требования законодательства к учету материальной помощи:

Важная рекомендация разработчику: Не копируйте способ отражения отпуска для материальной помощи автоматически. Для нее необходимо предусмотреть отдельную схему отражения. Лучше всего оставить реквизит ОтражениеВУчете для строки материальной помощи пустым (Неопределено).

---

Архитектурный аспект: приоритет поиска проводок в 1С

Что произойдет, если в движении регистра расчета по материальной помощи поле СпособОтражения останется пустым? Система 1С не оставит эту запись без проводки. При формировании документа «Отражение зарплаты в регламентированном учете» запустится стандартный алгоритм поиска счетов по приоритетам (от наивысшего к наинизшему):

  1. Способ отражения из записи регистра расчета: Тот самый, который мы заполняем из табличной части документа. Если он заполнен, система безоговорочно использует его.
  2. Способ отражения из настроек Вида расчета: Если в документе поле пустое, система обращается к справочнику «Основные начисления». Если для начисления «Материальная помощь к отпуску» там жестко задан способ (например, Дт 91.02 — Кт 70), программа применит его. (Это идеальный вариант для социальных выплат!)
  3. Способ отражения для Сотрудника: Персональная настройка в карточке сотрудника или учете его затрат.
  4. Способ отражения для Подразделения: Заданный в свойствах подразделения организации.
  5. Способ отражения для Организации в целом: Самый низкий приоритет, используемый по умолчанию.

Таким образом, оставляя поле СпособОтражения пустым для строки матпомощи в регистре расчета, мы действуем абсолютно правильно. Система автоматически подставит верный счет (например, 91.02) из настроек самого вида расчета «Материальная помощь», даже если основные отпускные будут распределены по производственным счетам 20 или 26 согласно табличной части документа.

← На главную