При разработке отчетов на Системе компоновки данных (СКД) часто возникает задача не просто открыть документ, на который ссылается ячейка, но и сделать это максимально удобно для пользователя. Например, если отчет посвящен анализу товаров, логично, чтобы при клике на документ открывалась именно вкладка «Товары», а не «Главное» или «Дополнительно». В этой статье мы подробно разберем, как реализовать такой функционал в управляемом приложении 1С.
Стандартное поведение системы при клике на поле со ссылкой — выполнение стандартной расшифровки, которая просто открывает основную форму объекта. Чтобы управлять этим процессом, нам потребуется вмешаться в событие ОбработкаРасшифровки табличного документа, в который выводится отчет. Основная сложность заключается в том, что в управляемых формах работа с данными расшифровки разделена между клиентом и сервером, а механизм активации конкретного элемента формы требует передачи специальных параметров.
Прежде всего, нам необходимо убедиться, что у формы отчета есть реквизиты для хранения данных компоновки. Обычно это ДанныеРасшифровки (тип Строка, адрес во временном хранилище). В модуле формы в обработчике ПриКомпоновкеРезультата или при программном выводе отчета этот адрес должен заполняться.
Затем для элемента формы «Результат» (тип ПолеТабличногоДокумента) создадим обработчик события РезультатОбработкаРасшифровки. Рассмотрим программный код, который позволит нам перехватить действие пользователя.
Разберем клиентскую процедуру. Главная задача здесь — установить СтандартнаяОбработка = Ложь, чтобы предотвратить обычное открытие ссылки, и вызвать серверный контекст для анализа того, на что именно нажал пользователь.
&НаКлиенте
Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь; // Останавливаем стандартное открытие
// Получаем настройки и значение расшифровки с сервера
СтруктураРезультата = ПолучитьЗначениеРасшифровкиНаСервере(Расшифровка);
Если СтруктураРезультата.СсылкаНаДокумент = Неопределено Тогда
Возврат;
КонецЕсли;
// Формируем параметры для открытия формы
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Ключ", СтруктураРезультата.СсылкаНаДокумент);
// Указываем имя элемента формы, который нужно активизировать.
// Это должно быть имя ТАБЛИЦЫ или ГРУППЫ (Страницы) в конфигураторе.
ПараметрыФормы.Вставить("ИмяЭлементаДляАктивизации", "Товары");
// Открываем форму конкретного документа
ОткрытьФорму("Документ." + СтруктураРезультата.ИмяМетаданных + ".ФормаОбъекта", ПараметрыФормы);
КонецПроцедуры
Проанализируем ситуацию: на сервере нам нужно извлечь саму ссылку из идентификатора расшифровки. Для этого используется объект ОбработкаРасшифровкиКомпоновкиДанных. Важный нюанс, который обсуждался на форуме: метод Расшифровать() может выдать ошибку «Нельзя расшифровывать детальные записи», если в настройках отчета не выбраны конкретные поля. Чтобы этого избежать, мы будем использовать прямой доступ к данным расшифровки.
&НаСервере
Функция ПолучитьЗначениеРасшифровкиНаСервере(ИдентификаторРасшифровки)
Результат = Новый Структура("СсылкаНаДокумент, ИмяМетаданных", Неопределено, "");
// Получаем данные расшифровки из временного хранилища
Данные = ПолучитьИзХранилища(ДанныеРасшифровки);
// Ищем выбранное поле
ПолеСсылка = Данные.Элементы[ИдентификаторРасшифровки];
Если ТипЗнч(ПолеСсылка) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда
Для Каждого Поле Из ПолеСсылка.ПолучитьПоля() Цикл
// Проверяем, является ли значение ссылкой на документ
Если Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Поле.Значение))
ИЛИ Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Поле.Значение)) Тогда
Результат.СсылкаНаДокумент = Поле.Значение;
Результат.ИмяМетаданных = Поле.Значение.Метаданные().Имя;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Рассмотрим подробнее механизм активации. Метод ОткрытьФорму передает структуру параметров в форму документа. Однако, чтобы параметр ИмяЭлементаДляАктивизации сработал автоматически, конфигурация должна поддерживать этот механизм (как это сделано во многих типовых решениях на БСП). Если ваша конфигурация самописная, в модуле формы документа (например, Реализация товаров и услуг) нужно добавить обработку этого параметра.
Выясним причину, почему фокус может не устанавливаться: это происходит, если в процедуре ПриСозданииНаСервере или ПриОткрытии не прописана логика переключения текущего элемента. Добавим следующий код в форму документа:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверяем наличие параметра активации
Если Параметры.Свойство("ИмяЭлементаДляАктивизации") Тогда
ЭлементДляФокуса = Элементы.Найти(Параметры.ИмяЭлементаДляАктивизации);
Если ЭлементДляФокуса <> Неопределено Тогда
ЭтаФорма.ТекущийЭлемент = ЭлементДляФокуса;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Важно помнить разницу между Объектом и Элементом формы. В коде 1С мы активизируем именно элемент формы. Если ваша табличная часть называется Товары, то и соответствующая ей таблица на форме чаще всего называется Товары. Если она находится на скрытой в данный момент странице (в группе страниц), установка ТекущийЭлемент заставит платформу автоматически переключить вкладку на нужную.
Если вы не хотите писать сложный код обработки расшифровки, существует более простой, но менее гибкий способ. В схеме компоновки данных для конкретного поля можно задать Макет поля. В этом макете можно разместить текстовый параметр или шаблон, а в свойствах ячейки указать навигационную ссылку. Однако этот метод плохо подходит для динамического управления вкладками и чаще используется для простого перехода.
ОбработкаРасшифровки.Выполнить(), помните, что этот метод предназначен для вывода стандартного меню (открыть, отфильтровать, сгруппировать). Для программного открытия используйте прямой анализ полей расшифровки, как показано в Шаге 3.ТипЗнч(), чтобы не попытаться открыть форму для числа или строки.Таким образом, мы разобрали комплексный подход к решению задачи. Сочетание перехвата расшифровки в СКД и использование параметров формы позволяет создавать интерфейсы, которые экономят время пользователя, сразу направляя его к нужным данным внутри документа.