В практике разработки на платформе 1С:Предприятие 8.3 часто возникает потребность в унификации кода. Представим ситуацию: у вас есть сотни форм, в которых нужно реализовать однотипную проверку или действие при изменении реквизита. Первое логичное желание программиста — использовать метод УстановитьДействие, указав в качестве обработчика процедуру из общего модуля. Однако здесь мы сталкиваемся с фундаментальным ограничением платформы. Давайте подробно разберем, почему это происходит и какие существуют стратегии для решения этой задачи в современных реалиях.
Метод УстановитьДействие (или англоязычный аналог SetAction) предназначен для динамического назначения обработчика события элементу формы или самой форме. Проанализируем, как работает поиск этой процедуры платформой. Когда вы вызываете код:
ЭлементФормы.УстановитьДействие("ПриИзменении", "ИмяПроцедуры");
Платформа ожидает найти процедуру ИмяПроцедуры строго в локальном контексте модуля формы. Если вы попытаетесь передать строку вида "ОбщийМодуль.ИмяПроцедуры", система примет установку действия без ошибки в момент выполнения строки кода, однако при попытке вызвать само событие (например, когда пользователь физически изменит поле на форме), вы получите исключение. Это происходит потому, что механизм разрешения имен (Name Resolution) для событий элементов управления не поддерживает внешние вызовы через точку.
Важный нюанс: даже если процедура в общем модуле помечена как Экспорт, она все равно не видна для движка событий формы напрямую. Это архитектурное решение 1С, сохраняющееся на протяжении многих лет, включая актуальные версии 8.3.24 и 8.3.25.
Если нам необходимо, чтобы основной программный код находился в общем модуле, мы не можем избежать создания «обертки» в модуле самой формы. Рассмотрим стандартный паттерн реализации:
РаботаСФормамиКлиент) создаем экспортную процедуру, которая будет принимать форму как параметр.Пример кода в модуле формы:
&НаКлиенте
Процедура ОбработчикПриИзменении(Элемент)
РаботаСФормамиКлиент.УниверсальныйОбработчик(Элемент, ЭтаФорма);
КонецПроцедуры
Затем мы программно подключаем эту локальную процедуру:
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Элементы.ПолеВвода.УстановитьДействие("ПриИзменении", "ОбработчикПриИзменении");
КонецПроцедуры
Безусловно, такой подход кажется трудозатратным, когда форм много. Выясним причину, почему разработчики часто ищут альтернативы: ручное копирование этого кода в сотни объектов ведет к ошибкам и усложняет поддержку конфигурации.
Рассмотрим современный способ решения задачи через механизм Расширений конфигурации. Вместо того чтобы менять каждую форму в основной конфигурации, мы можем использовать расширение для перехвата событий.
Проанализируем преимущества этого метода:
&После или &Вместо для существующих обработчиков.Однако даже в расширении вам придется добавить процедуру в модуль расширяемой формы. Чтобы ускорить этот процесс, программисты часто используют скрипты автоматизации или обработку выгруженных в XML файлов конфигурации.
Интересно заметить, что в платформе существует объект ОписаниеОповещения (NotifyDescription), который штатно поддерживает указание общего модуля. Посмотрим на пример:
Оповещение = Новый ОписаниеОповещения("ИмяПроцедурыВОбщемМодуле", ОбщийМодуль);
К сожалению, этот объект нельзя передать в метод УстановитьДействие. Он используется только в асинхронных методах платформы (например, при открытии окон или выборе файлов). Тем не менее, это показывает, что технически платформа умеет работать с внешними обработчиками, но для стандартных интерфейсных событий (ПриИзменении, Нажатие) эта возможность пока закрыта.
Если ваша задача — добавить кнопки или команды во множество форм, проанализируем механизм Подключаемых команд из состава Библиотеки Стандартных Подсистем (БСП). Это наиболее «правильный» архитектурный путь для типовых конфигураций.
Алгоритм действий следующий:
ПриОпределенииКомандПодключенныхКОбъекту).Этот метод избавляет от необходимости писать код в каждой форме, так как логика внедряется динамически через программный интерфейс БСП.
Когда стоит задача массово внедрить вызов общего модуля в сотни форм, профессиональные разработчики используют инструменты класса OneScript или V8Reader. Рассмотрим, как это работает:
Выгрузить конфигурацию в файлы...).Form.xml и Module.bsl.Этот подход позволяет избежать рутины и гарантирует, что во всех 192 формах код будет идентичным.
Выясним причину, по которой 1С сохраняет такое ограничение: это связано с производительностью и жесткой типизацией контекста формы. На текущий момент (2024 год) прямого способа прописать ОбщийМодуль.Процедура в УстановитьДействие не существует.
Для решения вашей задачи выберите один из наиболее подходящих путей:
Помните, что архитектурно правильным считается вынос сложной бизнес-логики в общие модули, оставляя в модуле формы лишь минимальный код для взаимодействия с интерфейсом.