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