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