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

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

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

Разберем разницу в работе консоли запросов и оптимизатора СКД

Чтобы понять, почему один и тот же запрос ведет себя по-разному, давайте рассмотрим внутренние механизмы платформы. Консоль запросов выполняет написанный код «как есть». Если у пользователя есть базовые права на чтение таблиц, участвующих в запросе, он получит результат.

СКД работает совершенно иначе. Она использует собственный интеллектуальный оптимизатор. Перед тем как отправить запрос к базе данных, СКД перестраивает исходный текст. При этом система учитывает:

  1. Выбранные пользователем группировки и поля вывода.
  2. Установленные отборы и сортировки.
  3. Доступные пользователю роли и ограничения прав доступа на уровне записей (RLS).

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

Влияние галочки «Автозаполнение» в схеме СКД

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

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

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

Разберем по шагам решение проблемы с правами на характеристики

Если вы столкнулись с подобной ситуацией, проанализируем последовательность действий для ее исправления:

  1. Откройте конфигуратор и найдите справочники или документы, которые используются в вашем запросе (особенно те, которые вызывали ошибку, например, справочник сотрудников или фондов рабочего времени).
  2. Зайдите в метаданные этих объектов и перейдите на вкладку «Данные».
  3. Найдите кнопки «Характеристики» и «Общие реквизиты».
  4. Нажмите на них и проверьте, какие объекты конфигурации (планы видов характеристик, регистры сведений) там указаны.
  5. Убедитесь, что у пользователя (через его профиль групп доступа или роли) есть права на чтение тех объектов, которые там прописаны. Если прав нет — их необходимо добавить в соответствующую роль.

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

Альтернативное решение: отказ от автозаполнения

Отключение автозаполнения и ручное добавление только нужных полей считается хорошим тоном при разработке сложных отчетов. Это предотвращает неявные обращения к таблицам конфигурации и существенно ускоряет инициализацию отчета.

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

Права «Чтение» и «Просмотр»: в чем разница для СКД?

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

Если у пользователя есть право на «Чтение», но нет права на «Просмотр», консоль запросов отработает без малейших проблем, а вот отчет СКД может вернуть пустой результат, так как система безопасности заблокирует вывод данных для интерактивного взаимодействия.

Как правильно использовать привилегированный режим в СКД

Иногда программисты пытаются обойти проблемы с правами, просто вызывая метод УстановитьПривилегированныйРежим(Истина) в модуле объекта отчета. Однако просто написать эту команду в обработчике бывает недостаточно. Как мы обсуждали выше, платформа «урежет» недоступные поля еще до начала компоновки макета — на этапе загрузки пользовательских настроек.

Чтобы отчет гарантированно выполнялся в привилегированном режиме без обрезки полей, разберем правильный алгоритм программного формирования:

  1. В основной схеме компоновки данных создайте «Набор данных - Объект» (а не набор данных - запрос). В этом случае настройки не будут предварительно проверяться на наличие прав к таблицам базы данных.
  2. В модуле объекта отчета в предопределенной процедуре перехватите формирование отчета.
  3. Включите привилегированный режим.
  4. Программно выполните реальный запрос и передайте его результат в СКД.

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


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Отключаем стандартное формирование отчета
    СтандартнаяОбработка = Ложь;
    
    // Включаем выполнение без контроля прав
    УстановитьПривилегированныйРежим(Истина);
    
    // Инициализируем настройки
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();
    
    // Выполняем наш запрос к базе данных
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ ... "; // Текст вашего запроса
    ТаблицаРезультат = Запрос.Выполнить().Выгрузить();
    
    // Передаем таблицу в СКД
    ВнешниеНаборыДанных = Новый Структура("ИсточникДанных1", ТаблицаРезультат);
    
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);

КонецПроцедуры

Использование признака «Обязательное» поле

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

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

← На главную