Разработка и Конфигурация · 10 мин
Как вызвать команду формы в 1С: программные способы и примеры
Как вызвать команду формы в 1С: метод ВыполнитьКоманду, программный вызов команд формы и объекта, типичные ошибки, примеры кода на встроенном языке.
В управляемых формах 1С часто возникает задача: выполнить команду формы не по нажатию кнопки, а программно — из обработчика другого события, из клиентского или серверного контекста. Типовой сценарий — имитация нажатия кнопки «Записать», «Провести», вызов команды перечитать данные или выполнить произвольную команду, созданную разработчиком в дереве команд формы.
Для этого платформа предоставляет несколько механизмов: метод ВыполнитьКоманду() у расширения формы, прямой вызов процедуры-обработчика команды, а также выполнение стандартных команд объекта через ВыполнитьКомандуИнтерактивно и смежные приёмы. У каждого способа есть ограничения по контексту исполнения (клиент или сервер) и по видимости команды.
Ниже разобраны рабочие способы вызова команд формы с примерами кода, условия выбора подходящего метода, проверка результата и типичные ошибки, из-за которых команда «не срабатывает».
Что такое команда формы и где она живёт
Команда формы — это именованное действие, объявленное в дереве команд формы (закладка «Команды» в редакторе формы) или унаследованное от объекта данных (например, стандартные команды документа: «Провести», «Записать», «Провести и закрыть»). Каждая команда имеет имя, заголовок, картинку, сочетание клавиш и обработчик — процедуру в модуле формы.
Команда становится видимой пользователю, когда её перетаскивают в дерево элементов формы как кнопку, пункт меню «Ещё» или командную панель. Но сама команда существует независимо от кнопки: её можно вызвать программно, даже если на форме нет ни одного связанного элемента.
Важно различать два уровня: команда формы (объявлена разработчиком в конкретной форме) и стандартная команда расширения формы (например, команды работы с объектом, динамическим списком). Оба вида вызываются программно, но синтаксис немного отличается.
Способ 1. Метод ВыполнитьКоманду
Основной универсальный приём — метод ВыполнитьКоманду(). Он доступен у объекта управляемой формы и принимает имя команды строкой или саму команду формы:
&НаКлиенте
Процедура ПровестиДокументПрограммно(Команда)
ЭтаФорма.ВыполнитьКоманду("Провести");
КонецПроцедуры
Метод работает и для стандартных команд объекта, если они доступны форме: ЭтаФорма.ВыполнитьКоманду("Записать"), ЭтаФорма.ВыполнитьКоманду("ПровестиИЗакрыть"). Платформа выполняет ту же логику, что и при нажатии соответствующей кнопки, включая серверные вызовы и вопросы пользователю.
Для команд динамического списка и других расширений формы применяется обращение через свойство расширения, например ЭтаФорма.РасширениеДинамическогоСписка — там доступны свои методы выполнения команд. Конкретный набор зависит от типа основного реквизита формы.
Способ 2. Прямой вызов обработчика команды
Если команда объявлена в модуле текущей формы, её обработчик — обычная процедура. Её можно вызвать напрямую, передав параметр Команда. Проще всего передать Неопределено, если внутри обработчика параметр не используется:
&НаКлиенте
Процедура КнопкаОбновить(Команда)
// вызываем обработчик другой команды
ОбновитьДанные(Неопределено);
КонецПроцедуры
&НаКлиенте
Процедура ОбновитьДанные(Команда)
// логика обновления
КонецПроцедуры
Если обработчик использует свойства параметра Команда (например, Команда.Имя), нужно передать реальный объект команды. Его можно получить из коллекции команд формы: ЭтаФорма.Команды.Найти("ОбновитьДанные").
Этот способ быстрее и прозрачнее для отладки, но работает только внутри модуля той же формы и только если директивы компиляции (&НаКлиенте / &НаСервере) совместимы с местом вызова.
Способ 3. Вызов команды из другой формы
Иногда нужно «нажать кнопку» в открытой форме извне — например, из формы обработки или из общего модуля. Для этого сначала получают ссылку на форму, затем вызывают её экспортную процедуру:
// в форме-источнике объявлена экспортная процедура
&НаКлиенте
Процедура ВыполнитьОбновление() Экспорт
ЭтаФорма.ВыполнитьКоманду("ОбновитьДанные");
КонецПроцедуры
// вызов извне
ФормаДокумента = ПолучитьФормуДокумента(); // способ получения зависит от задачи
Если ФормаДокумента <> Неопределено И ФормаДокумента.Открыта() Тогда
ФормаДокумента.ВыполнитьОбновление();
КонецЕсли;
Напрямую вызывать ВыполнитьКоманду чужой формы технически возможно, если есть ссылка на форму, но устойчивая практика — создать в целевой форме экспортный метод-обёртку с понятным именем. Тогда при переименовании команды внешний код не сломается.
Альтернатива для слабосвязанного взаимодействия — оповещения: Оповестить("ОбновитьДанныеДокумента", Параметры, Владелец) в одной форме и обработчик ОбработкаОповещения в другой. Это безопаснее, потому что не требует хранить ссылку на форму.
Сравнение вариантов
Универсально, повторяет поведение кнопки, включая стандартные команды. Только на клиенте внутри формы.
Быстро и удобно отлаживать, но только внутри своего модуля формы и без стандартной логики платформы.
Для вызова извне; требует контроля, что форма открыта, и ссылки на неё.
Слабая связанность между формами; нет гарантии, что получатель существует и обработает событие.
Вызов стандартных команд объекта: записать и провести
Частая задача — программно записать или провести документ из его формы. Здесь есть два уровня решения, и важно не смешивать их.
На клиенте корректно вызвать команду формы: ЭтаФорма.ВыполнитьКоманду("Записать") или ЭтаФорма.Записать() — оба варианта выполнят стандартную логику с вопросами пользователю при необходимости. Метод Записать() формы принимает параметры, например режим записи.
На сервере формы (в обработчике &НаСервере) работают иначе: получают объект через РеквизитФормыВЗначение("Объект"), вызывают Объект.Записать(РежимЗаписиДокумента.Проведение) и возвращают данные в форму через ЗначениеВРеквизитФормы. Вызвать «команду формы» на сервере нельзя — команды существуют только в клиентском контексте.
&НаКлиенте
Процедура ПровестиИзКода(Команда)
Если ЭтаФорма.Модифицированность Тогда
ЭтаФорма.Записать();
КонецЕсли;
ЭтаФорма.ВыполнитьКоманду("Провести");
КонецПроцедурыПроверка результата и контроль ошибок
Метод ВыполнитьКоманду не возвращает осмысленный результат успеха — команда считается выполненной, если не возникло исключения. Поэтому результат проверяют по косвенным признакам: снятию модифицированности после «Записать», изменению признака проведения объекта, обновлению данных на форме.
Если команда не срабатывает, проверьте: существует ли команда с таким именем в дереве команд формы (имя чувствительно к регистру в коде), не перекрыта ли она настройкой доступности, выполняется ли вызов на клиенте, а не на сервере. Текст исключения «Команда не найдена» почти всегда означает опечатку в имени.
Как проверить результат
Нет исключения, данные формы изменились ожидаемо
Ошибка «Метод объекта не обнаружен» или «Команда не найдена»
Признак Модифицированность сброшен, объект записан в базу
Форма осталась модифицированной, запись не произошла
Экспортный метод отработал, форма открыта
Ошибка обращения — форма уже закрыта или ссылка потеряна
Типичные ошибки и ограничения
Самая частая ошибка — попытка вызвать ВыполнитьКоманду в серверном обработчике. Команды формы живут на клиенте; на сервере нужно работать с объектом данных напрямую. Вторая типичная проблема — вызов команды, которая недоступна в текущем состоянии формы: платформа может проигнорировать её или выдать ошибку, если команда отключена по функциональным опциям.
Ещё одна ловушка — рекурсивный вызов: обработчик команды вызывает сам себя через ВыполнитьКоманду, что приводит к переполнению стека. Перед программным вызовом убедитесь, что внутри обработчика нет обратного вызова инициирующей команды.
FAQ
Можно ли вызвать команду формы из общего модуля?
Напрямую — нет, потому что в общем модуле нет ссылки на форму. Нужно передать форму как параметр в экспортную процедуру общего модуля или использовать механизм оповещений: общий модуль вызывает Оповестить, а форма реагирует в ОбработкаОповещения.
Как вызвать команду с параметрами?
Метод ВыполнитьКоманду принимает только имя команды, параметры передать нельзя. Если обработчику нужны данные, сохраните их в реквизит формы перед вызовом и прочитайте внутри обработчика, либо вызывайте процедуру-обработчик напрямую с нужными аргументами.
Почему ВыполнитьКоманду("Записать") не задаёт вопросы пользователю?
Поведение зависит от настроек и контекста. Для явного интерактива используйте метод Записать() формы или покажите вопрос сами через ПоказатьВопрос перед вызовом команды, а в обработчике ответа уже выполняйте запись.
Как узнать имена всех команд формы программно?
Переберите коллекцию ЭтаФорма.Команды в цикле — у каждого элемента есть свойства Имя, Заголовок, Действие. Это удобно для отладки, когда непонятно, под каким именем команда доступна.
Работает ли ВыполнитьКоманду в обычных (неуправляемых) формах?
Нет, метод относится к управляемым формам. В обычных формах обработчики кнопок вызываются как обычные процедуры модуля формы, а стандартные действия выполняются методами объекта (Записать, Провести).
Как вызвать команду глобального командного интерфейса?
Для этого есть метод ВыполнитьКомандуИнтерфейса — он доступен в клиентском контексте и выполняет команды интерфейса приложения, а не конкретной формы. Не путайте его с ВыполнитьКоманду формы.
Что важно запомнить
Внутри формы команду вызывают через ЭтаФорма.ВыполнитьКоманду(Имя) на клиенте или прямым вызовом процедуры-обработчика. На сервере команд нет — там работают с объектом данных. Извне формы используют экспортные методы или оповещения, а результат проверяют по состоянию данных, а не по возвращаемому значению.