Кнопка на форме 1С через расширение: от метаданных до обработчика

· 9 мин

Содержание

Добавить команду в командную панель формы 1С можно двумя способами. Первый: нарисовать команду в редакторе формы расширения и перетащить её в панель. Второй: создать команду и кнопку кодом в ПриСозданииНаСервере. Первый проще и нагляднее, второй нужен, когда набор кнопок зависит от прав, настроек или данных.

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

Подготовка: расширение и заимствование формы

Сначала нужен контейнер для ваших изменений. Откройте Конфигуратор, выберите Конфигурация → Расширения конфигурации и нажмите «Добавить». Задайте имя и префикс. Префикс (например, Расш1_) потом ставится перед всеми новыми именами, чтобы они не пересеклись с типовыми.

Затем заимствуйте то, что будете менять:

  1. В дереве расширения вызовите контекстное меню у нужного объекта (документ, справочник, обработка) и выберите «Заимствовать объекты из основной конфигурации».
  2. Отметьте сам объект и его форму. Форму нужно заимствовать явно, иначе её не получится открыть в расширении.
  3. Откройте заимствованную форму двойным щелчком. Редактор покажет те же закладки, что и в обычной конфигурации: «Элементы», «Команды», «Реквизиты».

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

Какой способ выбрать — подскажет таблица.

СпособКогда подходитОграничения
Команда в форме расширения (визуально)Кнопка нужна всем и всегдаКаждую форму правите отдельно
Общая команда расширенияОдна кнопка на многих формах разных объектовМенее гибко управлять видимостью
Программное создание в ПриСозданииНаСервереСостав кнопок зависит от прав, роли, данныхНужно следить за уникальностью имён

Создание команды на закладке «Команды»

Перейдите на закладку «Команды» и нажмите «Добавить». Заполните свойства:

  • 🏷 Имя — с префиксом расширения, например Расш1_ПечатьАкта;
  • 📝 Заголовок — то, что увидит пользователь на кнопке;
  • 💬 Подсказка — всплывающий текст при наведении;
  • 🖼 Картинка — из библиотеки картинок, если кнопка должна быть узнаваемой;
  • ⚙ Действие — имя процедуры-обработчика. Нажмите на лупу, платформа создаст заготовку в модуле формы.

Заготовка получится клиентской:

&НаКлиенте
Процедура Расш1_ПечатьАкта(Команда)
	// здесь будет вызов
КонецПроцедуры

Обработчик пока пустой, к нему мы вернёмся ниже. Сначала разместим команду на форме.

Размещение кнопки в командной панели формы

Команда без кнопки пользователю не видна. Откройте закладку «Элементы», найдите в дереве элемент командной панели формы (обычно он называется ФормаКоманднаяПанель) и добавьте в него кнопку.

Самый быстрый путь: перетащите команду с закладки «Команды» на нужную группу в «Элементах». Платформа создаст кнопку и привяжет её сама. Можно и вручную: правый щелчок на группе, «Добавить» → «Кнопка формы», затем в свойстве «Имя команды» выберите свою команду.

Два свойства кнопки стоит проверить сразу:

  • Вид — «Кнопка командной панели» для обычной кнопки в панели или «Гиперссылка командной панели» для текстовой ссылки;
  • Расположение — порядок задаётся положением в дереве, перетащите кнопку выше или ниже соседей.

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

Общая команда для нескольких форм

Когда одна и та же кнопка нужна на формах десятка документов, не копируйте её руками. Создайте в расширении общую команду: ветка «Общие команды» → «Добавить». У неё есть три важных свойства:

  • Группа — куда команда встанет на форме (командная панель формы, панель действий, панель навигации );
  • Тип параметра команды — список объектов, на чьих формах кнопка появится;
  • Модуль команды — процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды).

После этого кнопка сама встанет на все формы перечисленных объектов, и править каждую форму не придётся.

Серверный обработчик: как кнопка выполняет работу

Клиентская процедура только принимает нажатие. Всё, что читает или пишет данные, вызывайте на сервере. Типичная связка выглядит так:

&НаКлиенте
Процедура Расш1_ПечатьАкта(Команда)
	Если Не ЗначениеЗаполнено(Объект.Ссылка) Тогда
		ПоказатьПредупреждение(, "Сначала запишите документ.");
		Возврат;
	КонецЕсли;
	Результат = Расш1_ПодготовитьАктНаСервере();
	ПоказатьОповещениеПользователя("Готово", , Результат);
КонецПроцедуры

