При разработке в среде 1С:Предприятие часто возникает задача программного добавления элементов управления на форму. Одной из главных трудностей становится привязка действия к кнопке: платформа требует, чтобы процедура-обработчик находилась строго в модуле самой формы. Однако, если мы работаем с типовой конфигурацией и не хотим вносить в неё изменения, или если логика должна быть вынесена в общий модуль для повторного использования, нам приходится искать обходные пути. Для решения задач автоматизации вообще без изменения кода можно использовать программных роботов для имитации работы пользователя в 1С.
В этой статье мы разберем, как реализовать добавление кнопки "извне" так, чтобы код выполнялся в общем модуле, не затрагивая основной код формы. Рассмотрим три основных подхода: использование механизмов Библиотеки стандартных подсистем (БСП), применение расширений конфигурации и механизм дополнительных обработок.
Если ваша конфигурация построена на базе БСП (а это почти все современные типовые решения: УТ 11, ERP, КА 2, БП 3.0), то наиболее правильным и "элегантным" способом будет использование механизма подключаемых команд. Этот механизм специально разработан для того, чтобы добавлять функциональность в формы объектов (справочников, документов) без изменения их кода.
Проанализируем алгоритм действий для этого метода:
ПодключаемыеКомандыПереопределяемый. Найдем в нем процедуру ПриОпределенииМодулейСКомандами и добавим туда наш модуль.
Процедура ПриОпределенииМодулейСКомандами(СписокМодулей) Экспорт
СписокМодулей.Добавить("МойОбщийМодульСКомандами");
КонецПроцедуры
МойОбщийМодульСКомандами) нужно создать экспортную процедуру ПриОпределенииКомандПодключенныхКОбъекту. Именно здесь мы описываем параметры нашей будущей кнопки.
Процедура ПриОпределенииКомандПодключенныхКОбъекту(НастройкиФормы, ПараметрыКоманд) Экспорт
Команда = ПараметрыКоманд.Добавить();
Команда.Идентификатор = "МояПрограммнаяКнопка";
Команда.Представление = НСтр("ru = 'Выполнить действие'");
Команда.ИмяГруппы = "ГруппаКоманднаяПанельВажное";
Команда.Порядок = 10;
Команда.СписокФорм = "ФормаОбъекта";
Команда.Обработчик = "МойОбщийМодульКлиент.ВыполнитьМоеДействие";
КонецПроцедуры
Подключаемый_ВыполнитьКоманду, которая и перенаправит вызов в ваш модуль).Преимущество этого метода: Вы вообще не трогаете код формы и даже не создаете расширение для самой формы. Все настройки хранятся в отдельных общих модулях.
Если механизм БСП кажется слишком сложным или форма не поддерживает подключаемые команды, мы можем воспользоваться расширением. Это стандартный и рекомендуемый способ доработки типовых конфигураций. Выясним, как это сделать правильно через перехват событий формы.
Рассмотрим пошагово процесс добавления кнопки через расширение:
ПриСозданииНаСервере с аннотацией &НаСервереПосле.
&НаСервереПосле("ПриСозданииНаСервере")
Процедура Расш_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
// Создаем команду формы
НоваяКоманда = ЭтаФорма.Команды.Добавить("ПрограммнаяКоманда");
НоваяКоманда.Действие = "Подключаемый_ВыполнитьДействиеИзОбщегоМодуля";
НоваяКоманда.Заголовок = "Нажми меня";
// Создаем кнопку на форме
НовыйЭлемент = ЭтаФорма.Элементы.Добавить("КнопкаПрограммная", Тип("КнопкаФормы"), ЭтаФорма.КоманднаяПанель);
НовыйЭлемент.ИмяКоманды = "ПрограммнаяКоманда";
КонецПроцедуры
Действие находился в модуле формы, нам придется создать там "прослойку". Это небольшая экспортная процедура в расширении формы, которая просто вызывает метод вашего общего модуля.
&НаКлиенте
Процедура Подключаемый_ВыполнитьДействиеИзОбщегоМодуля(Команда)
// Вызываем логику из общего модуля
МойОбщийМодульКлиент.ОсновнаяЛогикаКнопки(ЭтаФорма);
КонецПроцедуры
Важный момент: Мы все равно создаем процедуру в модуле формы, но делаем это в расширении, не снимая основную конфигурацию с поддержки и не изменяя оригинальный объект.
Разберем ситуацию, когда программист пытается использовать метод УстановитьДействие при программном создании элементов. Часто возникает соблазн написать что-то вроде НовыйЭлемент.УстановитьДействие("Нажатие", "ОбщийМодуль.Процедура").
Проанализируем, почему это не сработает:
Платформа 1С строго ограничивает область видимости обработчиков событий элементов формы. Вторым параметром метода УстановитьДействие должна быть строка, содержащая имя экспортной процедуры &НаКлиенте, которая физически расположена в модуле этой же самой формы. Обратиться напрямую к общему модулю здесь невозможно.
Единственное исключение — если в форме уже существует некий универсальный "диспетчер" команд (как в случае с БСП), который принимает имя команды и перенаправляет его дальше. Именно поэтому использование типовых механизмов БСП (см. пункт 1) является приоритетным.
Если задача стоит максимально изолированно (например, нужно добавить кнопку печати или заполнения), стоит рассмотреть механизм Дополнительные отчеты и обработки.
В этом случае вы создаете внешнюю обработку (файл .epf), регистрируете её в справочнике "Дополнительные отчеты и обработки" и указываете объект, к которому она относится. БСП сама добавит кнопку в подменю "Заполнение" или "Печать".
Выясним преимущества этого подхода:
Подведем итоги нашего исследования. Если вы работаете в современной типовой конфигурации, наилучшим решением будет использование переопределяемых модулей БСП (ПодключаемыеКомандыПереопределяемый). Это позволяет сохранить чистоту кода и следовать стандартам разработки "1С".
Если же форма не поддерживает БСП или вам требуется сложная визуальная кастомизация, используйте расширение формы. Создайте в расширении команду, привяжите её к кнопке в событии ПриСозданииНаСервере, а в качестве обработчика в модуле формы расширения напишите короткий вызов вашего общего модуля.
Помните, что прямое указание общего модуля в методах установки действий элементов формы невозможно из-за архитектурных особенностей платформы 1С:Предприятие 8.