Кнопка на форме 1С через расширение: от метаданных до обработчика
Содержание
Добавить команду в командную панель формы 1С можно двумя способами. Первый: нарисовать команду в редакторе формы расширения и перетащить её в панель. Второй: создать команду и кнопку кодом в ПриСозданииНаСервере. Первый проще и нагляднее, второй нужен, когда набор кнопок зависит от прав, настроек или данных.
Правка типовой конфигурации напрямую закрывает вам путь к обновлениям. Поэтому всё ниже делается в расширении: типовой код остаётся нетронутым, а ваша кнопка переживает смену релиза. Речь об управляемых формах платформы 8.3 с интерфейсом «Такси».
Подготовка: расширение и заимствование формы
Сначала нужен контейнер для ваших изменений. Откройте Конфигуратор, выберите Конфигурация → Расширения конфигурации и нажмите «Добавить». Задайте имя и префикс. Префикс (например, Расш1_) потом ставится перед всеми новыми именами, чтобы они не пересеклись с типовыми.
Затем заимствуйте то, что будете менять:
- В дереве расширения вызовите контекстное меню у нужного объекта (документ, справочник, обработка) и выберите «Заимствовать объекты из основной конфигурации».
- Отметьте сам объект и его форму. Форму нужно заимствовать явно, иначе её не получится открыть в расширении.
- Откройте заимствованную форму двойным щелчком. Редактор покажет те же закладки, что и в обычной конфигурации: «Элементы», «Команды», «Реквизиты».
Если форм у объекта несколько, заимствуйте только ту, что нужна. Каждая лишняя заимствованная форма — это ещё одно место, которое платформа будет сверять при обновлении основной конфигурации.
Какой способ выбрать — подскажет таблица.
| Способ | Когда подходит | Ограничения |
|---|---|---|
| Команда в форме расширения (визуально) | Кнопка нужна всем и всегда | Каждую форму правите отдельно |
| Общая команда расширения | Одна кнопка на многих формах разных объектов | Менее гибко управлять видимостью |
Программное создание в ПриСозданииНаСервере | Состав кнопок зависит от прав, роли, данных | Нужно следить за уникальностью имён |
Создание команды на закладке «Команды»
Перейдите на закладку «Команды» и нажмите «Добавить». Заполните свойства:
- 🏷 Имя — с префиксом расширения, например
Расш1_ПечатьАкта; - 📝 Заголовок — то, что увидит пользователь на кнопке;
- 💬 Подсказка — всплывающий текст при наведении;
- 🖼 Картинка — из библиотеки картинок, если кнопка должна быть узнаваемой;
- ⚙ Действие — имя процедуры-обработчика. Нажмите на лупу, платформа создаст заготовку в модуле формы.
Заготовка получится клиентской:
&НаКлиенте
Процедура Расш1_ПечатьАкта(Команда)
// здесь будет вызов
КонецПроцедуры
Обработчик пока пустой, к нему мы вернёмся ниже. Сначала разместим команду на форме.
Размещение кнопки в командной панели формы
Команда без кнопки пользователю не видна. Откройте закладку «Элементы», найдите в дереве элемент командной панели формы (обычно он называется ФормаКоманднаяПанель) и добавьте в него кнопку.
Самый быстрый путь: перетащите команду с закладки «Команды» на нужную группу в «Элементах». Платформа создаст кнопку и привяжет её сама. Можно и вручную: правый щелчок на группе, «Добавить» → «Кнопка формы», затем в свойстве «Имя команды» выберите свою команду.
Два свойства кнопки стоит проверить сразу:
- Вид — «Кнопка командной панели» для обычной кнопки в панели или «Гиперссылка командной панели» для текстовой ссылки;
- Расположение — порядок задаётся положением в дереве, перетащите кнопку выше или ниже соседей.
Если в панели много кнопок, платформа убирает лишние в меню «Ещё». Для нужной команды заведите отдельную группу кнопок или поставьте её в начало, иначе пользователи её не найдут.
Общая команда для нескольких форм
Когда одна и та же кнопка нужна на формах десятка документов, не копируйте её руками. Создайте в расширении общую команду: ветка «Общие команды» → «Добавить». У неё есть три важных свойства:
- Группа — куда команда встанет на форме (командная панель формы, панель действий, панель навигации );
- Тип параметра команды — список объектов, на чьих формах кнопка появится;
- Модуль команды — процедура
ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды).
После этого кнопка сама встанет на все формы перечисленных объектов, и править каждую форму не придётся.
Серверный обработчик: как кнопка выполняет работу
Клиентская процедура только принимает нажатие. Всё, что читает или пишет данные, вызывайте на сервере. Типичная связка выглядит так:
&НаКлиенте
Процедура Расш1_ПечатьАкта(Команда)
Если Не ЗначениеЗаполнено(Объект.Ссылка) Тогда
ПоказатьПредупреждение(, "Сначала запишите документ.");
Возврат;
КонецЕсли;
Результат = Расш1_ПодготовитьАктНаСервере();
ПоказатьОповещениеПользователя("Готово", , Результат);
КонецПроцедуры
&НаСервере
Функция Расш1_ПодготовитьАктНаСервере()
// работа с объектом и базой
Возврат "Акт сформирован";
КонецФункции
Если серверной процедуре не нужны реквизиты формы, используйте &НаСервереБезКонтекста. Она работает быстрее, потому что платформа не передаёт на сервер весь контекст формы.
Новую процедуру в заимствованном модуле можно просто дописать. А вот для перехвата уже существующих обработчиков применяют аннотации:
&После("ИмяПроцедуры")— ваш код после типового;&Перед("ИмяПроцедуры")— до типового;&Вместо("ИмяПроцедуры")— полная замена, с вызовомПродолжитьВызов()при необходимости.
Пример: подготовить форму после её создания.
&После("ПриСозданииНаСервере")
Процедура Расш1_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// ваш код после типового
КонецПроцедуры
Создание команды и кнопки кодом
Когда состав кнопок меняется динамически, команду создают прямо при открытии формы. Этот код пишется в ПриСозданииНаСервере (удобно через &После, как выше):
Команда = Команды.Добавить("Расш1_ПечатьАкта");
Команда.Заголовок = "Печать акта";
Команда.Подсказка = "Сформировать и показать акт";
Команда.Действие = "Расш1_ПечатьАкта";
Кнопка = Элементы.Добавить("Расш1_КнопкаПечатьАкта", Тип("КнопкаФормы"), Элементы.ФормаКоманднаяПанель);
Кнопка.Вид = ВидКнопкиФормы.КнопкаКоманднойПанели;
Кнопка.ИмяКоманды = "Расш1_ПечатьАкта";
Что здесь важно:
- Действие — строка с именем процедуры. Сама процедура должна существовать в модуле формы и быть клиентской. Если её нет, платформа не найдёт обработчик при нажатии.
- Имена уникальны. Повторное
Команды.ДобавитьилиЭлементы.Добавитьс занятым именем вызовет ошибку. Перед созданием проверьтеКоманды.Найти(Имя) = Неопределено. - Родитель кнопки — любая группа формы. Чтобы вставить кнопку не в конец, у метода
Элементы.Вставитьесть параметр «перед каким элементом». - Создавать можно только на сервере в момент создания формы. После открытия менять состав команд нельзя.
Хотите кнопку в подменю? Сначала создайте группу: Элементы.Добавить("Расш1_Группа", Тип("ГруппаФормы"), Элементы.ФормаКоманднаяПанель), задайте ей Вид = ВидГруппыФормы.Подменю, а затем указывайте её родителем кнопки.
Видимость и доступность: кому и когда показывать кнопку
Кнопка, которую видят все, часто лишняя. Платформа даёт несколько рычагов, и они сочетаются.
В редакторе формы. У кнопки есть свойства «Видимость» и «Доступность». Для условия по роли или функциональной опции задайте их у команды: в свойстве «Функциональные опции» перечислите опции, при которых команда существует.
Из кода. Чаще всего меняют после ПриСозданииНаСервере или в обработчике события формы:
Элементы.Расш1_КнопкаПечатьАкта.Видимость = ПравоДоступа("Просмотр", Метаданные.Документы.РеализацияТоваровУслуг);
Элементы.Расш1_КнопкаПечатьАкта.Доступность = Объект.Проведен;
Разница между свойствами простая:
- 👁 Видимость = Ложь — кнопка исчезает совсем;
- 🔒 Доступность = Ложь — кнопка видна, но серая; удобно, когда нужно показать, что действие существует, но сейчас недоступно.
Условие «документ проведён» или «статус равен…» нужно пересчитывать в обработчиках ПриЧтенииНаСервере и ПослеЗаписиНаСервере, а не только при открытии. Иначе после записи кнопка останется в старом состоянии.
Права пользователя проверяйте в коде явно, а не полагайтесь на то, что роль «спрячет» кнопку сама: команда без ограничений доступна всем, у кого открыта форма.
Какой вариант выбрать для вашего случая
ПравоДоступа или по данным документа.ПриСозданииНаСервере.Контекст команды: с каким объектом работает кнопка
Кнопка в командной панели списка и кнопка в форме элемента получают данные по-разному. Это частая причина «не работает на списке».
Форма элемента. Текущий объект лежит в реквизите Объект. Если документ ещё не записан, Объект.Ссылка пустая, поэтому в начале обработчика проверяйте ЗначениеЗаполнено(Объект.Ссылка) и предлагайте записать.
Форма списка. Объекта нет, есть выделенные строки. Берите их из элемента формы:
&НаКлиенте
Процедура Расш1_ОбработатьВыбранные(Команда)
Выбранные = Элементы.Список.ВыделенныеСтроки;
Если Выбранные.Количество() = 0 Тогда
ПоказатьПредупреждение(, "Выделите хотя бы одну строку.");
Возврат;
КонецЕсли;
Расш1_ОбработатьНаСервере(Выбранные);
КонецПроцедуры
&НаСервереБезКонтекста
Процедура Расш1_ОбработатьНаСервере(Выбранные)
Для Каждого Ссылка Из Выбранные Цикл
Объект = Ссылка.ПолучитьОбъект();
// действия с объектом
Объект.Записать();
КонецЦикла;
КонецПроцедуры
Общая команда. Здесь ссылки приходят параметром: ПараметрКоманды содержит выбранную ссылку или массив ссылок, в зависимости от настройки «Режим использования параметра команды». Выберите «Множественный», если кнопка должна работать сразу с несколькими строками списка.
Для длинных операций над сотнями документов не держите пользователя перед зависшей формой. Запускайте обработку фоновым заданием и показывайте индикатор: пакетная запись тысячи документов в одном серверном вызове упирается в таймаут клиента.
Заголовок, картинка и порядок кнопок
Мелочи решают, найдут ли кнопку. Заголовок формулируйте глаголом: «Сформировать акт», а не «Акт». Картинку берите из библиотеки стандартных картинок, чтобы она не выбивалась из интерфейса. Для кнопки с картинкой без текста обязательно заполните подсказку.
Порядок кнопок определяется положением в дереве элементов. Если нужно поставить свою кнопку строго перед типовой, при программном создании используйте Элементы.Вставить(Имя, Тип, Родитель, ПередЭлементом), а в редакторе просто перетащите её выше.
Префиксы и совместимость с обновлениями
Три правила, которые сохранят кнопку при смене релиза:
- ставьте префикс расширения на каждое новое имя: команды, кнопки, процедуры, реквизиты;
- не переименовывайте и не удаляйте заимствованные типовые элементы, лучше скройте их свойством «Видимость»;
- после каждого обновления типовой конфигурации открывайте заимствованные формы и смотрите, не перестала ли находиться группа, в которую вы вставляли кнопку.
Последний пункт особенно важен для программного способа: если разработчики типовой конфигурации переименуют группу ФормаКоманднаяПанель, строка Элементы.ФормаКоманднаяПанель вызовет ошибку при открытии формы. Для страховки проверьте группу перед использованием: Родитель = Элементы.Найти("ФормаКоманднаяПанель"), и если вернулся Неопределено, добавляйте кнопку прямо в корень формы.
Отладка и проверка новых команд
После правки примените расширение к базе. В Конфигураторе запустите отладку (Отладка → Начать отладку) или обновите конфигурацию базы данных клавишей F7, затем откройте 1С:Предприятие под нужным пользователем. Поставьте точку останова в клиентской и серверной процедурах расширения: отладчик остановится в обеих.
Проверьте по списку:
Что чаще всего идёт не так:
- 🚫 Кнопки нет вообще. Расширение отключено или не применено к базе. Проверьте список расширений в Конфигураторе:
Конфигурация → Расширения конфигурации. - 🔁 Ошибка «Дублирование имени». Имя команды или элемента уже занято: либо вы добавили его и в редакторе, и в коде, либо метод вызывается дважды.
- 🧩 Нажатие ничего не делает. В
Команда.Действиеуказано имя, которого нет в модуле, или процедура объявлена как&НаСервере, а не&НаКлиенте. - 👤 У пользователя кнопки нет, у администратора есть. Сработало ограничение прав в коде видимости или доступа к объекту.
- 🔄 После обновления типовой конфигурации форма «поехала». Откройте расширение и сравните заимствованную форму с обновлённой типовой: если разработчики переместили или переименовали элемент, вашу кнопку нужно перепривязать.