&НаСервере
Функция Расш1_ПодготовитьАктНаСервере()
	// работа с объектом и базой
	Возврат "Акт сформирован";
КонецФункции

Если серверной процедуре не нужны реквизиты формы, используйте &НаСервереБезКонтекста. Она работает быстрее, потому что платформа не передаёт на сервер весь контекст формы.

Новую процедуру в заимствованном модуле можно просто дописать. А вот для перехвата уже существующих обработчиков применяют аннотации:

  • &После("ИмяПроцедуры") — ваш код после типового;
  • &Перед("ИмяПроцедуры") — до типового;
  • &Вместо("ИмяПроцедуры") — полная замена, с вызовом ПродолжитьВызов() при необходимости.

Пример: подготовить форму после её создания.

&После("ПриСозданииНаСервере")
Процедура Расш1_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	// ваш код после типового
КонецПроцедуры

Создание команды и кнопки кодом

Когда состав кнопок меняется динамически, команду создают прямо при открытии формы. Этот код пишется в ПриСозданииНаСервере (удобно через &После, как выше):

Команда = Команды.Добавить("Расш1_ПечатьАкта");
Команда.Заголовок = "Печать акта";
Команда.Подсказка = "Сформировать и показать акт";
Команда.Действие  = "Расш1_ПечатьАкта";

Кнопка = Элементы.Добавить("Расш1_КнопкаПечатьАкта", Тип("КнопкаФормы"), Элементы.ФормаКоманднаяПанель);
Кнопка.Вид        = ВидКнопкиФормы.КнопкаКоманднойПанели;
Кнопка.ИмяКоманды = "Расш1_ПечатьАкта";

Что здесь важно:

  1. Действие — строка с именем процедуры. Сама процедура должна существовать в модуле формы и быть клиентской. Если её нет, платформа не найдёт обработчик при нажатии.
  2. Имена уникальны. Повторное Команды.Добавить или Элементы.Добавить с занятым именем вызовет ошибку. Перед созданием проверьте Команды.Найти(Имя) = Неопределено.
  3. Родитель кнопки — любая группа формы. Чтобы вставить кнопку не в конец, у метода Элементы.Вставить есть параметр «перед каким элементом».
  4. Создавать можно только на сервере в момент создания формы. После открытия менять состав команд нельзя.

Хотите кнопку в подменю? Сначала создайте группу: Элементы.Добавить("Расш1_Группа", Тип("ГруппаФормы"), Элементы.ФормаКоманднаяПанель), задайте ей Вид = ВидГруппыФормы.Подменю, а затем указывайте её родителем кнопки.

Видимость и доступность: кому и когда показывать кнопку

Кнопка, которую видят все, часто лишняя. Платформа даёт несколько рычагов, и они сочетаются.

В редакторе формы. У кнопки есть свойства «Видимость» и «Доступность». Для условия по роли или функциональной опции задайте их у команды: в свойстве «Функциональные опции» перечислите опции, при которых команда существует.

Из кода. Чаще всего меняют после ПриСозданииНаСервере или в обработчике события формы:

Элементы.Расш1_КнопкаПечатьАкта.Видимость   = ПравоДоступа("Просмотр", Метаданные.Документы.РеализацияТоваровУслуг);
Элементы.Расш1_КнопкаПечатьАкта.Доступность = Объект.Проведен;

Разница между свойствами простая:

  • 👁 Видимость = Ложь — кнопка исчезает совсем;
  • 🔒 Доступность = Ложь — кнопка видна, но серая; удобно, когда нужно показать, что действие существует, но сейчас недоступно.

Условие «документ проведён» или «статус равен…» нужно пересчитывать в обработчиках ПриЧтенииНаСервере и ПослеЗаписиНаСервере, а не только при открытии. Иначе после записи кнопка останется в старом состоянии.

Права пользователя проверяйте в коде явно, а не полагайтесь на то, что роль «спрячет» кнопку сама: команда без ограничений доступна всем, у кого открыта форма.

Какой вариант выбрать для вашего случая

Для кого нужна кнопка?

Контекст команды: с каким объектом работает кнопка

Кнопка в командной панели списка и кнопка в форме элемента получают данные по-разному. Это частая причина «не работает на списке».

Форма элемента. Текущий объект лежит в реквизите Объект. Если документ ещё не записан, Объект.Ссылка пустая, поэтому в начале обработчика проверяйте ЗначениеЗаполнено(Объект.Ссылка) и предлагайте записать.

Форма списка. Объекта нет, есть выделенные строки. Берите их из элемента формы:

