Работа с событиями в 1С:Предприятие 8.3 — основа динамичного программирования на платформе. Без понимания, где находится обработчик событий, невозможно создать интерактивные формы, автоматизировать бизнес-процессы или интегрировать внешние системы. Эта статья разберёт все ключевые места, где размещаются обработчики: от стандартных модулей до пользовательских расширений, с акцентом на практические примеры и типичные ошибки.

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

1. Базовые понятия: что такое событие и обработчик в 1С

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

Ключевые типы событий:

  • 📌 События форм: ПриСозданииНаСервере, ПриАктивизацииСтроки (для табличных частей).
  • 📝 События объектов: ПередУдалением, ПриПроводке (для документов).
  • 🔄 События платформы: ПриНачалеРаботыСистемы, ПриЗавершенииРаботыСистемы.
  • 🖱️ События элементов управления: Нажатие (для кнопок), Изменение (для полей ввода).

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

⚠️ Внимание: В версиях 1С:Предприятие 8.3.20+ появились асинхронные обработчики событий (с ключевым словом Асинх). Они выполняются в отдельном потоке и требуют особого подхода к отладке. Если ваша конфигурация старше, такие обработчики работать не будут.

2. Где искать обработчики событий в конфигураторе

Основные места размещения обработчиков:

Тип объекта Где искать обработчик Пример события
Форма (управляемая/обычная) Модуль формы (МодульФормы.bsl) или модуль объекта (МодульОбъекта.bsl) ПриОткрытии, ОбработкаКоманды
Документ/Справочник Модуль объекта (МодульДокумента.bsl) ПередЗаписью, ПриПроводке
Отчёт/Обработка Модуль объекта или модуль формы (если есть) ПриКомпоновкеРезультата, ПередВыводом
Глобальный модуль Модуль ОбщийМодуль.Глобальный (раздел "Общие → Общие модули") ПриНачалеРаботыСистемы
Подсистема Модуль подсистемы (МодульПодсистемы.bsl) ПриСозданииНаСервере (для управляемых форм подсистемы)

Чтобы быстро найти обработчик:

  1. Откройте объект в конфигураторе (например, документ РеализацияТоваровУслуг).
  2. Перейдите на вкладку Модули (для форм) или Модуль объекта (для документов/справочников).
  3. В левом меню выберите событие из списка — платформа автоматически создаст заготовку процедуры.

Для динамически создаваемых форм (например, через ПолучитьФорму()) обработчики событий прописываются непосредственно в коде формирования формы. Пример:

Форма = ПолучитьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта");

Форма.УстановитьДействие("ПриОткрытии", "МойОбработчикПриОткрытии");

📊 Где вы чаще всего ищете обработчики событий?
В модулях форм
В модулях объектов
В глобальных модулях
Использую отладчик
Не знаю, где искать

3. Как создать обработчик события: пошаговая инструкция

Рассмотрим создание обработчика на примере события ПередЗаписью для документа ПоступлениеТоваров:

  1. Откройте конфигуратор и найдите документ ПоступлениеТоваров в дереве объектов.
  2. Перейдите на вкладку Модуль объекта.
  3. В выпадающем списке событий выберите ПередЗаписью — платформа сгенерирует шаблон процедуры:
    Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроводки)
    

    // Вставить содержимое обработчика

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

  4. Добавьте логику. Например, проверка заполненности реквизита Контрагент:
    Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроводки)
    

    Если ЗначениеЗаполнено(Контрагент) = Ложь Тогда

    Отказ = Истина;

    Сообщить("Не указан контрагент!", СтатусСообщения.Важное);

    КонецЕсли;

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

Особенности для управляемых форм:

  • 🔧 События формы (например, ПриСозданииНаСервере) обрабатываются в модуле формы, а не объекта.
  • 📱 Для клиентских событий (как ОбработкаКоманды) используйте директиву &НаКлиенте:
    &НаКлиенте
    

    Процедура ОбработкаКоманды(Команда, ПараметрКоманды)

    Если Команда = "МояКоманда" Тогда

    Сообщить("Команда выполнена!");

    КонецЕсли;

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

