Рассмотрим классическую ситуацию при разработке в платформе 1С:Предприятие 8. Вы создаете или настраиваете форму списка документа (например, Авансовый отчет), где присутствует динамический список. В нем выводится определенная колонка, например, статус электронного документооборота. Когда вы заходите в базу под администратором, все работает корректно. Но как только мы заходим под пользователем с сильно ограниченными правами (урезанной ролью), при открытии формы программа "крашится" с ошибкой Поле объекта не обнаружено.
Проанализируем эту ситуацию в отладчике. Выясняется, что если поставить точку останова на первой строке процедуры ПриСозданииНаСервере, то нужного реквизита уже нет в коллекции Элементы. А поскольку чуть ниже по коду происходит обращение к этому элементу, система выдает ошибку. Разберем по шагам, почему платформа удаляет элемент до инициализации формы и как с этим правильно бороться.
Выясним причину такого поведения. Динамические списки в управляемых формах 1С работают на базе Системы Компоновки Данных (СКД). Процесс генерации и отрисовки формы происходит в строго определенном порядке:
Элементы.Именно поэтому, когда управление передается в обработчик ПриСозданииНаСервере, "каркас" формы уже сформирован с учетом прав доступа. Элемента управления физически не существует, и прямое обращение к нему вызывает программную ошибку.
Посмотрим на важный нюанс: элемент формы удаляется платформой только в том случае, если у пользователя нет базовых прав (на чтение/просмотр) на сам объект метаданных. В рассматриваемом примере реквизит динамического списка получал данные из регистра сведений через левое соединение в произвольном запросе. У роли пользователя не было прав на этот регистр.
Если бы права на регистр сведений были предоставлены, но действовало бы ограничение на уровне записей (RLS — Record Level Security), колонка бы не исчезла. Она бы осталась на форме, но для тех строк, к которым доступ запрещен, отображалась бы пустой или выводила бы служебную надпись <Объект не найден>.
Проанализируем ситуацию шире. Помимо прав доступа на таблицы запроса, элементы могут пропадать из-за следующих факторов:
Разберем правила написания безопасного кода. Чтобы избежать ошибок Поле объекта не обнаружено при включении/отключении прав, функциональных опций или при обновлении конфигурации, программисты должны проверять наличие элемента на форме перед обращением к нему.
Прямое обращение через точку (например, Элементы.СостояниеЭДО.Видимость = Ложь;) к элементам, которые управляются правами или ФО, является нарушением стандартов разработки 1С.
Рассмотрим правильный пример кода для работы с потенциально отсутствующими элементами формы:
// Безопасный поиск элемента в коллекции Элементы
ЭлементСостояние = Элементы.Найти("СостояниеЭДО");
Если ЭлементСостояние <> Неопределено Тогда
// Элемент существует, пользователь имеет на него права
// Выполняем необходимую логику, например, меняем видимость
ЭлементСостояние.Видимость = Истина;
Иначе
// Элемента нет (нет прав, скрыт ФО и т.д.)
// Код не падает с ошибкой, мы просто пропускаем логику
КонецЕсли;
Если речь идет о типовых конфигурациях (1С:Бухгалтерия, ERP, УТ), реквизиты, отображающие статусы (например, состояние электронного документооборота), часто добавляются программно механизмами Библиотеки стандартных подсистем (БСП).
Чтобы ограниченный сотрудник корректно видел эти статусы (и чтобы колонка присутствовала), недостаточно дать права только на документ. Необходимо назначить специализированную базовую роль, поставляемую подсистемой. Обычно это роли вида "Использование электронной подписи и ЭДО" или точечные права на чтение соответствующих регистров сведений подсистемы обмена, к которым обращается динамический список.
Применяя описанный подход и защищая код проверкой через метод Найти, вы создадите отказоустойчивую архитектуру, которая не будет "ломаться" при изменении матрицы доступов в компании.