Почему возникает ошибка "Недостаточно прав для работы с таблицей Документ.ПереносДанных", если документ не указан в запросе, и как её исправить?

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

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

Анализируем исходную проблему: косвенное обращение к данным

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

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

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

В нашем случае, в запросе присутствует несколько конструкций, которые косвенно могут затрагивать Документ.ПереносДанных:


| И ЗарплатаКВыплатеОбороты.Регистратор ССЫЛКА Документ.ВедомостьНаВыплатуЗарплатыВБанк
| И ЗарплатаКВыплатеОбороты.Регистратор.Дата МЕЖДУ ДОБАВИТЬКДАТЕ(&НПериод, МЕСЯЦ, 1) И ДОБАВИТЬКДАТЕ(&КПериод, МЕСЯЦ, 1)

Или, например, подобная конструкция:

| И ЗарплатаКВыплате.ДокументОснование ССЫЛКА Документ.БольничныйЛист

Конструкция Регистратор.Дата или ДокументОснование ССЫЛКА ... означает, что запрос пытается обратиться к полям различных документов-регистраторов, которые могли быть привязаны к записям регистра. Если среди этих регистраторов или документов-оснований был Документ.ПереносДанных, и у пользователя нет прав на его чтение, возникнет ошибка. Запрос в таком случае "не знает", что ему нужен именно Документ.ПереносДанных, он просто пытается получить данные из всех возможных регистраторов, и сталкивается с недоступным.

Решение 1: Предоставление прав пользователю

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

Разберем по шагам, как добавить права:

  1. Определяем роли с правами: Прежде всего, нам нужно выяснить, какие роли в конфигурации уже имеют право на чтение документа ПереносДанных. Для этого:

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

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

Важно: Всегда рекомендуется настраивать доступ для групп пользователей (по ролям, отделам), а не для каждого отдельного пользователя. Это упрощает администрирование и поддержание системы прав в актуальном состоянии.

Решение 2: Использование конструкции "ВЫБРАТЬ РАЗРЕШЕННЫЕ" в запросе

В 1С существует специальная конструкция ВЫБРАТЬ РАЗРЕШЕННЫЕ, предназначенная для работы с системой ограничения прав на уровне записей (RLS). Она позволяет выполнить запрос, игнорируя строки, на которые у текущего пользователя нет прав доступа. Это означает, что если в запросе будет встречена запись, созданная Документ.ПереносДанных, на который нет прав, эта запись просто не попадет в результат запроса, и ошибка не возникнет.

Пример использования:


ВЫБРАТЬ РАЗРЕШЕННЫЕ
    ЕСТЬNULL(СУММА(ЗарплатаКВыплатеОбороты.СуммаКВыплате), 0) КАК СуммаКВыплатеОЗПВСледующемМесяце,
    // ... остальной текст запроса
ИЗ
    РегистрНакопления.ЗарплатаКВыплате КАК ЗарплатаКВыплатеОбороты
// ...

Мы добавляем ключевое слово РАЗРЕШЕННЫЕ сразу после ВЫБРАТЬ в начале каждого блока запроса или перед именами таблиц/регистров, к которым обращаемся.

Ограничения и последствия:

Хотя этот метод позволяет избежать ошибки, он имеет существенный недостаток, о котором справедливо упомянул автор в сообщении 5: результат запроса может быть неполным или недостоверным. Если критически важные данные для отчета были внесены через Документ.ПереносДанных, и у пользователя нет на него прав, эти данные просто не попадут в отчет. В итоге, отчет сформируется без ошибки, но с некорректными суммами, что может привести к неправильным управленческим решениям или учетным ошибкам.

Поэтому использовать ВЫБРАТЬ РАЗРЕШЕННЫЕ следует с осторожностью и только в тех случаях, когда мы точно знаем, что отсутствие некоторых данных не повлияет на бизнес-логику или когда допустимо представление частичных данных. В большинстве случаев для критически важных отчетов требуется полная информация.

Решение 3: Установка привилегированного режима

Для программистов 1С существует мощный инструмент — УстановитьПривилегированныйРежим(). Этот метод позволяет временно отключить проверку прав доступа для текущего сеанса или определенного участка кода. Это может быть полезно, когда необходимо получить данные, к которым у пользователя нет прямого доступа, но которые логически необходимы для выполнения операции (например, для сложных расчетов в отчете).

Пример использования:


УстановитьПривилегированныйРежим(Истина); // Включаем привилегированный режим

Попытка
    Запрос = Новый Запрос;
    // ... ваш текст запроса ...
    РезультатЗапроса = Запрос.Выполнить();
Исключение
    Сообщить("Ошибка выполнения запроса: " + ОписаниеОшибки());
КонецПопытки;

