При разработке сложных интерфейсов на управляемых формах 1С разработчики часто сталкиваются с ситуацией, когда на одной форме расположены две или более связанные таблицы. Распространенный сценарий: при выборе строки в любой из таблиц в отдельную область формы выводятся подробные сведения по текущему объекту (например, по выбранной задаче или документу). Однако если в одной из таблиц остается всего одна строка, штатное событие ПриАктивизацииСтроки перестает вызываться при переключении между таблицами. Разберем причины такого поведения платформы и рассмотрим надежные способы обхода этого ограничения.
Событие таблицы управляемой формы ПриАктивизацииСтроки генерируется платформой только при фактическом изменении идентификатора текущей строки (ТекущаяСтрока). Проанализируем цепочку действий пользователя:
С точки зрения платформы 1С, получение таблицей фокуса ввода не является сменой строки. Курсор в первой таблице как указывал на единственную строку, так и продолжает на нее указывать. Соответственно, событие ПриАктивизацииСтроки не вызывается повторно, а блок детальной информации на форме остается не обновленным или отображает данные из другой таблицы. Кроме того, в управляемых формах отсутствуют стандартные события формы уровня получения или потери фокуса элементами управления.
Событие ПриАктивизацииЯчейки (или ПриАктивизацииПоля) срабатывает не только при смене строки, но и при получении фокуса конкретной ячейкой таблицы при клике мышью. Это позволяет перехватить факт активации элемента, даже если строка осталась прежней.
Посмотрим на практическую реализацию. Чтобы избежать лишних вызовов при переходе между колонками внутри одной и той же строки, проверим текущий активный элемент формы и вызовем процедуру обновления:
&НаКлиенте
Процедура ЗадачиМнеПриАктивизацииЯчейки(Элемент)
// Проверяем, что фокус действительно находится на данном элементе
Если ЭтотОбъект.ТекущийЭлемент = Элемент Тогда
ОбновитьОтображениеДетализации(Элемент.ТекущиеДанные);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ЗадачиМнеПринятыеПриАктивизацииЯчейки(Элемент)
Если ЭтотОбъект.ТекущийЭлемент = Элемент Тогда
ОбновитьОтображениеДетализации(Элемент.ТекущиеДанные);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ОбновитьОтображениеДетализации(ТекущиеДанные)
Если ТекущиеДанные = Неопределено Тогда
// Очищаем область детализации, если данных нет
РеквизитТекстОписания = "";
Возврат;
КонецЕсли;
// Заполняем реквизиты формы данными выбранной строки
РеквизитТекстОписания = ТекущиеДанные.ОписаниеЗадачи;
КонецПроцедуры
Еще один надежный подход заключается в принудительном сбросе выделения у второй таблицы при переходе в первую. Если при активации первой таблицы мы программно снимем фокус со второй таблицы, установив ее свойство ТекущаяСтрока в значение Неопределено, то при следующем возврате во вторую таблицу платформа зафиксирует изменение строки с Неопределено на конкретный идентификатор строки. В этом случае событие ПриАктивизацииСтроки отработает штатно даже при наличии одной записи.
Рассмотрим пример реализации обработчиков активизации строк для двух таблиц:
&НаКлиенте
Процедура ЗадачиМнеПриАктивизацииСтроки(Элемент)
// Сбрасываем позицию курсора во второй таблице, чтобы при переходе в нее событие вызвалось снова
Элементы.ЗадачиМнеПринятые.ТекущаяСтрока = Неопределено;
ОбновитьОтображениеДетализации(Элементы.ЗадачиМне.ТекущиеДанные);
КонецПроцедуры
&НаКлиенте
Процедура ЗадачиМнеПринятыеПриАктивизацииСтроки(Элемент)
// Сбрасываем позицию курсора в первой таблице
Элементы.ЗадачиМне.ТекущаяСтрока = Неопределено;
ОбновитьОтображениеДетализации(Элементы.ЗадачиМнеПринятые.ТекущиеДанные);
КонецПроцедуры
Если таблицы на форме обновляются динамически (например, регламентным запросом или по кнопке обновления), платформа автоматически пытается спозиционировать курсор на первую строку без генерации события смены строки. В таких ситуациях необходимо вызывать метод обновления детализации сразу после завершения алгоритма заполнения таблиц на клиенте.
&НаКлиенте
Процедура ОбновитьДанныеНаФорме()
ОбновитьТаблицыНаСервере();
// Явно инициируем обновление панели детализации по активной таблице
Если Элементы.ЗадачиМне.ТекущиеДанные <> Неопределено Тогда
ОбновитьОтображениеДетализации(Элементы.ЗадачиМне.ТекущиеДанные);
ИначеЕсли Элементы.ЗадачиМнеПринятые.ТекущиеДанные <> Неопределено Тогда
ОбновитьОтображениеДетализации(Элементы.ЗадачиМнеПринятые.ТекущиеДанные);
Иначе
ОбновитьОтображениеДетализации(Неопределено);
КонецЕсли;
КонецПроцедуры
Если специфика интерфейса позволяет, стоит рассмотреть альтернативные варианты компоновки формы:
ПриСменеСтраницы. При переключении вкладок достаточно считывать ТекущиеДанные таблицы, расположенной на активной странице, и передавать их в процедуру отображения.