В процессе разработки сложных систем на платформе 1С:Предприятие 8 часто возникает задача предоставить пользователю возможность самостоятельно настраивать сложные фильтры для различных алгоритмов. Вместо того чтобы создавать громоздкие формы с массой флажков и полей ввода, наиболее эффективным и гибким решением является использование механизмов Системы компоновки данных (СКД). Это позволяет задействовать стандартный конструктор условий, знакомый пользователям по отчетам, и применять эти условия в произвольном программном коде.
В данной статье мы разберем, как реализовать механизм произвольного отбора, где его подсмотреть в типовых конфигурациях и какие технические нюансы необходимо учесть для корректной работы алгоритмов.
Прежде чем приступать к написанию собственного кода, полезно проанализировать, как этот механизм реализован разработчиками фирмы «1С». В современных конфигурациях на базе УТ 11, ERP 2 и КА 2 функционал произвольных отборов встречается повсеместно:
Для начала нам необходимо создать макет типа СхемаКомпоновкиДанных. В этой схеме мы описываем набор данных (запрос или объект), к которому будут применяться отборы. Рассмотрим пример, когда нам нужно отфильтровать список товаров.
В схеме достаточно определить один набор данных — запрос. Важным моментом является использование расширений языка запросов СКД. Это позволит системе «понимать», куда именно подставлять пользовательские условия.
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка,
Номенклатура.Код КАК Код,
Номенклатура.Наименование КАК Наименование
ИЗ
Справочник.Номенклатура КАК Номенклатура
{ГДЕ
Номенклатура.Ссылка.* КАК Ссылка,
Номенклатура.Код КАК Код,
Номенклатура.Наименование КАК Наименование}
Тэг {ГДЕ...} в запросе является критически важным. Он указывает СКД, что пользовательские настройки отбора должны внедряться именно в эту часть SQL-запроса, что значительно повышает производительность по сравнению с фильтрацией уже полученной таблицы значений.
Чтобы пользователь мог взаимодействовать с отборами, нам нужно разместить на форме элемент управления, связанный с компоновщиком настроек. Разберем последовательность действий:
КомпоновщикНастроекКомпоновкиДанных.КомпоновщикНастроек.Настройки.Отбор.Проанализируем пример кода инициализации в модуле формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Получаем схему из макета обработки
Схема = РеквизитФормыВЗначение("Объект").ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
// Инициализируем компоновщик настроек
URLСхемы = ПоместитьВоВременноеХранилище(Схема, УникальныйИдентификатор);
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(URLСхемы));
// Загружаем настройки по умолчанию
КомпоновщикНастроек.ЗагрузитьНастройки(Схема.НастройкиПоУмолчанию);
КонецПроцедуры
После того как пользователь настроил фильтры, нам необходимо применить их в нашем алгоритме. Если мы хотим получить результат в виде Таблицы Значений, нужно правильно настроить генератор макета.
Выясним причину, почему иногда отбор работает некорректно: часто разработчики используют стандартный генератор макета для отчета, тогда как для выгрузки в коллекцию нужен специальный тип. Рассмотрим правильный алгоритм:
&НаСервере
Функция ПолучитьДанныеПоОтбору()
Схема = РеквизитФормыВЗначение("Объект").ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
// КРИТИЧЕСКИ ВАЖНО: используем генератор для коллекции значений
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки, , ,
Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ТаблицаРезультат = Новый ТаблицаЗначений;
ПроцессорВывода.УстановитьОбъект(ТаблицаРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Возврат ТаблицаРезультат;
КонецФункции
Важное замечание: При работе с ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений убедитесь, что колонки в вашей результирующей таблице значений (если вы используете набор данных - объект) имеют четко заданные типы. СКД чувствительна к типам данных при сравнении значений в отборах.
Чтобы пользователю не приходилось настраивать фильтры каждый раз заново, настройки необходимо сохранять. Лучшим способом является сериализация настроек СКД в строку XML. Это позволяет хранить их в реквизитах справочников, константах или дополнительных сведениях.
Рассмотрим пример сохранения настроек:
// Сериализация настроек в XML-строку
Сериализатор = Новый СериализаторXDTO(ФабрикаXDTO);
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
Сериализатор.ЗаписатьXML(ЗаписьXML, КомпоновщикНастроек.Настройки, "Settings", "http://v8.1c.ru/8.1/data-composition-system/settings");
НастройкиСтрокой = ЗаписьXML.Закрыть();
Для восстановления настроек используется обратный процесс: чтение XML и метод компоновщика ЗагрузитьНастройки().
Если вы работаете в современной конфигурации, в которой интегрирована Библиотека стандартных подсистем (БСП), задача упрощается. Рассмотрим подробнее возможности подсистемы «Групповое изменение объектов». Там есть готовые программные интерфейсы для работы с отборами, которые позволяют вывести компактное поле настройки прямо на форму обработки без ручного создания макетов СКД.
Также стоит обратить внимание на возможность проверки соответствия конкретного объекта настроенному отбору без выполнения тяжелого запроса. Это реализуется через создание временной схемы компоновки, в которую в качестве внешнего набора данных передается текущий объект. Если после компоновки результат не пустой — значит, объект подходит под условия.
Подводя итог, выделим основные этапы внедрения произвольного отбора СКД в ваш проект:
КомпоновщикНастроек как основной посредник между интерфейсом и логикой.ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений.{ГДЕ...} для оптимизации производительности.Использование СКД для произвольных отборов делает ваше решение профессиональным, надежным и удобным для конечного пользователя, предоставляя ему всю мощь механизмов фильтрации платформы 1С.