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