К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как вызвать команду формы в 1С: программные способы и примеры

Как вызвать команду формы в 1С: метод ВыполнитьКоманду, программный вызов команд формы и объекта, типичные ошибки, примеры кода на встроенном языке.

В управляемых формах 1С часто возникает задача: выполнить команду формы не по нажатию кнопки, а программно — из обработчика другого события, из клиентского или серверного контекста. Типовой сценарий — имитация нажатия кнопки «Записать», «Провести», вызов команды перечитать данные или выполнить произвольную команду, созданную разработчиком в дереве команд формы.

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

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

Что такое команда формы и где она живёт

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

Команда становится видимой пользователю, когда её перетаскивают в дерево элементов формы как кнопку, пункт меню «Ещё» или командную панель. Но сама команда существует независимо от кнопки: её можно вызвать программно, даже если на форме нет ни одного связанного элемента.

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

Способ 1. Метод ВыполнитьКоманду

Основной универсальный приём — метод ВыполнитьКоманду(). Он доступен у объекта управляемой формы и принимает имя команды строкой или саму команду формы:

&НаКлиенте

Процедура ПровестиДокументПрограммно(Команда)

ЭтаФорма.ВыполнитьКоманду("Провести");

КонецПроцедуры

Метод работает и для стандартных команд объекта, если они доступны форме: ЭтаФорма.ВыполнитьКоманду("Записать"), ЭтаФорма.ВыполнитьКоманду("ПровестиИЗакрыть"). Платформа выполняет ту же логику, что и при нажатии соответствующей кнопки, включая серверные вызовы и вопросы пользователю.

Для команд динамического списка и других расширений формы применяется обращение через свойство расширения, например ЭтаФорма.РасширениеДинамическогоСписка — там доступны свои методы выполнения команд. Конкретный набор зависит от типа основного реквизита формы.

Способ 2. Прямой вызов обработчика команды

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

&НаКлиенте

Процедура КнопкаОбновить(Команда)

// вызываем обработчик другой команды

ОбновитьДанные(Неопределено);

КонецПроцедуры

&НаКлиенте

Процедура ОбновитьДанные(Команда)

// логика обновления

КонецПроцедуры

Если обработчик использует свойства параметра Команда (например, Команда.Имя), нужно передать реальный объект команды. Его можно получить из коллекции команд формы: ЭтаФорма.Команды.Найти("ОбновитьДанные").

Этот способ быстрее и прозрачнее для отладки, но работает только внутри модуля той же формы и только если директивы компиляции (&НаКлиенте / &НаСервере) совместимы с местом вызова.

Способ 3. Вызов команды из другой формы

Иногда нужно «нажать кнопку» в открытой форме извне — например, из формы обработки или из общего модуля. Для этого сначала получают ссылку на форму, затем вызывают её экспортную процедуру:

// в форме-источнике объявлена экспортная процедура

&НаКлиенте

Процедура ВыполнитьОбновление() Экспорт

ЭтаФорма.ВыполнитьКоманду("ОбновитьДанные");

КонецПроцедуры

// вызов извне

ФормаДокумента = ПолучитьФормуДокумента(); // способ получения зависит от задачи

Если ФормаДокумента <> Неопределено И ФормаДокумента.Открыта() Тогда

ФормаДокумента.ВыполнитьОбновление();

КонецЕсли;

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

Альтернатива для слабосвязанного взаимодействия — оповещения: Оповестить("ОбновитьДанныеДокумента", Параметры, Владелец) в одной форме и обработчик ОбработкаОповещения в другой. Это безопаснее, потому что не требует хранить ссылку на форму.

Сравнение вариантов

ВыполнитьКоманду

Универсально, повторяет поведение кнопки, включая стандартные команды. Только на клиенте внутри формы.

Прямой вызов процедуры

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

Экспортный метод формы

Для вызова извне; требует контроля, что форма открыта, и ссылки на неё.

Оповестить / ОбработкаОповещения

Слабая связанность между формами; нет гарантии, что получатель существует и обработает событие.

Вызов стандартных команд объекта: записать и провести

Частая задача — программно записать или провести документ из его формы. Здесь есть два уровня решения, и важно не смешивать их.

На клиенте корректно вызвать команду формы: ЭтаФорма.ВыполнитьКоманду("Записать") или ЭтаФорма.Записать() — оба варианта выполнят стандартную логику с вопросами пользователю при необходимости. Метод Записать() формы принимает параметры, например режим записи.

