Формулы для задания фильтров

Содержание

Компонент «Формулы для задания фильтров» предназначен для настройки сложных фильтров при конструировании реестров, форм и отчетов. Сложные фильтры задаются с помощью специальных формул, накладывающих ограничения на информационные объекты NetDB.

Для того чтобы задать сложный фильтр, используется стандартный интерфейс добавления фильтра в заголовках строк или столбцов в конструкторе отчетов. Укажите нужный показатель и вместо стандартной операции «=» выберите «задание формулой». Далее в строке ввода запишите формулу, задающую условия, ограничивающие выбор значений указанного показателя.

При записи формул для задания фильтров используются идентификационные номера (id) объектов хранилища NetDB.

Чтобы определить id элемента справочника, нужно зайти в справочник, затем нажать правой кнопкой на элемент справочника и выбрать строку «История изменений».

_images/209.png

В поле «Объект» будет отражен id элемента.

_images/210.png

Подробнее об id объектов см. подраздел Идентификационные номера объектов.

Основные правила построения формул для задания фильтров

Формула для задания фильтров состоит из двух частей. В левой части формулы указывается выражение, а в правой - значение, которое должно принимать данное выражение.

В выражении участвует показатель, к которому применяется формула, этот показатель обозначается символом self.

Результатом применения формулы может быть как одиночный заголовок, так и множество заголовков отчета.

Если формула применяется к показателю, который является параметром отчета, то система не будет генерировать несколько заголовков - заголовок всего один, а формулы задают ограничение на возможные значения параметра (см. подраздел Ограничение вариантов выбора параметра из справочника).

Рассмотрим примеры задания фильтров с помощью формул.

Допустим, в системе имеется справочник «Организации», содержащий данные об организациях:

_images/211.png

На данный справочник ссылается показатель «Организация».

Если при построении отчета в фильтре на заголовки строк мы зададим для показателя «Организация» формулу self = obj(55407), то в заголовках строк отчета появится элемент справочника «Организации», имеющий id = 55407, т.е. элемент «Организация 1».

_images/212.png

Если укажем формулу self = obj(55410), то в заголовках строк отчета появится элемент «Организация 4».

_images/213.png

Вывод всех элементов справочника

Если при задании фильтра на показатель вместо стандартной операции «=» будет выбрано «задание формулой», а формула задана не будет, то в заголовки отчета попадут все значения справочника:

_images/214.png

Использование «показателей по цепочке»

В выражении можно использовать не только показатель, к которому применяется формула (заданный символом «self»), но и связанные с ним показатели - аналитические признаки.

В общем виде выражение в левой части формулы представляет собой конструкцию «цепочка показателей»:

self[.obj(id1)[.obj(id2)[.obj(id3)[...]]]]

где id1, id2, id3, … - идентификационные номера (id) объектов-показателей, каждый из которых является аналитическим признаком предыдущего показателя в цепочке.

Таким образом по цепочке можно переходить от одного показателя к другому, связанному с ним. Условие формулы, применяемой к исходному показателю, будет задано как ограничение на конечный показатель цепочки.

Рассмотрим пример использования конструкции «показатели по цепочке».

В справочнике «Организации» свойство «Адрес организации» задано соответствующим показателем «Адрес организации» (типа «Строка»), имеющим id = 55415.

_images/215.png

С помощью данного показателя мы можем задать множественный выбор заголовков строк:

_images/216.png

В формуле self.obj(55415) = «Москва», заданной для показателя «Организация», для каждого объекта, содержащего показатель «Организация», определяется связанное с ним значение показателя «Адрес организации», и выбираются те организации, у которых в поле «Адрес организации» указан город «Москва». Таким образом в отчет попадают сразу 2 заголовка строк: «Организация 1» и «Организация 3».

Использование константы в правой части формулы

В качестве значения формулы в ее правой части может быть указана константа (числовая, текстовая, булева и пр.).

Один из примеров использования константы приведен выше, это формула self.obj(55415) = «Москва».

