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

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

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

Главная причина: кэширование и пользовательские настройки

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

Рассмотрим, как разработчики обычно пытаются решить эту проблему, и как это делать правильно.

  1. Быстрый, но "грязный" метод: Переименование отчета. Как выяснил автор исходного кода, изменение имени внешнего отчета заставляет систему создать для него новую ветку настроек. Кэш сбрасывается, и новые колонки появляются. Однако постоянно менять имя отчета при каждой доработке — плохая практика, которая приводит к путанице.
  2. Метод для пользователя: Сброс настроек. Самый простой и правильный путь в режиме предприятия — открыть отчет, нажать кнопку "Еще" и выбрать пункт Установить стандартные настройки. Это принудительно прочитает актуальную схему СКД.
  3. Метод для разработчика (при использовании БСП): Если отчет встроен в конфигурацию с Библиотекой стандартных подсистем, необходимо обновить версию отчета в справочнике ИдентификаторыОбъектовМетаданных или запустить обработку обновления вариантов отчетов. Тогда новые настройки применятся у всех пользователей автоматически без их участия.

Оптимизация подготовки данных: избавляемся от циклов

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

Посмотрим на пример такого неоптимального подхода:


КЧ = Новый КвалификаторыЧисла(20,2);
Массив = Новый Массив;
Массив.Добавить(Тип("Число"));
ОписаниеТиповЧ = Новый ОписаниеТипов(Массив, , ,КЧ);

ТаблицаДанных.Колонки.Добавить("ОбъемПродажТовары", ОписаниеТиповЧ);
// ... добавление других колонок ...

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл 
    НоваяСтрока = ТаблицаДанных.Добавить();
    ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
КонецЦикла;

Этот подход работает медленно, требует написания большого объема рутинного кода и увеличивает вероятность опечаток (например, несовпадение имени колонки в таблице и в выборке). Разберем, как сделать это гораздо элегантнее и быстрее.

Вместо ручного конструирования достаточно выгрузить результат запроса напрямую в таблицу значений. Платформа 1С сама создаст все нужные колонки с идеальным совпадением типов данных:


// Выполняем запрос и сразу получаем готовую таблицу значений со всеми типизированными колонками
ТаблицаДанных = Запрос.Выполнить().Выгрузить();

Одна эта строка заменяет десятки строк ручного объявления колонок и цикл обхода выборки, полностью исключая ошибку несовпадения типов между переданной таблицей и схемой СКД.

Обязательные требования к настройке схемы СКД

Даже если мы идеально сформировали таблицу значений в коде, СКД не увидит новые данные автоматически. При использовании источника данных типа "Набор данных - Объект" необходимо соблюдать строгие правила.

  1. Ручное описание полей. Каждое новое поле должно быть вручную заведено на вкладке "Наборы данных" в схеме компоновки.
  2. Совпадение имен. Имя поля в схеме СКД и имя колонки в передаваемой таблице значений (в нашем случае ТаблицаДанных) должны совпадать с точностью до символа. Если в схеме СКД поля нет, система просто проигнорирует эту колонку при загрузке внешнего набора.

Настройка ресурсов и выражений

Если добавленные колонки содержат числовые показатели (например, ОбъемПродажТовары или БаллыЗаТовар), и мы хотим выводить по ним итоги в группировках, их необходимо добавить на вкладку "Ресурсы".

Важный нюанс: для ресурсов обязательно должно быть прописано выражение агрегации. Например, Сумма(ОбъемПродажТовары). Если выражение ресурса не задано или содержит синтаксическую ошибку, поле не сможет быть рассчитано для группировочных записей и в отчет не выведется.

Архитектурная ошибка: конкатенация текста запроса

Рассмотрим еще одну распространенную проблему, присутствующую в исходном алгоритме — динамическую склейку текста запроса с помощью условий Текст = Текст + " ГДЕ ".


Если ЗначениеЗаполнено(СотрудникДляРасчета) и не ЗначениеЗаполнено(мМагазин) Тогда
    Текст = Текст + " ГДЕ РасчетБалловСистемыМотивации.Сотрудник  = &СотрудникДляРасчета";
ИначеЕсли ЗначениеЗаполнено(СотрудникДляРасчета) и ЗначениеЗаполнено(мМагазин) Тогда
    // ... и так далее

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

Даже если вы используете внешний набор данных, язык запросов 1С позволяет обрабатывать необязательные параметры без изменения самого текста запроса. Если параметр может быть не заполнен, условие пишется следующим образом:


ВЫБРАТЬ
    // ... поля ...
ИЗ
    РегистрСведений.РасчетБалловСистемыМотивации КАК РасчетБаллов
ГДЕ
    (&СотрудникДляРасчета = ЗНАЧЕНИЕ(Справочник.Сотрудники.ПустаяСсылка) 
        ИЛИ РасчетБаллов.Сотрудник = &СотрудникДляРасчета)
    И (&Магазин = ЗНАЧЕНИЕ(Справочник.Магазины.ПустаяСсылка) 
        ИЛИ РасчетБаллов.Магазин = &Магазин)

Идеальное решение: Перенести запрос из программного кода непосредственно в саму схему СКД (использовать "Набор данных - Запрос"). СКД обладает мощнейшим механизмом — расширением языка запросов. Используя конструкции в фигурных скобках {ГДЕ РасчетБаллов.Сотрудник.*}, мы поручаем системе самой определять, нужно ли накладывать условие. СКД автоматически подставит фильтр в запрос только в том случае, если пользователь установил отбор по этому полю в настройках отчета.

← На главную