К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как в 1С узнать, какая кнопка нажата

Как в 1С определить, какая кнопка нажата: обработчики команд, имя команды, ОтветВопроса, общие команды. Примеры кода для обычных и управляемых форм.

В форме 1С несколько кнопок могут запускать один и тот же обработчик, и тогда разработчику нужно понять, какая именно из них нажата. Задача решается по-разному в зависимости от типа формы: обычная форма (толстый клиент) передаёт имя кнопки в параметры обработчика, а управляемая форма работает через команды и их имена.

Единого универсального вызова «какая кнопка нажата» в платформе нет: вместо этого используются обработчики команд, параметр Команда, значение диалога вопроса (КодВозвратаДиалога) и отдельные обработчики для каждой кнопки. Ниже разобраны все рабочие способы с примерами кода.

Как устроена обработка нажатий кнопок в 1С

Каждая кнопка формы в 1С связана с командой. Команда — это объект с именем, заголовком и обработчиком. Когда пользователь нажимает кнопку, платформа вызывает обработчик, назначенный команде, и передаёт в него ссылку на объект команды. Через свойство Команда.Имя обработчик узнаёт, какая именно команда сработала.

Такой подход позволяет назначить один общий обработчик на несколько кнопок и внутри него ветвить логику по имени команды. Это типовой приём для программно создаваемых кнопок, динамических меню и табличных частей с одинаковыми действиями над строками.

В обычных формах (режим совместимости, толстый клиент) механика проще: у события «Нажатие» есть параметр Кнопка, у которого доступно свойство Имя. Там ветвление строится напрямую по имени элемента формы.

Определение нажатой кнопки в управляемой форме через команду

Основной способ для управляемых форм — общий обработчик, который получает параметр Команда. Создайте несколько команд формы (например, «СохранитьИЗакрыть», «СохранитьИНовый»), назначьте им один обработчик и сравнивайте имена:

&НаКлиенте

Процедура ОбработкаКомандыОбщая(Команда)

Если Команда.Имя = "СохранитьИЗакрыть" Тогда

ЗаписатьДанные();

Закрыть();

ИначеЕсли Команда.Имя = "СохранитьИНовый" Тогда

ЗаписатьДанные();

ОчиститьФормуДляНового();

Иначе

Сообщить("Неизвестная команда: " + Команда.Имя);

КонецЕсли;

КонецПроцедуры

Чтобы назначить один обработчик нескольким кнопкам, в палитре свойств каждой кнопки в поле «Действие» выберите одну и ту же процедуру. Платформа сама передаст в неё объект команды, связанной с конкретной кнопкой.

Порядок действий
  1. 1
    Создайте в форме нужные команды с понятными именами
  2. 2
    Перетащите команды на форму — появятся кнопки
  3. 3
    Для каждой кнопки в свойстве Действие укажите общий обработчик
  4. 4
    В обработчике сравнивайте Команда.Имя с ожидаемыми значениями
  5. 5
    Проверьте работу каждой кнопки в режиме 1С:Предприятие

Программно созданные кнопки

Если кнопки создаются кодом (например, по списку значений), команды тоже добавляются программно, а обработчик назначается через Команда.Действие. Имя команды формируют так, чтобы по нему можно было восстановить контекст — например, включить в имя идентификатор строки:

&НаСервере

Процедура СоздатьКнопки()

Для Каждого Стр Из СписокДействий Цикл

НоваяКоманда = Команды.Добавить("Действие_" + Стр.Код);

НоваяКоманда.Заголовок = Стр.Наименование;

НоваяКоманда.Действие = "ОбработкаКомандыОбщая";

НоваяКнопка = Элементы.Добавить("Кнопка_" + Стр.Код, Тип("КнопкаФормы"), Элементы.ГруппаКнопок);

НоваяКнопка.ИмяКоманды = "Действие_" + Стр.Код;

КонецЦикла;

КонецПроцедуры

