Почему ДокументОснование в отладчике равен Неопределено при записи движений регистра

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

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

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

Причина 1. Банальная путаница между регистрами (Регистр расчета vs Регистр накопления)

Очень часто разработчики поддаются замыливанию глаза при длительной работе со схожими по названиям объектами метаданных. В подсистемах расчета заработной платы (ЗУП 3.1, ERP) параллельно существуют сходные по назначению структуры:

Проанализируем ситуацию на примере кода, который изучал автор темы:


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

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

Вывод: Всегда проверяйте, свойства какого именно объекта метаданных вы анализируете в коде. Одноименные таблицы в разных ветках метаданных могут иметь принципиально разную структуру.

Причина 2. Особенности работы платформы с Определяемыми типами

Если реквизит ДокументОснование имеет тип ОпределяемыйТип.ДокументОснование (или аналогичный определяемый тип), платформа накладывает жесткие ограничения на присваиваемые значения. Разберем этот механизм подробнее.

Определяемый тип в 1С — это именованное описание составного типа данных, централизованно задаваемое в конфигураторе. Если вы программно пытаетесь присвоить свойству этого типа ссылку на документ, тип которого не входит в состав определяемого типа в метаданных вашей конфигурации, система не вызовет ошибку времени выполнения (Runtime Error). Вместо этого произойдет следующее:

  1. Платформа попытается привести присваиваемое значение к одному из типов, входящих в определяемый тип.
  2. Так как тип присваиваемого документа отсутствует в разрешенном списке, приведение типов завершится неудачей.
  3. Значение свойства автоматически будет сброшено в Неопределено (или пустую ссылку соответствующего типа).

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

Причина 3. Запись движений через подписки на события или общие модули

Если в коде обработки проведения документа вы видите, что реквизит остается пустым, но после проведения в режиме «1С:Предприятие» он заполнен, это указывает на то, что окончательное заполнение происходит позже или в другом контексте. Рассмотрим два основных сценария:

1. Использование подписок на события.

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

Отладчик по умолчанию не заходит в модули подписок на события, если вы пошагово идете по модулю проведения документа (клавишей F11). Чтобы поймать этот момент, выполните следующие действия:

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

2. Выполнение расчетов в фоновых заданиях.

В современных конфигурациях на базе БСП (Библиотеки стандартных подсистем) проведение сложных документов или расчет заработной платы могут выполняться во временных таблицах на сервере или передаваться на откуп фоновым заданиям. Это делается для повышения отзывчивости интерфейса.

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

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

Резюме и рекомендации

Для предотвращения подобных трудностей при разработке придерживайтесь простых правил:

← На главную