Рассмотрим еще один подобный пример. В справочнике «Организации» свойство «Организация активна?» задано соответствующим показателем «Организация активна?» (типа «Да/Нет»), имеющим id = 55412.

Зададим для показателя «Организация» формулу self.obj(55412) = «Нет»:

_images/217.png

и получим заголовок «Организация 2» - это единственная организация, у которой признак «Организация активна?» равен «Нет».

Выбор нескольких значений для одного выражения

В правой части формулы может быть задано не одно значение, а список из нескольких значений. Такая конструкция работает как логическое «объединяющее ИЛИ».

Если, например, для показателя «Организация» будет задана формула self.obj(55415) = [«Москва», «Елец»] - в заголовках отчета появятся и организации, у которых указан город «Москва» («Организация 1», «Организация 3»), и организации, у которых указан город «Елец» («Организация 2»).

_images/218.png

Список из нескольких значений в правой части формулы может быть построен не только для констант, но и для объектов - элементов справочника, например:

_images/219.png

Формула self = [obj(55407),obj(55410)] выводит в отчет 2 заголовка: элемент справочника «Организации» с id = 55407 («Организация 1») и элемент справочника «Организации» с id = 55410 («Организация 4»).

Использование нескольких формул для одного показателя

К одному показателю могут быть применены несколько формул. Если эти формулы должны выполняться одновременно (логическая операция «И», AND), то они просто записываются друг за другом, каждая формула - с новой строки. Если должна выполняться хотя бы одна из нескольких формул (логическая операция «объединяющее ИЛИ», OR), то между формулами нужно вставлять строку с указанием операции OR. Совместное использование операций «И» и «ИЛИ» для одного и того же показателя не предусмотрено.

Рассмотрим примеры использования нескольких формул для одного показателя.

_images/220.png

К показателю «Организация» применены 2 формулы, соединенные операцией OR (логическое «объединяющее ИЛИ»). В отчет попадают 3 заголовка строк: заголовки «Организация 1» и «Организация 3» являются результатом первой формулы self.obj(55415) = «Москва», а третий заголовок «Организация 4» является результатом второй формулы self = obj(55410).

_images/221.png

В данном случае к показателю «Организация» применены 2 формулы, по умолчанию соединенные AND (логическое «И»), и в заголовки отчета попадают только те организации, для которых верны обе формулы.

Первая формула self.obj(55415) = «Москва» верна для 2-х элементов: «Организация 1» и «Организация 3». Вторая формула self = obj(55407) верна для одного элемента «Организация 1».

Таким образом, в отчет выводится только один заголовок «Организация 1».

Ограничение вариантов выбора параметра из справочника

Рассмотрим пример использования формул для ограничения вариантов выбора параметра отчета из справочника.

Если показатель «Организация», к которому применяются формулы, является параметром отчета, то при задании фильтра для этого показателя нужно выбрать опцию «Параметр» (сделать это нужно со стандартной операцией «=», и только после этого переключить на «задание формулой»):

_images/222.png

Псоле этого в окне формул прописываются формулы:

OR
    self.obj(55415) = "Москва"
    self = obj(55410)
_images/223.png

Результатом заданных формул является список из трех организаций: «Организация 1», «Организация 3» и «Организация 4».

В данном случае в отчет попадает только один заголовок, а этот список ограничивает выбор параметра при просмотре отчета:

_images/224.png

Задание параметров отчета формулами

Можно указать, что значения в правой части формулы являются параметрами отчета, задаваемыми пользователем при просмотре отчета. Для этого используется слово param до указания значения условия.

Например, если для показателя «Организация» зададим формулу self = param(obj(55407))

_images/225.png

получим отчет с параметром «Организация», который может быть изменен при просмотре отчета:

_images/226.png

«По умолчанию» в отчете устанавливается то значение параметра, которое указано в формуле.

Если для показателя «Организация» зададим формулу с двумя значениями парамера self = param([obj(55407),obj(55410)])