На сервере формы (в обработчике &НаСервере) работают иначе: получают объект через РеквизитФормыВЗначение("Объект"), вызывают Объект.Записать(РежимЗаписиДокумента.Проведение) и возвращают данные в форму через ЗначениеВРеквизитФормы. Вызвать «команду формы» на сервере нельзя — команды существуют только в клиентском контексте.

bsl
&НаКлиенте
Процедура ПровестиИзКода(Команда)
    Если ЭтаФорма.Модифицированность Тогда
        ЭтаФорма.Записать();
    КонецЕсли;
    ЭтаФорма.ВыполнитьКоманду("Провести");
КонецПроцедуры

Проверка результата и контроль ошибок

Метод ВыполнитьКоманду не возвращает осмысленный результат успеха — команда считается выполненной, если не возникло исключения. Поэтому результат проверяют по косвенным признакам: снятию модифицированности после «Записать», изменению признака проведения объекта, обновлению данных на форме.

Если команда не срабатывает, проверьте: существует ли команда с таким именем в дереве команд формы (имя чувствительно к регистру в коде), не перекрыта ли она настройкой доступности, выполняется ли вызов на клиенте, а не на сервере. Текст исключения «Команда не найдена» почти всегда означает опечатку в имени.

Контрольные точки

Как проверить результат

Команда выполнилась
Норма

Нет исключения, данные формы изменились ожидаемо

Тревожный признак

Ошибка «Метод объекта не обнаружен» или «Команда не найдена»

Стандартная команда Записать
Норма

Признак Модифицированность сброшен, объект записан в базу

Тревожный признак

Форма осталась модифицированной, запись не произошла

Вызов из другой формы
Норма

Экспортный метод отработал, форма открыта

Тревожный признак

Ошибка обращения — форма уже закрыта или ссылка потеряна

Типичные ошибки и ограничения

Самая частая ошибка — попытка вызвать ВыполнитьКоманду в серверном обработчике. Команды формы живут на клиенте; на сервере нужно работать с объектом данных напрямую. Вторая типичная проблема — вызов команды, которая недоступна в текущем состоянии формы: платформа может проигнорировать её или выдать ошибку, если команда отключена по функциональным опциям.

Ещё одна ловушка — рекурсивный вызов: обработчик команды вызывает сам себя через ВыполнитьКоманду, что приводит к переполнению стека. Перед программным вызовом убедитесь, что внутри обработчика нет обратного вызова инициирующей команды.

Типичные ошибки
01
Вызов ВыполнитьКоманду в контексте &НаСервере — метод недоступен, нужна работа с объектом данных напрямую
02
Опечатка в имени команды строкой — компилятор не проверяет строковые имена, ошибка всплывёт только в runtime
03
Вызов команды закрытой формы из другой формы — обращение к несуществующему объекту и падение кода
04
Ожидание возвращаемого значения от ВыполнитьКоманду — метод не сообщает об успехе, результат проверяют по состоянию данных

FAQ

Можно ли вызвать команду формы из общего модуля?

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

Как вызвать команду с параметрами?

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

Почему ВыполнитьКоманду("Записать") не задаёт вопросы пользователю?

Поведение зависит от настроек и контекста. Для явного интерактива используйте метод Записать() формы или покажите вопрос сами через ПоказатьВопрос перед вызовом команды, а в обработчике ответа уже выполняйте запись.

Как узнать имена всех команд формы программно?

Переберите коллекцию ЭтаФорма.Команды в цикле — у каждого элемента есть свойства Имя, Заголовок, Действие. Это удобно для отладки, когда непонятно, под каким именем команда доступна.

Работает ли ВыполнитьКоманду в обычных (неуправляемых) формах?

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

Как вызвать команду глобального командного интерфейса?

Для этого есть метод ВыполнитьКомандуИнтерфейса — он доступен в клиентском контексте и выполняет команды интерфейса приложения, а не конкретной формы. Не путайте его с ВыполнитьКоманду формы.

Итог

Что важно запомнить

Внутри формы команду вызывают через ЭтаФорма.ВыполнитьКоманду(Имя) на клиенте или прямым вызовом процедуры-обработчика. На сервере команд нет — там работают с объектом данных. Извне формы используют экспортные методы или оповещения, а результат проверяют по состоянию данных, а не по возвращаемому значению.