====== Описание построения формул в системе CleverForms | Document ====== ===== 1. Формула может иметь следующие элементы: ===== • **Числа** - константы, используемые для вычисления. Дробная часть отделяется точкой.\\ • **Ссылки на локальные поля** в виде ${field_id}. Пробелы внутри скобок допускаются. field_id - номер поля, в котором хранится необходимое значение. может быть числом или id (указывает на поле, в котором хранится ID объекта)\\ • **Ссылки на поля в других документах** в виде ${field_id1.field_id2.field_id3}. Пробелы внутри\\ скобок допускаются. field_id - номер поля, в котором хранится ссылка или необходимое значение. Может быть \\ числом. parent (указывает на родительский объект, если есть), а id (указывает на поле, в котором хранится ID объекта)\\ • **Даты** - выражения, заключенные в одинарные кавычки. Форматы: 'dd.MM.yyyy' - дата, 'dd.MM.yyyy hh:mm:ss' - дата и время.\\ • **Зарезервированные слова** (используется только в функциях)\\ • Все остальные данные считаются строками.\\ • Знаки математических операций: +, -, /, *\\ • Знаки логических операций: !, &&, ||\\ • Знаки бинарных операций: ~, &, |\\ • **Знаки сравнения**: ==, !=, >, >=, =>, <, <=, =<\\ • Знаки скобок: ()\\ • Знак разделения операндов: **,**\\ ===== 2. Очередность выполнения операций ===== **2.1. Очередность выполнения операций - классическая.**\\ **2.2. Допускается использование операндов как результат выполнения функции(операции).** Например:\\ ''⇒ find(diff(x, y, day), 1024, id, long)'' ===== 3. Использование типов данных. ===== **3.1. Все вычисления выполняются с использованием типов данных. Контроль над корректностью типов возлагается на того, кто пишет формулу.**\\ Используемые типы: * целочисленный (Long) * дробный (Double) * логический * дата * строка. **3.2. Все математические функции возвращают Double.**\\ **3.3. Все бинарные функции возвращают Long.**\\ **3.4. Все логические функции возвращают Boolean.**\\ **3.5. В случае преобразования Double => Long теряется дробная часть, но ошибка не возникает.**\\ **3.6. Допускается сложение строк (склейка). Для преобразования значения в строку используется выражение: +"value".** ===== 4. Встроенные функции: ===== ==== 4.1. Логические функции: ==== * is_null(x), где x – проверяемый аргумент. Сравнивает аргумент с null; * is_not_null(x), где x – проверяемый аргумент. Сравнивает аргумент с null; * is_empty(x), где x – проверяемая строка. Проверяет является ли строка пустой; * is_not_empty(x), где x – проверяемая строка. Проверяет является ли строка пустой; ==== 4.2. Агрегатные функции: ==== * avg(x), где x – номер поля или id. Вычисляет среднее арифметическое среди значений одного поля всех документов. Возвращаемый тип данных - double; * count(x), где x – номер поля или id. Вычисляет количество документов, имеющих это поле. Имеет сокращение – cnt(x). Возвращаемый тип данных - long; * min(x, type), где x – номер поля или id, type – тип данных. Вычисляет минимальное значение * среди одного поля всех документов; * max(x, type), где x – номер поля или id, type – тип данных. Вычисляет максимальное значение среди одного поля всех документов; * sum(x, type), где x – номер поля или id, type – тип данных. Вычисляет сумму значений одного * поля всех документов. **Например:** ''⇒ avg(37) – вычисляет среднее арифметическое среди значений поля № 37;\\ ⇒ cnt(37) – вычисляет количество полей № 37;\\ ⇒ min(37, long) – вычисляет минимальное значение поля № 37 как long;\\ ⇒ max(37, timestamp) – вычисляет максимальное значение поля № 37 как timestamp;\\ ⇒ sum(37, integer) – вычисляет сумму значений поля № 37 как integer.'' ==== 4.3. Агрегатные функции для таблиц: ==== *avg_t(x), где x – номер поля или y.id (y – номер формы таблицы).Вычисляет среднее арифметическое среди значений одного поля всех документов таблицы. Возвращаемый тип данных - double; *count_t(x), где x – номер поля или y.id (y – номер формы таблицы). Вычисляет количество документов таблицы, имеющих это поле. Имеет сокращение – cnt_t(x). Возвращаемый тип данных - long; *min_t(x, type), где x – номер поля или y.id (y – номер формы таблицы), type – тип данных. Вычисляет минимальное значение среди одного поля всех документов таблицы; *max_t(x, type), где x – номер поля или y.id (y – номер формы таблицы), type – тип данных. Вычисляет максимальное значение среди одного поля всех документов таблицы; *sum_t(x, type), где x – номер поля или y.id (y – номер формы таблицы), type – тип данных. Вычисляет сумму значений одного поля всех документов таблицы; **Например:** ''⇒ avg_t(37) – вычисляет среднее арифметическое среди значений поля № 37 таблицы;\\ ⇒ count_t(10.id) – вычисляет количество полей id, таблицы, номер формы которой - 10;\\ ⇒ min_t(37, long) – вычисляет минимальное значение поля № 37 как long, таблицы;\\ ⇒ max_t(37, timestamp) – вычисляет максимальное значение поля № 37 как timestamp, таблицы;\\ ⇒ sum_t(37, integer) – вычисляет сумму значений поля № 37 как integer, таблицы.\\ '' ==== 4.4. generator(field, dim) или gen(field, dim) – генерирует новый номер документа. ==== Field – номер поля, в котором хранится номер документа, dim – тип периода времени: day, week, month, year. Dim служит для указания периода повторения номеров.\\ Возвращаемый тип данных - long; **Например:** ''⇒ gen(10, week). Генерирует номер для поля 10 с периодичностью в неделю.\\ ⇒ generator(12, year). Генерирует номер для поля 12 с периодичностью в год'' ==== 4.5. add_date(${parent.512.452.41}, -7, month). Отнимает от даты (значение берется из поля if(eval, x, y) - функция "если". ==== Классическое условие: если eval, то вернуть x, иначе - вернуть y. ==== 4.6. add_date(date, val, dim) – прибавляет к дате заданное количество единиц. ==== Допустимые значения параметра dim: milisecond, second, minute, hour, day, week, month, year.\\ **Например:**\\ ''⇒ add_date('10.02.1975', 5, week). Прибавляет к дате 5 недель.\\ ⇒ add_date(${parent.512.452.41}, -7, month).\\ Отнимает от даты (значение берется из поля родительского документа) 7 месяцев. ⇒ add_date(${512}, ${587}, year). Прибавляет к дате из поля 512 значение поля 587, выраженное в годах.\\ ==== 4.7.diff(date1, date2, dim) - функция вычисления расстояния между датами в заданных единицах.'' ==== Если date1 > date2 - результат позитивный, в противном случае - негативный. Допустимые значения параметра dim: milisecond, second, minute, hour, day, week, month, year. Например: ''⇒ diff('10.02.1975', '25.02.2005', week). Возвращает разницу между двумя датами (заданы константами), выраженную в неделях. ⇒ diff(${parent.512.452.41}, '25.02.2005', month). Возвращает разницу между двумя датами (поле и константа), выраженную в месяцах. ⇒ diff(${512}, ${587}, year). Возвращает разницу между двумя датами (значение из полей), выраженную в годах.'' ==== 4.8. find(val, searchId, resultId, type) - ищет заданное значение в поле и возвращает значение другого поля, найденного объекта. ==== val - искомое значение или ссылка на поле, в котором это значение.\\ searchId - номер поля, где ищем (число).\\ resultId - номер поля, из которого извлекаем данные или id для получения ID объекта\\ type – тип данных значения, которое ищет функция.\\ **Например:**\\ ''⇒ find(test string, 1253, id, string). Возвращает ID объекта в поле №1253 которого, имеется значение test string (как string).\\ ⇒ find(true, 6787, 3847, boolean). Возвращает значение поля №3847 объекта, поле № 6787 которого равно true (как boolean).\\ ⇒ find(${343}, 153, 9874, date). Возвращает значение поля №9874 объекта, поле №153 которого равно значению поля №343 (как date).''\\ ==== 4.9. between(val, startId, endId, resultId, type) - ищет объект, имеющий два поля, которые описывают диапазон, в который попадает заданное значение, и возвращает значение другого поля этого объекта. ==== val - искомое значение или ссылка на поле, в котором это значение.\\ startId - номер поля, где записаны начальные значения диапазонов.\\ endId - номер поля, где записаны конечные значения диапазонов.\\ resultId - номер поля, из которого извлекаем данные или id для получения ID объекта.\\ type – тип данных значения, которое ищет функция.\\ **Например:**\\ ''⇒ between('12.10.1975', 1253, 1254, id, date). Осуществляет поиск вхождения даты 12.10.1975. Диапазон указан в полях №1253 и №1254. Результирующее значение – ID объекта.\\ ⇒ between(235, 251, 252, 253, integer). Осуществляет поиск вхождения числа 235. Диапазон указан в полях №251 и №252. Результирующее значение – значение поля №253 объекта.\\ ⇒ between($(235), 251, 252, 253, string). Осуществляет поиск вхождения значения поля №235. Диапазон указан в полях № 251 и № 252. Результирующее значение – значение поля № 253 объекта.\\ '' ==== 4.10. exchange(currency, relevance) - ищет информацию об обменном курсе валюты (currency) на указанную дату (relevance). ==== Синоним названия - ex_rate. Currency может быть как строкой с кодом валюты, так и числом со значением ID для нужной валюты. **Например:**\\ ''⇒exchange(usd, '12.10.2015'). Осуществляет поиск обменного курса для американского доллара на дату '12.10.2015.\\ ⇒ ex_rate(3, '10.11.2016'). Осуществляет поиск обменного курса для евро (ID = 2) на дату '10.11.2016.'' ===== 5. Пример получения коэффициента страховки, в зависимости от возраста человека на момент начала страховки. ===== ==== 5.1. Создаем справочник, в котором храним зависимость возраста и коэф., поля: ==== * название (# 523) * от (# 524) в годах * до (# 525) в годах * коэф (# 526) в абсолютных единицах ==== 5.2. Заносим значения справочника: ==== * "до 14", 0, 14, 0.5 * "15-18", 15, 18, 0.75 * "19-35", 19, 35, 1 * "36-50", 36, 50, 1.25 * "51-75", 51, 75, 1.5 * "76 и старше", 76, 150, 2 ==== 5.3. В документе создаем поле-ссылку на справочник контрагентов (№ 1235) и поле начала действия страховки (№1236). ==== ==== 5.4. Дата рождения рождения находится в поле № 222 справочника контрагентов. ==== ==== 5.5. Формула будет иметь вид: between(diff($(1236}, ${1235.222}, year), 524, 525, 526, integer) ==== Она вернет значение коэффициента страховки, в зависимости от возраста контрагента на момент начала страховки.