Формули у тригерах: значення, яке програма рахує сама

15 хв

Правило вміє записати в поле документа постійне значення — одне й те саме для всіх записів. Формули у тригерах знімають це обмеження: замість «завжди VIP» ви пишете «VIP, якщо сума більша за пʼять тисяч, інакше звичайний», і програма підставляє потрібне сама. Механізм крихітний — пʼять функцій і три джерела даних, — і прощає помилки: неправильну формулу не дадуть зберегти, а якщо вона зламається вже на реальному записі, поле просто лишиться без змін.

Вікно
«Автоматичні правила» → картка правила → команда
Право доступу
те саме, що й на вікно правил — окремого права у формул немає
Підготувати
готове правило з командою, яка змінює або створює запис

Шлях від нуля до працюючої формули

  1. Відкрити картку правила й перейти до командиАвтоматичні правила
  2. Вибрати ліворуч поле, яке треба заповнитиНалаштування команди
  3. Написати у значенні формулу, що починається з @Налаштування команди
  4. Натиснути «Зберегти умову» й перевірити на одному записіНалаштування команди

Де це у програмі

Окремого вікна у формул немає. Вони живуть усередині команди правила — у тому самому конструкторі, яким збирається умова, але прочитаному інакше: ліворуч поле, праворуч значення, яке треба записати. Оператор посередині в цьому режимі не використовується.

Меню
пункту меню немає
Шлях
список документів або контрагентів → меню в шапці → «Автоматичні правила» → олівець на правилі → секція «Команда» → олівець на команді
Підказка в інтерфейсі
під конструктором є пам'ятка з назвами джерел і чотирма прикладами — там же видно, як пишеться поле
Збереження
кнопкою «Зберегти умову» під конструктором; сама картка правила зберігається автоматично, а ось значення полів команди — ні
Перевірка
при збереженні: формулу з помилкою програма не приймає і показує червоне повідомлення «Умову не збережено — помилка у формулі»
Вікно налаштування команди «Змінити дані документа» з трьома рядками конструктора та памʼяткою про формули
1Поле документа, яке заповнюємо
2Значення — тут пишеться формула
3Памʼятка про синтаксис формул
  1. Ліворуч обирається поле документа, значення якого буде змінено.
  2. Праворуч — значення поля; текст, що починається з @, Elbuz обчислює як формулу.
  3. Памʼятка нижче пояснює синтаксис формул на прикладах @calc, @if, @concat і @json.

Як влаштоване саме правило — подія, умова, порядок виконання команд і захист від повторного спрацювання — розібрано в посібнику з автоматичних правил. Ця стаття тільки про те, що написати у значенні поля.

Як це працює

Коли правило спрацювало, програма бере кожну пару «поле — значення» з команди й дивиться на перший символ значення. Якщо це @ — значення рахується як формула. Якщо ні — записується як є.

Розбір формули завжди однаковий: після @ має стояти назва функції, одразу за нею — дужка, а останній символ значення має бути закриваючою дужкою. Усередині дужок — параметри через кому. Далі програма підставляє дані замість посилань виду джерело.поле й повертає результат.

Помилки ловляться двічі. Перший раз — при збереженні команди: програма проганяє кожну формулу «вхолосту», підставляючи замість будь-якого поля одиницю. Так знаходяться зламаний синтаксис, невідома функція і сторонні символи в @calc — команда не зберігається, а над конструктором зʼявляється червоне «Умову не збережено — помилка у формулі» з переліком того, що не прийнялося.

Другий раз — коли правило спрацювало на реальному записі. Те, що при збереженні перевірити не можна (поле виявилося порожнім, текстовим замість числа, нульовим дільником), вилазить тільки тут. У цьому випадку поле не змінюється зовсім — старе значення лишається на місці, а в журналі операцій самого запису зʼявляється рядок «Формулу не розібрано, поле не змінено» з назвою правила, команди й самою формулою. Решта полів команди записуються як звичайно.

НіТакНіТакТакНі: текст замість числа,порожнє поле, ділення нанульЗначення поля в командіПерший символ — «@»?Записується як звичайнийтекстРозбирається як формулаСинтаксис цілий?Перевірка при збереженні:замість полівпідставляється одиниця«Умову не збережено —помилка у формулі».Команда не зберігаєтьсяКоманда збереженаПравило спрацювало назаписі:формула рахуєтьсяреальними данимиОбчислення вдалося?Значення записується вполеПоле лишається зі старимзначенням.У журналі операцій запису—«Формулу не розібрано,поле не змінено»
Дві точки, у яких може зламатися формула, і два різні наслідки: у першому випадку не збережеться команда, у другому — мовчки не зміниться поле