Изучен список доступных событий для объекта|Выбрано правильное место (модуль объекта/формы)|Учтена директива &НаКлиенте или &НаСервере|Проверена совместимость с версией платформы-->

4. Скрытые события: как найти то, чего нет в палитре

Не все события отображаются в интерфейсе конфигуратора. Некоторые доступны только через:

  • 🔍 Программное подключение: например, событие ОбработкаПолученияДанных для HTTP-сервисов подключается через УстановитьОбработчикОжидания().
  • 📜 Документацию платформы: событие ПриИзмененииДанных для динамических списков не видно в форме, но описано в синтакс-помощнике.
  • 🛠️ Метаданные: некоторые события (как ПриАктивизацииСтроки) появляются только после добавления табличной части.

Пример подключения скрытого события для HTTP-сервиса:

Процедура ПриСозданииНаСервере(Отказ)

HTTPСервис = Новый HTTPСервис("МойСервис");

HTTPСервис.УстановитьОбработчикОжидания("ОбработкаЗапроса");

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

Процедура ОбработкаЗапроса(Запрос) Экспорт

// Логика обработки HTTP-запроса

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

Критичный нюанс: события, начинающиеся с "При_" (например, ПриИзменении), обычно видно в палитре, а события с "Обработка_" (как ОбработкаПолученияДанных) — нет. Это правило помогает быстро сориентироваться.

Как найти событие, если его нет в списке?

Используйте синтакс-помощник (F1 в конфигураторе) и ищите по ключевым словам "событие" или "обработчик".

Просмотрите модули типовых конфигураций (например, УТ 11 или БП 3.0) — там часто реализованы неочевидные обработчики.

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

5. Отладка обработчиков: инструменты и приёмы

Частые проблемы при работе с обработчиками:

  • ❌ Обработчик не срабатывает — проверьте директиву выполнения (&НаКлиенте/&НаСервере).
  • ❌ Код выполняется не в тот момент — уточните последовательность событий (например, ПередЗаписью идёт до ПриЗаписи).
  • ❌ Ошибка "Процедура не найдена" — убедитесь, что имя обработчика совпадает с именем события (регистр важен!).

Инструменты отладки:

  1. Точки останова: установите в начале процедуры-обработчика (клавиша F9).
  2. Журнал регистрации: включите запись событий платформы в Администрирование → Журнал регистрации.
  3. Вывод в сообщения: используйте Сообщить() для отслеживания выполнения:
    Процедура ПриОткрытии()
    

    Сообщить("Форма открыта! Текущий пользователь: " + ТекущийПользователь());

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

Для асинхронных обработчиковАсинх) отладка усложняется — точки останова могут не срабатывать. В этом случае:

  • Используйте ЗаписьЖурналаРегистрации() вместо Сообщить().
  • Проверяйте логи в 1Cv8.log (файл находится в каталоге временных файлов платформы).
💡

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

6. Типичные ошибки и как их избежать

Ошибка 1: Несовпадение имён

Если имя процедуры не совпадает с именем события (даже по регистру), обработчик не вызовется. Например, передзаписьюПередЗаписью.

Ошибка 2: Неверная директива

Клиентский обработчик с директивой &НаСервере (и наоборот) приведёт к ошибке выполнения. Всегда проверяйте контекст:

&НаКлиенте // Обработчик выполняется на клиенте

Процедура МояКоманда()

// Код

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

&НаСервере // Обработчик выполняется на сервере

Процедура ПередЗаписью(Отказ)

// Код

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

Ошибка 3: Зацикливание событий

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

Перем БлокировкаОбработкиИзменения;

Процедура КонтрагентПриИзменении(Элемент)

Если БлокировкаОбработкиИзменения Тогда

Возврат;

КонецЕсли;

БлокировкаОбработкиИзменения = Истина;

// Ваш код

БлокировкаОбработкиИзменения = Ложь;

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

