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

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

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

Проанализируем ситуацию на практическом примере. Представим, что мы дорабатываем внешний отчет по себестоимости продаж. Нам требуется вывести дубликат колонки себестоимости для дополнительных расчетов, а также разобраться, почему по оптовым заказам себестоимость выводится, а по розничным продажам — колонка остается пустой, хотя сам запрос в консоли возвращает заполненные строки.

---

Часть 1. Почему не дублируется колонка (ресурс) в выбранных полях СКД?

Рассмотрим стандартную ситуацию: разработчик переходит на вкладку Настройки -> Выбранные поля и добавляет туда одно и то же поле (например, Себестоимость) дважды. При формировании отчета колонка выводится только один раз. Почему так происходит?

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

Разберем два эффективных способа обойти это ограничение.

Способ 1. Использование вычисляемых полей (рекомендуемый)

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

  1. Откроем схему компоновки данных и перейдем на вкладку Вычисляемые поля.
  2. Добавим новую строку. В колонке Путь к данным укажем уникальное имя для новой колонки, например, СебестоимостьКопия.
  3. В колонке Выражение напишем имя нашего исходного поля: Себестоимость.
  4. Зададим понятный заголовок для новой колонки в поле Заголовок (например, "Предварительная себестоимость").
  5. Перейдем на вкладку Ресурсы. Чтобы наше вычисляемое поле правильно суммировалось в группировках и итогах, добавим его в список ресурсов. В колонке Выражение укажем формулу расчета агрегата: Сумма(СебестоимостьКопия).
  6. Теперь перейдем на вкладку Настройки -> Выбранные поля и перетащим туда как исходную Себестоимость, так и наше новое вычисляемое поле СебестоимостьКопия.

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

Способ 2. Создание псевдонима в тексте запроса

Если мы хотим решить задачу на уровне источника данных, то можем продублировать поле непосредственно в тексте запроса схемы компоновки данных. Посмотрим на пример кода:


ВЫБРАТЬ
    Продажи.Документ КАК Документ,
    Продажи.Себестоимость КАК Себестоимость,
    Продажи.Себестоимость КАК СебестоимостьВторая
ИЗ
    РегистрНакопления.ВыручкаИСебестоимостьПродаж КАК Продажи

После изменения запроса на вкладке Наборы данных появится новое поле СебестоимостьВторая. Нам останется лишь зайти на вкладку Ресурсы, сделать его ресурсом по аналогии с основным полем и добавить в выбранные поля настроек отчета.

---

Часть 2. Данные в консоли запросов есть, а в СКД по рознице пусто — ищем причины

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

Причина 1. Оптимизация запроса компоновщиком (неиспользуемые поля)

СКД — это интеллектуальный механизм. Перед отправкой SQL-запроса к СУБД он анализирует, какие поля выбраны пользователем в настройках отчета. Если в настройках не выбраны ключевые поля, по которым происходит связь таблиц (например, реквизиты документов или аналитика), СКД в целях повышения производительности вырезает «лишние» соединения из итогового запроса.

Если данные по розничным продажам подтягивались через левое соединение, которое СКД посчитал ненужным, данные по себестоимости розницы просто исчезнут.

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

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

Причина 2. Ограничения прав доступа на уровне записей (RLS) и обращение через точку

Когда мы тестируем запрос в консоли под полными правами, RLS не применяется. Но при формировании отчета СКД запускается под правами текущего пользователя.

Если в тексте запроса мы обращаемся к реквизитам через точку от реквизита составного типа (например, Регистратор.Организация или Регистратор.Дата), а у пользователя нет прав на чтение хотя бы одного из типов документов, входящих в этот регистратор (например, закрыты права на документ ОтчетОРозничныхПродажах), то СКД вернет NULL для всех подобных строк.

Решение: Используем явное приведение типов с помощью конструкции ВЫРАЗИТЬ(). Рассмотрим пример правильного написания запроса:


ВЫБРАТЬ
    ВЫБОР 
        КОГДА Ссылка ССЫЛКА Документ.ОтчетОРозничныхПродажах 
            ТОГДА ВЫРАЗИТЬ(Ссылка КАК Документ.ОтчетОРозничныхПродажах).Себестоимость
        КОГДА Ссылка ССЫЛКА Документ.ЗаказКлиента 
            ТОГДА ВЫРАЗИТЬ(Ссылка КАК Документ.ЗаказКлиента).Себестоимость
    КОНЕЦ КАК СебестоимостьДокумента
ИЗ
    ...

Явное приведение типов исключает избыточные проверки безопасности СУБД и предотвращает появление пустых значений из-за ограничений RLS.

Причина 3. Искажение параметров виртуальных таблиц и автозаполнение периодов

Если в СКД включен флаг Автозаполнение, система автоматически управляет параметрами виртуальных таблиц остатков и оборотов.

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

Решение: Проверим и настроим параметры в СКД:

  1. Перейдем на вкладку Параметры.
  2. Для параметра КонецПериода в колонке Выражение пропишем приведение к концу дня: КонецПериода(&КонецПериода, "ДЕНЬ").
  3. Если используется тип Граница, то выражение будет выглядеть так: Новый Граница(КонецПериода(&КонецПериода, "ДЕНЬ"), ВидГраницы.Включая).

---

Как гарантированно найти скрытую ошибку?

Если вышеописанные способы не помогают, применим профессиональный метод отладки — просмотр сгенерированного SQL-запроса через Консоль компоновки данных.

Эта обработка позволяет увидеть финальный текст запроса, который СКД отправляет в СУБД после наложения всех пользовательских настроек, отборов и оптимизаций. Открыв макет компоновки для табличного документа в консоли СКД, мы сможем скопировать этот итоговый запрос, запустить его в обычной консоли запросов и сразу увидеть, на каком этапе (из-за условий связей, параметров или отборов) отсекаются строки по розничным продажам.

← На главную