&НаКлиенте
Процедура Расш1_ОбработатьВыбранные(Команда)
	Выбранные = Элементы.Список.ВыделенныеСтроки;
	Если Выбранные.Количество() = 0 Тогда
		ПоказатьПредупреждение(, "Выделите хотя бы одну строку.");
		Возврат;
	КонецЕсли;
	Расш1_ОбработатьНаСервере(Выбранные);
КонецПроцедуры

&НаСервереБезКонтекста
Процедура Расш1_ОбработатьНаСервере(Выбранные)
	Для Каждого Ссылка Из Выбранные Цикл
		Объект = Ссылка.ПолучитьОбъект();
		// действия с объектом
		Объект.Записать();
	КонецЦикла;
КонецПроцедуры

Общая команда. Здесь ссылки приходят параметром: ПараметрКоманды содержит выбранную ссылку или массив ссылок, в зависимости от настройки «Режим использования параметра команды». Выберите «Множественный», если кнопка должна работать сразу с несколькими строками списка.

Для длинных операций над сотнями документов не держите пользователя перед зависшей формой. Запускайте обработку фоновым заданием и показывайте индикатор: пакетная запись тысячи документов в одном серверном вызове упирается в таймаут клиента.

Заголовок, картинка и порядок кнопок

Мелочи решают, найдут ли кнопку. Заголовок формулируйте глаголом: «Сформировать акт», а не «Акт». Картинку берите из библиотеки стандартных картинок, чтобы она не выбивалась из интерфейса. Для кнопки с картинкой без текста обязательно заполните подсказку.

Порядок кнопок определяется положением в дереве элементов. Если нужно поставить свою кнопку строго перед типовой, при программном создании используйте Элементы.Вставить(Имя, Тип, Родитель, ПередЭлементом), а в редакторе просто перетащите её выше.

Префиксы и совместимость с обновлениями

Три правила, которые сохранят кнопку при смене релиза:

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

Последний пункт особенно важен для программного способа: если разработчики типовой конфигурации переименуют группу ФормаКоманднаяПанель, строка Элементы.ФормаКоманднаяПанель вызовет ошибку при открытии формы. Для страховки проверьте группу перед использованием: Родитель = Элементы.Найти("ФормаКоманднаяПанель"), и если вернулся Неопределено, добавляйте кнопку прямо в корень формы.

Отладка и проверка новых команд

После правки примените расширение к базе. В Конфигураторе запустите отладку (Отладка → Начать отладку) или обновите конфигурацию базы данных клавишей F7, затем откройте 1С:Предприятие под нужным пользователем. Поставьте точку останова в клиентской и серверной процедурах расширения: отладчик остановится в обеих.

Проверьте по списку:

Проверка новой команды
Выполнено: 0 / 6

Что чаще всего идёт не так:

  • 🚫 Кнопки нет вообще. Расширение отключено или не применено к базе. Проверьте список расширений в Конфигураторе: Конфигурация → Расширения конфигурации.
  • 🔁 Ошибка «Дублирование имени». Имя команды или элемента уже занято: либо вы добавили его и в редакторе, и в коде, либо метод вызывается дважды.
  • 🧩 Нажатие ничего не делает. В Команда.Действие указано имя, которого нет в модуле, или процедура объявлена как &НаСервере, а не &НаКлиенте.
  • 👤 У пользователя кнопки нет, у администратора есть. Сработало ограничение прав в коде видимости или доступа к объекту.
  • 🔄 После обновления типовой конфигурации форма «поехала». Откройте расширение и сравните заимствованную форму с обновлённой типовой: если разработчики переместили или переименовали элемент, вашу кнопку нужно перепривязать.

Частые вопросы

Можно ли добавить команду в обычное приложение (не управляемое)?
Описанный способ работает только для управляемых форм. В обычных формах панели настраиваются иначе, и расширения для них не применяются.
Нужно ли обязательно расширение?
Нет, но если вы правите типовую конфигурацию напрямую, обновление придётся объединять вручную. Для чужих конфигураций расширение — единственный безопасный путь.
Почему кнопка есть у меня, но не у коллег?
Чаще всего расширение не подключено в их базе или стоит ограничение по ролям в коде видимости. Откройте форму от имени такого пользователя и проверьте обе версии.
Можно ли поставить одну кнопку на все формы справочников?
Да. Создайте общую команду, укажите в типе параметра нужные справочники и поставьте группу «Командная панель формы».
Как задать горячую клавишу для команды?
В свойстве «Сочетание клавиш» команды. Выберите комбинацию, которую платформа и типовые команды ещё не заняли.