_images/227.png

получим отчет с возможностью множественного выбора параметра, в котором «по умолчанию» заданы указанные два значения параметра:

_images/228.png

ВАЖНО: при задании параметров формулой НЕ НУЖНО ставить галочку в чекбоксе «Параметр».

Текущий пользователь

В формулах на заголовки можно оперировать текущим пользователем:

self.obj(-2001) = user().obj(-2001)

так будут выведены только те объекты, у которых Административная структура (id = -2001) равна Административной структуре пользователя, который просматривает отчет.

Наследование значений

Если в заголовках строк или столбцов используются вложенные фильтры, то значения фильтра-родителя можно использовать при задании формул для вложенных фильтров:

self.obj(-20) = parent

В этом примере если фильтр, который является родителем данного по иерархии вложенности фильтров, задает какой-то определенный домен, то элементы рассматриваемого фильтра будут отсортированы именно по этому домену. Можно также наследовать значения у родителя любого уровня вложенности:

self.obj(-20) = parent(2)

этот фильтр будет наследовать значение из родителя родителя по иерархии вложенности заголовков. Уровень вложенности (число в скобках) можно задать любой, главное - проследить, что такой родитель есть, и его значение соответствует условию фильтра.

Системный показатель «Родительский элемент в дереве» (id = -400) используется для формирования иерархической структуры заголовков отчета на основе древовидного справочника.

Например, формула:

self.obj(-400) = parent

заданная во вложенном фильтре, обеспечит вывод в заголовки отчета всех элементов-потомков указанного выше элемента древовидного справочника

_images/284.png

Обратите внимание: в верхнем фильтре нужно снять «галочку» в чекбоксе «применять фильтр ко вложенным заголовкам».

_images/285.png

Метки

Если в одном отчете используются несколько заголовков с одним и тем же показателем-параметром, принимающим одно и то же значение, для установления связей между заголовками нужно использовать метки.

Для стандартных единичных фильтров (задаваемых равенством) при указании, что фильтр является параметром, есть дополнительное окно ввода «метка», в котором можно указать какое-нибудь слово или набор символов, например, метка1.

_images/229.png

Для заголовков, которые должны брать значение из помеченного параметра, формулой задается ссылка на помеченный параметр:

self = mark("метка1")

Если пользователь изменит значение помеченного параметра при просмотре отчета, то одновременно изменятся значения всех заголовков, ссылающихся на помеченный параметр.

Меток в одном отчете можно задавать неораниченное количество, но не больше одной в каждом конкретном фильтре.

Числовой ряд (int_iterate)

Формула:

self = int_iterate(1, param(10))

задает ряд целых чисел от 1 до 10, где верхняя граница будет параметром.

Формулы для работы с периодами

Ряд периодов (period_iterate)

Интервал времени задается двумя периодами: Период_А и Период_Б. Оба они должны быть одного типа (например, месяцы).

Ряд периодов будет содержать все периоды того же типа, начиная от периода Период_А и заканчивая периодом Период_Б:

self = period_iterate(Период_А, Период_Б)

Период задается текстовой строкой так же, как отображается в отчетах. Например, «2002 г.» или «1 кв. 2001 г.»:

self = period_iterate("1 кв. 2001 г.", "4 кв. 2002 г.")

Чтобы начало и/или конец интервала можно было задавать как параметр при просмотре отчета, нужно соответствующий аргумент функции period_iterate заключить в конструкцию param():

self = period_iterate(param("2001 г."), param("2002 г."))

Периоды-потомки (period_in)

Формула:

self = period_in(Период_Родитель, Тип_Периода_Потомка)

задает ряд периодов-потомков типа Тип_Периода_Потомка, содержащихся внутри периода-родителя Период_Родитель.

Тип_Периода_Потомка – текстовая константа из системного справочника «Периоды» (id = -60):

_images/230.png

Напрмер, формула:

self = period_in("2001 г.", "месяц")

