Почему не срабатывает событие ПриАктивизацииСтроки в табличной части управляемой формы и как это исправить?

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

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

Анализ проблемы и логики работы платформы 1С

Событие таблицы управляемой формы ПриАктивизацииСтроки генерируется платформой только при фактическом изменении идентификатора текущей строки (ТекущаяСтрока). Проанализируем цепочку действий пользователя:

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

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

Способ 1. Использование события ПриАктивизацииЯчейки (ПриАктивизацииПоля)

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

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


&НаКлиенте
Процедура ЗадачиМнеПриАктивизацииЯчейки(Элемент)
    
    // Проверяем, что фокус действительно находится на данном элементе
    Если ЭтотОбъект.ТекущийЭлемент = Элемент Тогда
        ОбновитьОтображениеДетализации(Элемент.ТекущиеДанные);
    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Процедура ЗадачиМнеПринятыеПриАктивизацииЯчейки(Элемент)
    
    Если ЭтотОбъект.ТекущийЭлемент = Элемент Тогда
        ОбновитьОтображениеДетализации(Элемент.ТекущиеДанные);
    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Процедура ОбновитьОтображениеДетализации(ТекущиеДанные)
    
    Если ТекущиеДанные = Неопределено Тогда
        // Очищаем область детализации, если данных нет
        РеквизитТекстОписания = "";
        Возврат;
    КонецЕсли;
    
    // Заполняем реквизиты формы данными выбранной строки
    РеквизитТекстОписания = ТекущиеДанные.ОписаниеЗадачи;
    
КонецПроцедуры

Способ 2. Программный сброс текущей строки неактивной таблицы

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

Рассмотрим пример реализации обработчиков активизации строк для двух таблиц:


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

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

Способ 3. Принудительное обновление при перезаполнении таблиц

Если таблицы на форме обновляются динамически (например, регламентным запросом или по кнопке обновления), платформа автоматически пытается спозиционировать курсор на первую строку без генерации события смены строки. В таких ситуациях необходимо вызывать метод обновления детализации сразу после завершения алгоритма заполнения таблиц на клиенте.


&НаКлиенте
Процедура ОбновитьДанныеНаФорме()
    
    ОбновитьТаблицыНаСервере();
    
    // Явно инициируем обновление панели детализации по активной таблице
    Если Элементы.ЗадачиМне.ТекущиеДанные <> Неопределено Тогда
        ОбновитьОтображениеДетализации(Элементы.ЗадачиМне.ТекущиеДанные);
    ИначеЕсли Элементы.ЗадачиМнеПринятые.ТекущиеДанные <> Неопределено Тогда
        ОбновитьОтображениеДетализации(Элементы.ЗадачиМнеПринятые.ТекущиеДанные);
    Иначе
        ОбновитьОтображениеДетализации(Неопределено);
    КонецЕсли;
    
КонецПроцедуры

Архитектурные альтернативы

Если специфика интерфейса позволяет, стоит рассмотреть альтернативные варианты компоновки формы:

  1. Объединение таблиц в одну: Использование одного динамического списка или таблицы формы с дополнительной колонкой статуса или переключателем режимов отображения (быстрым отбором). В этом случае пользователь всегда работает внутри одного элемента управления, и рассинхронизации активных строк между разными таблицами не происходит.
  2. Размещение таблиц на страницах панели: Если расположить каждую таблицу на отдельной вкладке группы страниц, можно использовать событие группы ПриСменеСтраницы. При переключении вкладок достаточно считывать ТекущиеДанные таблицы, расположенной на активной странице, и передавать их в процедуру отображения.
← На главную