Объявление переменных: var и let

Объявить переменную можно как через var, так и через let. В отличие от JavaScript, в Ninox между let и var нет разницы в области видимости.

Тип переменной определяется типом присвоенного ей значения:

Ninox
var t := "my text";
var b := false;
var n := 10;

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

Ninox
var b := true;
dialog("Message 1", "Value of b: " + b, ["ok"]);
var b := 12;
dialog("Message 2", "Value of b: " + b, ["ok"]);

Путаница между именами переменных и идентификаторами таблиц и полей

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

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

Ninox
sum('Invoice Items'.Total)

будет сохранён в системном коде так, где D — идентификатор таблицы 'Invoice Items', а E — идентификатор поля Total:

Ninox
sum(D.E)

Если в этом контексте создать переменную D, компилятор может запутаться: по системному коду будет непонятно, обозначает ли D.E таблицу или объявленную ранее переменную D:

Ninox
(var D := "hello"; sum(D.E))

Чтобы избежать такой путаницы, переменным следует давать имена, которые вряд ли совпадут с идентификаторами или именами таблиц и полей. Именно поэтому переменные часто называют короткими строчными именами (например, a, b или c) — так их не спутать с идентификаторами.

Кто побеждает: переменная, без всякого сообщения

Ninox ничего не сообщает: после сохранения кода переменная берёт верх над полем с тем же идентификатором. Пример из базы, где поле Number таблицы Sessions имеет идентификатор B:

Ninox
var B := 5;
cnt(select Sessions[Number = 1])

Этот код сохраняется в виде (var B := 5; cnt(select A[B = 1])). При повторном чтении фильтр сравнивает с 1 уже не поле Number, а переменную B: результат равен 0, без какой-либо ошибки. С [Number = 5] он посчитал бы все записи; сортировка order by Number перестала бы следовать за номерами. (Измерено через API на таблице из 48 записей.)

Ловушка проявляется только после сохранения: проверка текста в том виде, в каком он отображается, с именами полей (например, запрос, отправленный через API), компилируется и даёт правильный результат. В коде, прочитанном после сохранения, идентификатор B остаётся записанным как есть там, где было имя поля: это признак путаницы (замечено в коде, загруженном инструментом командной строки Ninox; в редакторе кода не проверялось).

Самое простое правило: никогда не давайте переменной или параметру имя из одной или двух заглавных букв (B, KD, A1). Лучше строчные имена, которые говорят, что в них хранится (firstDay, total).