⚠️ Внимание: В 1С:Предприятие 8.3.18+ появился механизм контекстных обработчиков (через ДобавитьОбработчик). Они позволяют динамически подключать процедуры к событиям без изменения конфигурации, но требуют аккуратного управления памятью — не забывайте удалять обработчики через УдалитьОбработчик!

7. Расширенные сценарии: события в расширениях и внешних обработках

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

  1. Создайте расширение в конфигураторе (Конфигурация → Расширения → Добавить).
  2. В дереве расширения найдите объект, для которого нужно добавить обработчик (например, документ ЗаказПокупателя).
  3. В модуле расширения объекта добавьте процедуру с именем события и префиксом ПодпискаНа_:
    Процедура ПодпискаНаПередЗаписью(Отказ, РежимЗаписи, РежимПроводки) Экспорт
    

    Если Объект.СуммаДокумента > 100000 Тогда

    Отказ = Истина;

    Сообщить("Сумма превышает лимит!", СтатусСообщения.Важное);

    КонецЕсли;

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

Для внешних обработок (файлы .epf) события подключаются через:

  • 📎 Прямое указание в коде формы:
    Форма = ПолучитьФорму("Документ.МойДокумент.ФормаОбъекта");
    

    Форма.УстановитьДействие("ПриОткрытии", "ВнешняяОбработка.МойОбработчик");

  • 🔗 Подключение как дополнение: через меню Файл → Открыть → Дополнение.

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

💡

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

FAQ: Частые вопросы по обработчикам событий в 1С

Как узнать последовательность вызова событий при записи документа?

Порядок такой:

  1. ОбработкаЗаполнения (если есть)
  2. ПередЗаписью
  3. ПриЗаписи
  4. ПослеЗаписи
  5. ОбработкаПроводки (если документ проводится)

Для управляемых форм добавляются ПередЗаписьюНаСервере и ПриЗаписиНаСервере.

Можно ли отменить стандартный обработчик события?

Да, если в обработчике установить параметр Отказ = Истина. Например:

Процедура ПередУдалением(Отказ)

Отказ = Истина; // Документ не будет удалён

Сообщить("Удаление запрещено!");

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

Для управляемых форм используйте ПрерватьОбработку().

Как передать параметры в обработчик события?

Параметры передаются через сигнатуру процедуры. Например, для события ОбработкаКоманды:

Процедура ОбработкаКоманды(Команда, ПараметрКоманды, СтандартнаяОбработка)

Если Команда = "МояКоманда" Тогда

Сообщить("Получен параметр: " + ПараметрКоманды);

КонецЕсли;

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

Для динамических событий используйте УстановитьДействие() с дополнительными параметрами:

Форма.УстановитьДействие("МояКоманда", "ОбработатьКоманду", ЭтотОбъект, Истина, "ДопПараметр");
Почему обработчик работает в отладке, но не работает в боевой базе?

Возможные причины:

  • Отсутствуют права на выполнение процедуры (проверьте роли).
  • Обработчик переопределён в расширении или другой подсистеме.
  • В боевой базе отключена функциональность (например, механизм полнотекстового поиска, от которого зависит ваш код).
  • Используются зависимости от тестовых данных (например, проверка на конкретного контрагента).

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

Как обработать событие для всех документов одного типа?

Используйте общий модуль с обработчиком и подключите его ко всем нужным документам через:

  1. Создайте общий модуль (например, ОбщийМодуль.ОбработчикиДокументов).
  2. Добавьте в него экспортную процедуру:
    Процедура ОбщийПередЗаписью(Объект, Отказ) Экспорт
    

    Если Объект.ЭтоГруппа() Тогда

    Отказ = Истина;

    Сообщить("Группы запрещены!");

    КонецЕсли;

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

  3. В модуле каждого документа вызовите её:
    Процедура ПередЗаписью(Отказ)
    

    ОбщийМодуль.ОбработчикиДокументов.ОбщийПередЗаписью(ЭтотОбъект, Отказ);

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

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