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