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