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