Значення, яке починається з @, але не є формулою, програма теж спробує обчислити — і не дасть зберегти команду. Якщо вам треба записати в поле текст на кшталт @shop, поставте перед ним пробіл або будь-який інший символ.

Сім команд, у яких формули працюють

Формула обчислюється не в будь-якому полі правила, а тільки там, де команда записує значення в поле запису:

  • «Змінити дані документа» і «Створити документ»;
  • «Змінити дані контрагента» і «Створити контрагента»;
  • «Створити організацію» і «Змінити дані організації»;
  • «Додати завдання».

У решті команд формул немає зовсім. У «Надіслати листа», «Надіслати SMS» і «Виконати HTTP-запит» дані запису підставляються макросами у фігурних дужках — {Документ: № документа} або коротко {{d.document_number}}, {{pc.name}}, {{cn.name}}. Символ @ там залишиться звичайним текстом. Команда «Запустити процес (Flow)» значень полів не задає взагалі — вона тільки вибирає процес.

Два поля в цих командах поводяться не як усі, і формула на них теж поширюється:

  • поле проводки в командах з документами не записує текст, а проводить документ. Формулу туди не ввести: у конструкторі це список «Так / Ні», а не рядок вводу;
  • поле типу документа в команді «Створити документ» задає, у який тип копіювати. Ввести формулу можна, але не варто: формула, що дала порожньо, мовчки зупинить команду — нічого не створиться.

Так само мовчки зупиняються «Створити контрагента» без імені й «Додати завдання» без назви — це захист від порожніх карток, але виглядає він як «правило не спрацювало».

Джерела даних: document, contractor, company

Дані беруться з трьох джерел, і звертаються до них через крапку:

  • document.поле — документ, через який спрацювала подія;
  • contractor.поле — його контрагент (а якщо подія була на контрагенті — сам контрагент);
  • company.поле — ваша організація з документа.

Перші два доступні в усіх семи командах. Джерело company. — лише в командах «Додати завдання», «Створити контрагента», «Створити документ» і «Змінити дані організації»; у решті воно поверне порожньо.

Джерела field. у тригерах не існує, хоча воно згадується в старих прикладах. Будь-яке field.щось завжди дасть порожній рядок, а всередині @calc порахується нулем. Джерела user. немає теж.

Порожнім джерело буває й законно: якщо подія піднялася на контрагенті, документа в ній немає, і всі document. дадуть порожньо. Те саме з company., якщо в документі не вказана ваша організація.

Пʼять функцій

@if — умова

Синтаксис: @if(умова, значення_якщо_так, значення_якщо_ні). Умова пишеться строго як джерело.поле оператор значення, і пробіли навколо оператора обовʼязкові. Оператори: equals, contains, >, <, >=, <=, !=.

Будь-яка умова, яку не вдалося розібрати, вважається невиконаною — програма мовчки бере третій параметр. Саме тому @if(document.document_sum>5000, 'VIP', 'Звичайний') без пробілів завжди повертає «Звичайний», хоча виглядає правильно.

contains шукає підрядок з урахуванням регістру: contains 'терміново' не знайде слово «ТЕРМІНОВО». equals порівнює нестрого, тому '5' і 5 для нього однакові.

@calc — арифметика

Синтаксис: @calc(вираз). Дозволені цифри, десятковий дріб через крапку, дужки й знаки + - * /. Посилання на поля підставляються значеннями до обчислення, тому @calc(document.document_sum * 1.2) на сумі 1000 дасть 1200.

Три випадки, у яких @calc відмовиться рахувати — команда при цьому не обривається, просто це поле лишиться без змін:

  • у полі текст, а не число: @calc(document.description * 2) дасть помилку «Поле document.description не число»;
  • ділення на нуль: @calc(100 / document.delivery_price), якщо вартість доставки нульова;
  • функції й інші символи: ніяких відсотків, ком замість крапки й імен функцій — тільки чотири дії.

Незаповнене поле помилкою не вважається: воно рахується нулем. @calc(document.document_sum + contractor.discount_percent) на контрагенті без знижки поверне просто суму документа.

@concat — склеїти текст

