Почему пропадает расшифровка в табличном документе при программном формировании отчета на СКД и как ее восстановить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке произвольных интерфейсов в 1С часто возникает задача встроить отчет на системе компоновки данных (СКД) в форму справочника, документа или внешней обработки. При использовании типовой кнопки отчета «Сформировать» платформа автоматически берет на себя управление механизмами расшифровки. Однако, если мы реализуем собственную кнопку и пишем программный код компоновки данных, двойной клик по ячейкам табличного документа может перестать открывать детальные данные или вызывать ошибку: «Значение данных расшифровки отсутствует, либо имеет неправильный тип».

Разберем подробно причины такого поведения управляемой формы и пошагово реализуем правильный алгоритм программного вывода отчета с сохранением полной функциональности расшифровки.

Причины возникновения проблемы в управляемом интерфейсе

Чтобы понять, почему стандартная расшифровка перестает работать, проанализируем архитектуру взаимодействия клиентской и серверной частей управляемого приложения:

  1. Разделение контекста: На сервере формируется специализированный объект ДанныеРасшифровкиКомпоновкиДанных. Этот объект является тяжелым и не может напрямую существовать на клиенте в контексте формы.
  2. Ожидаемый тип реквизита: Свойство элемента формы «Табличный документ» ДанныеРасшифровки, а также соответствующий строковый реквизит управляемой формы ожидают не сам объект расшифровки, а строковый URL-адрес во временном хранилище (тип Строка).
  3. Отсутствие стандартного контекста: В формах объектов (справочников, документов) в отличие от типовых форм отчетов нет автоматических обработчиков компоновки, поэтому всю цепочку генерации и регистрации адреса расшифровки разработчик должен реализовать вручную.

Пошаговый алгоритм решения проблемы

Рассмотрим правильную схему программного формирования отчета на СКД в контексте управляемой формы.

  1. Создание реквизита формы: Добавим в управляемую форму реквизит ДанныеРасшифровки с типом данных Строка.
  2. Связывание с табличным документом: В свойствах элемента формы типа «Поле табличного документа» найдем свойство ДанныеРасшифровки и укажем имя созданного реквизита формы.
  3. Инициализация данных расшифровки: В серверной процедуре компоновки создадим объект ДанныеРасшифровкиКомпоновкиДанных и передадим его в компоновщик макета и процессор компоновки.
  4. Помещение во временное хранилище: Сохраним полученный объект в оперативной памяти сервера с помощью функции ПоместитьВоВременноеХранилище() с привязкой к уникальному идентификатору формы.

Пример программного формирования отчета на сервере

Посмотрим на пример законченной серверной процедуры формирования отчета СКД, вызываемой по нажатию пользовательской кнопки:


&НаСервере
Процедура СформироватьОтчетНаСервере()
    
    // Получаем схему компоновки данных и текущие настройки
    СхемаКД = РеквизитФормыВЗначение("Отчет").ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
    НастройкиКД = Отчет.КомпоновщикНастроек.ПолучитьНастройки();
    
    // Инициализируем объект для сбора данных расшифровки
    ДанныеРасшифровкиСКД = Новый ДанныеРасшифровкиКомпоновкиДанных;
    
    // Создаем макет компоновки с передачей объекта расшифровки
    КомпоновщикМакетаКД = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКД = КомпоновщикМакетаКД.Выполнить(СхемаКД, НастройкиКД, ДанныеРасшифровкиСКД);
    
    // Инициализируем процессор компоновки данных
    ПроцессорКД = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКД.Инициализировать(МакетКД, , ДанныеРасшифровкиСКД, Истина);
    
    // Очищаем и выводим результат в табличный документ на форме
    Элементы.ТабличныйДокументПоле.Очистить();
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ТабличныйДокумент);
    ПроцессорВывода.Вывести(ПроцессорКД);
    
    // Помещаем данные расшифровки во временное хранилище формы
    ДанныеРасшифровки = ПоместитьВоВременноеХранилище(ДанныеРасшифровкиСКД, ЭтаФорма.УникальныйИдентификатор);
    
КонецПроцедуры

Тонкости работы с памятью и временным хранилищем

Рассмотрим важные нюансы, которые необходимо учитывать при многократном формировании отчетов:

  1. Время жизни данных: Передача параметра ЭтаФорма.УникальныйИдентификатор в ПоместитьВоВременноеХранилище гарантирует, что расшифровка будет доступна пользователю все время, пока форма открыта, и автоматически удалится из оперативной памяти сервера при ее закрытии.
  2. Очистка предыдущих версий: При повторных нажатиях кнопки в пределах одной формы в памяти могут накапливаться старые данные расшифровки. Если отчет оперирует большими объемами информации, перед повторным помещением полезно вызывать УдалитьИзВременногоХранилища(ДанныеРасшифровки), передавая старый адрес.

Перехват и кастомная обработка расшифровки

Если в форме требуется не просто открыть типовое окно или форму объекта, а выполнить специализированные действия (например, перенести выбранное значение в реквизиты текущей формы), используем событие табличного документа ОбработкаРасшифровки на клиенте:


&НаКлиенте
Процедура ТабличныйДокументОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)
    
    // Отключаем стандартное контекстное меню расшифровки
    СтандартнаяОбработка = Ложь;
    
    // Получаем и анализируем выбранные данные на сервере
    ОбработатьВыбраннуюЯчейкуНаСервере(Расшифровка);
    
КонецПроцедуры

&НаСервере
Процедура ОбработатьВыбраннуюЯчейкуНаСервере(ИдентификаторРасшифровки)
    
    ОбъектРасшифровки = ПолучитьИзВременногоХранилища(ДанныеРасшифровки);
    
    Если ОбъектРасшифровки <> Неопределено Тогда
        ЭлементДанных = ОбъектРасшифровки.Элементы[ИдентификаторРасшифровки];
        // Выполняем требуемые действия со значениями полей
    КонецЕсли;
    
КонецПроцедуры

Таким образом, передача адреса временного хранилища в реквизит формы восстанавливает штатную работу механизма расшифровки СКД в любых произвольных управляемых формах 1С.

← На главную