1С СКД: отбор программно — элементы, группы и виды сравнения
Чтобы установить отбор 1С СКД программно, добавьте элемент в коллекцию
Настройки.Отбор.Элементы методом Добавить() с типом
ЭлементОтбораКомпоновкиДанных и заполните три свойства:
ЛевоеЗначение — Новый ПолеКомпоновкиДанных("ИмяПоля"),
ВидСравнения — значение ВидСравненияКомпоновкиДанных,
ПравоеЗначение — искомое значение.
Для условий вида «ИЛИ» и «НЕ» в ту же коллекцию добавляется
ГруппаЭлементовОтбораКомпоновкиДанных со свойством ТипГруппы.
Отбор действует на данные после выборки набора, параметр — внутри
запроса, поэтому по скорости почти всегда выигрывает параметр.
Как программно установить отбор в СКД: ЭлементОтбораКомпоновкиДанных
Точка входа — объект НастройкиКомпоновкиДанных: это либо
КомпоновщикНастроек.Настройки в отчёте, либо
СхемаКомпоновкиДанных.НастройкиПоУмолчанию при программной компоновке.
Свойство Отбор возвращает ОтборКомпоновкиДанных, а его
Элементы — коллекцию, в которую и добавляется условие:
Настройки = КомпоновщикНастроек.Настройки;
ЭлементОтбора = Настройки.Отбор.Элементы.Добавить(
Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Контрагент");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = ВыбранныйКонтрагент;
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.Представление = "Только выбранный контрагент";
ЛевоеЗначение — это не строка, а объект
ПолеКомпоновкиДанных. Путь к данным пишется так же, как имя поля в схеме
компоновки: "Номенклатура.ВидНоменклатуры" для реквизита через точку,
"Склад" для поля верхнего уровня.
Коллекция элементов отбора: добавить, найти, удалить, очистить
Настройки.Отбор.Элементы — это КоллекцияЭлементовОтбораКомпоновкиДанных.
Она поддерживает полный набор операций, поэтому отборы 1С СКД можно не только добавлять,
но и пересобирать перед каждым запуском отчёта:
Элементы = Настройки.Отбор.Элементы;
// Полная пересборка отбора отчёта СКД
Элементы.Очистить();
Новый1 = Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Новый1.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Организация");
Новый1.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
Новый1.ПравоеЗначение = ТекущаяОрганизация;
// Точечное удаление ранее заданного условия
Для Каждого Элемент Из Элементы Цикл
Если ТипЗнч(Элемент) = Тип("ЭлементОтбораКомпоновкиДанных")
И Строка(Элемент.ЛевоеЗначение) = "Склад" Тогда
Элементы.Удалить(Элемент);
Прервать;
КонецЕсли;
КонецЦикла;
Обход коллекции обязан учитывать, что в ней лежат объекты двух типов —
элементы и группы. Проверка ТипЗнч() перед обращением к
ЛевоеЗначение избавляет от ошибки на группе, у которой такого свойства нет.
Виды сравнения отбора СКД: полный список ВидСравненияКомпоновкиДанных
Свойство ВидСравнения принимает значения системного перечисления
ВидСравненияКомпоновкиДанных. Доступны:
- Равенство и порядок:
Равно,НеРавно,Больше,БольшеИлиРавно,Меньше,МеньшеИлиРавно. - Списки:
ВСписке,НеВСписке,ВСпискеПоИерархии,НеВСпискеПоИерархии. - Иерархия:
ВИерархии,НеВИерархии. - Строки:
Содержит,НеСодержит,НачинаетсяС,НеНачинаетсяС,Подобно,НеПодобно. - Заполненность:
Заполнено,НеЗаполнено.
Для отбора по нескольким значениям одного поля используйте ВСписке и
СписокЗначений либо массив в ПравоеЗначение — это короче и быстрее,
чем группа «ИЛИ» из одиночных равенств:
СписокСкладов = Новый СписокЗначений;
СписокСкладов.Добавить(СкладОсновной);
СписокСкладов.Добавить(СкладРозница);
Отбор = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Отбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Склад");
Отбор.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
Отбор.ПравоеЗначение = СписокСкладов;
Виды Заполнено и НеЗаполнено — единственные, для которых
ПравоеЗначение заполнять не нужно. Для ВИерархии
правое значение — ссылка на группу-родителя, а не список.
Группы элементов отбора: условия И, ИЛИ, НЕ
Все условия верхнего уровня объединяются логическим «И». Чтобы получить «ИЛИ» или
отрицание, добавьте в коллекцию ГруппаЭлементовОтбораКомпоновкиДанных
и заполните её собственную коллекцию Элементы:
Группа = Настройки.Отбор.Элементы.Добавить(
Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
Группа.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли;
Группа.Использование = Истина;
Группа.Представление = "Просроченные или крупные заказы";
Условие1 = Группа.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Условие1.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ДатаОплаты");
Условие1.ВидСравнения = ВидСравненияКомпоновкиДанных.Меньше;
Условие1.ПравоеЗначение = ТекущаяДата();
Условие2 = Группа.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Условие2.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("СуммаДокумента");
Условие2.ВидСравнения = ВидСравненияКомпоновкиДанных.Больше;
Условие2.ПравоеЗначение = 100000;
ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаНе инвертирует результат
вложенных условий. Группы вкладываются друг в друга, поэтому выражение вида
«(А ИЛИ Б) И НЕ В» собирается из трёх групп без обходных приёмов.
Отбор по группировке: своё условие на уровень структуры
Кроме общего отбора отчёта, СКД поддерживает отбор на отдельной группировке. У объекта
ГруппировкаКомпоновкиДанных есть собственное свойство Отбор
с такой же коллекцией Элементы:
Группировка = Настройки.Структура[0];
ОтборГруппировки = Группировка.Отбор.Элементы.Добавить(
Тип("ЭлементОтбораКомпоновкиДанных"));
ОтборГруппировки.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("КоличествоОстаток");
ОтборГруппировки.ВидСравнения = ВидСравненияКомпоновкиДанных.Больше;
ОтборГруппировки.ПравоеЗначение = 0;
Такой отбор применяется к уже посчитанным итогам этой группировки — это штатный способ убрать нулевые остатки или показать только группы с оборотом. Общий отбор отчёта такую задачу не решает: он работает до расчёта итогов.
Проверить и снять отбор конкретного элемента структуры удобно методами самого объекта настроек:
Если Настройки.НаличиеОтбораУЭлемента(Группировка) Тогда
Настройки.ОчиститьОтборЭлемента(Группировка);
КонецЕсли;
// Идентификатор нужен для адресации настройки из формы отчёта
Идентификатор = Настройки.ПолучитьИдентификаторПоОбъекту(Группировка);
ТотЖеОбъект = Настройки.ПолучитьОбъектПоИдентификатору(Идентификатор);
Применение отбора: элементы, иерархия, только иерархия
Свойство Применение элемента и группы отбора принимает значения
ТипПримененияОтбораКомпоновкиДанных: Элементы,
Иерархия, ТолькоИерархия. Оно определяет, к каким записям
результата компоновки применяется условие — к обычным строкам, к строкам иерархии или
только к иерархическим итогам:
Отбор = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Отбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Номенклатура");
Отбор.ВидСравнения = ВидСравненияКомпоновкиДанных.ВИерархии;
Отбор.ПравоеЗначение = ГруппаНоменклатуры;
Отбор.Применение = ТипПримененияОтбораКомпоновкиДанных.Элементы;
У элементов из коллекции пользовательских настроек свойства
Применение и ЛевоеЗначение недоступны — они существуют только
у основных настроек. Это частая причина ошибки «поле не найдено» при попытке
донастроить отбор из формы отчёта.
Отбор или параметр СКД: чем отличаются и что быстрее
Оба механизма ограничивают данные, но работают на разных этапах:
- Параметр подставляется в текст запроса набора данных и ограничивает
выборку в СУБД. Задаётся через
Настройки.ПараметрыДанных. - Отбор применяется компоновщиком к уже полученным данным набора (кроме случаев, когда платформа сама может протолкнуть условие в запрос).
// Параметр данных — ограничение на уровне запроса
Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("НачалоПериода", НачалоДня(ДатаС));
Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("КонецПериода", КонецДня(ДатаПо));
// Чтение и выключение параметра
ЗначениеПараметра = Настройки.ПараметрыДанных.НайтиЗначениеПараметра(
Новый ПараметрКомпоновкиДанных("НачалоПериода"));
Если ЗначениеПараметра <> Неопределено Тогда
ЗначениеПараметра.Использование = Истина;
КонецЕсли;
Практическое правило: период, организация и прочие условия, которые всегда есть, — параметры; произвольные пользовательские условия — отбор. Отбор по полю виртуальной таблицы почти всегда нужно дублировать параметром, иначе платформа сначала прочитает все записи и отсечёт лишние в памяти.
Отдельная тема — параметры выбора в СКД: они не фильтруют данные, а
ограничивают список значений, который видит пользователь при заполнении отбора.
Задаются в схеме компоновки на доступном поле отбора, программно в момент установки
условия значение всё равно кладётся в ПравоеЗначение.
Отбор в пользовательских настройках отчёта
Если отбор должен остаться видимым и редактируемым, его нужно вывести в
ПользовательскиеНастройкиКомпоновкиДанных. Для этого элементу задаются
ИдентификаторПользовательскойНастройки и
РежимОтображения:
Отбор = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Отбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Склад");
Отбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
Отбор.ПравоеЗначение = СкладОсновной;
Отбор.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.БыстрыйДоступ;
Отбор.ИдентификаторПользовательскойНастройки = "ОтборПоСкладу";
Отбор.ПредставлениеПользовательскойНастройки = "Склад";
Обратная задача — изменить уже существующий пользовательский отбор перед формированием отчёта. Элемент ищется в коллекции пользовательских настроек по идентификатору:
ПользовательскиеНастройки = КомпоновщикНастроек.ПользовательскиеНастройки;
Для Каждого ЭлементПН Из ПользовательскиеНастройки.Элементы Цикл
Если ТипЗнч(ЭлементПН) = Тип("ЭлементОтбораКомпоновкиДанных")
И ЭлементПН.ИдентификаторПользовательскойНастройки = "ОтборПоСкладу" Тогда
ЭлементПН.ПравоеЗначение = НужныйСклад;
ЭлементПН.Использование = Истина;
КонецЕсли;
КонецЦикла;
Чтобы от пользовательской настройки перейти к основной, используйте
ПользовательскиеНастройки.ПолучитьОсновныеНастройкиПоИдентификаторуПользовательскойНастройки()
— там доступны все свойства элемента отбора, включая ЛевоеЗначение.
ПользовательскиеНастройки.Элементы с типами
и идентификаторами.
Полный пример: отчёт 1С СКД с отбором программно
Формирование отчёта СКД без формы — схема, настройки по умолчанию, отбор, компоновка в таблицу значений:
Схема = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
Компоновщик.Инициализировать(
Новый ИсточникДоступныхНастроекКомпоновкиДанных(Схема));
Компоновщик.ЗагрузитьНастройки(Схема.НастройкиПоУмолчанию);
Настройки = Компоновщик.Настройки;
Настройки.Отбор.Элементы.Очистить();
Отбор = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Отбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Организация");
Отбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
Отбор.ПравоеЗначение = ТекущаяОрганизация;
Отбор.Использование = Истина;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Макет = КомпоновщикМакета.Выполнить(Схема, Настройки);
Процессор = Новый ПроцессорКомпоновкиДанных;
Процессор.Инициализировать(Макет);
Вывод = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
Результат = Новый ТаблицаЗначений;
Вывод.УстановитьОбъект(Результат);
Вывод.Вывести(Процессор);
Сообщить("Строк после отбора: " + Результат.Количество());
Порядок важен: отбор задаётся до вызова
КомпоновщикМакетаКомпоновкиДанных.Выполнить(). Изменение настроек после
получения макета ни на что не влияет — макет уже скомпонован.
Частые ошибки при программной установке отбора СКД
-
Строка вместо
ПолеКомпоновкиДанных.ЭлементОтбора.ЛевоеЗначение = "Склад"не даст ожидаемого результата: нужноНовый ПолеКомпоновкиДанных("Склад"). -
Поля нет среди доступных полей отбора. Поле должно быть в
Настройки.ДоступныеПоляОтбора: если в схеме у него не установлен признак использования в отборе, условие молча не сработает. -
Изменение настроек после компоновки макета. Отбор, добавленный после
Выполнить(), игнорируется — макет формируется один раз. -
Забытое
Использование = Истина. Элемент, скопированный из существующих настроек или загруженный из варианта отчёта, может прийти выключенным. -
Обращение к
ЛевоеЗначениеу группы. В коллекции лежат объекты двух типов; без проверкиТипЗнч()цикл падает на первой же группе. -
Отбор вместо параметра на больших объёмах. Условие по периоду или
организации, поставленное отбором, заставляет набор данных прочитать лишние записи —
такие ограничения выносите в
ПараметрыДанных. -
Правка отбора в пользовательских настройках через
ЛевоеЗначение. У пользовательских элементов это свойство недоступно — работайте поИдентификаторПользовательскойНастройки.
Частые вопросы про отбор в СКД
Как программно добавить отбор по нескольким значениям в СКД?
Используйте один элемент отбора с ВидСравненияКомпоновкиДанных.ВСписке и
СписокЗначений (или массивом) в ПравоеЗначение. Это короче и
быстрее, чем группа ГруппаИли из отдельных равенств.
Чем отбор СКД отличается от параметра?
Параметр подставляется в запрос набора данных и ограничивает выборку в СУБД, отбор применяется компоновщиком к полученным данным. Постоянные условия (период, организация) лучше делать параметрами, произвольные пользовательские — отбором.
Почему программный отбор в отчёте СКД не применяется?
Три типовые причины: ЛевоеЗначение задано строкой вместо
ПолеКомпоновкиДанных; поле отсутствует в
Настройки.ДоступныеПоляОтбора; отбор добавлен уже после вызова
Выполнить() компоновщика макета.
ИИ Консоль запросов 1С
Лайт
Для ознакомления с возможностями
- Полный набор инструментов без урезаний
- Без ввода карты
Старт
Популярный выборДля индивидуального использования
- До 5ти конфигураций
-
≈ 100 задач Подробнее про лимиты
- Техническая поддержка
Продвинутый
Для интенсивного использования или команд
- До 15-ти конфигураций
-
≈ 300 задач Подробнее про лимиты
- Техническая поддержка