Почему параметр "Источник" в подписке на событие 1С принимает значение "Истина" и как это исправить?

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

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

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

Причины возникновения проблемы

Выясним главную причину такого поведения платформы. Проблема возникает из-за смещения порядка передаваемых параметров. Когда булевый параметр Отказ смещается на первую позицию в списке аргументов, процедура-обработчик принимает его значение как параметр Источник.

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

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

Правила объявления процедур-обработчиков подписок

Разберем по шагам, как должна выглядеть правильная сигнатура процедуры подписки на событие ПередЗаписью для документов. Убедимся, что число параметров экспортной процедуры в общем модуле строго соответствует правилу N + 1, где N — количество параметров стандартного события объекта.

Правильный заголовок экспортной процедуры для события ПередЗаписью документа выглядит следующим образом:


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

    // Ваша бизнес-логика обработки документа
    // Пример: Источник.Комментарий = "Изменено подпиской";

КонецПроцедуры

Как найти и устранить ошибку в коде

Посмотрим на практический алгоритм отладки этой проблемы:

  1. Воспользуемся стеком вызовов. Установим точку останова на первой строчке процедуры подписки и запустим сценарий, приводящий к ошибке. Откроем окно Стек вызовов (Ctrl + Alt + C). Если перед вызовом подписки в стеке отображается другой модуль (например, модуль формы или общий модуль), значит, процедура вызывается напрямую с ошибочной передачей параметров.
  2. Проверим количество и порядок аргументов. Сопоставим список параметров в подписке на событие в дереве метаданных и в заголовке процедуры общего модуля.
  3. Разделим архитектурные обязанности. Вынесем прикладную бизнес-логику в отдельную экспортную процедуру общего модуля с явным набором параметров, чтобы не вызывать процедуру подписки напрямую из стороннего кода.

Рассмотрим пример правильной архитектурной выноски бизнес-логики:


// Процедура-обработчик подписки на событие
Процедура ПодпискаПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
    ЗаполнитьРеквизитыДокумента(Источник, Отказ);
КонецПроцедуры

// Самостоятельная процедура с понятной сигнатурой для вызова из любого места
Процедура ЗаполнитьРеквизитыДокумента(ДокументОбъект, Отказ) Экспорт
    Если Отказ Тогда
        Возврат;
    КонецЕсли;
    
    // Выполнение прикладных действий с объектом
КонецПроцедуры

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

← На главную