Синтаксис: @concat(частина, частина, …), скільки завгодно частин. Текст береться в одинарні лапки, посилання на поля — без лапок. Пробіли всередині лапок зберігаються, між параметрами — ні.

@concat('Замовлення від ', contractor.name, ' на суму ', document.document_sum) дасть «Замовлення від ТОВ Ромашка на суму 1000».

@json — дістати значення з JSON

Синтаксис: @json(джерело.поле, 'ключ'). Так читаються поля, у яких лежить JSON — насамперед додаткові поля документа й контрагента. Якщо в полі {"16":"test1","17":"443355"}, то @json(document.custom_field_ext, '17') поверне 443355.

Читається тільки верхній рівень: вкладеність через крапку не підтримується. Якщо ключа немає або в полі не JSON, результат — порожній рядок, і ніякої помилки при цьому не буде.

@field — просто значення поля

Синтаксис: @field('джерело.поле'), шлях обовʼязково в лапках. Це найкоротший спосіб перенести значення з одного запису в інший: @field('contractor.phones') покладе в поле телефон контрагента.

Без крапки у шляху (@field('name')) функція поверне порожньо — джерело вказувати обовʼязково.

Формула всередині формули

Гілки @if і аргументи @concat, @json, @field самі можуть бути формулами. Так збирається логіка, яка однією функцією не виражається:

  • @if(contractor.customer_type equals 'VIP', @calc(document.document_sum * 9 / 10), document.document_sum) — знижка десять відсотків тільки VIP-клієнтам;
  • @concat('Клієнт: ', contractor.name, @if(document.document_sum > 5000, ' (великий)', '')) — приписка тільки до великих замовлень.

Рахується лише та гілка, яку вибрала умова. Тому у другій гілці можна залишити дію, яка на цьому записі заздалегідь неможлива — наприклад ділення на поле, яке в частини записів нульове: поки умова туди не заводить, помилки не буде.

Звідки брати імена полів

У лівому списку конструктора поля названі по-людськи, а у формулі потрібне службове імʼя — те саме, що використовується в коротких макросах HTTP-запиту ({{d.document_number}}). Найчастіше потрібні:

  • документ: document_number — номер, document_sum — сума, description — примітка, tag — мітка, delivery_price — вартість доставки, email, phone, custom_field_ext — додаткові поля, document_status_name — статус, contractor_name — назва контрагента;
  • контрагент і організація: name — назва, phones і email — контакти, description — опис, discount_percent — знижка, customer_type — тип клієнта, contractor_group_name — група, code_iin — податковий код.

Імені, якого немає, програма не помітить: document.neisnuiuche тихо дасть порожній рядок. Перевірка при збереженні цього теж не ловить: неіснуюче поле для неї виглядає як звичайне. Перевіряють одним прогоном на тестовому записі — якщо поле заповнилося порожнім, справа майже завжди в імені.

Окремо працює поле терміну в команді «Додати завдання»: крім формул, воно розуміє підстановки дат — {current_date}, {current_date+3day}, {current_date+1week}. Одиниці ті самі, що й в умовах правила: minute, hour, day, week, month, year.

Готові формули

Усе нижче перевірене й працює як написане.

  • Позначити великі замовлення: поле «Мітка» → @if(document.document_sum >= 10000, 'VIP', 'Звичайний').
  • Термінові за приміткою: поле «Мітка» → @if(document.description contains 'терміново', 'Терміново', 'Звичайно').
  • Перенести телефон клієнта в документ: поле «Телефон» → @field('contractor.phones').
  • Зібрати назву завдання: поле «Назва задачі» → @concat('Передзвонити: ', contractor.name, ' · ', document.document_number).
  • Дістати код із додаткових полів: @json(document.custom_field_ext, '17').
  • Порахувати суму з націнкою двадцять відсотків: @calc(document.document_sum * 1.2).
  • Скопіювати статус оплати в примітку доставки: @concat('Оплата: ', document.payment_status_name).
  • Знижка тільки постійним клієнтам: @if(contractor.customer_type equals 'Постійний', @calc(document.document_sum * 0.95), document.document_sum).
  • Очистити поле: значення null без жодного @ — програма запише порожньо навмисно.

Небезпечні місця

Пробіл у кінці значення. Формула має закінчуватися дужкою: якщо після неї залишився пробіл, розбору не буде. Такий пробіл легко з'являється при копіюванні, а на вигляд його не видно — зате команда не збережеться, і в повідомленні ви побачите свою формулу цілком.

