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