В общем обработчике из имени команды методом СтрЗаменить или СтрРазделить извлекают код действия и выполняют нужную ветку логики. Важно, чтобы имена команд были уникальными и не содержали пробелов и спецсимволов.

Определение нажатой кнопки в обычной форме

В обычных формах у события кнопки «Нажатие» есть параметр Элемент (или Кнопка для командных панелей), через который доступно имя элемента управления:

Процедура КоманднаяПанельОбработчик(Кнопка)

Если Кнопка.Имя = "Печать" Тогда

НапечататьДокумент();

ИначеЕсли Кнопка.Имя = "Отправить" Тогда

ОтправитьПоПочте();

КонецЕсли;

КонецПроцедуры

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

Сравнение подходов

Отдельный обработчик на каждую кнопку

Проще читать и отлаживать; не требует определения имени. Неудобен при динамическом создании кнопок

Один общий обработчик + Команда.Имя

Обязателен для программно создаваемых кнопок; требует аккуратного соглашения об именах команд

ПоказатьВопрос с КодВозвратаДиалога

Подходит, когда «кнопки» — это варианты ответа в диалоге, а не элементы формы

Как узнать, какую кнопку нажали в диалоге «Вопрос»

Частный, но очень распространённый случай: диалог с вариантами «Да/Нет/Отмена» или произвольным списком кнопок. Здесь нажатая кнопка определяется не по имени, а по возвращаемому значению — КодВозвратаДиалога. В тонком клиенте используется асинхронный вызов с описанием оповещения:

&НаКлиенте

Процедура ПередЗакрытиемОбработка()

Оповещение = Новый ОписаниеОповещения("ПослеОтветаНаВопрос", ЭтотОбъект);

ПоказатьВопрос(Оповещение, "Сохранить изменения?", РежимДиалогаВопрос.ДаНетОтмена);

КонецПроцедуры

&НаКлиенте

Процедура ПослеОтветаНаВопрос(Результат, ДопПараметры) Экспорт

Если Результат = КодВозвратаДиалога.Да Тогда

ЗаписатьДанные();

ИначеЕсли Результат = КодВозвратаДиалога.Отмена Тогда

Возврат; // пользователь передумал закрывать

КонецЕсли;

КонецПроцедуры

Если нужны нестандартные кнопки, используйте СписокЗначений с собственными значениями вместо типового РежимДиалогаВопрос. Тогда в Результат вернётся именно то значение, которое вы положили в список для нажатой кнопки — это самый гибкий способ «узнать, что нажали» в диалоге.

Как передать контекст нажатия через дополнительные параметры

Иногда имени команды недостаточно: нужно знать, например, из какой строки таблицы вызвана кнопка или с какими данными работать. Для этого в обработчике читают текущие данные связанного элемента формы, а в оповещениях используют ДополнительныеПараметры:

&НаКлиенте

Процедура КнопкаСтрокиНажатие(Команда)

ТекСтрока = Элементы.ТаблицаТоваров.ТекущиеДанные;

Если ТекСтрока = Неопределено Тогда

ПоказатьПредупреждение(, "Сначала выберите строку");

Возврат;

КонецЕсли;

// Команда.Имя говорит ЧТО делать, ТекСтрока — С ЧЕМ делать

ВыполнитьДействие(Команда.Имя, ТекСтрока.Номенклатура);

КонецПроцедуры

При создании ОписаниеОповещения третьим параметром передаётся произвольная структура или значение — оно придёт в обработчик вторым аргументом. Так можно связать с кнопкой любой контекст без глобальных переменных.

Отладка: как проверить, какой обработчик срабатывает

Если кнопка «не работает» или срабатывает не та ветка, проверьте цепочку: команда → обработчик → ветвление по имени. Самый быстрый способ — поставить точку останова в общем обработчике и посмотреть значение Команда.Имя в отладчике конфигуратора.

Без отладчика помогает временный вывод имени команды:

Сообщить("Нажата команда: " + Команда.Имя);

