6.18 Где располагаются процедуры-обработчики событий прикладных объектов?
Опубликовано: Обновлено:
❓ 6.18 Где располагаются процедуры-обработчики событий прикладных объектов (например СправочникОбъект.<Имя справочника>), такие как ПередЗаписью, ПередУдалением?
📚 Документация
Заголовок раздела «📚 Документация»-
ИТС: Руководство разработчика 1С:Предприятия 8.3.27 https://its.1c.ru/db/v8327doc#bookmark:dev:TI000000290
-
ИТС: Разработка интерфейса прикладных решений https://its.1c.ru/db/pubv8devui/content/218/hdoc
-
ИТС: Обработчик события
ОбработкаЗаполнения
https://its.1c.ru/db/v8std/content/396/hdoc
🧠 Краткая теория
Заголовок раздела «🧠 Краткая теория»Прикладной объект и модуль объекта
Заголовок раздела «Прикладной объект и модуль объекта»Как разбирали в вопросе 6.16, для работы с отдельным объектом базы данных используются типы с постфиксом Объект.
Например, для справочника:
СправочникМенеджер.<Имя> ↓СоздатьЭлемент() ↓СправочникОбъект.<Имя>СправочникОбъект.<Имя> позволяет работать с данными отдельного элемента справочника: изменять реквизиты, записывать и удалять объект.
Поведение отдельного экземпляра прикладного объекта описывается в модуле объекта.
Именно в нём располагаются процедуры-обработчики событий объекта:
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
КонецПроцедуры
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
КонецПроцедуры
Процедура ПередЗаписью(Отказ)
КонецПроцедуры
Процедура ПриЗаписи(Отказ)
КонецПроцедуры
Процедура ПередУдалением(Отказ)
КонецПроцедурыЧтобы посмотреть, какие свойства, методы и события доступны для конкретного типа объекта, можно использовать Синтакс-помощник.
Для справочника нужно найти тип:
СправочникОбъект.<Имя справочника>
В описании типа отдельно перечислены его свойства, методы и события.

Среди событий СправочникОбъект.<Имя справочника> находятся ОбработкаЗаполнения, ОбработкаПроверкиЗаполнения, ПередЗаписью, ПриЗаписи, ПередУдалением и другие.
События объекта и события формы — разные события.
Например,
ПередЗаписьюформы относится к процессу интерактивной записи из формы, аПередЗаписьюмодуля объекта возникает при записи самого прикладного объекта.
ОбработкаЗаполнения
Заголовок раздела «ОбработкаЗаполнения»ОбработкаЗаполнения предназначена для начального заполнения нового объекта.
Один из основных параметров обработчика — ДанныеЗаполнения.
Его значение зависит от того, каким способом создаётся объект.
| Способ создания | ДанныеЗаполнения |
|---|---|
| Обычное интерактивное создание (кнопка создать) | Неопределено |
| Создание глобальной командой | Неопределено |
| Создание на основании | ссылка на объект-основание |
| Создание из списка с установленным отбором | Структура со значениями отбора |
Вызов метода Заполнить() | Значение, переданное в параметр метода |
Например, если новый объект создаётся из списка с отбором по поставщику и складу, в ДанныеЗаполнения будет передана структура со свойствами Поставщик и Склад.
Это позволяет в ОбработкаЗаполнения определить, откуда и каким способом создаётся объект, и выполнить необходимую логику заполнения.
Программный вызов Заполнить()
Заголовок раздела «Программный вызов Заполнить()»Метод СоздатьЭлемент() или СоздатьДокумент() создаёт объект в памяти, но сам по себе не запускает механизм ОбработкаЗаполнения.
Например:
ОбъектНакладной = Документы.Накладная.СоздатьДокумент();Если требуется программно запустить заполнение, используется метод Заполнить():
ЭлементыОтбора = Новый Структура( "Поставщик, Дата", СсылкаНаПоставщика, ТекущаяДата());
ОбъектНакладной = Документы.Накладная.СоздатьДокумент();
ОбъектНакладной.Заполнить(ЭлементыОтбора);В этом случае вызывается ОбработкаЗаполнения, а переданная структура поступает в параметр ДанныеЗаполнения.
Интерактивное создание и данные заполнения
Заголовок раздела «Интерактивное создание и данные заполнения»Данные заполнения может сформировать и сама платформа.
Например, пользователь находится в списке документов, где установлен отбор:
Поставщик = ООО "Поставщик"Склад = Основнойи создаёт новый документ.
Платформа передает значения такого отбора в ДанныеЗаполнения:
Список с отбором ↓Создать ↓ДанныеЗаполнения = Структура ↓ОбработкаЗаполнения(...)Таким образом, новый объект может автоматически получить значения, соответствующие контексту, из которого он был создан.
Программное открытие формы с данными заполнения
Заголовок раздела «Программное открытие формы с данными заполнения»Такой же механизм можно использовать программно.
Для управляемой формы данные заполнения можно передать через параметр формы ЗначенияЗаполнения:
ЭлементыОтбора = Новый Структура( "Поставщик, Склад", СсылкаНаПоставщика, СсылкаНаСклад);
ПараметрыФормы = Новый Структура( "ЗначенияЗаполнения", ЭлементыОтбора);
ОткрытьФорму( "Документ.Накладная.ФормаОбъекта", ПараметрыФормы);В ЗначенияЗаполнения передаются те данные, которые платформа могла бы сформировать при соответствующем интерактивном создании объекта.
Аналогичный принцип используется и при получении формы программно через ПолучитьФорму().
Свойства реквизитов, влияющие на начальное заполнение
Заголовок раздела «Свойства реквизитов, влияющие на начальное заполнение»На начальное заполнение объекта влияют свойства реквизитов метаданных.

