Ошибка RLS при записи документа в 1C:УНФ: «Ожидается выражение ")"». Как найти и исправить?

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

При обновлении конфигураций на базе 1С:УНФ (или отраслевых решений, таких как "1С:Автосервис") пользователи и программисты могут столкнуться с загадочной ошибкой при записи документов. Система выдает сообщение об ошибке в коде, указывая на номер строки, которого физически не существует в модулях конфигурации.

Рассмотрим конкретную ситуацию: при попытке записать документ (например, "Заявка на ремонт") возникает ошибка ограничения доступа к данным со следующим текстом:


{(127, 2)}: Ожидается выражение ")"
<>ЕСТЬNULL(СтруктурнаяЕдиница, НЕОПРЕДЕЛЕНО) <> НЕОПРЕДЕЛЕНО

Глобальный поиск по конфигурации не дает результатов: строки ЕСТЬNULL(СтруктурнаяЕдиница, НЕОПРЕДЕЛЕНО) нигде нет. В этой статье мы разберем природу этой ошибки, выясним, откуда берется "призрачный" код, и рассмотрим способы решения проблемы.

Почему возникает ошибка в несуществующей строке?

Первое, что сбивает с толку — указание на строку (в примере это строка 127), которой нет ни в модуле объекта, ни в модуле менеджера. Чтобы понять причину, нам нужно углубиться в механику работы RLS (Record Level Security — ограничение прав на уровне записей).

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

Процесс выглядит так:

  1. Платформа берет основной запрос (запись документа).
  2. Платформа считывает шаблоны ограничений доступа из Ролей пользователя.
  3. Происходит "склейка" основного запроса и текста RLS.
  4. Полученный итоговый текст запроса отправляется в СУБД.

Ошибка {(127, 2)} относится именно к этому динамически сформированному запросу, который существует только в оперативной памяти сервера в момент выполнения транзакции. Именно поэтому найти этот текст через Ctrl+F в конфигураторе невозможно — его там просто нет в явном виде.

Анализ текста ошибки

Внимательно посмотрим на проблемный фрагмент:


ЕСТЬNULL(СтруктурнаяЕдиница, НЕОПРЕДЕЛЕНО) <> НЕОПРЕДЕЛЕНО

Эта конструкция выглядит подозрительно для языка запросов 1С. Обычно поля ссылочного типа (каким является СтруктурнаяЕдиница) сравниваются с ЗНАЧЕНИЕ(Справочник.СтруктурнаяЕдиница.ПустаяСсылка), а не с НЕОПРЕДЕЛЕНО. Значение НЕОПРЕДЕЛЕНО чаще применяется для полей составного типа, когда тип не выбран.

Ошибка «Ожидается выражение ")"» говорит о том, что транслятор запроса 1С в SQL не смог корректно обработать литерал НЕОПРЕДЕЛЕНО внутри функции ЕСТЬNULL в данном контексте, что привело к нарушению синтаксиса скобок в итоговом SQL-запросе. В таких случаях может помочь подсистема прав доступа с гибкими отборами, позволяющая обойти стандартные механизмы.

Чаще всего это происходит из-за рассинхронизации шаблонов RLS в Библиотеке Стандартных Подсистем (БСП). Например, если при обновлении конфигурации обновились общие модули, отвечающие за права, но в ролях (или расширениях) остались старые вызовы шаблонов, подставляющие неверные параметры.

Как найти проблемный код в Конфигураторе

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

  1. Откроем конфигуратор. Иногда проблему можно решить не через RLS, а используя управление доступом к формам.
  2. Перейдем в ветку Общие — Роли.
  3. Вместо того чтобы открывать каждую роль, воспользуемся общим списком ограничений. Нажмем правой кнопкой мыши на ветку "Роли" и выберем пункт Все ограничения доступа.
  4. В открывшемся окне мы увидим сводную таблицу всех RLS по всем объектам метаданных.

К сожалению, стандартный поиск (Ctrl+F) в этом окне может не работать, но мы можем использовать кнопку "Отбор" или вывести список в табличный документ (через меню "Все действия" — "Вывести список") и искать уже там.

Искать следует фрагменты текста, похожие на часть ошибки, например NULL или вызовы шаблонов доступа (обычно они начинаются с символа #, например #ПоЗначениям). Это поможет понять, какая именно Роль накладывает некорректное ограничение на документ.

Решение проблемы: метод "Дополнительной роли"

Если быстро исправить код шаблонов затруднительно (например, ошибка находится внутри защищенного модуля отраслевого решения или сложного расширения), мы можем воспользоваться особенностью механизма прав доступа в 1С.

Принцип работы прав: Доступ к объекту разрешен, если он разрешен хотя бы в одной из назначенных пользователю ролей. Условия RLS разных ролей объединяются через логическое "ИЛИ".

Это значит, что если мы добавим пользователю роль, в которой доступ к документу разрешен без ограничений (условие "Истина"), то платформа может проигнорировать сложный и ошибочный RLS запрос из другой роли.

Пошаговое решение:

  1. Создадим новую Роль в конфигурации (или в расширении конфигурации, что предпочтительнее, чтобы не снимать конфигурацию с поддержки). Назовем её, например, ПолныеПраваНаЗаявки.
  2. Найдем в списке объектов проблемный документ (в нашем случае ЗаявкаНаРемонт). Аналогичным образом работает установка разрешения или запрета редактирования справочников.
  3. Установим флажки на права:
  4. Важно: Не устанавливайте "Интерактивное удаление", если это не требуется бизнес-логикой.
  5. Убедимся, что для этой роли в поле "Ограничение доступа к данным" (внизу справа в редакторе роли) пусто. Пустое поле означает полное отсутствие ограничений (доступ разрешен всегда).
  6. Сохраним изменения и обновим конфигурацию БД.
  7. В режиме "1С:Предприятие" назначим эту новую роль (или профиль групп доступа, включающий эту роль) проблемному пользователю.

После этих действий документ должен начать записываться. Поскольку в новой роли нет RLS, условие доступа превращается в ГДЕ ИСТИНА, и платформа успешно выполняет запись, минуя ошибочный блок кода.

Диагностика через Технологический журнал

Если метод с дополнительной ролью не подходит (например, вам критически важно сохранить ограничение видимости документов), необходимо точно найти ошибку в запросе. Для этого используем Технологический журнал (ТЖ).

Настроим файл logcfg.xml на сбор событий EXCP (исключения) и DBMSSQL (запросы к SQL) или RLS (если версия платформы позволяет). В логах мы увидим полный текст запроса, который платформа пыталась выполнить. Это будет выглядеть примерно так:


SELECT
T1._IDRRef,
T1._Marked,
...
FROM dbo._Document355 T1
WHERE ((T1._Fld1234RRef = ... OR ... ) AND (CASE WHEN ... THEN 1 ELSE 0 END = 1))

Анализируя полный текст SQL-запроса в логах, мы увидим, во что именно развернулся шаблон RLS и почему возникла синтаксическая ошибка. Это позволит скорректировать шаблон в конфигураторе: заменить НЕОПРЕДЕЛЕНО на ЗНАЧЕНИЕ(...) или исправить параметры шаблона БСП.

Резюме

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

← На главную