Можно ли в методе УстановитьДействие использовать процедуру общего модуля и как это реализовать?

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

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

Анализируем техническое ограничение платформы

Метод УстановитьДействие (или англоязычный аналог SetAction) предназначен для динамического назначения обработчика события элементу формы или самой форме. Проанализируем, как работает поиск этой процедуры платформой. Когда вы вызываете код:


ЭлементФормы.УстановитьДействие("ПриИзменении", "ИмяПроцедуры");

Платформа ожидает найти процедуру ИмяПроцедуры строго в локальном контексте модуля формы. Если вы попытаетесь передать строку вида "ОбщийМодуль.ИмяПроцедуры", система примет установку действия без ошибки в момент выполнения строки кода, однако при попытке вызвать само событие (например, когда пользователь физически изменит поле на форме), вы получите исключение. Это происходит потому, что механизм разрешения имен (Name Resolution) для событий элементов управления не поддерживает внешние вызовы через точку.

Важный нюанс: даже если процедура в общем модуле помечена как Экспорт, она все равно не видна для движка событий формы напрямую. Это архитектурное решение 1С, сохраняющееся на протяжении многих лет, включая актуальные версии 8.3.24 и 8.3.25.

Разберем по шагам решение через «Процедуры-заглушки»

Если нам необходимо, чтобы основной программный код находился в общем модуле, мы не можем избежать создания «обертки» в модуле самой формы. Рассмотрим стандартный паттерн реализации:

  1. В общем модуле (например, РаботаСФормамиКлиент) создаем экспортную процедуру, которая будет принимать форму как параметр.
  2. В модуле каждой из 192-х форм создаем небольшую процедуру-обработчик.
  3. В этой процедуре вызываем наш общий модуль.

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


&НаКлиенте
Процедура ОбработчикПриИзменении(Элемент)
    РаботаСФормамиКлиент.УниверсальныйОбработчик(Элемент, ЭтаФорма);
КонецПроцедуры

Затем мы программно подключаем эту локальную процедуру:


Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Элементы.ПолеВвода.УстановитьДействие("ПриИзменении", "ОбработчикПриИзменении");
КонецПроцедуры

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

Применение расширений для массовой модификации

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

Проанализируем преимущества этого метода:

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

Использование «ОписанияОповещения» как альтернативы

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


Оповещение = Новый ОписаниеОповещения("ИмяПроцедурыВОбщемМодуле", ОбщийМодуль);

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

Решение проблемы «192 форм» через подключаемые команды БСП

Если ваша задача — добавить кнопки или команды во множество форм, проанализируем механизм Подключаемых команд из состава Библиотеки Стандартных Подсистем (БСП). Это наиболее «правильный» архитектурный путь для типовых конфигураций.

Алгоритм действий следующий:

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

Этот метод избавляет от необходимости писать код в каждой форме, так как логика внедряется динамически через программный интерфейс БСП.

Автоматизация внедрения через скрипты

Когда стоит задача массово внедрить вызов общего модуля в сотни форм, профессиональные разработчики используют инструменты класса OneScript или V8Reader. Рассмотрим, как это работает:

  1. Конфигурация выгружается в файлы (через стандартный механизм Выгрузить конфигурацию в файлы...).
  2. Скрипт проходит по всем файлам Form.xml и Module.bsl.
  3. В XML добавляется привязка события к имени процедуры, а в BSL дописывается сама процедура-заглушка с вызовом общего модуля.
  4. Файлы загружаются обратно в 1С.

Этот подход позволяет избежать рутины и гарантирует, что во всех 192 формах код будет идентичным.

Подведем итоги

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

Для решения вашей задачи выберите один из наиболее подходящих путей:

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

← На главную