Как программно вызвать событие элемента управляемой формы в 1С?

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

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

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

Почему события формы не срабатывают при программном заполнении

В платформе 1С:Предприятие существует четкое разделение между интерактивными действиями пользователя и программной модификацией данных:

  1. Интерактивная природа событий элементов управления. Обработчики событий формы, такие как ПриИзменении, АвтоПодбор, Очистка, Нажатие, вызываются клиентом платформы исключительно в ответ на физические действия пользователя в интерфейсе (ввод с клавиатуры, выбор мышью из списка). Простая установка значения свойства объекта или реквизита формы через код вида Форма.Реквизит = Значение или Форма.Объект.Организация = НоваяОрганизация меняет данные в памяти, но не генерирует пользовательские события.
  2. Область видимости процедур модуля формы. По умолчанию процедуры-обработчики создаются без ключевого слова Экспорт. Они являются локальными для модуля конкретной формы и недоступны для вызова извне (из внешней обработки или другого клиентского контекста).

Способ 1. Использование встроенного механизма автоматизированного тестирования

Если главная цель — проверить работоспособность событий и поведение интерфейса в конфигурации, находящейся на поддержке (без изменения метаданных и без добавления расширений), штатным инструментом платформы является механизм автоматизированного тестирования.

Разберем по шагам, как устроен этот механизм:

  1. Сеанс приложения с тестируемой конфигурацией запускается из командной строки с параметром /TestClient.
  2. Управляющий сеанс (внешняя обработка или тестовый сценарий) запускается с параметром /TestManager.
  3. В коде менеджера тестирования создаются объекты управления интерфейсом: ТестируемоеПриложение, ТестируемаяФорма, ТестируемоеПолеФормы.

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


ТестируемоеПриложение = Новый ТестируемоеПриложение;
ТестируемоеПриложение.УстановитьСоединение();

// Открываем форму документа
ТестируемоеПриложение.ВыполнитьКоманду("Документ.РеализацияТоваровУслуг.Создать");
ФормаДокумента = ТестируемоеПриложение.ПолучитьФорму("Документ.РеализацияТоваровУслуг.Форма.ФормаДокумента");

// Получаем элемент управления и эмулируем интерактивный ввод
ПолеОрганизация = ФормаДокумента.ПолучитьЭлемент("Организация");
ПолеОрганизация.ВвестиТекст("Основная организация");

// Платформа генерирует событие ПриИзменении и отрабатывает всю цепочку алгоритмов

Способ 2. Объявление процедуры экспортной через расширение конфигурации

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

Рассмотрим порядок действий:

  1. Подключим к информационной базе расширение конфигурации в безопасном режиме.
  2. Добавим в расширение требуемую управляемую форму.
  3. Определим в модуле формы расширения экспортную процедуру, которая вызывает требуемый обработчик или содержит необходимую логику пересчета.

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


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

// Устанавливаем значение реквизита
Форма.Объект.Организация = НужнаяОрганизация;

// Вызываем экспортную процедуру формы, инициирующую пересчет
Форма.ОрганизацияПриИзмененииЭкспорт();

Способ 3. Передача значений заполнения при открытии формы

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

Разберем пример передачи параметров:


ЗначенияЗаполнения = Новый Структура;
ЗначенияЗаполнения.Вставить("Организация", ВыбраннаяОрганизация);
ЗначенияЗаполнения.Вставить("Контрагент", ВыбранныйКонтрагент);

ПараметрыОткрытия = Новый Структура;
ПараметрыОткрытия.Вставить("ЗначенияЗаполнения", ЗначенияЗаполнения);

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

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

Способ 4. Тестирование бизнес-логики на уровне объекта

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


НовыйДокумент = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
НовыйДокумент.Организация = ВыбраннаяОрганизация;

// Вызываем типовые методы заполнения объекта
НовыйДокумент.Заполнить(Неопределено);

// Либо вызываем специализированные методы пересчета из общих модулей
// Например: ОбработкаТабличнойЧастиКлиентСервер.ПересчитатьСумму(НовыйДокумент);
← На главную