Пять способов создать действие в форме 1С 8.3
Содержание
«Действие» в 1С 8.3 — это команда формы (или общая команда) и привязанный к ней обработчик. Чтобы добавить действие, нужно создать команду
, вывести её на форму кнопкой и написать процедуру-обработчик. Самый быстрый путь — конфигуратор, вкладка Команды формы; задача из кода решается через свойство Действие команды.
Ниже — пять рабочих способов: от мышки без единой строки кода до динамического создания кнопок на лету. Для каждого дам точный путь в конфигураторе и проверенный пример. В конце — права доступа и ошибки, на которых спотыкаются новички.
Все пути и примеры рассчитаны на платформу 8.3.2x с интерфейсом «Такси». В толстом клиенте обычных форм (8.1/8.2) термин «действие кнопки» означал то же самое, но редактор там другой.
Что в 1С называют «действием» и из чего оно состоит
У любого действия на форме три части, и путать их — главная причина, почему кнопка «не работает »:
- 🔹 Команда — объект, у которого есть заголовок, картинка и свойство
Действие(имя процедуры-обработчика). Сама по себе команда невидима. - 🔸 Кнопка (элемент формы) — то, что видит пользователь. Кнопка ссылается на команду через свойство
ИмяКоманды. - 🟢 Обработчик — процедура в модуле формы или модуле команды, где и лежит логика.
Команды бывают трёх видов, и от этого зависит способ:
| Вид команды | Где создаётся | Для чего |
|---|---|---|
| Команда формы | Вкладка Команды формы редактора формы | Действие на одной конкретной форме |
| Общая команда | Ветка Общие → Общие команды дерева конфигурации | Одно действие на многих формах/объектах |
| Стандартная команда | Генерируется платформой | Записать, Провести, Обновить — их не добавляют |
Кнопка без команды и команда без обработчика — две самые частые пустышки. Проверяйте цепочку целиком: кнопка → команда → процедура.
Отдельно оговорюсь про путаницу. Новички иногда ищут «действие» в начальной странице — там есть панель с виджетами, но к командам форм она отношения не имеет. Если задача — «чтобы по нажатию что-то происходило на форме документа, справочника или обработки», вам нужна команда, а не настройка рабочего стола.
Способ 1. Команда и кнопка через конфигуратор без кода
Подойдёт, когда обработчик пишется позже, а пока нужно вывести кнопку и каркас процедуры.
- Откройте форму в конфигураторе: двойной клик по форме в дереве объекта (например,
Документ → ЗаказПокупателя → Формы → ФормаДокумента). - В окне редактора формы перейдите на вкладку
Команды формы(панель слева, рядом с «Элементы» и «Реквизиты»). - Нажмите зелёный плюс — добавится новая команда. В палитре свойств задайте имя латиницей (например,
ОтметитьВыполнение) иЗаголовоккириллицей — он попадёт на кнопку. - В строке свойства
Действиенажмите лупу. Конфигуратор сам создаст пустую процедуру&НаКлиентев модуле формы и откроет её. - Вернитесь на вкладку
Элементы, перетащите команду мышкой из списка команд на нужную группу формы (например, на командную панель). Появится кнопка.
Сохраните конфигурацию (F7) и обновите базу (F11 в режиме отладки). Кнопка уже на форме — остаётся наполнить обработчик, об этом ниже.
Чтобы кнопка не выглядела безликой, в свойствах команды задайте Картинку из стандартной библиотеки и Подсказку — короткий текст, который всплывёт при наведении. Для кнопки на форме можно выбрать режим отображения: только текст, только картинка или всё вместе. Это мелочь, но она заметно влияет на то, найдёт ли пользователь ваше действие.
Если вы правите типовую конфигурацию (БП 3.0, ЗУП 3.1, УТ 11), снимите замок с объекта — конфигурация встанет на полную поддержку, и типовое обновление усложнится. Чистый способ не трогать типовую — расширение (способ 4).
Способ 2. Обработчик команды в модуле формы
Логику действия пишут в модуле формы, разделяя клиент и сервер директивами компиляции. Клиент реагирует на нажатие, но к данным базы ходит только сервер.
&НаКлиенте
Процедура ОтметитьВыполнение(Команда)
ЗаписатьОтметкуНаСервере();
Сообщить("Отметка сохранена");
КонецПроцедуры
&НаСервере
Процедура ЗаписатьОтметкуНаСервере()
Объект.Выполнено = Истина;
// при необходимости записать: ЗаписатьДанныеФормы() или Записать() в форме документа
КонецПроцедуры
Разберём, что здесь важно:
- 🔹 Обработчик команды всегда
&НаКлиентеи принимает один параметрКоманда. Имя процедуры должно совпадать со значением свойстваДействие. - 🔸 Работа с реквизитами объекта, запросами и регистрами — только в
&НаСервере. Из клиентской процедуры серверную вызывают по имени. - 🟢 Данные формы редактируются через
Объект.<Реквизит>, а не через ссылку из базы напрямую.
Если действию нужны данные с сервера без контекста формы — используйте директиву &НаСервереБезКонтекста: она быстрее, потому что не передаёт на сервер и обратно данные формы. Такую процедуру делают, когда результат зависит только от переданных параметров:
&НаКлиенте
Процедура ПересчитатьИтог(Команда)
Итог = ПолучитьИтогПоТаблице(Объект.Товары.Выгрузить());
Сообщить("Сумма по строкам: " + Формат(Итог, "ЧГ=0"));
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьИтогПоТаблице(ТаблицаТоваров)
Возврат ТаблицаТоваров.Итог("Сумма");
КонецФункции
Число со строкой склеиваем через Формат(...) — иначе платформа подставит разделители разрядов не так, как ожидаешь. Клиент здесь только собирает данные и показывает результат, а расчёт идёт на сервере.
Способ 3. Общая команда для нескольких форм
Когда одно действие нужно на десятке форм или прямо из списка документов, команду формы на каждой заводить бессмысленно. Делают общую команду.
- В дереве конфигурации раскройте
Общие → Общие команды, добавьте новую. - В свойстве
Группавыберите, где команда появится: панель навигации формы, панель действий, командная панель списка и т. д. - В
Тип параметра командыукажите объект, с которым работает команда (например,ДокументСсылка.ЗаказПокупателя). Тогда платформа сама покажет команду на формах и в списках этого документа. - Откройте модуль команды и заполните процедуру
ОбработкаКоманды.
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
// ПараметрКоманды — ссылка на объект (или массив ссылок при групповой обработке)
ПараметрыФормы = Новый Структура("Основание", ПараметрКоманды);
ОткрытьФорму("Обработка.ПечатьЭтикеток.Форма", ПараметрыФормы);
КонецПроцедуры
Сигнатура фиксированная: ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды). Первый параметр — выбранный объект (или массив, если Использование параметра команды = Множественное).
Общая команда с типом параметра автоматически доступна из формы списка и формы объекта — не нужно вручную размещать кнопку на каждой форме.
Способ 4. Добавить действие в расширении, не трогая типовую
Расширения конфигурации появились в 8.3.6 и решают главную боль: добавить кнопку в типовую БП или ЗУП так, чтобы она пережила обновление.
- В конфигураторе откройте
Конфигурация → Расширения конфигурации, создайте расширение (назначение —Дополнение). - В расширении заимствуйте нужную форму: правый клик по форме в основной конфигурации →
Добавить в расширение. - В заимствованной форме добавьте команду и кнопку ровно как в способе 1, напишите обработчик.
- Сохраните расширение и обновите конфигурацию базы.
Через меню Администрирование → Печатные формы, отчёты и обработки (в режиме предприятия) расширение можно подключить и файлом .cfe, не заходя в конфигуратор.
Загрузка .cfe и «Обновить конфигурацию
базы данных» — два разных шага. Пока вы не обновили конфигурацию БД, изменения в базе не появятся.
Заимствуя форму, не меняйте её реквизиты и обработчики без необходимости: чем меньше правок в расширении, тем надёжнее оно встанет поверх следующего релиза типовой.
Способ 5. Динамическое добавление команды кодом
Иногда кнопку нужно создавать на лету — например, только для определённых пользователей или в зависимости от данных. Это делают в обработчике ПриСозданииНаСервере.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
НоваяКоманда = Команды.Добавить("ОбновитьДанные");
НоваяКоманда.Действие = "ОбновитьДанныеНаКлиенте";
НоваяКоманда.Заголовок = "Обновить";
Кнопка = Элементы.Добавить("КнопкаОбновить", Тип("КнопкаФормы"), Элементы.ФормаКоманднаяПанель);
Кнопка.ИмяКоманды = "ОбновитьДанные";
КонецПроцедуры
&НаКлиенте
Процедура ОбновитьДанныеНаКлиенте(Команда)
// логика действия
КонецПроцедуры
На что обратить внимание:
- 🔹 Свойство
Действиеновой команды — это имя уже существующей&НаКлиенте-процедуры. Создать саму процедуру динамически нельзя, она должна быть в модуле формы заранее. - 🔸 Третий параметр
Элементы.Добавить— родитель (группа или командная панель). Точное имя панели возьмите из дерева элементов своей формы; если его нет — сначала создайте группу. - 🟢 Процедура-обработчик принимает параметр
Команда, как и в способе 2.
Так удобно строить переменный набор кнопок, но не злоупотребляйте: статически описанная команда нагляднее и легче сопровождается. Динамика оправдана, когда состав действий заранее неизвестен — например, кнопки формируются по списку подключённых отчётов или по настройкам пользователя. Если же набор кнопок фиксирован, опишите команды на вкладке Команды формы — отлаживать такую форму проще, а код модуля не разрастается.
Права доступа: кто увидит и запустит действие
Добавить кнопку мало — надо решить, кому она видна. Механизмов несколько, применяйте подходящий:
- Роли. У общей команды в ролях есть право
Просмотр. Снимите его — и пользователи с этой ролью команду не увидят. Это основной способ разграничения для общих команд. - Видимость элемента по ролям. У кнопки на форме в свойстве видимости можно задать настройку по ролям: часть пользователей увидит кнопку, часть — нет.
- Функциональные опции. Привяжите команду или элемент к функциональной опции — кнопка появляется, только когда опция включена в настройках.
- Проверка в коде. Внутри обработчика можно явно проверить право:
Если РольДоступна("ПолныеПрава") Тогда .... Удобно, когда действие опасное и его нельзя запускать «обычному» пользователю.
Видимость по ролям и функциональные опции только скрывают кнопку. Если действие критично (списание, проведение, изменение чужих данных), дублируйте проверку прав и в серверном обработчике — скрытая кнопка не защищает от вызова команды из кода.
Ограничение доступа к самим данным (RLS, ограничения на уровне записей) — это отдельный механизм ролей, не связанный с кнопкой. Видимость команды управляет интерфейсом, а RLS решает, какие записи пользователь вообще имеет право прочитать и изменить. Для действия, которое массово меняет документы, продумайте оба уровня: и кому видна кнопка, и к каким записям у роли есть доступ.
Частые ошибки при добавлении действия
Ошибки почти всегда в разрыве цепочки «кнопка → команда → процедура» или в путанице клиент/сервер.
- ❌ Кнопка есть, но ничего не происходит. Чаще всего не заполнено свойство
Действиекоманды или имя процедуры не совпадает с ним. Сверьте строку в строку. - ❌ «Процедура не обнаружена» при нажатии. Обработчик объявлен без директивы
&НаКлиентелибо лежит не в том модуле. У команды формы процедура — в модуле формы, у общей команды — в модуле команды. - ❌ Обращение к
Объектили запросу из клиентской процедуры. К данным базы ходят только с сервера. Вынесите работу в&НаСервере-процедуру и вызовите её. - ❌ Команда создана, кнопки нет. Команду забыли перетащить на вкладку
Элементы. Без кнопки команда формы недоступна пользователю. - ❌ Правки в типовой слетели после обновления. Действие добавили прямо в типовую конфигурацию , а не в расширение. Перенесите в расширение (способ 4).
Чем команда отличается от действия в 1С?
Действие. Само действие — процедура-обработчик, на которую команда ссылается. В разговоре «добавить действие» обычно означает «создать команду и написать её обработчик».Почему кнопка серая и не нажимается?
Действие, либо кнопка связана с командой, у которой нет обработчика, либо сработало ограничение по роли или функциональной опции. Проверьте по очереди свойство Действие, ИмяКоманды кнопки и права.Можно ли добавить кнопку в типовую, не снимая её с поддержки?
Где писать обработчик общей команды?
ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды). Модуль формы здесь не используется.Как сделать действие доступным только администратору?
Просмотр у лишних ролей. Для кнопки на форме задайте видимость по ролям или привяжите к функциональной опции, а в серверном обработчике продублируйте проверку РольДоступна().