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