Рассмотрим классическую ситуацию в разработке на платформе 1С: мы написали простейший запрос в конструкторе, проверили его в консоли — данные успешно извлекаются. Однако при формировании отчета через Систему Компоновки Данных (СКД) некоторые поля просто пропадают. Выясним причину такого поведения и разберем по шагам все возможные нюансы платформы, которые влияют на вывод данных пользователю.
Проанализируем базовый пример запроса, с которым часто возникают трудности:
ВЫБРАТЬ
ЗаказПокупателя.Ссылка КАК ЗаказПокупателя,
ЗаказПокупателя.ДатаОтгрузки КАК ДатаОтгрузки,
ВЫРАЗИТЬ(ЗаказПокупателя.Ссылка КАК Документ.ЗаказПокупателя).Контрагент КАК Контрагент
ИЗ
Документ.ЗаказПокупателя КАК ЗаказПокупателя
ГДЕ
ЗаказПокупателя.Ссылка В ИЕРАРХИИ(&Ссылка)
В этом примере мы хотим увидеть сам заказ, дату отгрузки и контрагента. Но в итоговом отчете колонок Контрагент и ДатаОтгрузки нет. Очистка кэша и полные права не помогают. Разберем основные причины, почему так происходит, и способы их устранения.
Первая и самая частая причина кроется в настройках структуры самого отчета. СКД не будет отображать поля, если они не относятся к текущей группировке. Посмотрим на этот механизм подробнее.
Если мы создали группировку только по полю ЗаказПокупателя, то СКД выведет только это поле и ресурсы (числовые итоги), если они заданы. Обычные реквизиты документа, такие как дата или контрагент, не появятся, так как система не знает, как их агрегировать в рамках этой группировки. Чтобы вывести информацию в виде обычной плоской таблицы (строка за строкой), настроим детальные записи:
Детальных записей.
ЗаказПокупателя, Контрагент, ДатаОтгрузки.Теперь отчет выведет плоскую таблицу без лишних строк с названиями группировок, и все текстовые или ссылочные поля станут видимыми. Для реализации обратного сценария, когда незаполненные колонки необходимо динамически убрать из отчета, можно использовать механизм автоматического скрытия столбцов при отсутствии данных.
Разберем еще одну неочевидную особенность. Платформа 1С строго разграничивает права: Чтение (доступ к данным на уровне кода) и Просмотр (право видеть данные в пользовательском интерфейсе). СКД автоматически анализирует права текущего пользователя перед выводом результата.
Если у пользователя есть права на чтение реквизитов документа, запрос отработает без ошибок. Но если нет прав на просмотр хотя бы одного выводимого поля, СКД молча исключит это поле из итогового макета. Проверим роли пользователя и убедимся, что для выводимых метаданных установлен флаг Просмотр. При необходимости обойти данные ограничения без перенастройки прав пользователя можно использовать метод запуска отчета СКД в привилегированном режиме.
Проанализируем ситуацию сложнее. Предположим, поле имеет составной тип данных (например, документ-регистратор в регистре накопления). Если у пользователя нет прав на просмотр хотя бы одного из возможных типов документов, входящих в этот составной тип, Система Компоновки Данных полностью скроет это поле из отчета.
Чтобы избежать этого, жестко ограничим тип прямо в тексте запроса конструкцией ВЫРАЗИТЬ. Посмотрим на пример:
ВЫБРАТЬ
ВЫРАЗИТЬ(Регистр.Регистратор КАК Документ.ЗаказПокупателя).Контрагент КАК Контрагент
ИЗ
РегистрНакопления.Продажи КАК Регистр
Таким образом мы подсказываем СКД, что работаем только с конкретным документом, и система будет проверять права только для него.
Рассмотрим вкладку Наборы данных в схеме СКД. Для каждого поля существуют галочки в колонках Ограничение поля, Ограничение условия и так далее. Если программист случайно или намеренно установил галочку ограничения, поле будет недоступно для выбора в пользовательских настройках.
Кроме того, вспомним про механизм Функциональных опций. Если выводимый реквизит в дереве метаданных привязан к определенной функциональной опции, и в самой базе данных эта опция выключена (например, снята галочка в настройках учета предприятия), СКД автоматически вырежет
это поле из отчета, даже если в запросе оно присутствует.
Усложним наш отчет. Добавим обращение к табличной части документа, чтобы вывести количество и вес номенклатуры:
ВЫБРАТЬ
ЗаказПокупателяЗапасы.Ссылка КАК Заказ,
ЗаказПокупателяЗапасы.Номенклатура КАК Номенклатура,
ЗаказПокупателяЗапасы.Количество КАК Количество,
ЗаказПокупателяЗапасы.Вес КАК Вес
ИЗ
Документ.ЗаказПокупателя.Запасы КАК ЗаказПокупателяЗапасы
Мы можем столкнуться с тем, что колонка Количество суммируется всегда правильно, а колонка Вес выводится не из всех документов или не рассчитывает итоги в группировках. Выясним причину.
Дело в том, что реквизит Вес в конфигурации имеет Определяемый тип (например, Число(15, 3)). Для платформы и СКД определяемый тип — это потенциально составной или неоднозначный тип данных. Автоматические математические операции для него могут отключиться. К тому же, при левых соединениях или в старых документах вместо нуля может содержаться значение NULL, которое разрушает расчет суммы.
Заставим СКД правильно считать этот определяемый тип. Выполним следующие шаги:
NULL, заменив их на числовой нуль.Посмотрим на исправленный фрагмент запроса:
ВЫБРАТЬ
ЕСТЬNULL(ВЫРАЗИТЬ(ЗаказПокупателяЗапасы.Вес КАК Число(15, 3)), 0) КАК Вес
ИЗ ...
Далее обязательно перенесем поле Вес на вкладку Ресурсы в схеме СКД и пропишем выражение агрегации: СУММА(Вес). Пока поле не назначено ресурсом явно, СКД не будет рассчитывать для него итоги в группировках.
В завершение разберем вопрос: зачем разработчики платформы используют этот механизм, если он требует дополнительных действий в СКД? Определяемый тип — это мощный архитектурный инструмент. Он позволяет зафиксировать единый стандарт данных (например, размерность веса или суммы) в одном узле метаданных конфигурации.
Если в будущем бизнесу потребуется увеличить точность учета веса до 4 знаков после запятой, нам не придется вручную искать и изменять сотни реквизитов в справочниках и документах по всей базе. Мы просто изменим настройки одного определяемого типа, и структура базы данных автоматически обновится во всех связанных объектах. Это радикально снижает количество ошибок и упрощает поддержку крупных систем.