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