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