задает ряд периодов от «январь 2001 г.» до «декабрь 2001 г.».

Задание параметров реализуется аналогиной формулой:

self = period_in(param("2001 г."), param("месяц"))

Периоды из даты (period)

Позволяет создать период по дате. В самом простом варианте указывается дата и тип периода, так, например, формула:

self = period("05.12.1985", "месяц")

задает период «декабрь 1985 г.», т.е. период типа «месяц», в который попадает дата «05.12.1985».

Формат представления даты задается в конфигурационном файле системы.

В данной формуле можно указать сдвиг периода, например, формула:

self = period("05.12.1985", "месяц", 1)

задает период «январь 1986 г.», т.е. следующий месяц за периодом «декабрь 1985 г.», в который попадает дата «05.12.1985».

Последним аргументом можно указать тип периода-потомка, в таком случае формула вернет список периодов данного типа. Формула:

self = period("05.12.1985", "месяц", 1, "день")

вернет список дней января 1986 года.

Можно получать дату как свойство какого-то объекта.

Напрмер, помеченный параметр «cow» может задавать определенную корову, а показатель «Дата рождения» (id = 123) задает дату рождения коровы. Формула:

self = period(get(mark("cow"), obj(123)), "месяц")

задает период - месяц, в котором родилась корова, выбранная пользователем в качестве параметра отчета.

Дни периода (days_in)

Формула возвращает список дней, содержащихся в указанном периоде, например:

self = days_in("1 кв. 2012 г.")

вернет список дней 1-го квартала 2012 года.

Начало периода (period_start)

Формула позволяет получить дату из периода, например:

self = period_start(mark("some_period"))

возвращает дату начала периода, заданного помеченным параметром «some_period».

Конвертация периодов (period + period_start)

Из квартала можно сделать год:

self = period(period_start(mark("period")), "год")

Так же работает сдвиг такого конвертированного периода на заданное число периодов того же типа (вперед дата сдвигается как с плюсом, так и без него):

self = period(period_start(mark("period")), "год", 1)
self = period(period_start(mark("period")), "год", +1)
self = period(period_start(mark("period")), "год", -2)

Сдвиг периода на несколько лет (shift_by_year)

Сдвигает период на целое число лет. Например, период «13.03.2013» (типа «день»), сдвинутый на -1 год, даёт «13.03.2012»:

self = shift_by_year("13.03.2013", -1)

Изменение названия параметра с помощью формулы

Если фильтр сделан параметром просмотра отчета (используется конструкция param()), то можно изменить видимое название фильтра, указав второй аргумент функции param(). Название параметра должно быть указано в кавычках:

param(obj(-2003), "Укажите тип региона")

Примеры:

self = period_iterate(param("2001 г.", "Итерации от"), param("2002 г.", "Итерации до"))
self = period_iterate(param("2001 г.", "Итерации от"), "2002 г.")
self = period_in(param("2001 г.", "Из периода"), param("месяц", "Тип периодов-потомков"))

Неравенства в формулах для задания фильтров

Обычно левая и правая части формулы соединяются знаком равенства «=».

Если показатель, к которому применяется формула, имеет тип «Справочник» или «Древовидный справочник», то можно использовать не только операцию равенства, но и другие операции сравнения: меньше «<», больше «>», меньше или равно «<=», больше или равно «>=», не равно «<>» (или «!=»).

Например:

self.obj(8196) != "462"

в заголовки отчета будут включены все элементы справочника, у которых значение данного свойства не равно «462»;

self.obj(7262) <= mark("param1")

в заголовки отчета будут включены такие элементы справочника, у которых указанное свойство не превышает значения параметра с меткой «param1».

Отбор активных записей справочника

Пример использования неравенств в формулах для отбора в заголовки формы/отчета активных записей справочника.

Допустим, справочник «Организации» содержит сведения о времени активности записей об организациях - это показатели «Дата начала активности» и «Дата окончания активности» (тип «Дата и время»).

_images/231.png

