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

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

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

Постановка задачи

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

Решение 1: Использование функции Выполнить()

Самый прямой способ вызвать процедуру, имя которой известно в виде строки — это использование встроенной функции Выполнить(). Эта функция интерпретирует переданную ей строку как фрагмент кода на языке 1С и исполняет его в текущем контексте.

Рассмотрим пример, где мы вызываем процедуру-обработчик по её имени. Допустим, обработчик команды называется МояКомандаВыполнить. Проанализируем код:


// Имя процедуры, которую нужно запустить
ИмяПроцедуры = "МояКомандаВыполнить";

// Выполняем вызов. 
// Важно: так как это обработчик команды, он ожидает параметр (саму команду).
// Передаем Неопределено, если объект команды нам не важен.
Выполнить(ИмяПроцедуры + "(Неопределено)");

Этот метод подкупает своей простотой, однако он требует, чтобы вы точно знали имя процедуры-обработчика. В управляемых формах имя команды и имя ее обработчика — это разные сущности.

Решение 2: Динамическое извлечение обработчика из свойств команды

Для создания по-настоящему универсального кода нам нужно научиться получать имя процедуры-обработчика непосредственно из самой команды формы. У каждой команды в коллекции ЭтаФорма.Команды есть свойство Действие, которое содержит строку с именем назначенной ей процедуры.

Разберем по шагам, как построить универсальную процедуру вызова:

  1. Находим объект команды в коллекции команд формы по ее имени.
  2. Извлекаем значение свойства Действие.
  3. Формируем строку вызова и используем Выполнить().

Проанализируем пример реализации такой функции:


&НаКлиенте
Процедура ВыполнитьКомандуФормыПрограммно(ИмяКоманды)
    
    // Поиск команды в коллекции формы
    КомандаОбъект = ЭтаФорма.Команды.Найти(ИмяКоманды);
    
    Если КомандаОбъект <> Неопределено Тогда
        // Получаем имя процедуры-обработчика (например, "ИсполнитьРасчет")
        ИмяПроцедуры = КомандаОбъект.Действие;
        
        Если ЗначениеЗаполнено(ИмяПроцедуры) Тогда
            // Вызываем процедуру, передавая объект команды в качестве параметра
            Выполнить(ИмяПроцедуры + "(КомандаОбъект)");
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Важный нюанс: при использовании Выполнить() в управляемом приложении помните, что этот метод работает только в том контексте, где он вызван. Если вы вызываете его на клиенте, процедура-обработчик также должна быть доступна на клиенте (иметь директиву &НаКлиенте).

Решение 3: Рекомендованный архитектурный подход (Best Practice)

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

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

Посмотрим на пример правильной структуры кода:


&НаКлиенте
// Это обработчик, привязанный к кнопке на форме
Процедура КомандаВыполнитьРасчет(Команда)
    ВыполнитьОсновнуюЛогику();
КонецПроцедуры

&НаКлиенте
// Это общая процедура с логикой
Процедура ВыполнитьОсновнуюЛогику()
    // Здесь размещается весь полезный код
    Сообщить("Логика выполнена!");
КонецПроцедуры

&НаКлиенте
// Ваша процедура автоматизации
Процедура ПослеИсправленияОшибокПользователем()
    // Просто вызываем общую процедуру напрямую без Выполнить()
    ВыполнитьОсновнуюЛогику();
КонецПроцедуры

Этот подход делает код типизированным, понятным и защищенным от ошибок при рефакторинге.

Использование обработчика ожидания для синхронизации интерфейса

Иногда программный вызов команды должен произойти не мгновенно, а после завершения всех экранных событий (например, после закрытия диалогового окна или окончания обновления связанных реквизитов). В таких случаях полезно использовать метод ПодключитьОбработчикОжидания(). Это позволит системе «перевести дух» и выполнить команду в чистом контексте.


&НаКлиенте
Процедура ПриИзмененииРеквизитаПослеПроверки()
    // Выполняем команду через 0.1 секунды однократно
    ПодключитьОбработчикОжидания("ВыполнитьЛогикуКоманды", 0.1, Истина);
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьЛогикуКоманды()
    // Вызываем процедуру-обработчик
    КомандаОбъект = ЭтаФорма.Команды.Найти("МояКоманда");
    ИмяПроцедуры = КомандаОбъект.Действие;
    Выполнить(ИмяПроцедуры + "(КомандаОбъект)");
КонецПроцедуры

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

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

← На главную