УстановитьПривилегированныйРежим(Ложь); // Обязательно выключаем привилегированный режим!

Важные меры предосторожности:

  1. Обязательное отключение: УстановитьПривилегированныйРежим(Истина) должен быть всегда парным с УстановитьПривилегированныйРежим(Ложь). Если вы забудете отключить привилегированный режим, все последующие операции в рамках текущего сеанса будут выполняться с полными правами, что создает серьезные угрозы безопасности и может привести к несанкционированному доступу к данным или их изменению. Рекомендуется использовать блок Попытка ... Исключение ... КонецПопытки, чтобы гарантировать отключение режима даже в случае возникновения ошибки.
  2. Целевое использование: Привилегированный режим следует применять только для тех минимальных участков кода, где это абсолютно необходимо. Не рекомендуется использовать его для всей обработки или отчета без крайней на то необходимости.
  3. Аудит и безопасность: Использование привилегированного режима требует внимательного анализа безопасности. Убедитесь, что нет возможности злонамеренного использования этой функции для получения несанкционированного доступа к данным.

Решение 4: Явное указание типа документа с помощью ВЫРАЗИТЬ

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

Для корректной работы рекомендуется использовать функцию ВЫРАЗИТЬ(<ПолеСсылка> КАК Документ.<ИмяДокумента>). Эта функция позволяет явно указать СУБД, что нас интересует только определенный тип документа, даже если поле-ссылка может указывать на другие типы. Это помогает системе точнее определить необходимые таблицы и применить соответствующие ограничения прав.

Рассмотрим пример из нашего запроса:


| И ЗарплатаКВыплатеОбороты.Регистратор ССЫЛКА Документ.ВедомостьНаВыплатуЗарплатыВБанк
| И ЗарплатаКВыплатеОбороты.Регистратор.Дата МЕЖДУ ДОБАВИТЬКДАТЕ(&НПериод, МЕСЯЦ, 1) И ДОБАВИТЬКДАТЕ(&КПериод, МЕСЯЦ, 1)

Здесь мы сначала фильтруем по типу регистратора (ССЫЛКА Документ.ВедомостьНаВыплатуЗарплатыВБанк), а затем обращаемся к полю Дата этого регистратора. Мы можем сделать это обращение более явным:


| И ВЫРАЗИТЬ(ЗарплатаКВыплатеОбороты.Регистратор КАК Документ.ВедомостьНаВыплатуЗарплатыВБанк).Дата МЕЖДУ ДОБАВИТЬКДАТЕ(&НПериод, МЕСЯЦ, 1) И ДОБАВИТЬКДАТЕ(&КПериод, МЕСЯЦ, 1)

Аналогично, для ДокументОснование:


| И ВЫРАЗИТЬ(ЗарплатаКВыплате.ДокументОснование КАК Документ.БольничныйЛист).ВидДокумента = &Вид

(предполагая, что мы хотим получить поле ВидДокумента из БольничногоЛиста).

Использование ВЫРАЗИТЬ может помочь СУБД лучше оптимизировать запрос и избежать обращения к метаданным тех документов, на которые у пользователя нет прав и которые не нужны для данного конкретного фильтра.

Дополнительные соображения и рекомендации

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

  1. Ограничения прав на уровне записей (RLS): Если для пользователя настроены сложные ограничения доступа на уровне записей (RLS), это также может быть причиной. RLS не просто запрещает доступ к объекту, а фильтрует записи внутри него. Если часть записей в регистре была создана Документ.ПереносДанных, и эти записи подпадают под RLS-ограничения, но пользователь не имеет прав на сам документ ПереносДанных, может возникнуть конфликт.

  2. Контекст "Документа.ПереносДанных" в ЗУП: В конфигурациях, подобных 1С:Зарплата и Управление Персоналом (ЗУП), документ ПереносДанных особенно часто используется для ввода начальных данных по сотрудникам, их зарплате, НДФЛ и взносам при запуске системы. Если вы создали свой отчет по регистрам, которые затрагивают эти данные, вероятность столкнуться с такой ошибкой выше.

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

  4. Обновление конфигурации: Иногда подобные ошибки могут быть связаны с недоработками в механизме прав доступа, которые были исправлены в более поздних версиях конфигурации. Убедитесь, что ваша конфигурация обновлена до актуальной версии.

Решение проблемы с "недостатком прав" на косвенно используемый Документ.ПереносДанных требует внимательного анализа и подбора оптимального метода. Чаще всего, предоставление явных прав на чтение документа является наиболее простым и безопасным путем, если это не противоречит политике безопасности предприятия. В противном случае, следует рассмотреть использование ВЫРАЗИТЬ, ВЫБРАТЬ РАЗРЕШЕННЫЕ или привилегированного режима с соблюдением всех мер предосторожности.

← На главную