Нужно построить отчетную форму о количестве контрактов, исполняемых организациями в отчетном месяце. Отчетный месяц - параметр, который пользователь может изменять при просмотре и вводе данных в форму.

При выводе заголовков в отчетную форму необходимо учитывать, какие из организаций были активны в течение отчетного периода, и включать в заголовки формы только названия активных организаций.

  1. Создадим отчетную форму «Количество контрактов организаций в отчетном месяце».

В качестве источника данных в столбце возьмем показатель «Количество контрактов». В строках формы зададим фильтр по показателю «Организация». В качестве внешнего фильтра зададим параметр «Период», который пользователь сможет изменять при просмотре и вводе данных:

_images/232.png

Метка «report_period» потребуется для ссылки на это значение параметра в формулах. На экране пользователя будет отображаться название этого параметра - «Отчетный месяц».

2. Зададим для показателя «Организация» сложный фильтр с помощью формул:

self.obj(55803)<period_start(period(period_start(mark(report_period)), "месяц", +1))

self.obj(55806)>=period_start(mark(report_period))
_images/233.png

Разберем формулы по шагам:

mark(report_period)

ссылка на период (отчетный месяц), заданный в качестве параметра (по умолчанию этот параметр принимает значение «ноябрь 2018 г.»).

period_start(mark(report_period))

дата начала периода (отчетного месяца), заданного в качестве параметра.

period(period_start(mark(report_period)), "месяц", +1)

новый период типа «месяц», следующий за месяцем, заданным в качестве параметра.

period_start(period(period_start(mark(report_period)), "месяц", +1))

дата начала нового периода, следующего за месяцем, заданным в качестве параметра.

Таким образом, первая формула требует, чтобы у Организации показатель «Дата начала активности» (id = 55803) был меньше, чем дата начала месяца, следующего за отчетным месяцем. То есть время активности Организации должно начинаться не позже, чем закончится отчетный месяц.

Вторая формула требует, чтобы у Организации показатель «Дата окончания активности» (id = 55806) был больше или равен дате начала отчетного месяца. То есть время активности Организации не должно заканчиваться раньше, чем начнется отчетный месяц.

В результате при выборе отчетного периода «ноябрь 2018 г.» получим такой набор заголовков строк:

_images/234.png

При выборе отчетного периода «сентябрь 2018 г.» состав заголовков строк формы будет другим:

_images/235.png

При выборе отчетного периода «ноябрь 2019 г.» получим:

_images/236.png

tree-формулы (динамические деревья)

Если необходимо добавить одно дерево (первое) в подзаголовки нижних уровней другого (второго), то можно использовать следующую формулу для показателя первого дерева:

tree:
Obj(11)

где 11 - это id показателя, берущего значения из второго дерева. Получается следующая структура: первое дерево раскрывается до самого нижнего уровня (до листьев), в каждый лист вложено второе дерево, но без корня: корнем второго дерева будет служить лист первого дерева. На каждую ячейку при этом будет действовать два фильтра (оба дерева): от корня до листьев первого дерева применяется соответствующий узел первого дерева И корень второго, от листьев первого дерева до листьев второго применяется лист первого И соответствующий уровень второго.

Например, есть дерево магазинов:

-Все магазины
--Район1
---Магазин11
---Магазин12
--Район2
---Магазин21
---Магазин22

и дерево товаров:

-Все товары
--ТоварАА
--ТоварББ

После написания формулы для показателя Магазинов с раскрытием по дереву Товаров получится следующая структура заголовков:

-Все магазины
--Район1
---Магазин11
----ТоварАА
----ТоварББ
---Магазин12
----ТоварАА
----ТоварББ
--Район2
---Магазин21
----ТоварАА
----ТоварББ
---Магазин22
----ТоварАА
----ТоварББ

Аналогично строится вложенная структура из трех деревьев. Для этого используется следующая формула для показателя первого дерева:

tree:
Obj(11)
Obj(12)

