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