Почему СКД требует право «Просмотр» для полей отчета и как решить проблему с недоступностью полей?

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

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

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

Суть проблемы: Чтение есть, Просмотра нет

Рассмотрим классическую ситуацию. В конфигурации «Управление производственным предприятием» (УПП) или любой другой при переходе на новую версию платформы у пользователей перестает формироваться отчет (например, «Свод начисленной зарплаты»). При анализе прав выясняется следующее:

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

Особенность СКД или баг платформы?

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

Проанализируем разницу между правами на уровне базы данных:

Логика работы СКД построена на том, что это инструмент интерактивного построения отчетов. Пользователь в режиме «1С:Предприятие» имеет возможность самостоятельно изменять структуру отчета: добавлять группировки, выводить новые поля, накладывать произвольные отборы.

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

Если у пользователя отсутствует право на интерактивный просмотр объекта метаданных, то система компоновки данных автоматически считает недоступными все поля таблицы этого объекта. Исключение составляли лишь старые версии платформы, работавшие в режиме совместимости с версией 8.1 — там это правило не применялось.

Как решить проблему? Варианты и обходные пути

В зависимости от требований безопасности в вашей организации, вы можете выбрать один из трех способов решения данной проблемы.

Решение 1. Административное (Рекомендуемое)

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

Для этого выполните следующие шаги:

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

Решение 2. Программное отключение проверки прав в СКД

Что делать, если по соображениям безопасности пользователю категорически нельзя давать право на интерактивный «Просмотр» объекта (чтобы он не мог найти его через меню «Все функции / Функции для технического специалиста» или открыть в стандартных списках), но отчет при этом должен работать?

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

Рассмотрим пример кода, который необходимо разместить в модуле отчета в процедуре ПриКомпоновкеРезультата:


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

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

Решение 3. Использование внешнего набора данных

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

Мы можем получить данные обычным запросом в коде (где достаточно права «Чтение» или можно использовать УстановитьПривилегированныйРежим(Истина)), выгрузить результат в таблицу значений и передать ее в СКД через «Набор данных - Объект».

Разберем этот алгоритм по шагам:

  1. В схеме компоновки данных вместо «Набора данных - запрос» создаем «Набор данных - объект» и указываем имя источника (например, ТаблицаРегистра).
  2. В модуле отчета пишем код заполнения этой таблицы в привилегированном режиме:

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

&НаСервереБезКонтекста
Функция ПолучитьДанныеНаСервере()
    
    УстановитьПривилегированныйРежим(Истина);
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   НДФЛКЗачету.ФизЛицо КАК ФизЛицо,
        |   НДФЛКЗачету.Сумма КАК Сумма
        |ИЗ
        |   РегистрНакопления.НДФЛКЗачету КАК НДФЛКЗачету";
        
    Возврат Запрос.Выполнить().Выгрузить();
    
КонецФункции

Важная деталь: Проблема с правами на Регистратор

Иногда возникает ситуация, когда у пользователя есть все права (и «Чтение», и «Просмотр») на сам регистр, но поля в отчете все равно заблокированы. Выясним причину этой неочевидной проблемы.

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

Чтобы избежать этого поведения, всегда используйте конструкцию ВЫРАЗИТЬ в запросах СКД, если вам нужно получить реквизиты регистратора. Это ограничит проверяемые типы документов только теми, которые действительно нужны в отчете:


ВЫБРАТЬ
    Продажи.Период КАК Период,
    ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.РеализацияТоваровУслуг).Номер КАК НомерРеализации,
    Продажи.Сумма КАК Сумма
ИЗ
    РегистрНакопления.Продажи КАК Продажи

В этом случае платформа будет проверять права «Просмотр» только для документа «Реализация товаров и услуг», игнорируя остальные типы документов-регистраторов.

← На главную