声明变量: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"]);

变量名与表/字段 ID 的混淆

Ninox 保存代码的格式与屏幕上显示的略有不同。具体来说,字段名和表名会被替换成它们的 ID,也就是字母。

例如,下面这段计算已售商品总额的脚本:

Ninox
sum('Invoice Items'.Total)

在系统代码中会保存成下面这样,其中 D 是表 'Invoice Items' 的 ID,E 是字段 Total 的 ID:

Ninox
sum(D.E)

在这种情况下,如果创建了一个名为 D 的变量,就可能让编译器产生混淆,因为下面的系统代码无法分辨 D.E 指的是一个表,还是先前声明的变量 D:

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

为避免这类混淆,变量的命名应尽量不与表或字段的 ID、以及表名或字段名重合。这正是变量常常采用简短小写名称(例如 a、b 或 c)的原因,以免与 ID 混淆。

谁占上风:变量,且没有任何提示

Ninox 不会给出任何提示:代码一旦保存,变量就会压过具有相同 ID 的字段。例如,在一个数据库中,表 Sessions 的字段 Number 的 ID 为 B:

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

这段代码会以 (var B := 5; cnt(select A[B = 1])) 的形式保存。重新读取时,过滤条件不再拿字段 Number 与 1 比较,而是拿变量 B 比较:结果为 0,且没有任何错误。若写成 [Number = 5],则会统计所有记录;order by Number 排序也不再按编号排列。(通过 API 在一张 48 条记录的表上实测。)

这个陷阱只在保存之后才会出现:以屏幕上显示的文本(带字段名)进行测试——例如通过 API 发送的查询——可以编译,结果也正确。在保存后重新读取的代码中,原本是字段名的位置仍原样写着 ID B:这正是混淆的迹象(在 Ninox 命令行工具下载的代码中观察到;未在代码编辑器中验证)。

最简单的规则:变量名或参数名绝不要只由一两个大写字母组成(B、KD、A1)。最好使用能说明其内容的小写名称(firstDay、total)。