Умова без пробілів навколо оператора. Це єдина помилка, яку перевірка при збереженні пропускає: @if(document.document_sum>5000, …) — синтаксично правильна формула, вона просто завжди йде в гілку «інакше». Помітити можна лише за результатом.

Формула в полі, яке заповнюється зі списку. Статус документа, тип оплати, валюта, проводка — у конструкторі це випадні списки, а не рядок вводу: формулу туди не набрати. Формули пишуться тільки в текстових і числових полях.

І найтихіше з усього: команда, у якій формула зламалася на реальному записі, все одно вважається виконаною. Правило запамʼятає, що вже відпрацювало на цьому документі, і вдруге його не чіпатиме — навіть після того, як формулу виправлять. Тому перевіряти виправлення треба на новому записі, а не на тому самому.

Чого формули не вміють

  • Немає функцій дати, обрізання тексту, заміни підрядка, округлення й переведення регістру.
  • Немає звернення до позицій документа: document. бачить тільки шапку.
  • Немає читання інших записів — сусіднього документа, залишку на складі, попереднього замовлення клієнта.
  • Немає порівняння двох полів між собою: праворуч від оператора в @if має стояти значення, а не друге поле.
  • Немає окремої перевірки «поле порожнє»: пишеться як equals '', і для тексту це працює, а от нуль у числовому полі порожнім не вважається.
  • Перевірка при збереженні не бачить даних запису: пробіли в умові, ділення на поле, яке в частини записів нульове, і невірне імʼя поля вона пропускає.

Розбір частих проблем

«Умову не збережено — помилка у формулі»
формула не розібралася. Перевірте: перший символ @, останній — ), назва функції з пʼяти дозволених, немає пробілу в кінці. У самому повідомленні перелічені формули, які не прийнялися.
Поле лишилося з колишнім значенням
формула зламалася вже на записі. Причина — рядком у журналі операцій цього документа чи контрагента: «Формулу не розібрано, поле не змінено». Найчастіше це @calc над текстовим полем або ділення на нуль.
Завжди підставляється друге значення з @if
умова не розібралася й вважається невиконаною. Найчастіше через відсутні пробіли навколо оператора або через невірне імʼя поля.
@json повертає порожньо
або ключа немає на верхньому рівні, або в полі не JSON. Вкладені ключі функція не читає.
Документ не створився
формула в полі типу документа дала порожньо. Тип має бути заданий обовʼязково, і краще — постійним значенням.
У поле треба записати текст із собачкою
не вийде: значення з @ на початку програма вважає формулою і команду не збереже. Поставте перед текстом пробіл.

Часті запитання

У яких полях правила можна писати формули?

Тільки у значеннях полів семи команд: «Змінити дані документа», «Створити документ», «Змінити дані контрагента», «Створити контрагента», «Створити організацію», «Змінити дані організації» та «Додати завдання». В умові правила, у листі, SMS і HTTP-запиті формули не працюють.

Як дізнатися, що у формулі помилка?

Двома способами. Зламаний синтаксис програма знаходить одразу: команда не збережеться, а над конструктором зʼявиться червоне повідомлення з переліком формул, які не прийнялися. Помилки, які видно тільки на даних, — ділення на нуль, текст замість числа — потрапляють у журнал операцій того документа чи контрагента, на якому спрацювало правило, рядком «Формулу не розібрано, поле не змінено».

Чи можна вкласти одну формулу в іншу?

Так. Гілки @if і аргументи @concat, @json, @field самі можуть бути формулами, вкладеність не обмежена. Рахується тільки та гілка @if, яку вибрала умова.

Чи рахує @calc дробові числа?

Так: @calc(document.document_sum * 1.2) на сумі 1000 дасть 1200. Дріб пишеться через крапку. Незаповнене поле у виразі рахується нулем, а текст у полі і ділення на нуль дають помилку — поле тоді лишається без змін.

Чому не працює user.поле з прикладів?

Такого джерела в тригерах немає — як і field.. Доступні лише document., contractor. і company., причому останнє — не в усіх командах.

Як записати в поле текст, що починається з собачки?

Через команду це не вийде: будь-яке значення з @ на початку програма намагається обчислити. Додайте перед ним пробіл або інший символ — тоді значення запишеться як звичайний текст.

Суміжні теми

Чи була стаття корисною?