Строковые отборы в 1С

01.02.21

Разработка - Универсальные функции

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

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
1С: Строковые отборы:
.epf 170,58Kb ver:2
4
4 Скачать (2 SM) Купить за 2 150 руб.

1. Отборы в 1С

При работе в программе 1С часто возникает необходимость ограничить данные, удовлетворяющую определенным требованиям. Для этого используются отборы. Отборы в 1С представляют из себя отдельный объект с определенными правилами установки. Отборы можно устанавливать интерактивно и программно. Интерактивная установка отборов предоставляется платформой 1С. Программно установка отборов также предоставляется платформой, но это не так наглядно и требует нескольких строк кода на каждое поле. Еще в интерактивных отборах есть ограничения на сложные отборы, накладываемые на несколько полей (условия на поля должны быть связаны только оператором «И»).

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

Пример 1: установка отбора на 2 поля обычным способом

СправочникСписок.Отбор.Наименование.ВидСравнения=ВидСравнения.Содержит;

СправочникСписок.Отбор.Наименование.Значение="а";

СправочникСписок.Отбор.Наименование.Использование=Истина;

           

СправочникСписок.Отбор.ТипКонтрагента.Установить(Перечисления.ТипыКонтрагентов.ФЛ);

 

Пример 2: Установка такого же отбора через строку отбора

ОтборУстановить(СправочникСписок.Отбор, "Наименование Содержит ""а"" и ТипКонтрагента=$З.пТипыКонтрагентов.ФЛ");

 

В первом примере для задания отбора на 1 поле с видом сравнения, отличным от равно, приходится вставлять 3 строки кода.

Во втором примере на самом деле 1 строка, искусственно разделенная для наглядности.

Пример 3: Установки НЕСТАНДАРТНОГО отбора через строку отбора

_ГМ.ОтборУстановить(СправочникСписок.Отбор, "Наименование Содержит ""а"" или ТипКонтрагента=$З.пТипыКонтрагентов.ФЛ" ,"СКонтрагенты");

В третьем примере при указании вида объекта ("СКонтрагенты") можно установить нестандартный отбор с помощью небольшой хитрости.

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

 

2. Варианты применения функции для работы с отборами в виде текстовой строки

Для начала определимся с синтаксисом текстовых отборов. Условия будут состоять последовательно из имени поля, слова сравнения (как идентификатор системного перечисления ВидСравнения, без пробелов) и одного или двух полей в зависимости от вида сравнения. Некоторые условия могут задаваться только полем. Поле может быть константой (число, строка, дата, булево), реквизитом или путем из реквизитов (разделенных «.»). Текстовый отбор может состоять из 0, 1 или нескольких условий, соединенных логическими операторами «НЕ», «И», «ИЛИ». Определение текстового отбора очень похоже на определение формулы, за исключением того, что конечными элементами являются условия.

Рассмотрим варианты применения функции для работы с отборами в виде строки (далее Функция).

  1.  

2.1 Установка отбора для форм списка

Допустим у нас есть форма списка СО (например, форма списка справочника или документа), но нам нужны не все элементы, а только удовлетворяющие определенным условиям (отбору). Отбор будем задавать текстовой строкой. Таким образом установить отбор возможно одним запуском данной Функции, указав в параметрах строку с отбором. Стандартным образом пришлось бы для каждого поля получать элемент отбора, устанавливать вид сравнения и 1 или 2 значения, в зависимости от вида сравнения. Это занимает гораздо больше строк кода и, соответственно, менее наглядно (было показано на примере).

  1.  

2.2 Задание условий на языке запросов в секции ГДЕ

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

В данном случае Функция должна выдать строку с условиями, адаптированную под этот запрос. Просто вставить строку с отбором в текст запроса не получится. К полям текущей таблицы необходимо добавить префикс в виде имени таблицы и точки. Также есть нюансы при трансформации условий на язык запросов.

Функция на входе получает псевдоним таблицы из секции ИЗ, структуру с параметрами запроса и строка с отбором. На выходе должна получиться строка с условиями запроса и возможно (но не обязательно) установленные параметры для данных условий. Это те параметры, которые не получится задать на языке запросов (непредопределенные ссылки).

  1.  

2.3 Проверка объекта на соответствие отбору

