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

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

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

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

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

Чаще всего задача «выполнить команду формы» возникает, когда нужно повторно использовать уже написанный обработчик: например, после изменения данных программно «нажать» кнопку пересчёта, обновления или сохранения. В управляемых формах для этого есть прямой механизм — вызов процедуры-обработчика или использование стандартных команд через ЭтаФорма.

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

Как устроена команда формы в 1С

Команда формы создаётся в конфигураторе на закладке «Команды» редактора формы. У каждой команды есть имя, заголовок, картинка, сочетание клавиш и обработчик действия. Обработчик — это процедура вида &НаКлиенте Процедура ИмяКоманды(Команда), которая выполняется при нажатии кнопки, связанной с командой.

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

Обработчик команды может быть клиентским, серверным или клиентским с вызовом серверной процедуры. Если логика работает с данными базы, правильный шаблон — клиентский обработчик, который вызывает серверную процедуру без контекста или в контексте формы.

Программный вызов команды внутри той же формы

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

bsl
&НаКлиенте
Процедура ПослеВводаКоличества(Элемент)
	// программно выполняем команду пересчёта
	ПересчитатьИтоги(Команды.ПересчитатьИтоги);
КонецПроцедуры

&НаКлиенте
Процедура ПересчитатьИтоги(Команда)
	// логика команды
КонецПроцедуры

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

Для стандартных команд формы (Записать, Провести, Перечитать) прямой вызов обработчика не нужен — у формы есть встроенные методы с тем же эффектом: ЭтаФорма.Записать(), ЭтаФорма.Прочитать(), ЭтаФорма.Закрыть(). Они выполняют те же действия, что и соответствующие кнопки командной панели, включая проверки заполнения и вопросы пользователю.

Выполнение команды с серверной логикой

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

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

Как программно выполнить серверную команду формы
  1. 1
    Убедитесь, что у команды есть клиентский обработчик с директивой &НаКлиенте
  2. 2
    Из нужного места модуля формы вызовите обработчик: ИмяКоманды(Команды.ИмяКоманды)
  3. 3
    Внутри обработчика при необходимости вызовите серверную процедуру &НаСервере
  4. 4
    Проверьте, что после выполнения форма обновила отображаемые данные (ЭтаФорма.ОбновитьОтображениеДанных() при необходимости)

Вызов команды другой формы

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

Первый вариант — оповещения. Форма-источник вызывает Оповестить("ИмяСобытия", Параметры, Источник), а форма-приёмник обрабатывает событие в ОбработкаОповещения и внутри него уже выполняет свою команду. Это стандартный способ «нажать кнопку» в другой форме.

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

Способы выполнить действие в другой форме

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

Гибкий способ для произвольных команд; требует, чтобы целевая форма была открыта и содержала обработчик события

ОповеститьОбИзменении(Ссылка)

Подходит для обновления форм после записи объекта; работает только со стандартной реакцией на изменение данных

ОписаниеОповещения при открытии формы

Выполняет действие в исходной форме после закрытия дочерней; не подходит для уже открытых независимых форм

Команды объекта и глобальные команды

Помимо команд формы, в 1С есть команды, определённые в метаданных: команды справочников, документов, отчётов и общие команды. Их нельзя «выполнить» как процедуру — они либо открывают форму, либо вызывают обработчик команды в модуле менеджера объекта или общем модуле.

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

Маршрут решения

Как выбрать способ выполнения

Нужно повторить действие кнопки в той же формеВызовите обработчик команды напрямую: ИмяКоманды(Команды.ИмяКоманды)
Нужно записать, провести или перечитать объект формыИспользуйте встроенные методы формы: Записать(), Прочитать(), Закрыть()
Нужно выполнить действие в другой открытой формеИспользуйте Оповестить() и ОбработкаОповещения в целевой форме
Логика нужна вне формы (фоновое задание, веб-сервис)Вынесите код в общий модуль или модуль менеджера и вызывайте его, а не команду формы

Команды формы в обычном приложении

В обычных формах (толстый клиент, режим обычного приложения) механика проще, потому что нет разделения на клиент и сервер внутри модуля формы. Обработчик команды вызывается так же — как обычная процедура, а кнопки командной панели имеют свойство «Действие», где указана процедура. Программный вызов сводится к вызову этой процедуры с нужными параметрами.

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

Типичные ошибки и проверка результата

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

Вторая типичная проблема — команда выполняется, но интерфейс не меняется. Это происходит, когда данные изменены на сервере, а форма продолжает показывать старое состояние. Решение — вызвать ЭтаФорма.ОбновитьОтображениеДанных() или ЭтаФорма.Прочитать() для полного перечитывания объекта.

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

Как проверить, что команда выполнилась

Изменение данных объекта
Норма

После вызова команды реквизиты формы содержат новые значения

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

Данные на форме не изменились — вероятно, логика отработала на сервере без обновления формы

Запись в базе
Норма

После Записать() свойство Модифицированность сброшено, объект доступен по ссылке

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

Модифицированность осталась Истина — запись не выполнена, проверьте ошибки проверки заполнения

Отсутствие ошибок
Норма

Команда завершается без сообщений об ошибках в журнале регистрации

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

В журнале регистрации ошибки вызова метода — проверьте имена процедур и директивы компиляции

FAQ

Можно ли выполнить команду формы по её имени строкой?

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

Как программно «нажать» стандартную кнопку «Записать и закрыть»?

Используйте метод формы Записать(), а после успешной записи — Закрыть(). Отдельного метода «ЗаписатьИЗакрыть» у формы нет, последовательность из двух вызовов даёт тот же результат.

Почему обработчик команды не виден при вызове из другого обработчика?

Проверьте директивы компиляции: процедура &НаСервере недоступна из кода &НаКлиенте напрямую, если не объявлена корректно, а процедура &НаКлиенте недоступна на сервере. Также убедитесь, что процедура объявлена с ключевым словом Экспорт, если вызывается извне модуля.

Как выполнить команду формы из фонового задания?

Никак — у фонового задания нет доступа к интерфейсу и формам. Логику команды нужно вынести в общий серверный модуль и вызывать её и из обработчика команды, и из фонового задания.

Чем отличается команда формы от общей команды конфигурации?

Команда формы существует только внутри конкретной формы и привязана к её контексту. Общая команда описывается в метаданных конфигурации, доступна из командного интерфейса и её обработчик размещается в модуле команды, а не в форме.

Можно ли отключить стандартную команду формы?

Да. В редакторе формы на закладке «Командный интерфейс» или через свойства кнопки можно скрыть стандартную команду, а в событиях формы (например, ПередЗаписью с Отказ = Истина) — заблокировать её действие по условию.

Итог

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

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