При разработке в среде 1С:Предприятие 8 на «обычных формах» (толстый клиент) программисты часто сталкиваются с ситуацией, когда код по добавлению кнопки на командную панель отрабатывает без ошибок, сама кнопка визуально появляется, но остается «серой» (недоступной для нажатия). Рассмотрим подробно, почему это происходит и как реализовать универсальный механизм вызова процедур из общих модулей.
Разберем типичный пример кода, который часто приводит к ошибке. Программист пытается добавить кнопку «Запрос» на командную панель и назначить ей действие, которое описано в глобальном общем модуле:
// Код в модуле формы
Действие = Новый Действие("ОткрытьФормуЗапроса");
Кнопка = ЭлементыФормы.КоманднаяПанель1.Кнопки.Добавить("Запрос", ТипКнопкиКоманднойПанели.Действие, , Действие);
А в общем модуле определена процедура:
Процедура ОткрытьФормуЗапроса(СсылкаОбъект) Экспорт
// Логика открытия формы
КонецПроцедуры
В данном сценарии кнопка будет создана, но 1С заблокирует ее (сделает Доступность = Ложь). Выясним основные причины такого поведения платформы.
Это самая распространенная ошибка. Платформа 1С предъявляет жесткие требования к количеству параметров процедур-обработчиков для различных элементов управления. Для кнопки командной панели, имеющей тип ТипКнопкиКоманднойПанели.Действие, процедура-обработчик обязана принимать ровно один параметр — саму кнопку, которая была нажата.
Проанализируем наш пример: процедура автора ожидает параметр СсылкаОбъект. Платформа при попытке связать кнопку с действием ищет метод с подходящей сигнатурой. Не найдя процедуру, принимающую объект кнопки, 1С считает действие невалидным и отключает элемент управления, чтобы предотвратить ошибку времени выполнения (Runtime Error).
В обычных формах объект Действие работает иначе, чем прямой вызов процедур в коде. Когда мы пишем Новый Действие("ИмяПроцедуры"), поиск этого имени осуществляется только в модуле самой формы. Даже если процедура в общем модуле помечена словом Экспорт, она не видна объекту Действие напрямую. Платформа не просматривает глобальное контекстное пространство при поиске обработчиков событий элементов формы.
Рассмотрим правильный алгоритм действий для реализации универсальной кнопки во всех документах (например, в УТ 10.3).
Поскольку мы выяснили, что обработчик должен быть в модуле формы, нам необходимо создать там небольшую процедуру-посредник. Она будет соответствовать требованиям платформы по количеству параметров и вызывать наш основной код из общего модуля.
Процедура ОбработчикНажатияКнопкиЗапрос(Кнопка)
// Здесь мы вызываем наш общий модуль
// Передаем "ЭтотОбъект" или "Ссылка", так как в форме документа они доступны напрямую
МойОбщийМодуль.ОткрытьФормуЗапроса(ЭтотОбъект);
КонецПроцедуры
Теперь в процедуре ПриОткрытии (или другой инициализирующей процедуре) мы меняем код создания кнопки, указывая на локальный обработчик:
Процедура ПриОткрытии()
// Проверяем, нет ли уже такой кнопки, чтобы избежать дублей при повторном вызове
Если ЭлементыФормы.КоманднаяПанель1.Кнопки.Найти("Запрос") = Неопределено Тогда
ДействиеОбработчик = Новый Действие("ОбработчикНажатияКнопкиЗапрос");
// Добавляем кнопку на панель
НоваяКнопка = ЭлементыФормы.КоманднаяПанель1.Кнопки.Добавить(
"Запрос",
ТипКнопкиКоманднойПанели.Действие,
"Открыть запрос",
ДействиеОбработчик
);
// Дополнительные настройки для наглядности
НоваяКнопка.Отображение = ОтображениеКнопкиКоманднойПанели.Надпись;
КонецЕсли;
КонецПроцедуры
Если ваша задача — добавить одинаковую кнопку во все документы конфигурации (как хотел автор темы), и вы не хотите вручную менять каждый модуль формы, можно воспользоваться следующими архитектурными советами:
&После). Поэтому вам в любом случае придется внести изменения в модуль формы каждой нужной сущности, добавив туда прокси-процедуру.Если вы исправили сигнатуру и перенесли процедуру в модуль формы, но кнопка все равно недоступна, проанализируйте следующие моменты:
ЭтаФорма.ТолькоПросмотр. Если форма открыта только для чтения, кнопки с типом Действие, не относящиеся к стандартным командам навигации, могут блокироваться автоматически.ИсточникДействий), убедитесь, что вы добавляете кнопку именно в коллекцию кнопок панели, а не пытаетесь подменить стандартные действия таблицы.Важный нюанс: В обычных формах при добавлении кнопки через Кнопки.Добавить() важно правильно указывать заголовок и имя. Имя (первый параметр) используется для обращения к кнопке в коллекции, а текст (третий параметр) — для отображения пользователю. Если текст не указан, кнопка может быть очень узкой или пустой, что также затрудняет взаимодействие с ней.
Таким образом, для успешного программного создания интерактивного элемента на форме 1С 8.2/8.3 (обычные формы) необходимо строго соблюдать локальность обработчика и его параметризацию. Использование прокси-процедуры в модуле формы является стандартным и наиболее надежным решением этой задачи.