Вспомогательная функция, но тоже нашла применение. На входе ссылка на объект и строка с отбором. На выходе Функция должна вернуть ИСТИНА, если объект соответствует отбору, иначе ЛОЖЬ. Проверяются не только реквизиты, но и путь из реквизитов, допускающий произвольное количество имен реквизитов.

Пример: для справочника Контрагенты проверка условия:

 ОсновнойДоговор.Наименование содержит "№"
  1.  

2.4 Получение реквизитов по отбору

Данный вариант использования Функции связан с п. 2.2, когда была реализована функция поиска объекта по отбору через запрос. Очень удобным инструментом стало создание объекта по заданному отбору.

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

  1.  

2.5 Упрощение формул

Особый вариант использования данной функции. Можно рассматривать как частный случай п.2.2, если запустить функцию для получения условий запроса с пустым именем таблицы. В результате мы получим упрощенный вариант изначальной формулы. Естественно, если формула не упрощается, то на выходе мы получим исходную формулу.

Рассмотрим случаи, когда можно сократить условия (формулу). В примерах по упрощению формул будем использовать символ «è» для разделения изначальной и упрощенной версий формулы.

  1. Можно убрать скобки, если несколько раз используются операторы с одним уровнем приоритета.

Пример: ((а ИЛИ b) ИЛИ с) è а ИЛИ b ИЛИ с

  1. В случае, когда скобки не нарушают порядок выполнения операторов.

Примеры: (НЕ а) ИЛИ b è НЕ а ИЛИ b

(а ИЛИ b) И с, в этом случае скобки нельзя убрать.

  1. В случае, когда подоператорные выражения одинаковы.

Пример: а=а èИСТИНА

Могут быть формулы из нескольких условий

а ≥ а èИСТИНА

  1. Когда начало и конец интервала совпадают, можно упростить сравнение.

Пример: а ИНТЕРВАЛ b и b è ЛОЖЬ

а ИНТЕРВАЛВКЛЮЧАЯГРАНИЦЫ b И b è   a=b

  1. В случае, когда элементарные условия применяются только к константам (результат можно сразу посчитать).

Пример: 5=6 è ЛОЖЬ

"Задача" СОДЕРЖИТ "а" è ИСТИНА

  1. Если в подоператорных выражениях используются константы

Пример: а ИЛИ ИСТИНА è ИСТИНА,

а И b И с И ЛОЖЬ è ЛОЖЬ

  1. В случае, когда используются вложенные операторы

Пример: НЕ (НЕ a) è a

НЕ (a ИЛИ НЕ b) è НЕ a И НЕ(НЕ b) è НЕ a И b

  1. Возможны случаи, когда есть комбинация всех этих способов

Пример: а = а ИЛИ с è ИСТИНА ИЛИ с è ИСТИНА.

 

3. Реализация функции для работы с отборами в виде текстовой строки

 

3.1 Определение функции

Заголовок Функции:

Функция СтрОтборДействие(псДействие,псОтбор,пПар=Неопределено) Экспорт

Варианты использования Функции различны, поэтому количество и состав входных параметров функции зависят от варианта использования. Но два первых входных параметра общие – сам вариант использования (Параметр псДействие, тип строка) и строка с отбором (Параметр псОтбор). Третий параметр (пПар) представляет собой структуру параметров, в случае если нужны дополнительные параметры, либо Неопределено (по умолчанию).

Параметр псДействие может принимать следующие значения:

  • "Отбор" (в пПар должны быть ключи Отбор, [Вид]) Устанавливает отбор в форме ссылочного объекта, возвращает Истина если применился отбор.
  • "ЗапросУсловие" (в пПар должны быть ключи ЗапросПараметры, ИмяТЗ). Получение строки условий для запроса, возвращает строку Условии запроса для секции ГДЕ.
  • "Объект" (в пПар должен быть ключ Объект) Проверить условие для объекта, возвращает булево.
  • "Реквизиты" Получение реквизитов объекта по отбору (только для определенных условий, связанных оператором И).

 

3.2 Устройство функции

Как видно из предыдущего раздела Функция объединяет в себе 4 подфункции. Они были консолидированы в одну функцию по той причине, что первым шагом в этих подфункциях строится схема выражения.

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

