Как в управляемых формах 1С 8.3 отследить переключение между таблицами значений

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке интерфейсов на управляемых формах 1С часто возникает задача: связать несколько таблиц так, чтобы при выборе строки в первой или второй таблице в третьей зависимой таблице сразу отображались детальные данные. Однако стандартное событие таблицы ПриАктивизацииСтроки срабатывает только тогда, когда внутри самой таблицы меняется активная строка. Если в таблице всего одна строка или пользователь переключает фокус между таблицами, щелкая по уже выбранной строке, платформа 1С не инициирует событие, так как значение свойства ТекущаяСтрока формально не изменилось.

В платформе 1С:Предприятие 8.3 у элементов управляемой формы отсутствуют штатные события получения и потери фокуса ввода, а у формы нет отдельного события при смене активного элемента. Разберем несколько способов обойти данное ограничение и гарантированно отслеживать выбор пользователем нужной таблицы.

Способ 1. Программный сброс выделения во второй таблице

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

Для реализации этого подхода выполним следующие шаги:

  1. Назначим для обеих таблиц управляемой формы обработчик события ПриАктивизацииСтроки.
  2. В обработчике первой таблицы очистим коллекцию выделенных строк и сбросим текущую строку у второй таблицы, после чего вызовем процедуру обновления третьей таблицы.
  3. Аналогичный код зеркально пропишем для обработчика второй таблицы.

Посмотрим на пример клиентского кода:


&НаКлиенте
Процедура ТЗ1ПриАктивизацииСтроки(Элемент)
    // Сбрасываем выделение во второй таблице
    Элементы.ТЗ2.ВыделенныеСтроки.Очистить();
    Элементы.ТЗ2.ТекущаяСтрока = Неопределено;
    
    // Обновляем зависимые данные
    ОбработатьВыборСтроки(Элемент);
КонецПроцедуры

&НаКлиенте
Процедура ТЗ2ПриАктивизацииСтроки(Элемент)
    // Сбрасываем выделение в первой таблице
    Элементы.ТЗ1.ВыделенныеСтроки.Очистить();
    Элементы.ТЗ1.ТекущаяСтрока = Неопределено;
    
    // Обновляем зависимые данные
    ОбработатьВыборСтроки(Элемент);
КонецПроцедуры

&НаКлиенте
Процедура ОбработатьВыборСтроки(Элемент)
    Если Элемент.ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Заполняем третью таблицу по выбранному объекту
    ТекущийДокумент = Элемент.ТекущиеДанные.Док;
    ЗаполнитьДанныеТЗ3(ТекущийДокумент);
КонецПроцедуры

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

Способ 2. Отслеживание текущего элемента через обработчик ожидания

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

Разберем логику работы обработчика ожидания:

  1. В модуле формы объявим клиентскую переменную для хранения имени предыдущего активного элемента.
  2. При открытии формы подключим обработчик ожидания с минимальным интервалом (например, 0.1 или 0.2 секунды).
  3. В процедуре обработчика сравним свойство ЭтаФорма.ТекущийЭлемент с сохраненным ранее значением. Если фокус перешел на другую таблицу или ее колонку, обновим данные и сохраним новое состояние.

Рассмотрим пример реализации:


&НаКлиенте
Перем ПредыдущийЭлемент;

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    ПодключитьОбработчикОжидания("ПроверитьСменуФокуса", 0.2);
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьСменуФокуса()
    Текущий = ЭтаФорма.ТекущийЭлемент;
    
    Если Текущий = Неопределено Или Текущий = ПредыдущийЭлемент Тогда
        Возврат;
    КонецЕсли;
    
    Если Текущий = Элементы.ТЗ1 Или Текущий.Родитель = Элементы.ТЗ1 Тогда
        ПредыдущийЭлемент = Текущий;
        ОбработатьВыборСтроки(Элементы.ТЗ1);
    ИначеЕсли Текущий = Элементы.ТЗ2 Или Текущий.Родитель = Элементы.ТЗ2 Тогда
        ПредыдущийЭлемент = Текущий;
        ОбработатьВыборСтроки(Элементы.ТЗ2);
    КонецЕсли;
КонецПроцедуры

Важно: постоянный опрос через обработчик ожидания создает небольшую дополнительную нагрузку на клиентский сеанс, поэтому данный способ рекомендуется применять только тогда, когда сброс выделения через обработчики строк по каким-то причинам не подходит.

Способ 3. Использование гиперссылки или кнопки в строке

Еще один надежный способ зафиксировать действие пользователя — перевести взаимодействие из пассивного выделения строки в явное нажатие.

Для этого в таблицах на форме настраивают ключевую колонку (например, представление документа):

  1. Устанавливаем для поля колонки свойство Вид в значение ПолеНадписи или ПолеВвода.
  2. Включаем свойство Гиперссылка (устанавливаем в значение Истина).
  3. Назначаем обработчик события Нажатие для данного поля.

Событие Нажатие гарантированно срабатывает при каждом клике пользователя по ячейке, даже если строка уже была активна до этого.

Способ 4. Внешняя компонента для перехвата событий Windows

В специфических сценариях (например, когда требуется точный перехват фокуса для управления раскладкой клавиатуры или оборудования) применяют внешние компоненты, скомпилированные по технологии Native API. Компонента через системные хуки отслеживает фокус оконных элементов и отправляет в 1С внешнее событие с помощью метода ВнешнееСобытие формы.

Однако для типовых прикладных задач управляемых форм использование внешних компонент избыточно и усложняет кроссплатформенную поддержку (работа в веб-клиенте или под управлением Linux).

Выводы

Для корректного отслеживания переключения между несколькими таблицами значений оптимальным решением является программная очистка выделения ВыделенныеСтроки.Очистить() в соседних таблицах при срабатывании ПриАктивизацииСтроки. Это восстанавливает чувствительность события и позволяет точно синхронизировать отображение зависимых данных в интерфейсе.

← На главную