Заполнять из данных заполнения
Заголовок раздела «Заполнять из данных заполнения»Позволяет платформе использовать одноимённое значение из ДанныеЗаполнения для автоматического заполнения реквизита.
Например, при создании объекта в ДанныеЗаполнения передано значение клиента:
ДанныеЗаполнения | Реквизит объекта | Свойство реквизита | Результат |
|---|---|---|---|
Клиент = СсылкаНаКлиента | Клиент | Заполнять из данных заполнения = Да | В реквизит Клиент будет передано значение СсылкаНаКлиента |
То есть платформа сопоставляет имя свойства в ДанныеЗаполнения с именем реквизита объекта и, если для реквизита разрешено «Заполнять из данных заполнения», использует переданное значение для его заполнения.
Значение заполнения
Заголовок раздела «Значение заполнения»Позволяет задать значение, используемое платформой для начального заполнения реквизита, если он не был заполнен другим способом.
Как работает стандартное заполнение
Заголовок раздела «Как работает стандартное заполнение»После вызова ОбработкаЗаполнения дальнейшее поведение зависит от параметра СтандартнаяОбработка.
Если он остаётся равным Истина, платформа продолжает стандартное заполнение.
Упрощённо:
Создание нового объекта ↓Формирование ДанныеЗаполнения ↓ОбработкаЗаполнения(...) ↓СтандартнаяОбработка = Истина ↓Реквизит уже заполнен? ┌─────────┴─────────┐ │ │ Да Нет │ ↓ │ Для реквизита установлено │ «Заполнять из данных заполнения»? │ ┌─────┴─────┐ │ Нет Да │ │ ↓ │ │ В ДанныеЗаполнения │ │ есть значение │ │ для этого реквизита? │ │ ┌───┴───┐ │ │ Нет Да │ │ │ ↓ │ │ │ Заполнение из │ │ │ ДанныеЗаполнения │ │ │ │ └────────┴───────┐ │ ↓ │ Реквизит заполнен? │ ┌──────┴──────┐ │ Да Нет │ │ ↓ │ │ Значение заполнения │ │ └───────────────────────┴─────────────То есть обработчик объекта может выполнить собственное заполнение, а затем платформа при включённой стандартной обработке дозаполняет реквизиты стандартными механизмами.
Если в обработчике установить:
СтандартнаяОбработка = Ложь;дальнейшее стандартное заполнение платформой выполняться не будет.
Копирование объекта — отдельный сценарий
Заголовок раздела «Копирование объекта — отдельный сценарий»Интерактивное создание объекта копированием обрабатывается отдельно.
Для этого существует событие:
ПриКопировании
Создать новый объект │ ├── обычное создание │ ↓ │ ОбработкаЗаполнения │ └── копирование ↓ ПриКопированииВ ПриКопировании передаётся копируемый объект.
При этом следует отдельно учитывать реквизиты типа ХранилищеЗначения: если такие данные необходимо перенести в новый объект, их копирование следует обрабатывать явно.
ОбработкаПроверкиЗаполнения
Заголовок раздела «ОбработкаПроверкиЗаполнения»Следующий важный обработчик модуля объекта —
ОбработкаПроверкиЗаполнения.
Для реквизитов объектов существует свойство Проверка заполнения.
Если для реквизита требуется проверять заполненность, платформа формирует массив таких реквизитов и передаёт его в параметр:
ПроверяемыеРеквизиты.
Например:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Если ОсобыйРежим Тогда
Индекс = ПроверяемыеРеквизиты.Найти("Комментарий");
Если Индекс <> Неопределено Тогда ПроверяемыеРеквизиты.Удалить(Индекс); КонецЕсли;
КонецЕсли;
КонецПроцедурыВ обработчике можно:
- выполнить дополнительные проверки значений;
- добавить реквизит в
ПроверяемыеРеквизиты; - исключить реквизит из стандартной проверки;
- самостоятельно выполнить проверку реквизита и после этого исключить его из дальнейшей стандартной проверки.
Это позволяет делать требование заполнения условным.
Например:
Обычный случай ↓Реквизит проверяет платформа
Особый случай ↓Проверку выполняет прикладной код ↓Реквизит исключаетсяиз ПроверяемыеРеквизитыОбработкаПроверкиЗаполнения выполняется вне транзакции записи объекта.
Программная запись и проверка заполнения
Заголовок раздела «Программная запись и проверка заполнения»Следует учитывать важное отличие интерактивной и программной записи.
При программной записи:
Объект.Записать();ОбработкаПроверкиЗаполнения автоматически не вызывается.
Если необходимо программно запустить механизм проверки заполнения объекта, используется:
Объект.ПроверитьЗаполнение();Этот метод инициирует проверку заполнения объекта и вызов соответствующего обработчика модуля объекта.
Форма и объект при интерактивной записи
Заголовок раздела «Форма и объект при интерактивной записи»Если запись выполняется интерактивно из управляемой формы, в процессе участвуют события формы и события модуля объекта.
При выполнении проверки заполнения последовательность упрощённо выглядит так:
ФОРМА ОБЪЕКТ │ │ │ ПередЗаписью │ ↓ │ │ ОбработкаПроверкиЗаполненияНаСервере │ ├───────────────────────────────────────→│ │ │ ОбработкаПроверкиЗаполнения │ ↓ │←───────────────────────────────────────┤ │ ПередЗаписьюНаСервере │ ↓ │ │ │ ├────── начало транзакции записи ────────┤ │ │ │ │ ПередЗаписью │ ↓ │ │ (Запись объекта) │ ↓ │ │ ПриЗаписи │ ↓ │ ПриЗаписиНаСервере │ ↓ │ ├──── завершение транзакции записи ──────┤ │ │ │ ПослеЗаписиНаСервере │ ↓ │ │ ПослеЗаписи │ ↓ │
Здесь хорошо видно различие между двумя уровнями:
| Место | Примеры событий |
|---|---|
| Модуль формы | ПередЗаписью, ОбработкаПроверкиЗаполненияНаСервере, ПередЗаписьюНаСервере, ПриЗаписиНаСервере |
| Модуль объекта | ОбработкаПроверкиЗаполнения, ПередЗаписью, ПриЗаписи |
ОбработкаПроверкиЗаполненияНаСервереотносится к форме, аОбработкаПроверкиЗаполнения— к самому прикладному объекту.
ПередЗаписью
Заголовок раздела «ПередЗаписью»ПередЗаписью модуля объекта возникает после начала транзакции записи, но до записи нового состояния объекта в базу данных.
Для ранее записанного объекта в этот момент сам объект уже содержит новые значения, а по Ссылка ещё можно получить ранее записанные значения.
Например, значение реквизита можно сравнить с ранее записанным значением через Ссылка:
Если Ссылка.НоменклатурнаяГруппа <> НоменклатурнаяГруппа Тогда // Номенклатурная группа была изменена.КонецЕсли;Ссылка.НоменклатурнаяГруппа → ранее записанное значениеНоменклатурнаяГруппа → новое значение объектаИменно поэтому ПередЗаписью удобно использовать, когда необходимо определить, изменился ли реквизит объекта.
ПриЗаписи
Заголовок раздела «ПриЗаписи»ПриЗаписи возникает после того, как данные объекта уже записаны в базу данных, но транзакция записи ещё не завершена.
Начало транзакции ↓ПередЗаписью ↓Запись объекта ↓ПриЗаписи ↓... ↓Завершение транзакцииТаким образом:
| Обработчик | Состояние записи |
|---|---|
ОбработкаПроверкиЗаполнения | Новое состояние ещё не записано, транзакция записи ещё не началась |
ПередЗаписью | Транзакция уже началась, новое состояние ещё не записано |
ПриЗаписи | Новое состояние уже записано, транзакция ещё не завершена |
Передача служебных параметров между обработчиками
Заголовок раздела «Передача служебных параметров между обработчиками»Для передачи служебных параметров важно различать два сценария.
Из внешнего кода в обработчики объекта
Заголовок раздела «Из внешнего кода в обработчики объекта»Если параметр необходимо передать из внешнего кода или из обработчика подписки на событие в обработчик модуля объекта, стандарт 1С рекомендует использовать свойство ДополнительныеСвойства.
📐 Стандарт разработки: #std639:2.1
Например, вызывающий код устанавливает служебный признак:
ФайлОбъект.ДополнительныеСвойства.Вставить( "КонвертацияФайлов", Истина);
ФайлОбъект.Записать();А в модуле объекта этот признак можно проверить:
Процедура ПередЗаписью(Отказ)
Если ДополнительныеСвойства.Свойство("КонвертацияФайлов") Тогда // Особая логика записи. КонецЕсли;
КонецПроцедурыТо есть для передачи такого параметра не рекомендуется создавать экспортную переменную модуля объекта.
Между обработчиками одного модуля объекта
Заголовок раздела «Между обработчиками одного модуля объекта»Если параметр нужен только внутри самого модуля объекта, например необходимо передать информацию из ПередЗаписью в ПриЗаписи, стандарт рекомендует использовать неэкспортную переменную модуля объекта.
Ранее записанное значение можно получить через Ссылка. При этом, как разбирали в вопросе 6.15, если требуется получить отдельные реквизиты объекта, предпочтительнее использовать запрос.
Перем ПредыдущееЗначениеОрганизации;
Процедура ПередЗаписью(Отказ)
// Получаем ранее записанное значение Организации запросом. ПредыдущееЗначениеОрганизации = ...;
КонецПроцедуры
Процедура ПриЗаписи(Отказ)
Если ПредыдущееЗначениеОрганизации <> Организация Тогда // Значение реквизита Организация изменилось. КонецЕсли;
КонецПроцедурыПолучается простое разделение:
| Откуда и куда передаём данные | Механизм |
|---|---|
| Из внешнего кода → в обработчики модуля объекта | ДополнительныеСвойства |
| Между обработчиками одного модуля объекта | Неэкспортная переменная модуля объекта |
🧠 Ключевая мысль
Заголовок раздела «🧠 Ключевая мысль»Процедуры-обработчики событий прикладного объекта описываются в его модуле объекта.
События ОбработкаЗаполнения, ОбработкаПроверкиЗаполнения, ПередЗаписью, ПриЗаписи, ПередУдалением относятся к жизненному циклу самого объекта. При этом их необходимо отличать от событий управляемой формы, которые участвуют в интерактивной работе пользователя с этим объектом.