Почему не работает событие "ОбработкаЗаполнения" в 1С при вводе на основании?

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

Создание документов на основании других объектов — одна из самых частых задач в разработке на платформе 1С:Предприятие. Основным механизмом для реализации этой логики является событие ОбработкаЗаполнения. Однако начинающие разработчики часто сталкиваются с ситуацией, когда написанный код заполнения просто не срабатывает: отладчик не останавливается на точке останова, а система ведет себя так, будто обработчика вовсе не существует.

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

Разбор ситуации: почему событие "молчит"?

Рассмотрим ситуацию, с которой столкнулся автор темы. В конфигурации "Управление торговлей 10.3" при вводе документа РеализацияТоваровУслуг на основании документа ЗаказПокупателя была написана следующая процедура в модуле объекта реализации:


Процедура РеализацияТоваровУслугОбработкаЗаполнения(Источник, Основание) Экспорт
    Если ТипЗнч(Основание) <> Тип("ДокументСсылка.ЗаказПокупателя") Тогда
        Сообщить("ОК");
    КонецЕсли;    
КонецПроцедуры

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

  1. Процедура не была связана с событием. Простое написание процедуры в модуле объекта (даже с ключевым словом Экспорт) не делает её обработчиком события. Платформа "не знает", что эту процедуру нужно вызывать, пока мы явно не свяжем её с событием в свойствах объекта метаданных.
  2. Неверная сигнатура (параметры) процедуры. Имена параметров и их порядок были перепутаны, что привело к искажению логики работы условий сравнения типов.

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

Ловушка параметров: почему оператор "=" ломал логику, а "<>" работал?

Обратите внимание на параметры, которые объявил автор: (Источник, Основание). Для локального обработчика события ОбработкаЗаполнения в модуле объекта стандартная сигнатура платформы выглядит так:

Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)

Когда платформа вызывает это событие, она передает параметры строго по их порядковому номеру, независимо от того, как вы их назвали в коде:

Теперь проанализируем, что происходило в коде автора при проверке условий:

Сценарий 1. Использование оператора "<>" (Не равно)

Код выглядел так: Если ТипЗнч(Основание) <> Тип("ДокументСсылка.ЗаказПокупателя"). Из-за смещения параметров в переменной Основание фактически находилось булево значение Истина. Платформа выполняла сравнение: равен ли тип Булево типу ДокументСсылка.ЗаказПокупателя? Разумеется, они не равны. Условие "Не равно" возвращало истину, и система выводила сообщение "ОК" (когда обработчик всё же удавалось запустить).

Сценарий 2. Использование оператора "=" (Равно)

Когда автор исправила условие на знак равенства: Если ТипЗнч(Основание) = Тип(...), платформа начала проверять: равен ли тип Булево типу ссылки документа. Это условие всегда возвращало ложь, поэтому сообщение "ОК" перестало выводиться, создавая иллюзию того, что код вообще не выполняется.

Выяснив причины неверного поведения системы, перейдем к правильным вариантам реализации.

Вариант 1. Настройка стандартного обработчика в модуле объекта

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

  1. Откроем палитру свойств документа РеализацияТоваровУслуг.
  2. Перейдем на вкладку События.
  3. Найдем событие ОбработкаЗаполнения и нажмем на кнопку с лупой. Платформа автоматически свяжет событие с процедурой в модуле объекта и создаст заготовку с правильными параметрами.
  4. Напишем корректный код проверки типа, используя первый параметр процедуры:

Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
    // ДанныеЗаполнения — это наш документ-основание (ЗаказПокупателя)
    Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
        Сообщить("Событие обработчика в модуле объекта сработало успешно!");
        
        // Здесь мы пишем логику заполнения реквизитов, например:
        // ЭтотОбъект.Контрагент = ДанныеЗаполнения.Контрагент;
        // ЭтотОбъект.ДоговорКонтрагента = ДанныеЗаполнения.ДоговорКонтрагента;
    КонецЕсли;
КонецПроцедуры

Вариант 2. Создание полноценной подписки на событие

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

Рассмотрим по шагам, как настроить подписку:

  1. Создадим новый Общий модуль (или используем существующий неглобальный модуль). В его свойствах обязательно должны быть установлены флаги Сервер и Вызов сервера (в зависимости от режима работы конфигурации), а флаг Глобальный должен быть снят.
  2. В ветке метаданных Общие -> Подписки на события добавим новый объект.
  3. В свойстве Источник выберем объект ДокументОбъект.РеализацияТоваровУслуг (именно объект, а не ссылку, так как заполняется новый, еще не записанный в базу документ).
  4. В свойстве Событие выберем ОбработкаЗаполнения.
  5. В свойстве Обработчик укажем нашу процедуру из общего модуля.

Важное правило подписок на события: Сигнатура процедуры-обработчика в общем модуле всегда должна содержать на один параметр больше, чем стандартное событие в модуле объекта. Первым параметром всегда передается сам объект-источник, который инициировал событие.

Напишем правильный код для общего модуля:


Процедура РеализацияТоваровУслугОбработкаЗаполнения(Источник, ДанныеЗаполнения, СтандартнаяОбработка) Экспорт
    // Параметр 'Источник' — это заполняемый объект (РеализацияТоваровУслугОбъект)
    // Параметр 'ДанныеЗаполнения' — это документ-основание (ЗаказПокупателяСсылка)
    
    Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
        
        // Заполняем реквизиты создаваемой реализации из заказа-покупателя:
        Источник.Контрагент = ДанныеЗаполнения.Контрагент;
        Источник.Организация = ДанныеЗаполнения.Организация;
        
        Сообщить("Заполнение через Подписку на событие выполнено!");
    КонецЕсли;
КонецПроцедуры

Полезные приемы и особенности отладки события "ОбработкаЗаполнения"

Для того чтобы процесс разработки и поиска ошибок проходил быстрее, рекомендуем учитывать несколько важных особенностей платформы 1С:

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

← На главную