Статья написана с использованием Renga версии 5.10.48974.0
Теория
Небольшое вступление
Для удобства различия в тексте значений и формул, используемых в свойствах, я буду брать их в такие скобки < >.
Отдельно о записи вида <null> - она будет отражать неинициализированное значение (имеется по умолчанию для определенных типов, также возникает в процессе вычисления формул). Пользователь видит это в окне «Свойства» у экземпляров объектов Renga, как просто отсутствие какого-либо значения. Одним словом, любая ошибка при вычислении значения формулы (причем не важно, в каком месте формулы она возникла) по причине использования некорректного имени свойства/параметра, неправильного применения функций и операторов Renga, несоответствия полученного значения типу свойства и т.д. и т.п. приводит нас в итоге к получению неинициализированного значения.
Далее мы научимся использовать данную концепцию разработчиков Renga, чтобы получить явное указание на отсутствие результата значения или проигнорировать определенное значение. Нетерпеливые, конечно, могут сразу пролистать к практике :))) (она ближе к концу статьи). Ну а я пока продолжу.
1. Краткое рассмотрение типов значений в Renga
По сути, нам для понимания неявного приведения (преобразования) типов нужны будут далее только следующие типы значений: Целое, Действительное, Строка, Булевый, Логический. Ну и конечно же <null>.
Почему?
У Типа Перечисление выходное значение всегда является строковым типом, но с формулами он не работает. Поэтому нам он сейчас не интересен.
Оставшиеся типы: Длина, Площадь, Объем, Масса и Угол сами по себе являются действительными (вещественными) числами, и отдельного интереса не представляют. Но есть один важный нюанс для этих типов:
помимо того, что все они могут иметь нулевое значение, т.е. <0> (не путать с <null>), непосредственно значения Длины и Угла могут быть отрицательными (по значению Длины я сам удивлен). а вот значения Массы, Объема и Площади только положительными (Renga просто не даст ввести пользователю отрицательные значения, а если при расчете данных свойств с использованием формул будет получено отрицательное значение, то на выходе значение будет <null>).
Также нам надо запомнить некоторые моменты в части допустимости неинициализированных значений у типов, а также наличия у них значений по умолчанию.
Идем далее.....
2. Краткое описание принципа работы формул в Renga
Знатокам этот пункт будет не интересен. А вот для новичков, как дополнение к справке Renga по формулам, просто отмечу важный момент:
Формула для свойства срабатывает только на тех экземплярах объектов Renga, где значение данного свойства не было отдельно переопределено пользователем. Говоря простым языком: как только пользователь ввел свое значение в свойство, заданное изначально формулой, на каком-либо экземпляре объекта в модели – формула перестает работать для данного экземпляра (используется введенное пользователем значение), пользователь удалил свое значение – формула снова заработала (виден результат формулы).
При этом в формуле мы можем также явно указать какое-либо нужное нам значение (без необходимости его вычисления через формулу). Запомните данную информацию – она нам еще понадобиться.
Также для новичков, в дополнении к справке Renga по ссылкам в формулах, повторю некоторые моменты, о которых уже писал в группе:
1. Ссылки с использованием фигурных скобок { } применяются только в формулах у свойств строкового типа. В других типах свойств их ставить НЕ НАДО!
2. Все, что указанно в { } не обязательно должно быть только ссылкой на какое-то свойство (первоначальная ошибка новичков). В фигурных скобках также указываются любые (!!!) вычисляемые значения, т.е. результаты математических операций, функций, операндов и т.д. вместе с содержащимися в них значениями и именами свойств/параметров.
3. Все, что будет указано вне скобок { }, станет обычным текстом (символами) в строке.
Просто банальные примеры для новичков:
{Свойство1+Свойство2} - будет сложение значений свойств с преобразованием результата в строку.
{Свойство1}+{Свойство2} - будет строка вида Значение1 + Значение2, т.е. сложения не будет, так как здесь + трактуется уже как символ, а не как арифметический оператор.
{Свойство1 == 2 ? 6 : 25} - выражение просчитается корректно.
{Свойство1} == 2 ? 6 : 25 - часть "== 2 ? 6 : 25" так и запишется, как текст.
3. Неявное приведение (преобразование) типов в формулах Renga. Начинаем погружение
Итак. Те, кто знаком с программированием, знают, что такое явное и неявное приведение типов. Остальным для общего интереса (но не обязательно) можно просто погуглить на эту тему. А пока итог:
Renga при расчете формул использует неявное приведение типов значений между собой
Определимся сразу, что под числовыми типами далее я подразумеваю Целое, Действительное, Длина, Масса, Объем, Площадь, и Угол.
Под строковым типом - только Строка (результат Перечисления - как строковый тип, нам все-также не интересен). Ну а с Булевым и Логическим и так понятно.
Итак. Поехали....
- <null> (неинициализированные значения свойств, а также результаты ошибочных операций, считаем его нетипизированным значением )
- Приведение к числовым типам: нет приведения, результат также будет <null>, все формулы и операции у данных типов в результате всегда дают <null>.
- Приведения к Булевому и Логическому типу: по сути приведения не будет, но так как данные типы не могут иметь неинициализированное значение, то наличие <null> будет вырождаться в значение <Нет>.
- Приведение к строковому типу: будет приведение к пустой строке (нулевой длины) именно в месте возникновения <null>, т.е. остальная часть значения строки, полученной из формулы, отобразиться корректно. Если же в результате всех операций в формуле итоговое значение ожидается <null>, то итоговое значение строки также будет пустой строкой нулевой длины, но уже не <null> (визуально пользователь это не отличит, но через метод HasValue() в API видно, что строковое значение теперь инициализировано).
- Булевый (нам он очень важен)
- Приведение к числовым типам: <Нет> это <0>, <Да> это <1>.
- Приведение к строковому типу: Нет и Да (как написано значение, так и будет написано текстом).
- Приведение к Логическому типу: без изменений, т.е. <Да> это <Да>, <Нет> это <Нет>.
- Логический (нам не особо полезен, просто указал его)
- Приведение к числовым типам: <Нет> это <0>, <Да> это <1>, <Неизвестно> это <2>.
- Приведение к строковому типу: Нет, Да и Неизвестно (как написано значение, так и будет написано текстом).
- Приведение к Булевому типу: без изменений <Да> и <Нет>, <Неизвестно> станет <Да>.
- Числовые типы
- Приведение к Булеву типу: <0> это <Нет>, любые остальные значения, в т. ч. отрицательные это <Да>.
- Приведение к строковому типу – число, отформатированное в соответствии с региональными настройками системы (региональным форматом данных в окне Административные языковые параметров ). Но здесь есть один нюанс - в русских региональных настройках используется пробел (код символа 32), а Renga использует неразрывный пробел (код символа 160), чтобы не было переноса части числа на новою строку при заполнении данных в спецификации.
- Строковые типы
1. Приведение к числовым типам: возможно приведение только значений, содержащие одни лишь цифры и пробелы, расположенные в строго определенных местах. Отсутствие значения в строковом типе (<null>) или наличие только пробелов в значении не преобразуются в числовой тип, а только в <null>. Прочее преобразование работает так:
- концевые пробелы (до и после числа, указанного цифрами), обрабатываются корректно, т.е. значения строки вида < 156 > преобразуется в число <156>;
- пробелы, разделяющие количество тысяч, миллионов и т.д., обрабатываются корректно. Т.е. значения строки вида <12 456> обработаются корректно в число <12456>;.
- пробелы в иных местах не дают преобразования, т.е. значение строки вида <12 5> не обработается (будет <null>);
- наличие точки или запятой в разделителе разрядов целой и дробной части не влияет на корректность приведения к Действительному (вещественному) типу, т.е. значения строк вида <156.56> (с точкой) и <156,56> (с запятой) преобразуются одинаково в число.
2. Приведение к Булеву типу: используется вырождение <null> в <Нет>, любые иные значения строк, из которых можно получить числа - в полном соответствии с приведением числовых типов к Булеву (описано уже ранее).
Практика
Отмечу, что неявные преобразования туда/обратно <null> и Булевого типа позволяют реально творить некоторые "чудеса".
Вы точно все поняли из теории? Или все это уже знали? А применяли ли на практике? Сейчас проверим :)))
Для удобства чтения формул я буду использовать у свойств простые названия, содержащие в себе именно наименование/название типа. А теперь приступим.
Пример № 1 (числовые свойства)
Любите писать в формулах у числовых свойств что-то наподобие Булево ? 1 : 0 или Число > 10 ? 1 : 0 ? Напишите просто Булево или Число > 10.
Пример № 2 (числовые свойства)
Нужно получить сумму, например, трех чисел, каждое из которых должно учитываться только при определенных условия? Напишите Булево1*Число1 + Булево2*Число2 + Булево3*Число3.
Пример № 3 (делаем для свойств значения по умолчанию)
Часто пользователи используют для ручного задания каких-либо значений (без использования формул) свойств с типами, имеющими по умолчанию неинициализированное значение, т.е. <null>. При этом предполагается, что данные свойства должны быть обязательно заполнены. А еще бывает так, что потом значения этих свойства уже используются далее в формулах.
Хм... А что нам мешает для таких свойств тоже использовать формулу, но только прописать в ней стразу определенное значение, которое будет использоваться как значение по умолчанию? Пишите сразу в формулу что-то наподобие <число>, <какой-то текст> и т.д. Теперь там, где надо, пользователь введет свое значение, отличное от значения по умолчанию. Не надо? Оставит имеющееся. Надо быстро сменить значение по умолчанию: зашли в формулу и сменили значение. Также любые иные формулы, содержащие ссылки на такие свойства, перестанут давать по итогу ошибки (результат <null>) по причине отсутствия у данных свойств не инициализированных значений.
Пример № 4 (прячем/показываем значения у числовых типов)
Временами пользователю необходимо, чтобы только в определенных ячейках спецификации были расчетные числовые значения, а там где значение <0>, ничего бы не показывалось.
У вас еще не созрел план, как превратить значение <0> в <nulll>? Значит вам надо познакомиться с некоторыми "мега-формулами" в Excel. А пока просто пишем в формуле Число/Булево (число делим на булево значение), где Булево задает показ значения. При значении <Да> результат - Число. При значении <Нет> итоговый результат уйдет в <null> и не отобразиться как значение в ячейке. Под Числом я подразумеваю как ссылку на числовое свойство, так и операцию по расчету числового значения (например, (156*Число1+2,45)/Булево).
Пример № 5 (прячем/показываем числовые значения в строках)
По умолчанию любое числовое значение просто так нельзя спрятать в строке. Но мы то уже знаем, что <null> в строковом типе (в месте получения результата <null>) будет приведен к пустой строке (строке с нулевой длиной).
Допустим, мы хотим иметь возможность местами отображать значение строки (просто условный пример) в виде <Текст1> или <Текст25>, а местами просто <Текст>. Хорошо.
Пишем в формуле для строки Текст{Число/Булево} (внимание, использованы фигурные скобки). При значении <Нет> у Булево получим только значение <Текст>.
Можно также комбинировать получение различных цифр/чисел в строке отдельными разрядами вида {Число1/Булево1}{Число2/Булево2} и т.д. и т.п..
Пример № 6 (создаем свойство, контролирующее корректность расчета всех вычисляемых значений у свойств с числовым типом)
Просто включаем фантазию. Имеем, например, три расчетных свойства числового типа Расчет_Число1, Расчет_Число2 и Расчет_Число3. А также имеем шанс, что при определенных условиях какие-то из этих значений могут переродиться в <null> (что-то где-то не так указали или не так рассчиталось... и понеслось по цепочке). Хорошо
Создаем Булево свойство с формулой и пишем туда:
Расчет_Число1 + Расчет_Число2 + Расчет_Число3 (сложение не принципиально, используем любые удобные нам арифметические операции).
Если у расчетных числовых свойств имеются конкретные значения, то значение у Булево свойства будет всегда <Да>. Если значение хотя бы одного из свойств вдруг станет неинициализированным из-за ошибки в вычислениях его формулы, то Булево станет <Нет>.
Выводим Булево в спецификацию и отслеживаем экземпляры объектов со сбившимися расчетами.
Пример № 7 (ищем переопределенные пользователем значения результатов формул)
Можно придумывать внесение каких либо значений вместо формулы, но нам проще ввести в данную формулу значение или математическую операцию, вызывающую по итогу <null> (предварительно сохранив/скопировав исходную формулу куда-либо) и далее в спецификации по конкретному свойству среди пустых значений будут видны только значения, заданные пользователем. Примеры для понимания: у Массы, Объема и Площади в формуле записали, например, -1, для иных числовых значений задали формулу 1/0 (единица деленная на ноль), а в строковом типе просто указали пустую ссылку вида {} (фигурные скобки).
Видите? Все просто! Ну и напоследок для новичков:
Прекратите уже мучить выражение (составной оператор) A ? B : C в попытках заставить его работать со стоковыми значениями. Он не работает пока с ними (Ни операнд A, ни B, ни C не понимает строковые значения, введенные напрямую или с помощью имени свойства строкового типа... значение выражения сразу уходит в <null>.
Всем удачи в своих экспериментах.
Для обсуждения статьи: группа в Телеграмм "Эксперименты с Renga".