Как программно определить, была ли запись объекта вызвана интерактивно из формы или программным кодом?

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

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

Использование коллекции ДополнительныеСвойства

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

Разберем алгоритм действий по шагам:

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

Посмотрим на пример реализации в модуле формы:


&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    // Добавляем флаг в коллекцию ДополнительныеСвойства
    ТекущийОбъект.ДополнительныеСвойства.Вставить("ЗаписьИзФормы", Истина);
КонецПроцедуры

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


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

Почему это лучшее решение?

Данный подход является «родным» для платформы 1С. Мы не пытаемся взломать стек вызовов или анализировать исключения, а используем штатное свойство объекта ДополнительныеСвойства. Важно помнить, что данные в этой коллекции существуют только до завершения процесса записи конкретного объекта и не записываются в базу данных, что исключает возникновение «мусора» в информационной базе.

Рекомендации по архитектуре и типичные ошибки

При реализации подобных механизмов важно учитывать несколько нюансов:

Чего делать не стоит

В ходе дискуссий иногда предлагаются «вредные советы», такие как анализ стека вызовов через искусственную генерацию исключения:


Попытка
    ВызватьИсключение "";
Исключение
    СтэкВызова = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;

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

← На главную