Функция СтрОтборДействие(псДействие,псОтбор,пПар=Неопределено) Экспорт
            {Инициализация контекста лКонт}
            лВыражение=СхемаВыражения(лКонт); //Построение схемы выражения
            {Обработка ошибок}

            Если псДействие="Отбор" Тогда
                        лСтандОтбор={Проверка на стандартный отбор};
                        Если не лСтандОтбор Тогда 
                                    {Из выражений делаем Запрос}
                                    {Отобираем ссылки и накладываем отбор по массиву ссылок}
                                    Возврат Истина;
                        КонецЕсли;
            КонецЕсли;
          
            лРез={Рекурсивная функция обработки выражения для действия псДействие}
            {Обработка ошибок}
           
            Если псДействие="Отбор" Тогда
                        Возврат Истина;
            КонецЕсли;
            Возврат лРез;
КонецФункции

Вначале идет операция инициализации контекста лКонт. Это нужно для упрощения вспомогательных подфункций. По факту лКонт – это структура, в которой хранятся 5 текущих параметров Функции:

 

лКонт = Структура("Стр,Ош,Поз,Пар,Пробелы");

 

Стр – исходная строка с отбором,

Поз – текущая позиция при распознании выражения,

Пар – дополнительные параметры, полученные при запуске Функции,

Ош – описание текущей ошибки (если была ошибка, иначе ""),

Пробелы – строка с пробельными символами.

              Вместо указания всех этих параметров во вспомогательных функциях достаточно передавать 1 параметр с данной структурой.

В устройстве Функции основными этапами являются: построение схемы выражения и функция обработки выражения. Рассмотрим их более подробно.

  1.  

3.3 Построение схемы выражения

3.3.1 Распознание элементов

Получение элементов из входящей строки отбора производится с помощью единственной функции СхемаВыраженияЭлемент.

Функция СхемаВыраженияЭлемент(пКонт,пСкобкиВМас) Экспорт

На входе контекст с исходной строкой и текущей позицией и дополнительный параметр пСкобкиВМас, предписывающий функции воспринимать открывающую скобку как начало массива.

