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

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

При разработке сложных отчетов на системе компоновки данных (СКД) часто возникает задача реализации "подчиненного" отчета — для этого подойдёт консоль СКД и инструменты для отладки компоновки. Это ситуация, когда при клике на ячейку основного отчета должен открываться другой отчет (или тот же самый, но с детализацией), сформированный на основе другого макета или другой схемы. Однако начинающие разработчики часто сталкиваются с проблемой: вместо привычного меню расшифровки или перехода к данным при наведении курсора появляется "белый плюс", а клик не вызывает никаких действий. Рассмотрим подробно, как правильно настроить программную расшифровку в подчиненном отчете.

Анализ проблемы: почему расшифровка "не видит" данные

Когда мы формируем отчет в 1С программно, мы берем на себя управление всеми этапами компоновки. Если в стандартном отчете платформа делает всё автоматически, то в ручном режиме нам нужно явно связать результат (табличный документ) с метаданными компоновки. Появление "белого плюса" вместо курсора расшифровки сигнализирует о том, что ячейка табличного документа не содержит идентификатора расшифровки или табличный документ не знает, где искать расшифровочные данные. Выясним основные причины этой ситуации:

  1. Объект ДанныеРасшифровкиКомпоновкиДанных не был передан в процессор компоновки.
  2. Объект расшифровки был создан на сервере, но не был сохранен в хранилище, доступном форме после завершения серверного вызова.
  3. В свойствах элемента формы "Поле табличного документа" не указан путь к данным расшифровки.

Шаг 1. Правильная инициализация процессора компоновки

Для начала проанализируем типичный код формирования отчета — в этом поможет инструмент для пошаговой отладки кода 1С. Чтобы расшифровка заработала, объект ДанныеРасшифровки должен пройти через всю цепочку формирования макета и процессора компоновки. Посмотрим на правильную последовательность инициализации на сервере:


// Создаем объект для сбора данных расшифровки
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;

// Инициализируем компоновщик макета
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

// Передаем данные расшифровки в метод Выполнить
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);

// Инициализируем процессор компоновки
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;

// КРИТИЧЕСКИ ВАЖНО: Передать ДанныеРасшифровки третьим параметром!
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки);

Многие разработчики совершают ошибку, инициализируя процессор компоновки только двумя параметрами: ПроцессорКомпоновки.Инициализировать(Макет,,). В этом случае данные расшифровки просто не будут заполнены в процессе работы процессора, и ячейки в итоговом документе останутся "пустыми" с точки зрения интерактивности.

Шаг 2. Работа с временным хранилищем в управляемых формах

В управляемом приложении объекты, созданные на сервере (такие как ДанныеРасшифровкиКомпоновкиДанных), "умирают" сразу после возврата управления на клиент, если они не сохранены. Чтобы форма могла обратиться к ним при клике пользователя на ячейку, эти данные нужно поместить во временное хранилище.

Рассмотрим алгоритм действий в серверной процедуре формирования подчиненного отчета:

  1. Сформируем отчет, заполнив объект ДанныеРасшифровки.
  2. Поместим объект во временное хранилище, обязательно привязав его к уникальному идентификатору формы (ЭтаФорма.УникальныйИдентификатор). Это гарантирует, что данные будут жить столько же, сколько открыта форма.
  3. Запишем полученный адрес (URL) в строковый реквизит формы.

Посмотрим, как это выглядит в коде:


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

Шаг 3. Связь реквизита формы с элементом управления

Финальный и обязательный штрих — настройка свойств самой формы. Проанализируем настройки элемента "Результат" (тип "Поле табличного документа"):

Важно: Если вы пропустите этот шаг, 1С не будет знать, по какому адресу в памяти искать расшифровку при взаимодействии пользователя с таблицей, и расшифровка работать не будет.

Дополнительные рекомендации для подчиненных отчетов

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


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

В подчиненной форме в процедуре ПриСозданииНаСервере мы извлекаем значение расшифровки. Если это идентификатор конкретного поля, мы можем получить само значение (например, ссылку на документ или справочник), используя переданный АдресДанных и метод ПолучитьИзВременногоХранилища. Для этой задачи можно использовать пример получения значений группировок в расшифровке СКД.

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


&НаСервере
Процедура ПолучитьЗначениеИзРасшифровки(АдресДанных, Идентификатор)
    Данные = ПолучитьИзВременногоХранилища(АдресДанных);
    // Теперь можно обратиться к конкретному элементу по ID
    ЗначениеПоля = Данные.Элементы[Идентификатор].ПолучитьПоля()[0].Значение;
    // Используем это значение как параметр для подчиненного отчета
КонецПроцедуры

Таким образом, для корректной работы расшифровки в подчиненном отчете необходимо обеспечить три условия: передать объект расшифровки в ПроцессорКомпоновкиДанных, сохранить его во временном хранилище и связать адрес этого хранилища со свойством табличного документа на форме.

← На главную