Типичная причина «неправильного» срабатывания — кнопке назначен другой обработчик в палитре свойств, либо у двух команд перепутаны имена. Ещё одна частая ошибка — сравнение Команда.Имя с заголовком кнопки: заголовок («Сохранить») и имя команды («СохранитьДокумент») — разные вещи.

Типичные ошибки
01
Сравнивать Команда.Имя с заголовком кнопки — имена и заголовки не совпадают, ветка никогда не выполнится
02
Использовать модальный Вопрос() в управляемом приложении — код не выполнится или выдаст ошибку режима модальности
03
Забыть назначить обработчик в свойстве Действие — кнопка визуально есть, но нажатие ничего не делает
04
Дублировать имена команд при программном создании — платформа выдаст ошибку добавления команды
05
Не проверять Неопределено у ТекущиеДанные таблицы — обращение к полям строки вызовет ошибку

Проверка результата и ограничения

После настройки проверьте каждую кнопку в режиме 1С:Предприятие: нажатие должно приводить к ожидаемой ветке кода. Для диалогов убедитесь, что все варианты ответа (включая «Отмена» и закрытие окна крестиком) обработаны — необработанная «Отмена» часто приводит к потере данных или зависанию логики закрытия формы.

Учтите ограничение: у кнопок стандартных команд формы (Записать, Провести, Закрыть) поведение переопределяется через подписки на события (ПередЗаписью, ПриЗакрытии), а не через определение «какая кнопка нажата». Перехватывать стандартные команды общим обработчиком не получится — для них используйте расширение обработчиков команд формы.

Контрольные точки

Как проверить результат

Нажатие каждой кнопки
Норма

Выполняется ожидаемая ветка кода, в отладчике видно правильное Команда.Имя

Тревожный признак

Срабатывает другая ветка или ничего не происходит

Диалог с вопросом
Норма

Все варианты ответа, включая Отмену, обработаны

Тревожный признак

При отмене данные теряются или форма закрывается без сохранения

Программно созданные кнопки
Норма

Имена команд уникальны, обработчик назначен, кнопки видны на форме

Тревожный признак

Ошибка при добавлении команды или кнопка без действия

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

Можно ли узнать, какая кнопка нажата, без имени команды?

Да, если назначить каждой кнопке отдельный обработчик — тогда сам факт вызова процедуры уже говорит, какая кнопка нажата. Определение по имени нужно только при общем обработчике.

Как определить нажатие кнопки в табличной части?

Кнопки в строках таблицы обычно реализуют через событие Выбор или команду, привязанную к таблице. В обработчике читайте Элементы.ИмяТаблицы.ТекущиеДанные — это даст строку, из которой вызвано действие.

Что вернёт ПоказатьВопрос, если пользователь закрыл диалог крестиком?

Если среди кнопок есть Отмена, вернётся КодВозвратаДиалога.Отмена. Если кнопок Отмены нет, при закрытии окна результатом будет Неопределено — этот случай нужно обрабатывать отдельно.

Работает ли сравнение Команда.Имя в глобальных общих командах?

Да, обработчик общей команды тоже получает параметр Команда. Но чаще для общих команд важнее параметр ПараметрКоманды — ссылка на объект, из которого команда вызвана.

Как узнать, какую кнопку нажали на форме выбора из списка?

Используйте ПоказатьВыборИзСписка с описанием оповещения: в обработчик придёт выбранный элемент списка значений, и по его значению или представлению определяется выбор пользователя.

Почему обработчик кнопки не вызывается вовсе?

Проверьте, что в свойстве кнопки «ИмяКоманды» указана команда, у команды в свойстве «Действие» назначен обработчик, а сама процедура имеет директиву &НаКлиенте и параметр Команда.

Итог

Что важно запомнить

Нажатая кнопка в управляемой форме определяется через Команда.Имя в общем обработчике, в обычной форме — через параметр Кнопка.Имя, а в диалогах — через КодВозвратаДиалога. Для динамических кнопок кодируйте контекст в имени команды и всегда обрабатывайте вариант отмены.