На выходе СхемаВыраженияЭлемент возвращает структуру Структура("Вариант,Значение"). Вариант – это символ, обозначающий тип прочитанного элемента: (з)Значение (м)Массив (М)Массив сложный (с)Сравнение (i)идентификатор с точками (N)Not (O)Or (A)And (!)ошибка (#)Конец. Значение – непосредственное значение прочитанного элемента. Варианты в виде символа удобно проверять строковой функцией Найти().

Функция «может» прочитать константу (строку, число, булево или дату), массив (постоянный или содержащий переменные), а также идентификатор (строка), оператор (строка). Соответственно возникает вопрос как воспринимать строку, которую возвращает функция. По этой причине для однозначного определения прочитанного элемента функция возвращает 2 параметра (Вариант и Значение) в виде структуры.

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

Дополнительно введен спецсимвол «$», с которого начинается специальные конструкции, возвращающие значение на этапе распознания. На данный момент определены: $МД.<ИмяМетаданных> (наличие в конфигурации метаданных <ИмяМетаданных>), $Об.<Вид.Псевдоним> (получить из дополнительного регистра ссылку вида Вид по псевдониму Псевдоним) и $З.<Вид.Идентификатор> (Получить предопределенный элемент вида Вид и именем Идентификатор).

Если предыдущие проверки не увенчались успехом, то данный элемент представляет собой слово. Читаем пока не закончатся буквы русского и латинского языка с «_» и «.». Далее проверяем полученный идентификатор (точнее путь из идентификаторов в общем случае) на равенство зарезервированным идентификаторам операторов (И, ИЛИ, НЕ) и значений булево и NULL (ИСТИНА, ЛОЖЬ). Соответственно, возвращаем оператор, значение или идентификатор.

    1.  

3.3.2 Распознание условий

Из элементов составляются условия. Функция СхемаВыраженияУсловие читает с текущей позиции условие либо вложенное выражение (будет рассмотрено в следующей главе) и возвращает его, сдвигая позицию на следующий элемент.

Функция СхемаВыраженияУсловие(пКонт)
//пКонт:           Структура("Стр,Ош,Поз,Пар,Пробелы");
//Возврат:
//          Структура("Вид,Поле1",1,лПоле1);
//          Структура("Вид,Сравнение,Поле1,Поле2",2,лсСрав,лПоле1,лПоле2);
//          Структура("Вид,Сравнение,Поле1,Поле2,Поле3",3,лсСрав,лПоле1,лПоле2,лПоле3);

 

Функция СхемаВыраженияУсловие возвращает структуру с полями Вид,Поле1[,Сравнение,Поле2[,Поле3]].

Обязательный ключ «Вид» принимает значение: 1, 2 или 3 в зависимости от количества полей. Ключ «Поле1» всегда присутствует. Ключ «Сравнение» (строка с видом сравнения) и «Поле2» присутствуют для Вида 2 и 3. Для Вида 3 дополнительно появляется ключ «Поле3» (это условия по вхождению поля1 в интервал между Поле2 и Поле3). Поля «Поле1», «Поле2» и «Поле3» представляют собой результат функции СхемаВыраженияЭлемент – Структура("Вариант,Значение"), где Вариант = «з» (Значение) или «i» (идентификатор – переменная/поле/реквизит поля).

Примеры Вид=1: Истина, Ложь, ОтражатьВБухгалтерскомУчете.

Примеры Вид=2: ОтражатьВБухгалтерскомУчете=Истина, а>б, Наименование СОДЕРЖИТ «Анна»,  ОсновнойДоговор.ДатаПодписания БОЛЬШЕИЛИРАВНО ’2010.01.01’.

Примеры Вид=3: ОсновнойДоговор.ДатаПодписания ИНТЕРВАЛВКЛЮЧАЯНАЧАЛО ’2010.01.01’ И ’2020.01.01’

 

3.3.3 Распознание выражений

Следующий уровень – распознание выражений. Рекурсивная функция СхемаВыражения возвращает оптимизированный минимальный массив с выражением (массивы могут быть вложенные) или структуру с простым условием.

Выражение в массив помещается следующим образом. В первом элементе (индекс 0) помещается буква оператора «N», «A» или «O» (Не, И, Или). Далее составные части Выражения: массивы (вложенные выражения) или структуры с простыми условиями. Для оператора НЕ количество составных частей 1, для других операторов количество составных частей не ограничено.

Схема функции:

Функция СхемаВыражения(пКонт)
            лРез=СхемаВыраженияУсловие(пКонт);
            лРезВариант="";         //"": Элемент, "A": And, "O": Or
           
            Пока Истина Цикл
                        Если {Текущий символ ")"} Тогда
                                   Прервать;
                        КонецЕсли;
                        лРазд=СхемаВыраженияЭлемент(пКонт,Ложь);
                        {Ошибка если лРазд не оператор};
                        лВариант=лРазд.Вариант;
                       
                        лРез2=СхемаВыраженияУсловие(пКонт);
                       
                        Если лРезВариант="" Тогда
                                   лРезВариант=лВариант;
                                   лМас=Массив(лРезВариант);
                                   Если ТипМассив(лРез) и лРез[0]=лРезВариант Тогда
                                               Для лн=1 По лРез.ВГраница() Цикл
                                                           лМас.Добавить(лРез[лн]);
                                               КонецЦикла;
                                   Иначе  
                                               лМас.Добавить(лРез);
                                   КонецЕсли;
                                   Если ТипМассив(лРез2) и лРез2[0]=лРезВариант Тогда
                                               Для лн=1 По лРез2.ВГраница() Цикл
                                                           лМас.Добавить(лРез2[лн]);
                                               КонецЦикла;
                                   Иначе  
                                               лМас.Добавить(лРез2);
                                   КонецЕсли;
                                   лРез=лМас;
                        ИначеЕсли лРезВариант=лВариант Тогда  //"AA" или "OO"
                                   Если ТипМассив(лРез2) и лРез2[0]=лРезВариант Тогда
                                               Для лн=1 По лРез2.ВГраница() Цикл
                                                           лРез.Добавить(лРез2[лн]);
                                               КонецЦикла;
                                   Иначе  
                                               лРез.Добавить(лРез2);
                                   КонецЕсли;
                        ИначеЕсли лРезВариант="A" Тогда //лРезВариант="A" лВариант="O"
                                   лРез=Массив("O",лРез,лРез2);
                                   лРезВариант="O";
                        Иначе   //лРезВариант="O" лВариант="A"
                                   лИндПосл=лРез.ВГраница();
                                   Если ТипМассив(лРез[лИндПосл]) Тогда
                                                лРез[лИндПосл].Добавить(лРез2);
                                   Иначе
                                               лРез[лИндПосл]=Массив("A",лРез[лИндПосл],лРез2);
                                   КонецЕсли;
                        КонецЕсли;
            КонецЦикла;
          
            Если лРезВариант<>"" Тогда 
                        {обработка значений Истина и Ложь для упрощения формул};
            КонецЕсли;
            Возврат лРез;
КонецФункции

Здесь используются дополнительные функции. Функция Массив(Эл1,Эл2,Эл3) возвращает массив из указанных параметров. ТипМассив(пЗнач) возвращает Истина, если пЗнач является массивом.

Принцип работы функции следующий. Функция сначала читает первое условие в переменную лРез. Переменная лРезВариант хранит текущий статус лРез, инициализируется значением "". Далее в цикле читается оператор и следующее условие в переменную лРез2. Переменные лРез и лРез2 могут содержать условие(структура) или подвыражение(массив). На основании типов лРез и лРез2 идет соединение подвыражений с помощью прочитанного оператора. лРезВариант в процессе соединения подвыражений может принимать 3 значения: "" одиночное подвыражение; "A" – группа подвыражений, связанных оператором И; "O" – группа подвыражений связанных, оператором ИЛИ.

Функция СхемаВыражения рекурсивная, может быть вызвана из вызовов функции СхемаВыраженияУсловие при получении переменных лРез и лРез2, например, при обработке условия в скобках или условия, начинающегося с оператора НЕ. Поэтому при появлении закрывающейся скобки функция СхемаВыражения возвращает текущее построенное выражение.

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

a1[ И a2[ И a3…]] ИЛИ b1[ И b2[ И b3…]] ИЛИ c1[ И c2[ И c3…]] ИЛИ …

В этом и заключается шаг рекурсии (a1, a2, b1, … могут быть выражениями либо конечными условиями). Оператор ИЛИ выполняется последним.

После того, как цикл будет закончен происходит анализ полученного выражения на наличие констант Истина и Ложь, которые в связке с остальными подвыражениями либо сокращаются, либо полностью заменяют выражение. Например, а и Истина ИЛИ b è a ИЛИ с. Стоит добавить, что данный анализ проводится только для текущего шага рекурсии (т.к. для подвыражений этот анализ уже будет проведен этой же функцией в предыдущей итерации рекурсии).

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

 

3.4 Упрощение формул

Формулы упрощаются во время построения схемы выражения. Здесь был принят компромисс между производительностью и идеальностью. Отдельно стоит рассмотреть оператор НЕ.

 

3.4.1 Оператор «НЕ»

Схему выражения можно рассматривать в виде дерева. Рекурсивная функция СхемаВыражения сначала формирует схемы листьев (это простые условия), постепенно переходя к корню дерева. Последней операцией функции всегда будет упаковка всех подвыражений в единое дерево (массив оператора «И» или «ИЛИ»).

На любом этапе может встретиться оператор «НЕ». Функции построения схемы выражения «стараются» избавиться от оператора «НЕ».

Если «НЕ» применяется к простому условию (это лист, нет подвыражений), то «НЕ» перемещается в вид сравнения. Исключение составляют только виды сравнений из группы Интервалов и одиночные переменные(поля).

Например: НЕ (a > b) è a <= b.

НЕ (a ВГРУППЕ b) è a НЕВГРУППЕ b

НЕ (a НЕСОДЕРЖИТ b) è a СОДЕРЖИТ b

 

Если «НЕ» применяется к выражению (или подвыражению), тогда также рекурсивно «НЕ» проникает внутрь подвыражений, пока не дойдем до листьев. С помощью формул Де Моргана (1) (2) и двойного отрицания (3) можно раскрывать скобки:

Не (а ИЛИ b) è Не а И НЕ b                  (1)

Не (а И b) è Не а ИЛИ НЕ b                  (2)

Не (Не а) è a                                          (3)

Таким образом избавление от оператора «НЕ» на уровне подвыражений превращается в работу с массивами (для (1) (2) формируется новый массив, И заменяется на ИЛИ и наоборот, далее «НЕ» рекурсивно применяется к каждому элементу массива).

    1.  

3.4.2 Вычисление константных условий

Любое условие можно сразу вычислить, если в нем нет переменных (т.е. все поля являются константами). В таком случае условие заменится на булево: ИСТИНА или ЛОЖЬ.

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

Не ИСТИНА è ЛОЖЬ, Не ЛОЖЬ è ИСТИНА

a И ИСТИНА è a, a И ЛОЖЬ è ЛОЖЬ

a ИЛИ ИСТИНА è ИСТИНА, a ИЛИ ЛОЖЬ è a

    1.  

3.4.3 Особенности сравнения РАВНО и НЕРАВНО

Условия со сравнением РАВНО и НЕРАВНО, если правая и левая части равны, можно также упростить до константы.

a = a  è ИСТИНА, a <> a  è ЛОЖЬ

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

  1.  

3.5 Обработка схемы выражения

Вернемся к исходной функции СтрОтборДействие. С помощью дополнительной функции СхемаВыражения получена коллекция со схемой выражения отбора. Следующим этапом будет применение данной схемы согласно действия из параметра псДействие.

Обработка схемы выражения происходит запуском рекурсивной функции СтрОтборДействиеЭлемент, примененной ко всей схеме выражения. Данная функция переберет все дерево схемы выполняя действие псДействие.

Функция СтрОтборДействиеЭлемент(пДействие,ппВыражение,пКонт)
    1.  

3.5.1 Отбор стандартного вида

Введем термины для более формального рассмотрения устройства функции.

Отбор стандартного вида (далее ОСВ) – это отбор, который может быть установлен на табличное поле справочника, документа, либо другой ссылочный объект метаданных (для удобства назовем его СО). Также к СО относятся: план видов характеристик, бизнес-процесс, задача, план обмена.

Другими словами, ОСВ – это отбор, который можно применить к форме списка справочника, документа или другого СО.

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

 

[<Условие1> [ И <Условие2>[ И<Условие3>…]]]

 

Условия можно применить (наложить) к колонке табличного поля СО. Вот полный список условий платформы 1С: РАВНО; НЕРАВНО; БОЛЬШЕИЛИРАВНО; МЕНЬШЕ; МЕНЬШЕИЛИРАВНО; БОЛЬШЕ; ВИЕРАРХИИ; НЕВИЕРАРХИИ; ВСПИСКЕ; НЕВСПИСКЕ; ВСПИСКЕПОИЕРАРХИИ; НЕВСПИСКЕПОИЕРАРХИИ; СОДЕРЖИТ; НЕСОДЕРЖИТ; ИНТЕРВАЛВКЛЮЧАЯГРАНИЦЫ; ИНТЕРВАЛВКЛЮЧАЯНАЧАЛО; ИНТЕРВАЛВКЛЮЧАЯОКОНЧАНИЕ; ИНТЕРВАЛ.

Условия задаются видом сравнения.

 

Правая часть условия – это одна (Значение) или две константы (Значение1, Значение2). Два поля в правой части используются только для интервалов. Важное ограничение платформы 1С: в ОСВ на одно поле может быть не больше одного элементарного условия.

Рассмотрим примеры отборов стандартного вида (Предположим у справочника есть поля: Наименование, НаименованиеПолное и ДатаРождения).

- Наименование СОДЕРЖИТ "А"

- ДатаРождения ИНТЕРВАЛВКЛЮЧАЯГРАНИЦЫ 01.01.2020 и 31.12.2020.

- (Наименование СОДЕРЖИТ "А")  и (ДатаРождения БОЛЬШЕ '2020.01.01') И (НаименованиеПолное СОДЕРЖИТ "ЗАО")

Не являются ОСВ такие варианты:

- НЕ ДатаРождения ИНТЕРВАЛ 01.01.2020 и 31.12.2020 (т.к. не является ЭУ, Интервалы применяются без «Не»)

- (ДатаРождения ИНТЕРВАЛ '2020.01.01' и '2020.12.31') ИЛИ (Наименование СОДЕРЖИТ "О") (т.к. ЭУ связаны оператором ИЛИ)

- Наименование <> НаименованиеПолное (т.к. в правая часть условия не является константой)

    1.  

3.5.2 Установка отбора для форм списка

Для псДействие="Отбор" на вход в функцию СтрОтборДействие передается Отбор формы списка. Дополнительно может быть передан параметр Вид объекта.

Первым делом проверяем, является ли схема выражения ОСВ. Если да, то все просто: элементы отбора устанавливаются условиями из схемы выражения. Булевые условия (которые состоят из одного Поля1 без сравнения) заменяются следующим образом:

a è a = ИСТИНА, НЕ a è a = ЛОЖЬ

Если схема выражения не является ОСВ, тогда стандартные средства платформы 1С не помогут в силу их ограниченности. Но т.к. у нас ссылочный объект (СО), то у него в отборе должно быть поле Ссылка. С помощью запроса (построение запроса по схеме выражения также реализовано в Функции) можно выбрать Массив ссылок СО, которые удовлетворяют этому отбору. Далее устанавливается отбор для поля Ссылка (этот отбор точно будет ОСВ):

Ссылка ВСписке МассивСсылок

Заметим, что для данного трюка нам потребуется Вид СО, чтобы построить запрос. Этот Вид необходимо передать в параметрах функции СтрОтборДействие.

Есть один минус данного способа: новые объекты, удовлетворяющие исходному отбору, не будут отображаться в форме списка, т.к. их ссылок просто не существовало при построении Массива ссылок.

Идея наложить произвольный отбор на форму списка СО конечно расширяет возможности системы в обычных формах.

Результатом функции СтрОтборДействие является ИСТИНА, если отбор получилось применить.

    1.  

3.5.3 Задание условий на языке запросов в секции ГДЕ

Для псДействие="ЗапросУсловие" на вход в Функцию СтрОтборДействие передаются ИмяТЗ, ЗапросПараметры.

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

Параметр ЗапросПараметры нужен для вставки значений, которые нельзя получить конструкциями языка запросов – непредопределенные элементы СО’ов. Строки, числа, даты, булево и предопределенные элементы сразу вставляются в условия запроса без добавления в структуру ЗапросПараметры.

Примеры:

ТЗ.Цена >= 5500

ТЗ.Наименование = "ООО ""Логистика"""

ТЗ.ТипКонтрагента = Значение(Перечисление.ТипыКонтрагентов.ФЛ)

Есть нюансы преобразования условий в условия языка запросов.

a СОДЕРЖИТ b è a ПОДОБНО %b%

a НЕСОДЕРЖИТ b è a НЕ ПОДОБНО %b%

a ИНТЕРВАЛВКЛЮЧАЯГРАНИЦЫ b И c è a МЕЖДУ b И c

a ИНТЕРВАЛВКЛЮЧАЯНАЧАЛО b И c è a >= b И a < c

a ИНТЕРВАЛВКЛЮЧАЯОКОНЧАНИЕ b И c è a > b И a <= c

a ИНТЕРВАЛ b И c è a > b И a < c

    1.  

3.5.4 Проверка выполнения отбора для объекта

Для псДействие="Объект" на вход в Функцию СтрОтборДействие передаются Объект. В построенной схеме выражения вместо полей подставляются значения реквизитов объекта (и их полей, если необходимо), в итоге получится константное выражение, которое можно вычислить.

    1.  

3.5.5 Получение реквизитов по отбору

Функция запускается при псДействие="Реквизиты". На выходе – структура со значениями реквизитов. В заполнении реквизитов объекта по отбору участвуют только условия корневого оператора И, остальные подвыражения игнорируются, не вызывая ошибки (т.е. обрабатываются только условия ОСВ), т.к. не понятно как их применять. Здесь стоит напомнить, что схема выражения оптимизирована и не содержит лишних условий, соответственно, если есть подвыражения, значит они отличаются оператором от корневого оператора (корневой - И, на втором уровне ИЛИ/НЕ).

Также не все условия отбираются для установки реквизитов. Например, условие НЕРАВНО не определяет значение реквизита по той же причине – не понятно какое значение должно быть (здесь только определено значение, которого не должно быть в реквизите).

Полный список видов сравнения, которые отбираются для установки реквизитов: РАВНО, БОЛЬШЕИЛИРАВНО, МЕНЬШЕИЛИРАВНО, СОДЕРЖИТ, ИНТЕРВАЛВКЛЮЧАЯГРАНИЦЫ, ИНТЕРВАЛВКЛЮЧАЯНАЧАЛО, ВСПИСКЕ, ВСПИСКЕПОИЕРАРХИИ.

 

4. Применение функции для работы с текстовыми отборами

Функция для работы со строковыми отборами получилась довольно гибким прикладным решением, не смотря на сложность ее реализации. Функция реализует 4 разных функционала (действия). Одна и та же строка с отбором может использоваться для разных действий функции. Например, можно открыть форму с отбором, а потом выбрать все элементы запросом, удовлетворяющие данному отбору, далее если не нашли, то еще и создать элемент под этот отбор.

Важная особенность функции – определение отбора без знания программирования 1С. Это позволяет создавать гибкие системы, которые может настроить продвинутый пользователь. Настройки отбора можно хранить в самой базе, что позволит без изменения конфигурации подстраивать базу под нужды пользователей. Еще один момент: меньше строк кода – меньше ошибок. А также наглядность отборов, заданных строкой по сравнению с программной установкой.

Функция разработана под нужды автора, соответственно, уже имеет практическое применение.

  1.  

4.1 Применение при установке отбора

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

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

Нестандартным решением является установка произвольного отбора на форму списка ссылочного объекта. Это вариант, как обойти ограничения платформы в обычных формах, где можно использовать только отборы определенного вида (ОСВ). Может быть очень полезным в случае, если нужно как можно меньше вносить изменения в имеющуюся конфигурацию и желательно только в код программы.  

  1.  

4.2 Применение в запросах

Это вспомогательная функция, используемая в других функциях как фундамент. Автор часто использовал эту подфункцию для формирования гибких запросов, которые выбирают не только все объекты заданного вида, но и ограниченные произвольным отбором.

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

  1.  

4.3 Проект «Утопия»

Данная разработка является частью авторского проекта Утопия (подробнее в публикации «Проект Утопия»).

Одно из мест, где используется функция – виртуальный справочник метаданных, в котором для любого ссылочного объекта можно задать действие над полями в пределах отбора, заданного строкой. Примеры действий: проверка заполнения, нормирование (удаление лишних пробелов, перевод первой буквы в верхний регистр).

  1.  

4.4 Прикладная обработка

Реализована обработка для тестирования Функции работы с текстовыми отборами. 

В обработке показано как использовать все варианты применения Функции. Основная Функция «СтрОтборДействие» определена в модуле обработки. Рядом определены вспомогательные функции, описанные в статье. Т.к. Функция использует большое количество дополнительных функций, то они все также присутствуют в модуле.

Обработка тестировалась на платформах 8.3.9.2170, 8.3.16.1030.

Отбор парсер анализ текста установка отбора отбор установить формула формулы Де Морган булево строка алгебра логики

См. также

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

21.05.2024    20118    dimanich70    81    

144

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    4091    3    John_d    11    

57

Универсальные функции Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    18051    atdonya    24    

56

Универсальные функции Программист Платформа 1С v8.3 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    5501    ke.92@mail.ru    16    

65

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    14729    YA_418728146    7    

166

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    3579    56    progmaster    8    

4

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    18478    171    sapervodichka    112    

135
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. _Alexei_ 28.02.21 05:43 Сейчас в теме
у меня динамический отчет, я бы хотел сконвертировать свои отборы для передачи в запрос
типа Запр = Новый Запрос;
Запр.Текст = ".................";
если отбор в списке, то в качестве параметров

у Вас это предусмотрено?
2. lastcontra 116 28.02.21 07:25 Сейчас в теме
Реализовано получение строки с условиями для запроса для секции ГДЕ. Передаете имя таблицы и Параметры запроса, на выходе получите строку условий, которую засунете в запрос после ГДЕ, и параметры могут быть установлены в запрос.

СтрОтборДействие("ЗапросУсловие",фОтбор,Новый Структура("ЗапросПараметры,ИмяТЗ",,"ТЗ"))
3. _Alexei_ 28.02.21 12:41 Сейчас в теме
нет, не торлько для секции ГДЕ, а еще и для выборки из регистров

я имею в виду интерпретацию элементов отбора формы настроек в свои динамические запросы
написал в ОбщийМодуль пару экспортируемых функций, которые обрабатывают ВидСравненияКомпоновкиДанных для каждого отбора
в типовой нашел только обработчики для ВидСравнения, но это не то
4. lastcontra 116 28.02.21 14:24 Сейчас в теме
Игра "пойми меня".
Для получения строки условий из отбора СКД функция не подойдет, у нее другое назначение.
Оставьте свое сообщение