В процессе разработки и аудита безопасности в системе 1С часто возникает задача получить полный перечень ролей, заданных в конфигурации. Стандартная постановка задачи подразумевает выгрузку списка, содержащего Имя, Синоним и Комментарий к каждой роли. Однако при попытке сделать это через обычную консоль запросов разработчики сталкиваются с тем, что роли не являются таблицами базы данных, к которым можно обратиться напрямую через оператор ВЫБРАТЬ.
В этой статье мы подробно разберем, почему стандартный запрос не видит метаданные, и рассмотрим несколько эффективных способов решения этой задачи, включая использование программного кода и специальных инструментов разработчика.
Прежде всего, проанализируем архитектуру платформы 1С. Язык запросов 1С предназначен для работы с данными: справочниками, документами, регистрами и их табличными частями. Все эти объекты имеют физические таблицы в SQL-базе. Роли же являются объектами метаданных. Информация о них хранится во внутренних структурах платформы, которые не отображаются в схеме данных, доступной для стандартного механизма запросов.
Поэтому, когда нам нужно получить список ролей в консоли запросов, мы фактически должны сначала программно «извлечь» эти данные из метаданных, а затем «подложить» их в запрос в виде временной таблицы или параметра.
Этот метод является наиболее универсальным и точным, так как позволяет получить любые свойства роли, включая комментарии. Разберем по шагам алгоритм действий, который обычно используется в расширенных консолях запросов (например, в консоли из состава «Инструментов разработчика» или консолях с возможностью выполнения произвольного кода перед запросом).
Проанализируем программный код, который решает нашу задачу:
// 1. Создаем таблицу значений с нужной структурой
ТаблицаРолей = Новый ТаблицаЗначений;
ТаблицаРолей.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(255)));
ТаблицаРолей.Колонки.Добавить("Синоним", Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(255)));
ТаблицаРолей.Колонки.Добавить("Комментарий", Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(1000)));
// 2. Обходим коллекцию метаданных "Роли"
Для Каждого ТекущаяРоль Из Метаданные.Роли Цикл
НоваяСтрока = ТаблицаРолей.Добавить();
НоваяСтрока.Имя = ТекущаяРоль.Имя;
НоваяСтрока.Синоним = ТекущаяРоль.Синоним;
НоваяСтрока.Комментарий = ТекущаяРоль.Комментарий;
КонецЦикла;
// 3. Передаем таблицу в запрос как параметр
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТЗ_Роли.Имя КАК Имя,
| ТЗ_Роли.Синоним КАК Синоним,
| ТЗ_Роли.Комментарий КАК Комментарий
|ПОМЕСТИТЬ ВтРоли
|ИЗ
| &ТаблицаРолей КАК ТЗ_Роли
|;
|
|ВЫБРАТЬ
| ВтРоли.Имя,
| ВтРоли.Синоним,
| ВтРоли.Комментарий
|ИЗ
| ВтРоли КАК ВтРоли";
Запрос.УстановитьПараметр("ТаблицаРолей", ТаблицаРолей);
РезультатЗапроса = Запрос.Выполнить();
Рассмотрим подробнее, что здесь происходит. Мы используем встроенный объект Метаданные, который предоставляет доступ к дереву конфигурации. Цикл Для Каждого перебирает все объекты типа ОбъектМетаданных: Роль. После заполнения ТаблицаЗначений мы передаем её в запрос через параметр. В самом тексте запроса мы используем конструкцию ПОМЕСТИТЬ, чтобы превратить внешние данные во временную таблицу базы данных, с которой можно работать обычными методами.
Если ваша конфигурация построена на базе Библиотеки стандартных подсистем (БСП), у вас есть возможность получить список ролей прямым запросом без написания программного кода. БСП хранит информацию о структуре метаданных в специальном справочнике.
Выясним, как составить такой запрос:
Справочник.ИдентификаторыОбъектовМетаданных.Пример запроса:
ВЫБРАТЬ
Идентификаторы.Имя КАК Имя,
Идентификаторы.Синоним КАК Синоним
ИЗ
Справочник.ИдентификаторыОбъектовМетаданных КАК Идентификаторы
ГДЕ
Идентификаторы.Родитель.Имя = "Роли"
И НЕ Идентификаторы.ПометкаУдаления
Важное ограничение: В справочнике ИдентификаторыОбъектовМетаданных обычно отсутствуют технические комментарии, которые разработчики пишут непосредственно в Конфигураторе. Если поле Комментарий критически важно, этот способ вам не подойдет, и придется вернуться к Способу 1.
Существуют профессиональные консоли запросов (например, консоль от С. Кузнецова или инструменты в составе подсистемы «Инструменты разработчика»), которые позволяют выполнять произвольный алгоритм перед основным запросом.
Рассмотрим, как это работает в таких консолях:
Проанализируем ситуацию, когда в базе используются расширения. Если роли добавлены или изменены в расширении, стандартный обход Метаданные.Роли может их не увидеть, так как он обращается только к основной конфигурации.
Для получения ролей из расширений необходимо перебирать коллекцию расширений конфигурации и обращаться к метаданным каждого из них:
Для Каждого Расширение Из РасширенияКонфигурации.Получить() Цикл
Для Каждого РольРасширения Из Расширение.Метаданные.Роли Цикл
// Обработка ролей из расширения
КонецЦикла;
КонецЦикла;
Мы выяснили, что напрямую получить роли через SQL-подобный запрос к базе невозможно из-за архитектурных особенностей платформы. Однако, используя коллекцию Метаданные.Роли, мы можем легко сформировать список программно.
Если вам нужно быстро получить список «Имя-Синоним» и в базе есть БСП — используйте запрос к справочнику ИдентификаторыОбъектовМетаданных. Если же требуется полный набор данных, включая Комментарий, или данные из расширений — используйте программный обход метаданных с последующей выгрузкой в таблицу значений.