где 11 - id второго дерева, а 12 - id третьего. В данном случае на каждую ячейку будет применяться три фильтра - по каждому из деревьев в соответствии с уровнем. При таком задании получится следующая структура: первое дерево раскрывается от корня до листьев (и применяется его соответствующий уровень и корни двух других деревьев); каждый лист первого дерева служит корнем второму - и второе также раскрывается до своих листьев (применяется лист первого, соответствующий уровень второго и корень третьего дерева); и каждый лист второго дерева служит корнем третьего (тут применяются значения листьев первых двух деревьев и соответствующий уровень третьего). На самом нижнем уровне к каждой ячейке применяются три значения конечных листьев всех трех деревьев.

Например, если к указанным в предыдущем примере добавить еще одно дерево, «доставка»:

-Все типы доставки
--Интернет-заказ
---Курьером
---Самовывоз
--Заказ по телефону
---Курьером
---Самовывоз
---По почте

то получится следующая структура заголовков:

-Все магазины
--Район1
---Магазин11
----ТоварАА
-----Интернет-заказ
------Курьером
------Самовывоз
-----Заказ по телефону
------Курьером
------Самовывоз
------По почте
----ТоварББ
-----Интернет-заказ
------Курьером
------Самовывоз
-----Заказ по телефону
------Курьером
------Самовывоз
------По почте
---Магазин12
----ТоварАА
-----Интернет-заказ
------Курьером
------Самовывоз
-----Заказ по телефону
------Курьером
------Самовывоз
------По почте
---
и т.д.

И так же строятся заголовки больше, чем по трем деревьям: порядок для второго, третьего, четвертого и всех последующих деревьев задается порядком их показателей в формуле.

Такие формулы эффективно поддерживают пропуск пустых строк - даже если деревья большие, то они быстро определят где есть данные (механизм аналогичен отчето-реестрам). Поэтому при использовании вложенности деревьев с большим количеством элементов рекомендуется включать пропуск пустых строк, т.к. перемножение всех элементов может сгенерировать число строк, превышающее общее ограничение системы (сейчас это 50000).

Если известно, что данные есть только в поддереве какого-либо из деревьев, или дерево большое и необходимо просмотреть только определенную его ветвь, то можно задать узел, с которого нужно начинать раскрытие. Для этого в строке нужного дерева после двоеточия нужно указать необходимую вершину дерева (для первого дерева, для показателя которого пишется формула, это строчка с записью «tree:»)

Например, чтобы просмотреть магазины только из первого района, формула для двух деревьев будет выглядеть так:

tree: Obj(10345)
Obj(11)

где 10345 - id узла «Район1» у дерева магазинов. Структура заголовков будет начинаться с указанного узла и будет выглядеть следующим образом:

-Район1
--Магазин11
---ТоварАА
---ТоварББ
--Магазин12
---ТоварАА
---ТоварББ

Другой пример: для тех же магазинов первого района нужно просмотреть доставку по товарам только из интернет-магазина. Тогда формула будет выглядеть так:

tree: Obj(10345)
Obj(11)
Obj(12): Obj(12678)

где 12678 - id узла «Интернет-заказ» из дерева доставок, а 10345 - id уже упомянутого узла «Район1» дерева магазинов. И заголовки будут выглядеть следующим образом:

-Район1
--Магазин11
---ТоварАА
----Курьером
----Самовывоз
---ТоварББ
----Курьером
----Самовывоз
--Магазин12
---ТоварАА
----Курьером
----Самовывоз
---ТоварББ
----Курьером
----Самовывоз

Таким образом можно задавать любой уровень у любого дерева, в т.ч. у всех деревьев одновременно.

Примечательно, что агрегация в данном случае учитывает вершину, с которой строятся заголовки каждого из деревьев, т.е. для самого нижнего дерева агрегация дойдет до указанного узла и дальше значения будут браться только за него, а не выше до корня. В последнем примере агрегация дойдет до уровня «Самовывоз», затем применится товар, а затем магазин.