Работа с событиями в 1С:Предприятие 8.3 — основа динамичного программирования на платформе. Без понимания, где находится обработчик событий, невозможно создать интерактивные формы, автоматизировать бизнес-процессы или интегрировать внешние системы. Эта статья разберёт все ключевые места, где размещаются обработчики: от стандартных модулей до пользовательских расширений, с акцентом на практические примеры и типичные ошибки.
Новички часто путают события платформы (например, ПриОткрытии формы) с событиями объектов (как ПередЗаписью документа). Мы структурируем информацию так, чтобы вы могли быстро найти нужный обработчик — будь то в конфигураторе, в коде или через отладчик. Особое внимание уделим скрытым событиям, которые не отображаются в палитре свойств, но доступны через программный интерфейс.
1. Базовые понятия: что такое событие и обработчик в 1С
Событие в 1С:Предприятие — это сигнал от системы о том, что произошло какое-либо действие: открытие формы, изменение реквизита, нажатие кнопки. Обработчик события — это процедура или функция, которая выполняется в ответ на это событие. Например, когда пользователь сохраняет документ, срабатывает событие ПередЗаписью, и платформа ищет соответствующий обработчик в модуле объекта.
Ключевые типы событий:
- 📌 События форм:
ПриСозданииНаСервере,ПриАктивизацииСтроки(для табличных частей). - 📝 События объектов:
ПередУдалением,ПриПроводке(для документов). - 🔄 События платформы:
ПриНачалеРаботыСистемы,ПриЗавершенииРаботыСистемы. - 🖱️ События элементов управления:
Нажатие(для кнопок),Изменение(для полей ввода).
Важно отличать предопределённые события (те, что доступны в палитре свойств конфигуратора) от динамических, которые создаются программно. Например, событие ОбработкаПолученияДанных для HTTP-сервисов не видно в интерфейсе, но его можно обработать в модуле.
⚠️ Внимание: В версиях 1С:Предприятие 8.3.20+ появились асинхронные обработчики событий (с ключевым словом Асинх). Они выполняются в отдельном потоке и требуют особого подхода к отладке. Если ваша конфигурация старше, такие обработчики работать не будут.
2. Где искать обработчики событий в конфигураторе
Основные места размещения обработчиков:
| Тип объекта | Где искать обработчик | Пример события |
|---|---|---|
| Форма (управляемая/обычная) | Модуль формы (МодульФормы.bsl) или модуль объекта (МодульОбъекта.bsl) |
ПриОткрытии, ОбработкаКоманды |
| Документ/Справочник | Модуль объекта (МодульДокумента.bsl) |
ПередЗаписью, ПриПроводке |
| Отчёт/Обработка | Модуль объекта или модуль формы (если есть) | ПриКомпоновкеРезультата, ПередВыводом |
| Глобальный модуль | Модуль ОбщийМодуль.Глобальный (раздел "Общие → Общие модули") |
ПриНачалеРаботыСистемы |
| Подсистема | Модуль подсистемы (МодульПодсистемы.bsl) |
ПриСозданииНаСервере (для управляемых форм подсистемы) |
Чтобы быстро найти обработчик:
- Откройте объект в конфигураторе (например, документ
РеализацияТоваровУслуг). - Перейдите на вкладку
Модули(для форм) илиМодуль объекта(для документов/справочников). - В левом меню выберите событие из списка — платформа автоматически создаст заготовку процедуры.
Для динамически создаваемых форм (например, через ПолучитьФорму()) обработчики событий прописываются непосредственно в коде формирования формы. Пример:
Форма = ПолучитьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта");
Форма.УстановитьДействие("ПриОткрытии", "МойОбработчикПриОткрытии");
3. Как создать обработчик события: пошаговая инструкция
Рассмотрим создание обработчика на примере события ПередЗаписью для документа ПоступлениеТоваров:
- Откройте конфигуратор и найдите документ
ПоступлениеТоваровв дереве объектов. - Перейдите на вкладку
Модуль объекта. - В выпадающем списке событий выберите
ПередЗаписью— платформа сгенерирует шаблон процедуры:Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроводки)// Вставить содержимое обработчика
КонецПроцедуры
- Добавьте логику. Например, проверка заполненности реквизита
Контрагент:Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроводки)Если ЗначениеЗаполнено(Контрагент) = Ложь Тогда
Отказ = Истина;
Сообщить("Не указан контрагент!", СтатусСообщения.Важное);
КонецЕсли;
КонецПроцедуры
Особенности для управляемых форм:
- 🔧 События формы (например,
ПриСозданииНаСервере) обрабатываются в модуле формы, а не объекта. - 📱 Для клиентских событий (как
ОбработкаКоманды) используйте директиву&НаКлиенте:&НаКлиентеПроцедура ОбработкаКоманды(Команда, ПараметрКоманды)
Если Команда = "МояКоманда" Тогда
Сообщить("Команда выполнена!");
КонецЕсли;
КонецПроцедуры
Изучен список доступных событий для объекта|Выбрано правильное место (модуль объекта/формы)|Учтена директива &НаКлиенте или &НаСервере|Проверена совместимость с версией платформы-->
4. Скрытые события: как найти то, чего нет в палитре
Не все события отображаются в интерфейсе конфигуратора. Некоторые доступны только через:
- 🔍 Программное подключение: например, событие
ОбработкаПолученияДанныхдля HTTP-сервисов подключается черезУстановитьОбработчикОжидания(). - 📜 Документацию платформы: событие
ПриИзмененииДанныхдля динамических списков не видно в форме, но описано в синтакс-помощнике. - 🛠️ Метаданные: некоторые события (как
ПриАктивизацииСтроки) появляются только после добавления табличной части.
Пример подключения скрытого события для HTTP-сервиса:
Процедура ПриСозданииНаСервере(Отказ)
HTTPСервис = Новый HTTPСервис("МойСервис");
HTTPСервис.УстановитьОбработчикОжидания("ОбработкаЗапроса");
КонецПроцедуры
Процедура ОбработкаЗапроса(Запрос) Экспорт
// Логика обработки HTTP-запроса
КонецПроцедуры
Критичный нюанс: события, начинающиеся с "При_" (например, ПриИзменении), обычно видно в палитре, а события с "Обработка_" (как ОбработкаПолученияДанных) — нет. Это правило помогает быстро сориентироваться.
Как найти событие, если его нет в списке?
Используйте синтакс-помощник (F1 в конфигураторе) и ищите по ключевым словам "событие" или "обработчик".
Просмотрите модули типовых конфигураций (например, УТ 11 или БП 3.0) — там часто реализованы неочевидные обработчики.
Воспользуйтесь отладчиком: установите точку останова на метод УстановитьДействие() и посмотрите, какие события подключаются динамически.
5. Отладка обработчиков: инструменты и приёмы
Частые проблемы при работе с обработчиками:
- ❌ Обработчик не срабатывает — проверьте директиву выполнения (
&НаКлиенте/&НаСервере). - ❌ Код выполняется не в тот момент — уточните последовательность событий (например,
ПередЗаписьюидёт доПриЗаписи). - ❌ Ошибка "Процедура не найдена" — убедитесь, что имя обработчика совпадает с именем события (регистр важен!).
Инструменты отладки:
- Точки останова: установите в начале процедуры-обработчика (клавиша
F9). - Журнал регистрации: включите запись событий платформы в
Администрирование → Журнал регистрации. - Вывод в сообщения: используйте
Сообщить()для отслеживания выполнения:Процедура ПриОткрытии()Сообщить("Форма открыта! Текущий пользователь: " + ТекущийПользователь());
КонецПроцедуры
Для асинхронных обработчиков (с Асинх) отладка усложняется — точки останова могут не срабатывать. В этом случае:
- Используйте
ЗаписьЖурналаРегистрации()вместоСообщить(). - Проверяйте логи в
1Cv8.log(файл находится в каталоге временных файлов платформы).
Если обработчик не срабатывает на сервере, проверьте права пользователя в ролях. Часто проблема кроется в отсутствии прав на выполнение серверных процедур.
6. Типичные ошибки и как их избежать
Ошибка 1: Несовпадение имён
Если имя процедуры не совпадает с именем события (даже по регистру), обработчик не вызовется. Например, передзаписью ≠ ПередЗаписью.
Ошибка 2: Неверная директива
Клиентский обработчик с директивой &НаСервере (и наоборот) приведёт к ошибке выполнения. Всегда проверяйте контекст:
&НаКлиенте // Обработчик выполняется на клиенте
Процедура МояКоманда()
// Код
КонецПроцедуры
&НаСервере // Обработчик выполняется на сервере
Процедура ПередЗаписью(Отказ)
// Код
КонецПроцедуры
Ошибка 3: Зацикливание событий
Если в обработчике ПриИзменении поля вы меняете это же поле, возникнет рекурсия. Используйте флаг блокировки:
Перем БлокировкаОбработкиИзменения;
Процедура КонтрагентПриИзменении(Элемент)
Если БлокировкаОбработкиИзменения Тогда
Возврат;
КонецЕсли;
БлокировкаОбработкиИзменения = Истина;
// Ваш код
БлокировкаОбработкиИзменения = Ложь;
КонецПроцедуры
⚠️ Внимание: В 1С:Предприятие 8.3.18+ появился механизм контекстных обработчиков (черезДобавитьОбработчик). Они позволяют динамически подключать процедуры к событиям без изменения конфигурации, но требуют аккуратного управления памятью — не забывайте удалять обработчики черезУдалитьОбработчик!
7. Расширенные сценарии: события в расширениях и внешних обработках
Если вы работаете с расширениями конфигурации, обработчики событий добавляются через механизм подписок:
- Создайте расширение в конфигураторе (
Конфигурация → Расширения → Добавить). - В дереве расширения найдите объект, для которого нужно добавить обработчик (например, документ
ЗаказПокупателя). - В модуле расширения объекта добавьте процедуру с именем события и префиксом
ПодпискаНа_:Процедура ПодпискаНаПередЗаписью(Отказ, РежимЗаписи, РежимПроводки) ЭкспортЕсли Объект.СуммаДокумента > 100000 Тогда
Отказ = Истина;
Сообщить("Сумма превышает лимит!", СтатусСообщения.Важное);
КонецЕсли;
КонецПроцедуры
Для внешних обработок (файлы .epf) события подключаются через:
- 📎 Прямое указание в коде формы:
Форма = ПолучитьФорму("Документ.МойДокумент.ФормаОбъекта");Форма.УстановитьДействие("ПриОткрытии", "ВнешняяОбработка.МойОбработчик");
- 🔗 Подключение как дополнение: через меню
Файл → Открыть → Дополнение.
Важно: обработчики из расширений и внешних обработок имеют ниже приоритет, чем встроенные в конфигурацию. Если событие обработано в основной конфигурации с отказом (Отказ = Истина), ваш код из расширения выполнен не будет.
Расширения — самый безопасный способ добавлять обработчики без изменения типовой конфигурации. Они сохраняются при обновлениях и легко отключаются.
FAQ: Частые вопросы по обработчикам событий в 1С
Как узнать последовательность вызова событий при записи документа?
Порядок такой:
ОбработкаЗаполнения(если есть)ПередЗаписьюПриЗаписиПослеЗаписиОбработкаПроводки(если документ проводится)
Для управляемых форм добавляются ПередЗаписьюНаСервере и ПриЗаписиНаСервере.
Можно ли отменить стандартный обработчик события?
Да, если в обработчике установить параметр Отказ = Истина. Например:
Процедура ПередУдалением(Отказ)
Отказ = Истина; // Документ не будет удалён
Сообщить("Удаление запрещено!");
КонецПроцедуры
Для управляемых форм используйте ПрерватьОбработку().
Как передать параметры в обработчик события?
Параметры передаются через сигнатуру процедуры. Например, для события ОбработкаКоманды:
Процедура ОбработкаКоманды(Команда, ПараметрКоманды, СтандартнаяОбработка)
Если Команда = "МояКоманда" Тогда
Сообщить("Получен параметр: " + ПараметрКоманды);
КонецЕсли;
КонецПроцедуры
Для динамических событий используйте УстановитьДействие() с дополнительными параметрами:
Форма.УстановитьДействие("МояКоманда", "ОбработатьКоманду", ЭтотОбъект, Истина, "ДопПараметр");
Почему обработчик работает в отладке, но не работает в боевой базе?
Возможные причины:
- Отсутствуют права на выполнение процедуры (проверьте роли).
- Обработчик переопределён в расширении или другой подсистеме.
- В боевой базе отключена функциональность (например, механизм полнотекстового поиска, от которого зависит ваш код).
- Используются зависимости от тестовых данных (например, проверка на конкретного контрагента).
Рекомендация: добавьте в обработчик запись в журнал регистрации (ЗаписьЖурналаРегистрации()) и проверьте логи.
Как обработать событие для всех документов одного типа?
Используйте общий модуль с обработчиком и подключите его ко всем нужным документам через:
- Создайте общий модуль (например,
ОбщийМодуль.ОбработчикиДокументов). - Добавьте в него экспортную процедуру:
Процедура ОбщийПередЗаписью(Объект, Отказ) ЭкспортЕсли Объект.ЭтоГруппа() Тогда
Отказ = Истина;
Сообщить("Группы запрещены!");
КонецЕсли;
КонецПроцедуры
- В модуле каждого документа вызовите её:
Процедура ПередЗаписью(Отказ)ОбщийМодуль.ОбработчикиДокументов.ОбщийПередЗаписью(ЭтотОбъект, Отказ);
КонецПроцедуры
Для управляемых форм можно использовать подписки на события в расширении.