В практике программирования на платформе 1С:Предприятие часто возникают задачи разработки универсальных механизмов. Одна из классических ситуаций — необходимость обратиться к данным справочника (или другого объекта метаданных), не зная заранее его тип в конфигураторе. Имя объекта приходит к нам в виде строки, например, в переменной ИмяСправочника содержится значение "Номенклатура".
Давайте подробно разберем, как получить выборку элементов или ссылку на данные, имея на руках только строковое название объекта. Мы рассмотрим два основных подхода: использование менеджера справочников и формирование динамического запроса.
Самый простой и очевидный способ — воспользоваться глобальным контекстом и коллекцией Справочники. Платформа 1С позволяет обращаться к элементам этой коллекции не только через точку (как мы привыкли делать: Справочники.Номенклатура), но и используя оператор квадратных скобок [], передавая туда строковое имя.
Рассмотрим пример кода:
ИмяСправочника = "Номенклатура";
// Обращаемся к менеджеру конкретного справочника по имени
Выборка = Справочники[ИмяСправочника].Выбрать();
Пока Выборка.Следующий() Цикл
// Обработка каждого элемента
Сообщить(Выборка.Наименование);
КонецЦикла;
Преимущества метода:
Недостатки:
Выбрать() получает все поля справочника, что может быть неоптимально, если вам нужны только ссылка и наименование, а в справочнике есть "тяжелые" реквизиты (например, хранилище значений или длинные строки).ИмяСправочника окажется строка с несуществующим именем, возникнет ошибка выполнения (исключение).Более профессиональным и гибким решением считается использование языка запросов. Однако, язык запросов 1С не поддерживает передачу имени таблицы (справочника) в качестве параметра. Мы не можем написать ИЗ &ИмяТаблицы. Поэтому текст запроса придется собирать программно.
Разберем пример, который позволяет создать универсальный запрос к любому справочнику.
Алгоритм действий следующий:
&Справочник или просто %1 для форматирования строки).Посмотрим на реализацию этого алгоритма:
ИмяСправочника = "Номенклатура";
// Формируем имя таблицы для запроса.
// Для справочников оно всегда начинается с ключевого слова "Справочник."
ИмяТаблицыБД = "Справочник." + ИмяСправочника;
Запрос = Новый Запрос;
// Текст запроса с меткой &Справочник в секции ИЗ
Запрос.Текст =
"ВЫБРАТЬ
| ТекСправочник.Ссылка КАК Ссылка,
| ТекСправочник.Код КАК Код,
| ТекСправочник.Наименование КАК Наименование
|ИЗ
| &Справочник КАК ТекСправочник";
// Заменяем метку &Справочник на реальное имя таблицы "Справочник.Номенклатура"
Запрос.Текст = СтрЗаменить(Запрос.Текст, "&Справочник", ИмяТаблицыБД);
// Выполняем запрос
Результат = Запрос.Выполнить();
В этом примере мы использовали функцию СтрЗаменить. Также можно использовать функцию СтрШаблон, что часто выглядит более аккуратно:
ШаблонЗапроса =
"ВЫБРАТЬ
| ТекСправочник.Ссылка,
| ТекСправочник.Наименование
|ИЗ
| Справочник.%1 КАК ТекСправочник";
Запрос.Текст = СтрШаблон(ШаблонЗапроса, ИмяСправочника);
Важные нюансы при использовании запроса:
1. Производительность. В отличие от метода Выбрать(), в запросе вы можете перечислить только необходимые поля (например, только Ссылка), что значительно снизит нагрузку на базу данных и сеть.
2. Права доступа. При выполнении запроса, если у пользователя нет прав на чтение конкретного справочника или отдельных записей (RLS), запрос может упасть с ошибкой. Чтобы этого избежать и получить только доступные данные, рекомендуется использовать ключевое слово РАЗРЕШЕННЫЕ:
ВЫБРАТЬ РАЗРЕШЕННЫЕ
Ссылка, Наименование...
3. Обработка результата. Результат запроса можно выгрузить в таблицу значений методом Выгрузить(), но при больших объемах данных это может переполнить оперативную память. Более правильный подход для массовой обработки — использовать выборку из результата:
ВыборкаДетальныеЗаписи = Результат.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Работаем с данными
КонецЦикла;
Прежде чем выполнять код (будь то обращение через Справочники[...] или формирование запроса), хорошей практикой является проверка: а существует ли вообще такой справочник в конфигурации? Это защитит программу от падения, если в переменную попадет некорректная строка.
Используем коллекцию Метаданные:
ИмяСправочника = "Номенклатура";
// Проверяем наличие справочника в метаданных
Если Метаданные.Справочники.Найти(ИмяСправочника) <> Неопределено Тогда
// Справочник найден, можно выполнять запрос или выборку
Выборка = Справочники[ИмяСправочника].Выбрать();
Иначе
Сообщить("Ошибка: Справочник с именем " + ИмяСправочника + " не найден!");
КонецЕсли;
Если вам нужно просто перебрать элементы и вы уверены в имени справочника, использование Справочники[Имя].Выбрать() — самый быстрый способ написания кода. Если же требуется высокая производительность, выборка конкретных полей или сложная фильтрация — используйте динамическое формирование текста запроса через СтрЗаменить или СтрШаблон.