Как отличить проведение документа из формы от групповой обработки в 1С 8.3

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

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

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

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

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

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

Пример кода в модуле формы:


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

Теперь проанализируем ситуацию в модуле объекта или в подписке на событие ОбработкаПроведения. Нам нужно проверить наличие этого свойства:


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

Метод 2: Использование расширений для чистоты конфигурации

Чтобы не снимать документ с поддержки, мы можем вынести установку признака в расширение. Посмотрим на пример того, как это сделать для формы документа. В расширении создадим обработчик &После для метода ПередЗаписьюНаСервере.

Код в расширении формы:


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

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

Метод 3: Определение работы в фоновом задании

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

Для проверки можно использовать следующий код:


Если ВыполняетсяВФоновомЗадании() Тогда
    // Мы в фоновом процессе (точно не форма)
Иначе
    // Возможно, это форма, а возможно — обычный программный вызов в основном потоке
КонецЕсли;

Однако помните, что этот метод не дает 100% гарантии отличия от программного вызова в обработке, которая запущена не в фоне.

Особенности вывода предупреждений (СообщенияПользователю)

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

Проанализируем, как это работает:

  1. В коде ОбработкаПроведения вы создаете объект СообщениеПользователю.
  2. Указываете текст сообщения и, желательно, поле, к которому оно относится.
  3. Метод Сообщить() сохраняет сообщение в специальный буфер.
  4. После успешного завершения транзакции или при ее отмене платформа передает этот буфер на клиент, и пользователь видит все сообщения в окне формы.

Пример кода:


Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Внимание: документ проведен с отклонениями от графика!";
Сообщение.Поле = "Дата";
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();

Важный момент: если ваша задача — задать пользователю вопрос («Вы уверены, что хотите продолжить?»), то это невозможно сделать внутри транзакции проведения. Такие вопросы должны задаваться на клиенте в модуле формы до вызова команды записи.

Метод 4: Анализ параметров записи в управляемой форме

В управляемых формах 1С 8.3 существует возможность передавать параметры напрямую в процедуру записи. Разберем, как использовать ПараметрыЗаписи. На клиенте в обработчике ПередЗаписью мы можем добавить свой ключ:


&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
    ПараметрыЗаписи.Вставить("ИнтерактивныйЗапуск", Истина);
КонецПроцедуры

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

Использование «ОбработкиПроверкиЗаполнения»

Если цель разделения контекстов — проверка данных, посмотрим на пример стандартного обработчика ОбработкаПроверкиЗаполнения. У него есть системный параметр ПроверятьПроведение. Также этот обработчик вызывается платформой автоматически перед проведением из формы, но его можно вызвать и программно. Если ваша логика касается только контроля корректности данных, возможно, стоит перенести её именно сюда, так как этот метод срабатывает до начала транзакции, что экономит ресурсы сервера.

Резюме по выбору решения

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

← На главную