编程公式的方法,介绍及窍门---不看后悔100年

编程公式的方法,介绍及窍门---不看后悔100年

希望能够对大家有所帮助   

如果觉得资料不错的哈 帮忙顶......啊:)

   
编写公式的方法

一个公式中含有一条或多条按顺序执行的语句。根据与公式相关联的对象和其他标准的不同,公式可以在所选的文档上运行一次或多次(每个文档运行一次)。

除了从公式返回以外,公式中没有循环和控制跳转的语句。公式中对条件执行路径也有限制。

代理公式将在选定的文档上多次地、有条件地执行。

您可以:

编写可得出计算结果的公式

以下公式都应该有最后结果:

复制公式 必须得出结果为真 (1) 或假 (0),并且可以应用到数据库的每个文档上。

表单公式 必须得出表单名称。

选择公式 必须得出结果为真 (1) 或假 (0),并且可以应用到视图中的每个文档上。

列公式 必须得出一个可以转换成文本字符串的值。

显示操作公式 必须得出真 (1) 或假 (0)。

弹出式公式 必须得出一个文本串。

窗口标题公式 必须得出一个文本或数字值,除非公式由一个任意类型的单独的域组成。

区段存取公式 必须得出一个姓名或姓名列表。

插入子表单公式 必须得出一个子表单的名称的文本值。

区段标题公式 必须得出一个文本或数字值,除非公式由一个任意类型的单独的域组成。

段落隐藏公式 必须得出真 (1) 或者假 (0)。

缺省值公式 必须得出一个可以存放在当前域中的值。

输入转换公式 必须得出一个可以存放在当前域中的值。

缺省校验公式 必须得出是成功 (1) 还是失败 (0)。

计算域公式 必须得出一个可以存放在当前域中的值。

关键字公式 必须得出一个可以存放在当前域中的值或值的列表。

这些公式可以简单到只有一个域、常量或者函数,也可以包含很多语句、使用临时变量、更改域的内容或者产生一些附加效果。但不论如何,其最后一个语句必须是一个合适的值。

如果关键字 SELECT 没有显式指定的话,它会加在一个逻辑语句之前,这个逻辑语句用来终止复制或选择公式。这些公式运行于数据库(复制公式)或视图(选择公式)的每一个文档上,以确定复制和查看过程中包括或不包括哪些文档。函数 @All 返回一个真值因此公式“SELECT @All”将包括所有文档。

样例:编写得出结果的公式

1. 此样例是标准讨论数据库中“From”域的缺省值公式。它只包含一个返回用户姓名的函数。

@UserName

2. 此样例是一个标准讨论数据库中“Subject”域的输入校验公式。它含有一个 @If 函数,如果“Subject”是空的(用户未输入任何值),它将返回一个失败的值,反之则返回成功值。失败时还将显示一个消息。

@If(Subject = ""; @Failure("You must enter a subject for your document."); @Success)

3. 该样例是标准讨论数据库的“Memo”表单的窗口标题公式。它只有一个语句,但包含有嵌套的 @If 命令。如果当前文档是新的,则窗口标题是“New Memo”。如果当前文档已经存在,并有一个“Subject”域,而且该域非空,则窗口标题将取“Subject”域中的内容(如果文档带有附件,则标题前还会出现“>>”)。如果不存在“Subject”域或该域为空,则窗口标题为创建日期。

@If(@IsNewDoc; "New Memo"; @If(@IsAvailable(Subject) & Subject != ""; @If(@Attachments; "* "; "") + Subject; @Text(@Created)))

编写执行操作的公式

下列公式不产生一个最后的可用结果,但可以改变域值和产生附加动作:

便捷图标公式 触发时执行一次。

代理公式 触发时在一个数据库上执行。一个代理公式运行在数据库中所选的每个文档上,这些文档由 UI 中指定的条件和公式中的 SELECT 关键字所决定。SELECT 关键字缺省是 SELECT @All。

操作公式 触发时在一个视图或表单中执行。

按钮公式 触发时在一个表单、导航器或 RTF 域中执行。

操作热点 触发时在一个表单、导航器或 RTF 域中执行。

样例:编写执行操作的公式

该代理?桓龌凇癕ain”表单的文档中的“Address”域的“Wayside Street”替换成“Wayside Drive”。有效的操作是 FIELD Address 赋值语句。如果 Address 中含有“Wayside Street”,则新的 Address 的内容是将字符串“Wayside Street”左边的字符,加上字符串“Wayside Drive”,然后再加上 Address 中“Wayside Street”右边的字符。否则,Address 将被重置为它的当前值。

SELECT Form = "Main Form";

ws := "Wayside Street";

wd := "Wayside Drive";

FIELD Address := @If(@Contains(Address; ws); @Left(Address; ws) + wd +

@Right(Address; ws); Address)

处理列表

列表就是一个可以包含多个同类型值的命名实体。列表出现在以下几种情况:

允许多值的域可能包含一个列表而非一个单值。

某些函数返回一个列表。

常量可以被指定为一个列表或者是单值。语法是多个单值用冒号分开;例如,"London":"New York":"Tokyo" 就是一个由三个元素构成的字符串列表常量。

由于列表的连接运算具有最高的优先级,所以如果列表元素中的表达式是一个仅用于其自身的表达式的话,它就必须用括号括起来。例如,如果 3 为负数而 4 不是负数的话就应该写成 1:2:(-3):4,而不是 1:2:-3:4 。

并列运算或交叉运算时的列表组合。

列表限制了操作的范围,因为列表操作仅限于每一个列表元素。就象在一个循环中处理数组一样。

以下函数是列表所特有的。

函数 描述

@Elements(list) 确定列表元素的数量。

@Explode(string) 将文本字符串转换成一个文本列表。空格、逗号和分号用于分隔字符串的元素。

@Explode(string; separator) 与上面的函数一样,但第二个参数指定了字符串中的元素的分隔符。

@Explode(string; separator; empties) 与上面的函数一样,但是返回值为 @True ,因为第三个参数包含空的列表元素,其中出现了连续的分隔符。

@Explode(date-range) 将一个日期范围转换成一个日期列表。参数必须是一个时间-日期值;返回值是文本列表。

@Implode(list) 将文本列表转换成文本字符串,用空格分隔各个元素。

@Implode(list; separator) 与上面的函数一样,但是第二个参数指定了字符串中每个元素之间的分隔符。

@IsMember(string; list) 确定一个字符串是否为一个列表的成员。返回真 (1) 或假 (0)。

@IsMember(list1; list2) 确定一个列表是否被包含在另一个列表中。返回真 (1) 或假 (0)。

@IsNotMember(string; list) 确定一个字符串是否不是一个列表的成员。返回真 (1) 或假 (0)。

@IsNotMember(list1; list2) 确定一个列表是否不被包含在另一个列表中。返回真 (1) 或假 (0)。

@Keywords(list1; list2) 在 list1 中找到与 list2 中的单词相匹配的单词。单词分隔符有 " , ? ! ; : [ ] { } < >。

@Keywords(list1; list2; separator) 与上面的函数一样,但第二个参数指定了单词的分隔符。

@Member(value; list) 确定一个值在字符串列表中的位置。

@Replace(list1; list2; list3) 将 list1 中与 list2 相匹配的值用 list3 中对应的值替换。

@Subset(list; n) 从列表中提取出 n 个值。用 -n 表示从右到左提取。

@Unique(list) 从字符串列表中删除重复的值。

@Unique 返回一个随机的,唯一的文本值。

样例:使用列表

1 (并列运算)该样例用并列算法把两个数字列表相加。结果列表中有四个值 11、22、27 和 44。

list1 := 10 : 20 : 30 : 40;

list2 := 1 : 2 : (-3) : 4;

list3 := list1 + list2;

result := @Text(list1) + " + " + @Text(list2) + " = " + @Text(list3);

@Prompt([OKCANCELLIST]; "Result"; ""; ""; result)

2 (交叉运算)该样例用交叉算法将两个列表连接起来。结果列表中有 12 个值:Blue Sedan、Blue Coupe、Blue Van、Blue Truck、Red Sedan 等等最后是 Yellow Truck。

cars := "Sedan" : "Coupe" : "Van" : "Truck";

colors := "Blue" : "Red" : "Yellow";

result := colors + " " *+ cars;

@Prompt([OKCANCELLIST]; "Result"; ""; ""; result)

3 (@Elements) 如果“Categories”域中没有元素,此例将显示一条消息,如果有的话则显示列表。

@If(@Elements(Categories) = 0; @Prompt([OK]; "Categories"; "No categories");

@Prompt([OKCANCELLIST]; "Categories"; ""; ""; Categories))

4 (@Explode) 该样例使用缺省的分隔符空格、逗号和分号,把一个字符串分离成一个列表。结果列表中的值是:Paris、London、Chicago 和 Seoul。

cityList := @Explode("Paris London,Chicago;Seoul");

@Prompt([OKCANCELLIST]; "List of cities"; ""; ""; cityList)

5 (@Explode) 该样例使用分隔符逗号和分号将一个字符串常量分离成一个列表。结果列表中的值为:Paris、London、New York 和 Hong Kong。New York 和 Hong Kong 没有分离成 New、York、Hong 和 Kong,这是因为没有将空格作为分隔符。

cityList := @Explode("Paris,London,New York;Hong Kong"; ",;");

@Prompt([OKCANCELLIST]; "List of cities"; ""; ""; cityList)

6 (@Explode) 该样例在 London 和 New York 之间有一个空条目。如果第三个参数是 @False 或者被忽略,那么多个连续的分隔符将被看作一个。请确信逗号是连续的,没有被空格分隔。

cityList := @Explode("Paris,London,,New York;Hong Kong"; ",;"; @True);

@Prompt([OKCANCELLIST]; "List of cities"; ""; ""; cityList)

7 (@Implode) 该样例将一个列表常量组合到一个字符串变量中,用空格(缺省)作为分隔符。结果字符串中的值为:Minneapolis Detroit Chicago。

city := "Minneapolis" : "Detroit" : "Chicago";

cityString := @Implode(city);

@Prompt([OK]; "Imploded string"; cityString)

8 (@Implode) 该样例将一个列表常量组合到一个字符串列表中,用逗号和空格作为分隔符。结果字符串中的值为:Minneapolis, Detroit, Chicago。

city := "Minneapolis" : "Detroit" : "Chicago";

cityString := @Implode(city; ", ");

@Prompt([OK]; "Imploded string"; cityString)

9 (@Implode) 该样例使用冒号作为分隔符将一个列表域分离成一个字符串。如果 Categories 域中的输入是 Minneapolis, Detroit, Chicago 则结果为:Minneapolis:Detroit:Chicago 。

@Prompt([OK]; "Categories"; @Implode(Categories; ":"))

10 (IsMember) 该代理样例检查所选的文档,看 Categories 列表中是否有 Adjusted,如果有,Categories 将不变化。如果没有,Adjusted 将被添加到 Categories 列表中。

FIELD Categories := @If(@IsMember("Adjusted"; Categories); Categories; @Explode(@Implode(Categories; ";") + ";Adjusted"; ";"));

SELECT @All

11 (@IsNotMember) 该样例检查所选文档,看 Categories 列表中是否有 Adjusted 和 Signed off。如果没有,则两者都被加入到 Categories 列表中。如果两者都已存在,则 Categories 维持原状。

FIELD Categories := @If(@IsNotMember("Adjusted" : "Signed off"; Categories); @Explode(@Implode(Categories; ";") + ";Adjusted;Signed off"; ";"); Categories);

SELECT @All

12 (@Keywords) 该样例查找在 Cities 域中用到了哪个关键字。

keywords := @Keywords(Cities ; "Paris" : "Moscow" : "Tokyo" : "Boston");

@Prompt([OK]; "Keywords"; keywords)

13 (@Member) 该样例让用户从一个列表中选择一个值,并显示该值在列表中的编号。

cars := "Sedan" : "Coupe" : "Van" : "Truck";

car := @Prompt([OKCANCELLIST] : [NOSORT]; "Cars"; "Pick one"; "Sedan"; cars);

n := @Member(car; cars);

@Prompt([OK]; "Your selection is ..."; "Number " + @Text(n))

14 (@Replace) 该样例将 colors 列表中的“red”替换成“scarlet”并将“blue”替换成“turquoise”。

colors := "red" : "blue" : "yellow" : "blue" : "black" : "red";

from := "red" : "blue";

to := "scarlet" : "turquoise";

result := @Replace(colors; from; to);

@Prompt([OKCANCELLIST] : [NoSort]; "Replacement list"; ""; ""; result)

15 (@Subset) 该样例将 New Orleans, London 和 Frankfurt 放到 first3 中,并将 Singapore 和 Sydney 放到 last2 中。

cities := "New Orleans" : "London" : "Frankfurt" : "Singapore" :"Sydney";

first3 := @Subset(cities; 3);

last2 := @Subset(cities; -2);

@Prompt([OKCANCELLIST] : [NoSort]; "First three"; ""; ""; first3);

@Prompt([OKCANCELLIST] : [NoSort]; "Last two"; ""; ""; last2)

16 (@Unique) 该样例返回一个有四个元素的列表:red, blue, yellow 和 black。

colors := "red" : "blue" : "yellow" : "blue" : "black" : "red";

result := @Unique(colors);

@Prompt([OKCANCELLIST] : [NoSort]; "Unique list"; ""; ""; result)

使用条件语句

@If 可以使您根据条件的真假执行不同的语句。这个条件通常是值和值的比较,但也可以是一个常量、一个变量或者一个函数的结果。例如:

如果当前视图是“By Author”,则 @ViewTitle = "By Author" 为真。

如果 Categories 至少有一个元素,@Elements(Categories) > 0 为真。

1 用在条件中时表示真。@True 和 @Yes 都返回 1。如果条件为真,则比较运算和判断条件的函数返回 1 。

0 用在条件中时表示假。@False 和 @No 都返回 0。如果条件为假,则比较运算和判断条件的函数返回 0 。

@If 语句有奇数个参数,必须至少有三个,例如:

条件为第一个参数,如果 @If 有多个条件的话,此后每隔一个参数就是一个条件。

条件为真时,执行的是第二个参数中的语句,如果 @If 有多个条件,则第二个参数以后的每隔一个参数都是一个可执行的语句。

条件为假时执行最后一个参数中的语句。

最简单的 @If 语句有如下的形式:

@If(condition; true statement; false statement)

三个条件的 @If 语句有如下形式:

@If(condition1; true1; condition2; true2; condition3; true3; false)

@If 函数从左到右依次计算,遇到第一个为真的条件就执行对应的语句(也就是接下来的那个参数中的语句)。此后就不再执行任何 @If 中的语句了。如果没有一个条件为真,则执行最后一个参数中的语句。

真值语句和假值语句的形式根据其前后关系的不同而有些变化:

如果 @If 语句是公式中最后一条需要得出结果的语句,则真值和假值语句必须得出一个计算结果。

如果 @If 语句是赋值语句右边的部分,则真值和假值语句必须能得出一个可以存放在左边的域或临时变量中的值。

否则,真值和假值语句必须产生一个操作。

@If 中的真值和假值语句不能包含一个赋值语句。赋值语句左边的部分只能出现在一个公式的最外层。以下语法形式是错误的:

@If(condition; variable := value1; variable := value2)

必须写成:

variable := @If(condition; value1; value2)

@If 语句是可以嵌套的。嵌套的 @If 语句对于解决公式语言有限的逻辑结构问题是很有帮助的,但它会导致复杂的语法表达。

@Do 函数可以使您在一个条件下执行多条语句。

样例:使用条件语句

1. 该代理的例子将 Categories 中元素的数量与 0 比较。如果域中有元素,则不作任何改变(设置成自己的值)。如果域中没有元素,则设置成一个常量字符串。

FIELD Categories := @If(@Elements(Categories) > 0; Categories; "To be supplied ...");

SELECT @All

2. 此窗口标题的样例首先检查 @IsNewDoc 的返回值。如果文档是新的,则窗口标题设置成文本常量“New Topic”。如果文档已经存在,并且当前视图是“AuthorView”的话,窗口标题设置为“Subject”域中的内容。否则,窗口标题就是“Subject”域的内容加上一个表示答复文档数目的字符串。

StandardTitle := Subject + @DocDescendants(" (No Responses)"; " (1 Response)"; " (% Responses)");

@If(@IsNewDoc; "New Topic"; @ViewTitle = "AuthorView"; Subject; StandardTitle)

 

编写消息和取得用户输入的方法

您可以通过以下技术与用户进行交互:

使用 @Prompt 编写消息

用以下形式的 @Prompt 编写消息,与用户交流。

@Prompt([OK]; title; prompt) 显示一个信息对话框,标题文本在对话框的顶部,提示文本在对话框的主体部分。

@Prompt([OKCANCELLIST] : [NOSORT]; title; prompt; default; choices) 将显示一个对话框,标题文本在对话框的顶部,提示文本在对话框的主体部分,选择文本列表在提示文本的下面。这种形式的 @Prompt 主要用于取得输入信息,但也可以用于显示。最后一个参数必须是一个文本列表。prompt 和 default 可以为空。然而,如果该语句不是公式的最后一条语句,而且用户单击了“Cancel”的话,则接下来的公式便不再执行了。如果您想将列表排序的话就不要指定 [NOSORT] 。

非文本值必须用 @Text 转换成文本才能用作 @Prompt 的参数。文本值可以是常量、临时变量、域或者表达式。

样例:使用 @Prompt 编写消息

1. 该样例在对话框中编写一个作为标题的文本常量和一个文本表达式。表达式是文本常量和已转换成文本的日期-时间值的组合。

@Prompt([OK]; "Current time and date"; "The date is " + @Text(@Now; "D0S0") + ". " + "The time is " + @Text(@Now; "T0S1") + ".")

2. 该样例编写一个文本常量作为标题。而对话框的内容是一个文本常量,后面跟一个多值域中的值。

@Prompt([OKCANCELLIST] : [NoSort]; "Field offices"; "Current field offices are located in the following cities:"; ""; Field_offices)

使用 @Prompt 和 @PickList 取得用户的输入

用以下形式的 @Prompt 和 @PickList 交互的取得用户输入:

@Prompt([YesNo]; title; prompt) 显示一个对话框,其中有标题文字、提示文本以及“是”和“否”按钮。如果用户单击“是”,则 @Prompt 返回真 (1),如果用户单击“否”,则返回假 (0)。

@Prompt([YesNoCancel]; title; prompt) 显示一个对话框,其中有标题文字、提示文本以及“是”、“否”和“取消”按钮。如果用户单击“是”,则 @Prompt 返回真 (1),如果用户单击“否”,则返回假 (0),如果用户单击“取消”,则返回 -1 。

@Prompt([OkCancelEdit]; title; prompt, default) 显示一个对话框,其中有标题文字、提示文本和一个用户可以键入信息的方框。@Prompt 将以文本值的形式返回用户的键入信息。如果用户单击“取消”,公式将立即终止。

@Prompt([Password]; title; prompt) 与上面的公式作用一样,只是在用户键入时方框中显示 X ,而不是用户所输入的内容,这是出于保密的考虑。

@Prompt([OkCancelList] : [NoSort]; title; prompt; default; choices) 将显示一个方框,标题文字在框的顶部,提示文本在框的主体部分,文字列表选项在提示文本的下面,并且突出显示缺省选项。最后一个参数必须是文本列表。@Prompt 将返回用户选择的列表元素。如果用户单击了“取消”,该公式将立即终止。如果您想让列表排序的话,请不要指定 [NoSort] 。@DbColumn 可以根据指定数据库中的当前视图的内容来生成一个列表。

@Prompt([OkCancelCombo]; title; prompt; default; choices) 与上面的公式作用一样,但使用的是一个下拉式列表,框中缺省项目位于列表最顶部。

@Prompt([OkCancelEditCombo]; title; prompt; default; choices) 与上面的公式作用一样,但是允许用户在列表上的方框中输入值或者从列表中选取一个值。

@Prompt([OkCancelListMult]; title; prompt; default; choices) 与 OkCancelList 一样,但是允许用户选择多个列表元素并返回一个列表。

@Prompt[(LocalBrowse]; title; filetype) 显示一个对话框,允许用户从本地文件系统中选择名称。标题文本位于对话框的顶部,在对话框主体部分的左边显示一个选择文件的列表框,在它下面是一个文件类型的列表框,在右边是一个选择目录的列表框。对话框中包含“选择”、“取消”和“网络”或“帮助”按钮。filetype 参数是一个文本值,从数字 1 到 3,指定初始化显示的文件类型:"1" 表示 .nsf 文件,"2" 表示 .ntf 文件;"3" 表示全部文件。

@PickList([Custom]:[Single]; server : file; view; title; prompt; column) 显示一个对话框,其中包含标题文本、提示文本以及选项列表。列表中是指定数据库的视图。用户可以选择一个(如果指定了 [Single])或任意数量的元素(如果未指定 [Single])。@PickList 返回所选列表元素的指定列中的值。这有点象用 @DbColumn 来生成一个列表给 @Prompt 的过程。

@PickList([Name]:[Single]) 与上面公式的作用类似,只是数据库是一个通讯录,而视图是“个人”视图。用户可以在 @PickList 对话框中选择通讯录。

当把非文本值用作 @Prompt 和 @PickList 的参数时,必须先通过 @Text 转换成文本。文本值可以是常量、临时变量、域或者表达式。

如果返回值要用作非文本值的话,它还必须再加以转换。

样例:使用 @Prompt 和 @PickList 取得用户的输入

1 (YesNo) 这个输入校验公式向用户查询的 TotalAmount 域。如果用户单击“否”,则出现一个错误消息。

@If(@Prompt([YesNo]; "Is this total within budget?"; @Text(TotalAmount; "C")); @Success; @Failure("Total not within budget"))

2 (OkCancelEdit) 此按钮公式要求用户指定一个服务器和数据库,并打开此数据库。如果用户没有向编辑框中输入信息而直接单击“是”,则返回值是一个空字符串。

server := @Prompt([OkCancelEdit]; "Server"; "Enter the name of a server"; "");

database0 := @Prompt([OkCancelEdit]; "Database"; "Enter the name of a database on " + @If(server = ""; "your workstation"; server); "");

database := @If(@Contains(database0; "."); database0; database0 + ".nsf");

@Command([FileOpenDatabase]; server : database)

3 (Password) 这个域输入校验公式从用户那里取得一个口令。并将此口令与文档中“Password”域的内容相比较。

pass := @Prompt([Password]; "Password"; "What is the password?");

@If(pass = Password; @Success; @Failure("Password incorrect"))

4 (OkCancelList) 此便捷图标公式向用户展示数据库目录中的数据库列表,并打开用户所选的数据库。第一个 @DbColumn 将 Databases by _Replica ID 视图的第 4 列的值的列表放入临时变量 titles 中。第二个 @DbColumn 将 Databases by _Replica ID 视图的第 2 列的值的列表放入临时变量 servers 中。第三个 @DbColumn 将 Databases by _Replica ID 视图的第 3 列的值的列表放入临时变量 databases 中。临时变量 list 将 titles,servers 和 databases 组合起来在 @Prompt 中呈现给用户。然后,该公式将 @Prompt 的返回值分解成服务器和数据库的名称以用在 FileOpenDatabase 命令中。

titles := @DbColumn(""; "doc":"catalog.nsf"; "Databases by _Replica ID"; 4);

servers := @DbColumn(""; "doc":"catalog.nsf"; "Databases by _Replica ID"; 2);

databases := @DbColumn(""; "doc":"catalog.nsf"; "Databases by _Replica ID"; 3);

list := titles + " *-* " + servers + " *:* " + databases;

member := @Prompt([OkCancelList]; "Open Database"; "Select a database"; ""; list);

server := @Left(@Right(member; " *-* "); " *:* ");

database := @Right(member; " *:* ");

@Command([FileOpenDatabase]; server:database)

5 (OkCancelListMult) 此按钮公式向用户展示了一个部门名称及销售总额的列表。用户可以从列表中选择任意数量的元素,公式计算其总和。

departments := @DbColumn(""; "" : "sales.nsf"; "Main View"; 1);

totalSales := @DbColumn(""; "" : "sales.nsf"; "Main View"; 2);

totalsList := @Text(totalSales; "C") + " " + departments;

sumList := @Prompt([OkCancelListMult]; "Total sales by department"; "Select the ones you want to sum"; ""; totalsList);

sum := @Sum(@TextToNumber(sumList)); @Prompt([OK]; "Sum"; @Text(sum))

6 (Custom) 此按钮公式向用户展示 DOC 服务器上的 CATALOG.NSF 中的 Databases by Replica ID 视图。用户从列表(视图)中选择一个元素(行),此公式将打开该行中第 3 列所指定的数据库。

name := @PickList([Custom]; "doc" : "catalog"; "Databases by Replica ID"; "Open database"; "Select a database that is on server Doc"; 3);

@Command([FileOpenDatabase]; "doc" : name)

使用 @DialogBox 填写表单

@DialogBox 将在一个对话框中显示一个设计的表单,其中有“确定”和“取消”按钮。当用户单击“确定”时,对话框中的某个域的内容将被传递到当前文档同名的域中。

@DialogBox 不传递 RTF 文本。在设计时要注意不能包含 RTF 文本。

出现在对话框中的表单最好使用一个区域布局来创建,而且 @DialogBox 应该使用[AutoVertFit] 和 [AutoHorzFit] 选项。

样例:使用 @DialogBox 填写表单

假如您有一个包含很多域的表单,但用户通常在创建文档时只填写其中很少的几个域。这时您可以创建另一个叫做“Dialog”的隐藏表单,在这个表单中包含一个区域布局,其中有用户通常填写的域。在主表单的最上面,您可以创建一个包含下列公式的按钮。当用户单击此按钮时,此公式将使用“Dialog”表单显示一个对话框。用户可以在对话框中填写域然后单击“确定”,于是填写的内容便被传递到主表单中。

@DialogBox("Dialog"; [AutoVertFit] : [AutoHorzFit])

取得和设置环境变量

您可以从 NOTES.INI 文件中设置和提取环境变量(Windows,OS/2 和 UNIX 都适用)。

@SetEnvironment(variable; value) 将一个已命名的变量设置成指定的值。您也可以用 ENVIRONMENT 关键字和双参数形式的 @Environment。

@Environment(variable) 提取一个已命名变量的值。

环境变量的值是文本。非文本值必须在设置值之前和提取值之后转换成文本。

用户环境变量是以 $ 字符开头的。如果您用编辑器或者 LotusScript 添加一个环境变量,此后您还想用 @Environment 提取的话,那么它的第一个字符必须是 $。

请了确信您已经清楚了您的公式将会影响到哪个 NOTES.INI 文件。如果公式在一个服务器数据库中,则以下几种情况下公式是运行在服务器上的:复制公式、由“当一个新邮件到来时执行”和定时执行触发的代理、选择公式或者列公式。否则,公式将运行于用户的工作站上。复本拷贝将根据其所在的服务器或工作站决定访问不同的 NOTES.INI 文件。服务器访问服从于管理限制(请参阅在“Notes 管理帮助”中的“限制服务器上的代理” 或者“管理员指南”)。

环境变量的作用有:

在不同的公式和数据库之间传递临时数据。

为一个用户生成连续的数字。

样例:取得和设置环境变量

1. 该样例将一个数字转换成文本并将其保存在一个环境变量中。

ENVIRONMENT OrderNumber := @Text(NewOrderNumber);

以下公式是等效的。

@Environment("OrderNumber"; @Text(NewOrderNumber);

@SetEnvironment("OrderNumber"; @Text(NewOrderNumber);

2. 该样例提取一个环境变量的值,并将其转换成一个数字并存放在局部变量中。

OldOrderNumber := @TextToNumber(@Environment("OrderNumber");

3. 该样例适用于“创建时计算”域。该公式保留有一个叫“OrderNumber”的环境变量。每当创建了一个新文档时,此公式从环境变量中取得该值然后加一。这种计算法对于一个要进行复制的数据库是不适用的,数据库必须存在于单个服务器或工作站上,而且公式必须运行在相同的机器上。

OldOrderNumber := @Environment("OrderNumber");

NewOrderNumber := @TextToNumber(@If(OldOrderNumber = ""; "0"; OldOrderNumber)) + 1;

ENVIRONMENT OrderNumber := @Text(NewOrderNumber);

NewOrderNumber;

4. 第一个公式被每个销售人员运行一次。该公式提示用户输入销售地区,并将其存放在一个叫“SalesArea”的环境变量中。在销售文档的表单中,您将第二个公式用作 SalesArea 域的缺省值公式。该公式从环境变量中取得值。这样销售人员便不再需要为每个新文档输入销售地区的信息了,而且也避免了在缺省值公式中硬性规定一个销售区域。

ENVIRONMENT SalesArea := @Prompt([OKCANCELLIST]; "Sales Area"; "What is your sales area?"; "Central"; "East" : "Central" : "West");

@Environment("SalesArea");

处理错误的方法

错误有两种类型:

语法错误

当您确认或退出正在编写的公式时可能会出现语法错误的提示。您将接到一条指定错误的消息,有错误的行被突出显示出来。必须查出错误并改正它。通常,语法错误包括:

函数名称或关键字拼写错误

缺少括号或括号多余

字符串常量两边缺引号

语句之间没有分号

您最好在写公式时随时检查。多重嵌套可能会使公式的语法非常复杂。

运行错误

运行错误在公式运行的时候发生。这种错误可分为以下几类:

无法预料的错误 — 这是在开发时出现的错误,您的用户是看不见的。例如,如果遗漏了函数的某个参数,则在运行时将出现以下消息:“函数的参数不够”。应该测试公式尽量修正所有无法预料的错误。

不予汇报的错误 — 这些是错误的结果,但是并不当作错误汇报。例如,如果试图用 @Prompt 来显示一个数字值,@Prompt 可以运行,但显示为空白。您的用户永远也看不见这些错误。应该测试公式,确保所有结果都是正确的。

可以预料的错误 — 这些错误可能是用户在运行公式时造成的。例如,在提示输入一个数据库的名称时,用户输入了一个并不存在的数据库名称。无法阻止这些错误的发生但可以预计得到,或者可以有意测试一下,然后给出适当的解决办法。

以下函数可以帮助您处理运行错误:

@IsError(value),当它发现一个域、临时变量或者表达式中包含错误时就返回 1 。

@Error 生成一个错误。

@Failure(message),在输入校验公式中用来显示消息。

@Success 总是返回 1。

@Return(value) 终止公式的运行并返回一个值。

当一个域内嵌的校验检查失败时,Notes 将产生一个错误。例如,如果将一个域指定为数字型的,而用户输入的是一个非数字型的值,Notes 将把该域的值设置为错误。您也可以设置一个域值为 @Error 来生成错误。

Notes 在用户试图保存文档时汇报域中的错误。例如,如果一个数字域包含一个非数字的值,那么当用户试图保存文档时,Notes 将产生一条消息“不能将文本转换为数字”。

为了在错误发生时改变消息或执行另一个操作,请在域的校验公式中使用 @IsError 来检查域中的错误。可以用 @Failure 生成您自己的消息,但仅仅只是在域校验公式中可以这样做。

为了在一个域中使用您自己的出错条件,请在域转换公式中测试域的值,并在检测出一个错误条件时返回一个 @Error。

除了域公式以外,例如在代理、按钮或者热点中,可以检查域的内容并对错误条件立即作出反应。例如,如果您用一个按钮来检查域,就可以在用户保存文档之前修改域值或者报告错误。在检查错误时,值得注意的是,内嵌的校验机制在用户输入值时马上就可以汇报错误,而使用 @Error 的转换公式直到用户保存文档时才报告错误。

样例:运行错误

1.如果 Price 域中有错误的话,这个校验公式将使该文档保存失败,并显示一条指定的错误信息。

@If(@IsError(Price); @Failure("The Price field must be numeric"); @Success)

2. 此样例包含输入转换和校验公式。如果 Price 域的值大于 14.99 的话,输入转换公式将在 Price 域中放置一个错误。如果发现此错误,输入校验公式它就会使文档的保存操作失败,并显示一条指定的错误信息。

REM "Input translation formula for Price field";

@If(Price > 14.99; @ERROR; Price)

REM "Input validation formula for Price field";

@If(@IsError(Price); @Failure("The Price field must be numeric and 14.99 or less"); @Success)

3. 此按钮公式在对 Price 打折扣之前先检查它是否有错误。如果该域有错误,则该公式返回一个错误信息。

FIELD Price := @If(!@IsError(Price) & @IsNumber(Price) & Price < 15; Price * 0.85; @Return(@Prompt([OK]; "Error in price field"; "Must be numeric and less than 15.00"; "")));

@All

4. 该按钮公式检测 Price 域中是否有错误。如果该域含有错误,则此公式将该域设置成一个通过 @Prompt 从用户那里得到的值。

FIELD Price := @If(!@IsError(Price) & @IsNumber(Price) & Price < 15; Price; @TextToNumber(@Prompt([OKCANCELEDIT]; "Error in price field"; "Enter a number under $15.00"; "")));

@All

使用函数

所有函数都能计算出一个值,并且可以放在公式中任何允许此类型值的地方。当公式执行的时候,公式的值代替了公式的位置。有些公式也有附加效果。例如,@Prompt 会产生一个消息框。

大多数函数可以用于任意 Notes 对象的公式中,但有一些函数却被限制在适当的范围内。以下表格列举了受限的函数,并列举了它们可以用在哪些对象中。此外,您必须进入相应的上下文中才能使函数返回有关当前数据库、视图、文档或者域的信息,也就是说,那些对象必须是当前的。

受限函数 函数只应用于这些 Notes 对象

@All 复制公式、代理、视图选择公式

@AllChildren 复制公式、视图选择公式

@AllDescendants 复制公式、视图选择公式

@Command 便捷图标公式、手动代理、按钮、操作热点

@DbColumn (Notes 数据库) 便捷图标公式、操作、按钮、热点、域设计、代理(除邮件以外)

@DbLookup (Notes 数据库) 便捷图标公式、操作、按钮、热点、域设计、代理(除邮件以外)

@DeleteDocument 代理

@DeleteField 代理

@DocChildren 列公式、窗口标题公式

@DocDescendants 列公式、窗口标题公式

@DocLevel 列公式、窗口标题公式

@DocMark 代理

@DocNumber 列公式、窗口标题公式

@DocParentNumber 列公式、窗口标题公式

@DocSiblings 列公式、窗口标题公式

@Failure 域校验公式

ENVIRONMENT 除弹出式热点公式以外的所有场合

@Environment 除了正在编写的弹出式热点公式以外的场合

FIELD 便捷图标公式、代理、按钮、操作热点、域设计

@IsCategory 列公式

@IsDocBeingLoaded 表单设计、域设计

@IsDocBeingMailed 按钮、热点、域设计

@IsDocBeingRecalculated 按钮、热点、域设计

@IsDocBeingSaved 按钮、热点、域设计

@IsExpandable 列公式

@IsNewDoc 便捷图标公式、按钮、窗口标题公式、表单设计、域设计

@MailSend 便捷图标公式、代理、按钮、操作热点

@PickList 便捷图标公式、手动执行的代理、按钮、操作热点、域设计

@Platform 便捷图标公式、手动执行的代理、按钮、热点、除选择公式和列公式以外的视图设计、表单设计、域设计

@Prompt 便捷图标公式、手动执行的代理、按钮、操作热点、域设计

@Responses 窗口标题公式、域设计

@Return 便捷图标公式、代理、按钮、热点、域设计

SELECT 复制公式、代理、视图选择公式

@SetDocField 便捷图标公式、代理、按钮、操作热点、域设计

@SetEnvironment 除了弹出式热点公式以外的所有场合

@SetField 便捷图标公式、代理、按钮、操作热点、域设计

@Success 校验公式

@Unavailable 代理

@ViewTitle 代理

使用命令

命令就是一些可以用户界面中执行即时操作的特殊函数。大多数命令是模仿与菜单命令的。例如以下公式,如果从按钮执行,就是将当前文档置于编辑模式并将插入点下移两次:

@Command([EditDocument]; "1");

@Command([EditDown]; "2")

命令的语法表示如下:

@Command([command-name]; arg1; arg2; ... argn)

@PostedCommand([command-name]; arg1; arg2; ... argn)

函数名称是 @Command 或者 @PostedCommand。第一个参数是用方括号括起来的命令名称。在帮助导航器中选择“Scripts & formulas”,然后选择“Notes 公式语言命令 A-Z”即可得到一个命令的列表,或者请参阅“程序员指南”的第八章。其他则是命令所带的参数。

您不能在一个不与用户交互的公式中使用命令,如定时代理、域公式或一个后台宏。

您不能在 Web 应用程序中使用大多数的命令,因为它们是基于 Notes 工作站用户界面的。在 Web 应用程序中只能够使用以下命令(在各个命令的描述中分别注明了它的限制):[CalendarFormat]、[CalendarGoTo]、[Compose]、[EditClear]、[EditDocument]、[EditInsertFileAttachment]、[FileCloseWindow]、[FileOpenDatabase]、[OpenDocument]、[FileSave]、[NavigateNext]、[NaviagtePrev]、[NavigateNextMain]、[NavigatePrevMain]、[OpenNavigator]、[OpenView]、[ToolsRunMacro]、[ViewChange]、 [ViewExpandAll]、ViewCollapseAll] 和 [ViewShowSearchBar]、[ViewRefreshFields] 和 [FileOpenDBRepID]。

@Command 函数按顺序和其他函数一起执行,但有一些例外。例如,以下公式就是先执行命令:

@Command([EditDocument]; "1");

@Prompt([OK]; "Edit mode"; "The document is now in edit mode.")

@PostedCommand 函数将在所有其他函数执行完毕后才按顺序执行。这是为了模仿 Notes R3 中的 @Command。例如,以下公式将在最后才执行命令:

@PostedCommand([EditDocument]; "1");

@Prompt([OK]; "Edit mode"; "The document will go into edit mode.")

您可以检查 @Command 的返回值(但 @PostedCommand 不行),并对其作出响应。如果命令执行正确返回值为 @True ,否则返回值为 @False 。以下便捷图标的公式样例在命令 FileOpenDatabase 执行失败时返回。

@If(@Command([FileOpenDatabase]; "NEWSUBJ"); ""; @Return(""));

@Command([Compose]; ""; "Main Topic");

@Command([EditGotoField]; "Subject");

@Command([EditInsertText]; "New subject");

@Command([EditGotoField]; "Body")

执行字符串操作的方法

公式语言函数支持数据类型转换、字符串长度、字符串比较、子串、大小写和修剪等操作。

您可以:

转换数据类型

在对数据操作时类型必须是正确的。以下的函数用来转换数据和测试数据类型。

函数 描述

@Text(value) 将一个值转换为文本字符串。

@Text(value; format) 根据指定的格式将一个数字或时间-日期值转换成文本字符串。

@TextToNumber(string) 将文本字符串转换成一个数字。

@TextToTime(string) 将文本字符串转换成一个日期-时间值。

@IsText(value) 如果值是文本字符串或文本字符串列表,则返回真值 (1) 。

@IsNumber(value) 如果值是数字或数字列表,则返回真值 (1) 。

@IsTime(value) 如果一个值是时间-日期或时间-日期列表,则返回真值 (1)。

@Char(number) 将一个 IBM 代码页 850 代码转换为对应的字符。

样例:转换数据类型

1 (@TextToNumber, @Text)。该样例使用 @Prompt 交互的读取一个数字,计算其对数,并用 @Prompt 交互的显示答案。由于 @Prompt 只能处理文本值,所以输入的值 i 在进行对数计算之前必须转换成数字,答案 n 必须在显示之前必须转换成文本字符串。

i := @Prompt([OKCANCELEDIT]; "@Log Test"; "Enter a number"; "");

n := @Log(@TextToNumber(i));

@If(@IsError(n); @Return(@Prompt([OK]; "@Log Test"; i + " is not a number")); ""); @Prompt([OK]; "@Log Test"; "The logarithm of " + i + " is " + @Text(n))

2 (@Text)。该样例根据日期-时间格式 T1S1 将 @Now 返回的日期-时间值转换成文本。T1 仅指时间,S1 仅指小时和分钟。在晚上六点时,用户可以看到一个信息框,其中的文字以“The time is ...”开头,后面是“06:00 PM”。

@Prompt([OK]; "The time is ..."; @Text(@Now; "T1S1"))

3 (@Text)。该样例根据数字格式 C,2 将数字 800 转换成文本并予以显示。C 表示货币格式(以美元符开头),2 表示保留两位小数。用户看到的信息框中的文字以“800 dollars”打头,后面是“$800.00”。

@Prompt([OK]; "800 dollars"; @Text(800; "C,2"))

4 (@Text, @TextToTime)。此样例将文本字符串“Today”转换成当天的日期,然后将此日期转换成文本供 @Prompt 使用。例如,如果今天是 1995 年 7 月 8 日,用户将看到一个信息框,其中的文字以“Today's Date”开头,后面跟着“07/08/95”。

@Prompt([OK]; "Today's Date"; @Text(@TextToTime("Today")))

5 (@IsNumber)。此样例将域 A 和 B 相加。如果某一个域不是数字型的话,它将被转换成数值 0。因为用户无法在一个数字域中输入非数字的值,所以如果一个数字域是空的,并且没有缺省值公式的话,它的缺省值就是一个空的文本字符串。此公式中的 @IsNumber 函数就避免了这个情况。

@If(@IsNumber(A); A; 0) + @If(@IsNumber(B); B; 0)

6 (@Char)。此样例将整数 65 转换成大写字符 A。

@Prompt([OK]; "IBM Code Page 850 code 65"; @Char(65))

连接、比较和判定长度

+ 运算符用来连接字符串。=、<>、!=、=!、><、<、>、<= 和 >= 运算符用来比较字符串。以下的函数用来判定字符串的长度和比较字符串:

函数 描述

@Length (string) 返回字符串的长度,以字符为单位。

@Length(stringlist) 返回字符串列表中每个元素的长度,以字符为单位。

@Matches (string; pattern) 判定两个字符串是否匹配。可以用通配符来扩展比较的范围。

@Like (string; pattern) 判定两个字符串是否匹配。遵循 ANSI SQL 标准。

@Like(string; pattern; esc) 与上面的一样只是多了一个转义字符。

@Matches 用 ? 来匹配任意一个单独的字符,用 * 来匹配任意的字符序列,此序列中也可以包括其他的通配符。@Like 使用 _(下划线)来匹配任意一个单独的字符,用 %(百分号)来匹配任意的字符序列,符合 ANSI X3.135-1992 标准。@Matches 使用 作为转义字符。

样例:连接、比较和判定长度

1 (+)。该样例连接两个字符串以形成 ABCDEF。

@Prompt([OK]; "Concatenation"; "ABC" + "DEF")

2 (+)。该样例连接两个输入的字符串。

Input1 := @Prompt([OKCANCELEDIT]; "Concatenation - first element"; "Enter any text in the box"; "ABC");

Input2 := @Prompt([OKCANCELEDIT]; "Concatenation - second element"; "Enter any text in the box"; "DEF"); @Prompt([OK]; "Concatenation - result"; Input1 + Input2)

3 (=)。如果两个输入字符串相等,该样例为 YesNo 返回 True,如果不等的话则为 YesNo 返回 False。

Input1 := @Prompt([OKCANCELEDIT]; "Comparison - first element"; "Enter any text in the box"; "ABC");

Input2 := @Prompt([OKCANCELEDIT]; "Comparison - second element"; "Enter any text in the box"; "DEF");

YesNO := @If(Input1 = Input2; "The strings are equal"; "The strings are not equal"); @Prompt([OK]; "Comparison - result"; YesNo)

4 (@Length)。该样例显示 9,即字符串 abcdefghi 的长度。

@Prompt([OK]; "Length of abcdefghi"; @Text(@Length("abcdefghi")))

5 (@Length)。该样例创建一个数字列表。该列表中的每个元素包含 TextList 中相应元素的长度。

@Length(TextList)

6 (@Matches)。如果输入 abc,则该样例在 YesNo 中返回 True。

Input := @Prompt([OKCANCELLIST]; "@Matches Input"; "Choose one"; "abc"; "abc" : "bcd" : "cde" : "xyz" : "123");

YesNo := @If(@Matches(Input; "abc"); " matches abc"; " does not match abc"); @Prompt([OK]; "@Matches Result"; Input + YesNo)

7 (@Matches). 该样例为 YesNo 返回 True,如果输入的每个字符都是字母的话,也就是说,从 a 到 z 的范围内。集合 {a-z} 指定字母的范围,前面的 + 表示任意多个字母。

Input := @Prompt([OKCANCELLIST]; "@Matches Input"; "Choose one"; "abc"; "abc" : "bcd" : "cde" : "xyz" : "123");

YesNo := @If(@Matches(Input; "+{a-z}"); " matches +{a-z}"; " does not match +{a-z}"); @Prompt([OK]; "@Matches Result"; Input + YesNo)

8 (@Matches)。如果每个输入的字符都不是字母,也就是说,在集合 {a-z} 之外,则该样例为 YesNo 返回 True。{!a-z} 表示不在集合 a 到 z 中。前面的 + 表示任意多个字母。

Input := @Prompt([OKCANCELLIST]; "@Matches Input"; "Choose one"; "abc"; "abc" : "bcd" : "cde" : "xyz" : "123");

YesNo := @If(@Matches(Input; "+{!a-z}"); " matches +{!a-z}"; " does not match +{!a-z}"); @Prompt([OK]; "@Matches Result"; Input + YesNo)

9 (@Matches)。如果输入包含由任意数目字符包围的连续的 bc 字符,则该样例为 YesNo 返回 True。

Input := @Prompt([OKCANCELLIST]; "@Matches Input"; "Choose one"; "abc"; "abc" : "bcd" : "cde" : "xyz" : "123");

YesNo := @If(@Matches(Input; "*bc*"); " matches*bc*"; " does not match *bc*"); @Prompt([OK]; "@Matches Result"; Input + YesNo)

10 (@Matches)。如果输入是以 a 开始并且有三个字符长,或者输入以 1 开始并且有三个字符长,则该样例为 YesNo 返回 True。

Input := @Prompt([OKCANCELLIST]; "@Matches Input"; "Choose one"; "abc"; "abc" : "bcd" : "cde" : "xyz" : "123");

YesNo := @If(@Matches(Input; "a??|1??"); " matches a??|1??"; " does not match a??|1??"); @Prompt([OK]; "@Matches Result"; Input + YesNo)

11 (@Like)。该代理检查每个文档中 textBody 域内的两个字符串集合。第一个字符串是顺序包含“acquisition”和“Acme”的任何文本。第二个字符串是顺序包含“Acme”和“51%”的任何文本。第二个 @Like 语句使用斜杠 (/) 作为转义字符,因而可以指定百分号 (%)。不要使用反斜杠 () 作为转义字符。

@If(@Like(textBody; "%acquisition%Acme%"); @Prompt([OK]; "Found reference to "acquisition""; Subject); "");

@If(@Like(textBody; "%Acme%51/%%"; "/"); @Prompt([OK]; "Found reference to "51%""; Subject); "");

SELECT @All

查找并提取子串

以下函数查找并提取子串:

函数 描述

@Contains(string; sub) 判定一个字符串是否包含一个子串。

@Contains(string; list) 判定一个字符串是否包含一个列表中的子串。

@Begins(string; sub) 判定一个字符串是否以一个子串开始。

@Ends(string; sub) 判定一个字符串是否以一个子串结束。

@Left(string; n) 从一个字符串中提取最左边的 n 个字符。

@Left(string; sub) 从一个字符串中提取最左边的字符,直到一个子串为止,从左到右搜索。

@LeftBack(string; n) 从一个字符串中提取最左边的字符,直到从右边开始的第 n 个字符为止。

@LeftBack(string; sub) 从一个字符串中提取最左边的字符,直到一个子串为止,从右到左搜索。

@Right(string; n) 从一个字符串中提取最右边的 n 个字符。

@Right(string; sub) 从一个字符串中提取最右边的字符,直到一个子串为止,从左到右搜索

@RightBack(string; n) 从一个字符串中提取最右边的字符,直到从右边开始的第 n 个字符为止。

@RightBack(string; sub) 从一个字符串中提取最右边的字符,直到一个子串为止,从右到左搜索。

@Middle(string; off; n) 从一个字符串中提取 n 个字符,从一个偏移量开始,从左到右搜索。

@Middle(string; sub; n) 从一个字符串中提取 n 个字符,从一个子串开始,从左到右搜索。

@Middle(string; off; sub) 从一个字符串中提取字符,从一个偏移量开始,到一个子串结束,从左到右搜索。

@Middle(string; sub; sub) 从一个字符串中提取字符,从一个子串开始,到另一个子串结束,从左到右搜索。

@MiddleBack(str; off; n) 从一个字符串中提取 n 个字符,从一个偏移量开始,从右到左搜索。

@MiddleBack(str; sub; n) 从一个字符串中提取 n 个字符,从一个子串开始,从右到左搜索。

@MiddleBack(str; off; sub) 从一个字符串中提取字符,从一个偏移量开始,到一个子串结束,从右到左搜索。

@MiddleBack(str; sub; sub) 从一个字符串中提取字符,从一个子串开始,到另一个子串结束,从右到左搜索。

@ReplaceSubstring(source; from; to) 在 source 中用 from 的内容替换 to 的内容。如果 from 和 to 都是列表,按次序替换对应的项目。

@Word(string; sep; n) 从 string 提取单词 n,其中单词是在指定的分隔符之间的文本。

@Word(list; sep; n) 从列表中的每个字符串中提取单词 n,其中单词是在指定的分隔符之间的文本。

样例:查找并提取子串

1 (@Contains)。如果 Substring 在 String 中的某个地方出现,则该样例为 R 返回 True。该搜索是区分大小写的。

String := @Prompt([OKCANCELEDIT]; "String"; "Enter a string"; "");

Substring := @Prompt([OKCANCELEDIT]; "Substring"; "Enter a beginning substring"; "");

Yes := Substring + " is in " + String;

No := Substring + " is not in " + String;

R := @Contains(String; Substring);

@If(R; @Prompt([OK]; "Yes"; Yes); @Prompt([OK]; "No"; No))

2 (@Contains)。如果 Substring1 或 Substring2 在 String 的某个地方出现,则该样例为 R 返回 True。该搜索是区分大小写的。

String := @Prompt([OKCANCELEDIT]; "String"; "Enter a string"; "");

Substring1 := @Prompt([OKCANCELEDIT]; "Substring"; "Enter substring 1"; "");

Substring2 := @Prompt([OKCANCELEDIT]; "Substring"; "Enter substring 2"; "");

Yes := Substring1 + " or " + Substring2 + " is in " + String;

No := Substring1 + " and " + Substring2 + " are not in " + String;

R := @Contains(String; Substring1 : Substring2);

@If(R; @Prompt([OK]; "Yes"; Yes); @Prompt([OK]; "No"; No))

3 (@Left)。该样例为 R 返回 String 中最左边的 N 个字符。

String := @Prompt([OKCANCELEDIT]; "String"; "Enter a string"; "");

Number := @Prompt([OKCANCELEDIT]; "Number of characters"; "Enter a number of characters"; "");

N := @TextToNumber(Number);

R := @Left(String; N); @Prompt([OK]; "Leftmost characters"; R)

4 (@Left)。该样例为 R 返回 String 中的 Substring 左边的字符。

String := @Prompt([OKCANCELEDIT]; "String"; "Enter a string"; "");

Substring := @Prompt([OKCANCELEDIT]; "Substring"; "Enter a substring"; "");

R := @Left(String; Substring); @Prompt([OK]; "Characters left of " + Substring; R)

5 (@RightBack, @Left)。如果在 ComposedBy 域中的公共名是“Judith Woo”,本公式计算出“Woo, Judith”。@RightBack 返回姓,@Left 返回名。

@RightBack(@Name([CN]; ComposedBy); " ") + ", " + @Left(@Name([CN]; ComposedBy); " ")

6 (@Middle)。该样例为 R 返回 String 中从 Substring 以后开始的 N 个字符。

String := @Prompt([OKCANCELEDIT]; "String"; "Enter a string"; "");

Substring := @Prompt([OKCANCELEDIT]; "Substring"; "Enter a substring"; "");

Number := @Prompt([OKCANCELEDIT]; "Number of Characters"; "Enter the number of characters"; "");

N := @TextToNumber(Number);

R := @Middle(String; Substring; N); @Prompt([OK]; Number + " characters starting after " + Substring; R)

7 (@ReplaceSubstring)。此代理样例对所选文档的 textBody 域作了三个替换。第三个替换是为了避免句子结尾连续出现两个句号。

FIELD textBody := @ReplaceSubstring(textBody; "Acme" : "mousetrap" : ".." ; "Acme, Inc." : "mouse detention device" : ".");

SELECT @All

8 (@Word)。该样例从字符串 s 中提取单词 n ,用空格作为单词分隔符。

s := @Prompt([OKCANCELEDIT]; "String"; "Enter a string of words"; "");

n := @Prompt([OKCANCELEDIT]; "Word"; "Enter the number of the word to extract"; "");

ss := @Word(s; " "; @TextToNumber(n)); @Prompt([OK]; "Substring"; "Word " + n + " is "" + ss + """)

修剪、重复、添加新行,并改变大小写

以下函数修剪字符串、重复字符、添加新行(回车),并改变大小写:

函数 描述

@Trim(string) 从字符串中删除开头、结尾和多余的空格。

@Trim(list) 从字符串列表的每个元素中删除开头、结尾和多余的空格,并从列表中删除空白元素。

@Repeat(string, number) 将字符串 string 重复 number 次。

@NewLine 在字符串中插入一个新行(回车)。

@LowerCase(string) 将字符串中所有的大写字符转换成小写。

@UpperCase(string) 将字符串中所有的小写字符转换成大写。

@ProperCase 将字符串中每个单词的第一个字符转换成大写,并将其余的字符转换为小写。

样例:修剪、重复、添加新行,并改变大小写

1 (@Trim)。该样例返回 [Now is the time],删除全部多余的空格。

Untrimmed := " Now is the time ";

Trimmed := @Trim(Untrimmed);

@Prompt([OK]; "Untrimmed"; "[" + Untrimmed + "]");

@Prompt([OK]; "Trimmed"; "[" + Trimmed + "]")

2 (@Trim, @ProperCase)。该样例将 Name 中的单词转换成首字母大写的单词,并删除开头、结尾和多余的空格。如果为 Name 输入“ jane j smith”,该公式将它转换为“Jane J Smith”。

@Trim(@ProperCase(Name))

3 (@Repeat)。如果 Sales 域大于或等于 100,000,则本样例在 Comments 域中返回“Great Month! Great Month! Great Month!”

FIELD Comments := @If(Sales >= 100000; @Repeat("Great Month! "; 3); Sales >= 50000; "Good Month"; "I want to see you in my office");

SELECT @All

4 (@NewLine)。本样例返回由一个新行分隔开的用户名和日期。

@UserName + @NewLine + @Text(@Now)

5 (@LowerCase)。本样例返回小写的用户名。

@LowerCase(@UserName)

6 (@UpperCase)。本样例返回大写的用户名。

@UpperCase(@UserName)

执行算术运算

乘、除、加、减运算符 (* / + -)。乘法和除法运算符的优先级高于加法和减法;运算的顺序是从左到右。以下列出的是一些算术运算函数。

函数 描述

@Abs(number) 计算一个数的绝对值。

@Sign (number) 对于正数返回 1,对于负数则返回 -1,对于零则返回 0。

@Sum(num; num; ...) 计算数字和数字列表的和。

@Integer(number) 去掉数字的小数部分。

@Integer(numberlist) 去掉数字列表元素的小数部分。

@Round(number) 对一个数字进行四舍五入。

@Round(number; factor) 以一个指定的因子规整数字。

@Round(numberlist) 将列表中的每个数字都进行四舍五入。

@Round(numlist; factor) 以一个指定的因子规整数字列表中的每个元素。

@Max(number; number) 取两个数中最大的一个。

@Max(numlist; numlist) 用矩阵式的列表操作计算最大值。

@Min(number; number) 取得两个数中最小的一个。

@Min(numlist; numlist) 用矩阵式的列表操作计算最小值。

@Modulo(number; number) 计算第一个数被第二个数除之后得出的余数。

@Modulo(numlist; numlist) 用矩阵式列表操作计算余数。

@Power(base; exp) 指数运算。

@Sqrt (number) 计算平方根。

@Pi 圆周率值。

@Log(number) 计算常用对数。

@Ln(number) 计算自然对数。

@Exp(number) 计算以 e 为底的指数。

@Random 返回一个 0 到 1 之间的随机数。

@Sin(angle) 计算角度的正弦(弧度)。

@Cos(angle) 计算角度的余弦(弧度)。

@Tan(angle) 计算角度的正切(弧度)

@Asin(sine) 反正弦函数。

@Acos(cosine) 反余弦函数

@Atan(tangent) 反正切函数

@Atan2(x; y) y/x 正切值的反正切函数

样例:执行算术运算

1 (*, 优先级)。对于第一个 @Prompt,该例样打印 15,因为先执行乘法 4 * 3。对于第二个 @Prompt 该样例打印 21,因为括号强制先运算 3 + 4。

@Prompt([OK]; "3 + 4 * 3"; @Text(3 + 4 * 3)); @Prompt([OK]; "(3 + 4) * 3"; @Text((3 + 4) * 3))

2 (/ *)。该样例对于第一个 @Prompt 打印 0.333333333333333,先执行除法再将结果四舍五入精确到小数点后 15 位。对于第二个 @Prompt,该样例打印 1.2635268885E+17,显示结果的 11 位小数作为乘以 1017 的系数。

@Prompt([OK]; "1 / 3"; @Text(1 / 3)); @Prompt([OK]; "123456789 * 1023456789"; @Text(123456789 * 1023456789))

3 (@Abs)。该样例计算 Score1 与 Score2 之差的绝对值。

@Abs(Score1 - Score2)

4 (@Abs)。该样例计算 Sales 和 CostOfSales 之差的绝对值,在文本域中将它格式化,并用括号括在负数结果两边。

GP := @Abs(Sales - CostOfSales); @If(Sales >= CostOfSales; @Text(GP); "(" + @Text(GP) + ")")

5 (@Sign)。该代理样例显示 Total 域。如果域值是负数,则在括号中放置的是它的绝对值;如果域值是0,则显示“Zero”。

sign := @Sign(Total);

display := @If(sign = 1; @Text(Total); sign = -1; "(" + @Text(@Abs(Total)) + ")"; "Zero");

@Prompt([OK]; "Total"; display);

SELECT @All

6 (@Sum)。该样例打印 15,列表 One23、变量 Four 和常量 5 的总和。

One23 := 1 : 2 : 3; Four := 4;

S := @Sum(One23; Four; 5); @Prompt([OK]; "Sum of 1-5"; @Text(S))

7 (@Integer)。该样例将 3.12 截为 3 而将 6.735 截为 6。

@Prompt([OK]; "@Integer(3.12)"; @Text(@Integer(3.12))); @Prompt([OK]; "@Integer(6.735)"; @Text(@Integer(6.735)))

8 (@Integer)。该样例在列表中将 Sales 和 Commission 截为整数。

@Integer(Sales : Commission)

9 (@Round)。该样例将 3.12 四舍五入为 3,将 6.735 取为 7,7.5 取为 8;753 以 10 为因子归整为 750; 列表元素中的 3.12、 6.735 和 7.5 分别归整为 3、 6 和 7(把它们转换为文本字符串以显示)。

@Prompt([OK]; "@Round(3.12)"; @Text(@Round(3.12))); @Prompt([OK]; "@Round(6.735)"; @Text(@Round(6.735))); @Prompt([OK]; "@Round(7.5)"; @Text(@Round(7.5))); @Prompt([OK]; "@Round(753; 10)"; @Text(@Round(753; 10))); @Prompt([OK]; "@Round(3.12 : 6.735 : 7.5)"; @Implode(@Text(@Round(3.12 : 6.735 : 7.5))))

10 (@Max)。该样例打印 3,即 1 和 3 中的最大值,第二个样例打印 99 6 7 8,即分别是两个列表中平行元素的最大值。

@Prompt([OK]; "@Max(1; 3)"; @Text(@Max(1; 3))); @Prompt([OK]; "@Max(99 : 2 : 3; 5 : 6 : 7 : 8)"; @Implode(@Text(@Max(99 : 2 : 3; 5 : 6 : 7 : 8))))

11 (@Min)。该样例打印 1,即 1 和 3 中的最小值,第二个样例打印 5 2 3 3,即分别是两个列表中平行元素的最小值。

@Prompt([OK]; "@Min(1; 3)"; @Text(@Min(1; 3))); @Prompt([OK]; "@Min(99 : 2 : 3; 5 : 6 : 7 : 8)"; @Implode(@Text(@Min(99 : 2 : 3; 5 : 6 : 7 : 8))))

12 (@Modulo)。该样例打印 4/3 的余数 1;-14/3 的余数 -2,(当被除数是负数时,余数是负数);还有 1 2 3 3,这分别是第一个列表中的被除数除以对应的第二个列表中的除数的余数。

@Prompt([OK]; "@Modulo(4; 3)"; @Text(@Modulo(4; 3))); @Prompt([OK]; "@Modulo(-14; 3)"; @Text(@Modulo(-14; 3))); @Prompt([OK]; "@Modulo(4 : 6 : 8 : 9; 3 : 4 : 5 : 6)"; @Implode(@Text(@Modulo(4 : 6 : 8 : 9; 3 : 4 : 5 : 6))))

13 (@Modulo)。该样例确定输入的数字是奇数还是偶数(被 2 除其余数为 0)。

n := @TextToNumber(@Prompt([OKCANCELEDIT]; "Input Number"; "Type a number"; "")); @Prompt([OK]; "The number is ..."; @If(@Modulo(n; 2) = 0; "Even"; "Odd"))

14 (@Power)。该样例打印 2 的 3 次幂即 8,和 -2 的 3 次幂即 -8,和 2 的 -3次幂即 0.125。

@Prompt([OK]; "@Power(2; 3)"; @Text(@Power(2; 3))); @Prompt([OK]; "@Power(-2; 3)"; @Text(@Power(-2; 3))); @Prompt([OK]; "@Power(2; -3)"; @Text(@Power(2; -3)))

15 (@Sqrt, @Power)。该样例是用于一个计算域的值公式,计算矩形的斜边,该矩形的边在 Length 和 Width 域中指定。

@If(Length = "" | Width = ""; ""; @Sqrt(@Power(Length; 2) + @Power(Width; 2)))

16 (@Pi, @Power)。该样例是用于一个计算域的值公式,计算一个圆形的面积,该圆形的半径在 Radius 域中指定。

@If(Radius = ""; ""; @Pi * @Power(Radius; 2))

17 (@Log)。该样例打印 0.602059991327962 和 14,它们分别是 4 和 1014 的常用对数。

@Prompt([OK]; "Common log of 4"; @Text(@Log(4))); @Prompt([OK]; "Common log of 1.0E+14"; @Text(@Log(1.0E+14)))

18 (@Ln)。该样例打印 0.693147180559945,即 2 的自然对数。

@Prompt([OK]; "Natural log of 2"; @Text(@Ln(2)))

19 (@Exp)。该样例计算出第一个 @Exp 函数值为 2.71828182845904 (e 的值),第二个 @Exp 函数值为 3.49034295746184 (e 的 1.25 次幂),第三个 @Exp 函数值为 0.28650479686019 (e 的 -1.25 次幂)。

@Prompt([OK]; "e to 1"; @Text(@Exp(1))); @Prompt([OK]; "e to 1.25"; @Text(@Exp(1.25))); @Prompt([OK]; "e to -1.25"; @Text(@Exp(-1.25)))

20 (@Random)。该视图操作样例从用户那里取得一个数字,并将它和 1 到 99 之间的随机数比较,包含 1 和 99 。

userNumber := @Prompt([OKCANCELEDIT]; "Number"; "Must be 1-99"; "");

winningNumber := @Text(@Integer(98 * @Random + 1));

@Prompt([OK]; "Result"; @If(userNumber = winningNumber; "YOU WIN"; "Sorry - winning number is " + winningNumber))

21 (@Sin, @Cos)。该样例显示两个计算域的公式。第一个公式计算矩形的长,第二个公式计算矩形的宽。

Diagonal * @Sin(Angle * @Pi / 180)

Diagonal * @Cos(Angle * @Pi / 180)

执行时间/日期运算

时间-日期值包含年、月、日、小时、分钟和秒。您可以象在时间-日期域中那样使用一个时间-日期值,但是必须用 @Text 把它们转换为字符串。您可以用 @TextToTime 将一个字符串转换成时间-日期值。

时间-日期常量可以是日期、时间或者两者的结合,它们被括在方括号中。日期的格式是年、月、日(年份可选。缺省为当前年;两位数的年如果年数大于或等于 50 表示是在 20 世纪,如果年数小于 50 表示是在 21 世纪),由斜杠 (/) 或连字符 (-)(对于 OS/2)分开。时间的格式是小时、分钟、秒(可选。缺省为 0),由冒号分开。您可以使用 24 小时的时间形式或用“PM”表示下午时间。您可以增加时区以指示一个时区。将这些部分用空格分开。以下是几个时间/日期常量的例子:[6/30/97]、[5:30:00 PM]、[17:30:00]、[17:30 EST]、[6/30 5:30 PM]。

日期可以进行比较或做减法。减法操作的结果是以秒为单位的数字。

以下的函数用来确定并操作时间-日期值。

函数 描述

@Created 返回文档创建的时间-日期。

@Accessed 返回最后一次访问文档的时间-日期。

@Modified 返回最后一次编辑并保存文档的时间-日期。

@Now 返回当前的时间-日期。

@Today 返回当天的日期。

@Tomorrow 返回明天的日期。

@Yesterday 返回昨天的日期。

@Weekday(time-date) 返回星期几如 1-7(星期日到星期六)。

@Day(time-date) 从时间-日期中提取月历中的日期。

@Month(time-date) 从时间-日期中提取月份值,从 1 到12。

@Year(time-date) 从时间-日期中提取年值。

@Hour(time-date) 从时间-日期中提取小时值。

@Minute(time-date) 从时间-日期中提取分钟值。

@Second(time-date) 从时间-日期中提取秒值。

@Date(y; m; d) 返回年,月,日中的日期部分。

@Date(y; m; d; h; m; s) 返回年,月,日,小时,分钟,秒中的日期部分。

@Date(time-date) 返回时间-日期中的日期部分。

@Time(y; m; d) 返回年,月,日中的时间部分。

@Time(y; m; d; h; m; s) 返回年,月,日,小时,分钟,秒中的时间部分。

@Time(time-date) 返回时间-日期的时间部分。

@Adjust(time-date; y; m; d; h; m; s) 通过加减某一数值以调整时间-日期。

@Zone 返回当前计算机的时区设置。

@Zone 返回当前时间-日期的时区设置。

样例:执行时间-日期运算

1 (@Created)。如果当前文档是在 1995 年以前创建,则该样例将“Archive”写入 Status 域,否则写入“Current”。

SELECT @All;

FIELD Status := @If(@Created < [01/01/95 12:00:00 AM]; "Archive"; "Current");

2 (@Modified, @Date, @Today, @Yesterday)。根据当前文档最后一次修改的日期,该代理样例将“Today”,“Yesterday”,或“Old”写入到 ViewStatus 域中。

FIELD ViewStatus := @If(@Date(@Modified) = @Today; "Today"; @Date(@Modified) = @Yesterday; "Yesterday"; "Old");

SELECT @All

3 (@Modified, @Date, @Weekday, @Today, @Adjust, @Yesterday)。该样例在上例的基础上做些修改,在指定“Yesterday”时要跳过星期六。如果今天是星期一,则 y 被设置为今天的日期再减去 3 天;否则设置为昨天的日期。用 y 代替 @Yesterday 用于测试 @Modified date。

d := @Date(@Modified);

y := @If(@Weekday(@Today) = 2; @Adjust(@Today; 0; 0; -3; 0; 0; 0); @Yesterday);

FIELD ViewStatus := @If(d = @Today; "Today"; d = y; "Yesterday"; "Old");

SELECT @All

4 (@Now, @Month, @Year, @Day)。该计算文本域的样例在 letterhead 表单的开头显示当天的日期。例如,6/30/95 显示为“June 30, 1995”。

months := "January" : "February" : "March" : "April" : "May" : "June" : "July" : "August" : "September" : "October" : "November" : "December";

month := @Subset(@Subset(months; @Month(@Now)); -1);

year := @Year(@Now);

day := @Day (@Now);

month + " " + @Text(day) + ", " + @Text(year)

5 (@Adjust, @Weekday, @Created)。这个计算时间域的样例显示距文档创建日期两天的日期。如果创建日期是星期五,则该样例增加 4 天以跳过周末。

increment := @If(@Weekday(@Created) = 6; 4; 2);

@Date(@Adjust(@Created; 0; 0; increment; 0; 0; 0))

访问用户环境

用户环境是包含公式的数据库所在的服务器或工作站,公式包括以下情况: 复制公式、由新邮件到达时或定时触发的代理、选择公式或列公式。否则,用户环境是用户运行公式的 Notes 工作站。

用户名可以是专有名称也可以是非专有名称,专有名称可以是规范或缩写的,使用 @Name 以改变用户名的格式。

以下是在用户环境中返回或处理信息的函数。

函数 描述

@UserName 返回用户名或服务器名.

@Name([key]; name) 改变用户名的结构。关键字包含 [CN] 以从一个专有名字中解析出公共名,[Abbreviate] 缩写规范格式的专有名字,[Canonicalize] 与上述作用相反,[ToKeyword] 将名字各部分按相反顺序排序,用反斜杠分开(用于分类视图)。

@UserRoles 对于服务器上的数据库,返回当前用户的角色列表。

@MailDbName 返回用户邮件数据库的服务器名和路径名。该函数判定两个元素的列表。

@OptimizeMailAddress(address) 从地址中删除无用的网络域。

@Platform 返回用户当前运行的平台:Macintosh、NetWare、OS2V1、OS2V2、UNIX、Windows/16 或 Windows/32。

@Version 返回正在运行的 Notes 版本(字符串)。

@Password(string) 对一个字符串编码。您无法从编码结果中确定原始字符串。

样例:访问用户环境

1. 该视图选择公式限制视图中只能有这样一些文档,这些文档的 From_1 域与当前用户名相匹配。From_1 和 @UserName 都被缩简至层次名称的公共名部分,以更好地确保匹配。

SELECT @Name([CN]; @UserName) = @Name([CN]; From_1)

2. 该列公式中,@Name 函数从“From”域中提取公共名部分。

Subject + " (" + @Name([CN]; From) + @DocDescendants(")"; ", % response)"; ", % responses)")

3. 该公式显示有关用户环境的信息。@MailDbName 的返回值被组合,因为这是一个包含服务器名和路径名的二元素列表。

@Prompt([OK]; "User name"; @Name([CN]; @UserName));

@Prompt([OK]; "Mail database"; @Implode(@MailDbName));

@Prompt([OK]; "Platform"; @Platform);

@Prompt([OK]; "Notes version"; @Version)

4. 这是“By Author”视图中第一列的公式。它转换 From 域,该域包含了一个典型的专有名字,将其转换为姓、逗号、名的格式。

AuthorName := @If(!@IsAvailable(From);"Anonymous";@Name([CN]; From));

Name := @Trim(@Word(AuthorName; "("; 1));

LastName := @RightBack(Name; " ");

FirstName := @LeftBack(Name; " ");

CombinedName := LastName + ", " + FirstName;

@If(CombinedName = ", "; Name; CombinedName)

5. 这是一个对于某表单的“Password”域的输入校验公式。作者可在口令被键入的时候看到口令,但是文档被保存后,口令被编码而且不可读。

@Password(Password)

访问当前数据库和视图

您对运行公式的数据库有直接的访问权(便捷图标公式除外,它没有数据库环境)。如果您在视图的上下文中,则您对运行公式的视图有直接的访问权。在文档的上下文中,您对文档所在视图有直接的访问权。

数据库和视图属性

下表列出返回数据库和视图属性的函数。

函数 描述

@DbManager 返回当前对数据库有“管理者”权限的用户、群组和服务器。 返回一个列表。

@DbName 返回当前 Notes 服务器和数据库的名字。返回二元素列表。

@ViewTitle 返回当前视图的标题。

窗口标题和列公式函数

许多函数提供了有关视图的答复层次和其他方面的信息。文档在视图中以 1, 2, 3 编号,这是对主文档而言。每组答复文档或答复的答复文档则有第二个和第三个层次的编号(从 1 开始)。缺省的情况下,完整的答复文档的编号以小数形式出现。例如,第三个主文档的第二个答复文档编号为 3.2,而它下面的第一个答复文档编号为 3.2.1。

这些函数仅工作于窗口标题和列公式中,有一些会被限制。返回值都是一个字符串。

函数 描述

@Responses 返回在当前视图中当前文档的答复编号。只限于窗口标题公式。

@DocLevel 返回在当前视图中当前文档的级别。

@DocSiblings 返回与当前文档同级的文档编号,包含当前文档。

@DocNumber 返回在当前视图中的当前文档或分类的编号。

@@DocNumber(sep) 与上相同,只是用 sep 分隔编号,替换了句点。

@DocNumber("") 与上相同,只是仅返回编号的最右边部分。

@DocParentNumber 返回在当前视图中当前文档或分类的父文档或父分类的编号。

@@DocParentNumber(sep) 与上相同,只是用 sep 分隔编号,替换了句点。

@DocParentNumber("") 与上相同,只是仅返回编号的最右边部分。

@DocDescendants 返回后续文档的编号,包含当前文档的子文档,子文档的子文档。

@DocDescendants(def) 与上相同,只是返回 def。在 def 中使用 % 以表示编号。

@DocDescendants(zero; def) 与上相同,只是如果没有后续文档的话则返回 zero。

@DocDescendants(one, zero; def) 与上相同,只是如果有一个后续文档的话则返回 one 。

@DocChildren 返回当前文档的直接子文档的编号。

@DocChildren(def) 与上相同,只是返回 def。在 def 中使用 % 以表示编号。

@DocChildren(zero; def) 与上相同,只是如果没有后续文档的话则返回 zero。

@DocChildren(one, zero; def) 与上相同,只是如果有一个后续文档的话则返回 one 。

@IsCategory 如果当前行的当前域右边任何域是一个分类的话,则返回一个星号。

@IsCategory(true) 与上相同,只是返回 true 代替星号。

@IsCategory(true; false) 与上相同,只是如果没有域是分类的话则返回 false 。

@IsExpandable 如果当前行是可展开的话则返回一个加号。

@IsExpandable(true) 与上相同,只是返回 true 代替加号。

@IsExpandable(true; false) 与上相同,只是如果当前行是不可展开的话则返回 false 。

样例:访问当前数据库和视图

1. 该样例显示数据库标题、它的服务器和数据库名和对它具有“管理者”权限的用户名。

@Prompt([OK]; "Title"; @DbTitle);

@Prompt([OK]; "Server and database"; @Trim(@Implode(@DbName)));

@Prompt([OK]; "Managers"; @Implode(@DbManager; ", "))

2. 如果视图标题公式为新文档显示“New Title”。如果视图标题为“AuthorView”则显示 Subject 域;否则显示 Subject 域加上答复文档的数目。

StandardTitle := Subject + @DocDescendants(" (No Responses)"; " (1 Response)"; " (% Responses)");

@If(@IsNewDoc; "New Topic"; @ViewTitle = "AuthorView"; Subject; StandardTitle)

3. 该列公式显示 Subject 域、用户名和答复文档的数目。

Subject + " (" + @Name([CN]; From) + @DocDescendants(")"; ", % response)"; ", % responses)")

在公式语言中访问当前文档

对于表单操作、按钮、热点和域公式,当前文档被是打开的那个。对于视图操作,当前文档是突出显示的那个(不是复选的文档)。对于代理,当前文档是根据代理构造器选择以及 SELECT 关键字标准激活的那个文档。

要阅读当前文档中的域,命名该域。命名不区分大小写,但是名字必须准确。

要编写当前文档中的域,您必须使用 FIELD 关键字或者 @SetField 函数。不能简单的命名该域。

关键字 FIELD 用于赋值语句并有以下格式。如果省略关键字 FIELD,则指定的变量将被认为是临时变量。

FIELD field-name := expression

@SetField 写入域,它与使用关键字 FIELD 的赋值语句效果相同。@SetField 可以嵌套到另一个语句;对于关键字 FIELD 则不能这样做。域名被表达成一个文本值,所以它可以是一个括号中的准确名字。有一个限制是 @SetField 只工作于已存在的域中;如果文档中不存在您想写入的域,则可使用 FIELD 赋值语句在公式开头“声明”它。@SetField 有以下格式。

@SetField( field-expression-name; expression )

DEFAULT 关键字是为了处理当一个域不在文档中的情况。如果文档中存在此域,那么就用它的值,如果没有,则用 DEFAULT 值。

DEFAULT field-name := expression

@MailSend 函数邮寄文档。不带参数的 @MailSend 邮寄当前文档,它必须包含一个域名为“SendTo”,该域包含收件人。带有参数的 @MailSend 构造文档并按指定参数邮寄。

@MailSend

@MailSend( to; cc; bcc; subject; body; fields; flags )

@DeleteField 函数删除域。在 FIELD 赋值语句中指定它作为表达式。

FIELD field-name := @DeleteField

@DocMark([NoUpdate]) 函数防止文档中公式的改变被保存。在公式处理完以后的文档与以前是一样的。该函数只影响代理。

该表格列出返回文档和域属性的函数。

函数
描述

@DocumentUniqueID
返回文档唯一的标识符,这是文档的全部复本唯一的标识符;在一个域中,创建一个当前文档的文档链接。

@InheritedDocumentUniqueID
返回文档的父文档唯一的标识符,在一个域中,创建一个当前文档的文档链接。

@NoteID
返回“NT”和跟在后面的文档的项目标识符。

@DocLength
返回文档的字节数大小。

@Author
返回全部作者的缩写姓名。

@DocFields
返回文档中全部域的名称。

@IsAvailable(field)
如果某域存在于文档中,则返回真 (1)。

@IsUnavailable(field)
如果某域不存在于文档中,则返回真 (1)。

@Attachments
返回附件的个数。

@AttachmentNames
返回全部附件的文件名。

@AttachmentLengths
返回每个附件的字节数大小。

@Responses
返回在当前视图中当前文档的答复数目。

@AllChildren
选择匹配文档的直接答复;只用于选择公式中。

@AllDescendants
选择匹配文档的所有答复;只用于选择公式中。

@IsResponseDoc
如果文档是一个答复则返回真 (1)。

@IsNewDoc
如果文档未被保存过则返回真 (1)。

@IsDocBeingEdited
如果文档处于编辑模式则返回真 (1)。

@IsDocBeingLoaded
如果文档正在被加载则返回真 (1)。

@IsDocBeingSaved
如果文档正在被保存则返回真 (1)。

@IsDocBeingMailed
如果文档正在被邮寄则返回真 (1)。

@IsDocBeingRecalculated
如果文档正在被重新计算则返回真 (1)。


样例:访问当前文档

1. 该计算域公式执行涉及文档中另外两个域的数学计算。这些域必须存在于文档中,必须是数字型的且被初始化为数字值。

TotalSales - CostOfSales

2. 该代理样例在当前文档中的两个域上执行数学运算,并将结果指定给第三个域。这两个被引用的域必须存在;GrossSales 域可以?切碌摹?

FIELD GrossSales := TotalSales - CostOfSales;

SELECT @All

3. 该代理公式在当前文档中的两个域上执行数学运算,并将一个数值放到第三个域中或者发送一个邮件信息。第一个语句初始化 GrossSales,如果您能肯定该域已经存在则无须此初始化操作。

FIELD GrossSales := 0;

gs := TotalSales - CostOfSales;

@If(gs > 0; @SetField("GrossSales"; gs); @MailSend("Ian Perron"; ""; ""; "No gross sales"; "Gross sales are zero or less for "; Subject));

SELECT @All

4. 该列公式样例判定文档是否包含 KeyThought 域。如果文档不包含一个 KeyThought 域,则它的缺省值为 Topic。

DEFAULT KeyThought := Topic;

KeyThought

5. 这是另一种实现上例的方法。

@If(@IsAvailable(KeyThought); KeyThought; Topic)

6. 该代理样例删除 GrossSales 域。

@If (@IsUnavailable(GrossSales); @Return(""); "");

FIELD GrossSales := @DeleteField;

SELECT @All

7. 该代理样例计算 GrossSales 域,然后显示结果,而且不标记文档为更新。作为结果,保存的文档未发生任何变化。如果忽略了 @DocMark 或者指定了“@DocMark([Update])”则变化被保存。

FIELD GrossSales := TotalSales - CostOfSales;

@Prompt([OK]; "Gross sales for " + Subject; @Text(GrossSales));

@DocMark([NoUpdate]);

SELECT @All

8. 该样例显示当前文档中的全部域。

@Prompt([OKCANCELLIST]; "Fields"; "Fields in document"; ""; @DocFields);

SELECT @All

9. 该窗口标题公式为一个新文档显示“New Document”。对于一个现有的文档,该公式显示 Subject 域和答复的个数。

@If(@IsNewDoc; "New Document"; Subject + " with " + @Text(@Responses) + " response(s)")

10. 该视图选择公式选择全部文档,除了那些 Form 域包含“Profile”或“Log”的文档。

SELECT !@Contains(Form; "Profile" : "Log")

11. 该视图选择公式选择所有 Subject 域包含“acme”(不区分大小写)的文档和它们的子文档。

SELECT @Contains(@LowerCase(Subject); "acme") | @AllDescendants

12. 该表单操作公式显示所有文档附件的名称和长度,或者如果文档没有附件的话,则显示“No attachments”。

@If(@Attachments > 0; @Prompt([OKCANCELLIST]; "Attachments"; "Attachment names and lengths"; ""; @AttachmentNames + " (" + @Text(@AttachmentLengths) + " bytes)"); @Prompt([OK]; "Attachments"; "No attachments"))

访问在当前文档和数据库以外的数据

以下函数从指定的数据库中取得数据值。您不能用这些函数设置数值。

@DbLookup 在指定数据库的指定视图中的第一个排序列中查找指定的值。对于每个匹配搜索值的文档,@DbLookup 返回文档或视图中的列的指定域中的值。

@DbColumn 返回指定数据库的指定视图中的指定列中的全部值。

前三个参数对于每个函数是相同的:

[NOTES] : [NOCACHE] 指定操作是在 Notes 数据库上并且未使用缓存。因为 [NOTES] 是缺省的,所以您可以为第一个列表元素指定空串 ""。如果数据是稳定的或者您访问过数据库许多次了,则可以指定第二个列表元素为空串 "",不使用缓存。您可以为整个参数使用一个空串 "" 表示打开一个 Notes 数据库而且没有缓存。

server : database 指定您访问的服务器和数据库。为第一个列表元素指定空串 "" 以表示本地 Notes 目录。指定整个参数为空串 "" 以表示当前数据库。您可以指定整个参数为数据库的复本标识符。Notes 将在本地和服务器上搜索,并且使用第一个它找到的复本。从“文件”“数据库”“设计摘要”“复制”中取得复本标识符。

view 指定通过哪个视图访问数据库。

对于 @DbLookup,第四个参数是关键字,它是在视图中第一个排序列中找到的值。@DbLookup 查找每一个与该关键字匹配的文档。

对于 @DbLookup,第五个参数或者是数据库中的域名,或者是视图中的列号。@DbLookup 返回找到文档中的域或列值的列表。

对于 @DbColumn,第四个参数是列号。@DbColumn 返回列中全部值的列表。

以下函数在当前数据库中取得并设置另一个文档的域值。不过,您必须知道文档的唯一的标识符。

@GetDocField(unid; fieldName) 给定唯一标识符,取得域值。

@SetDocField(unid; fieldName; value) 给定唯一标识符,设置域值。

由于父文档的唯一标识符在子文档的 $Ref 域中,所以该函数适用于在答复文档的父文档中访问并设置域值。在设置了“公式继承选定文档中的数值”的文档中,可以在基文档的一个隐藏域的公式中使用 @InheritedDocumentUniqueID,然后在继承文档的一个隐藏域的公式中使用上述隐藏域的名称。否则,您必须设计一种保存并提取您想访问文档的标识符的方法。

样例:访问当前文档和数据库以外的数据

1. 该样例在本地通讯录 (NAMES.NSF) 的“个人”视图中查找一个人的姓名,并从包含此姓名的文档中取得办公室的电话号码。

inputName := @Prompt([OKCANCELEDIT]; "User name"; "Enter user name as FIRST LAST"; "");

adjName := @Right(inputName; " ") + ", " + @Left(inputName; " ");

phoneNumber := @DbLookup("Notes" : "NoCache"; "" : "NAMES"; "People"; adjName; "OfficePhoneNumber");

@Prompt([OK]; "Office phone number"; inputName + "'s office phone is " + phoneNumber)

2. 该样例除了有两点不同以外,与上面的例子一样。在这里使用的是通讯录数据库的复本标识符而不是其名称。Notes 先在本地搜索复本然后上服务器搜索,并确定使用第一个发现的复本。@DbLookup 的最后一个参数是列 2,而不是 OfficePhoneNumber。实际上它与列 2 是一回事,因为列 2 中就包含电话号码。

inputName := @Prompt([OKCANCELEDIT]; "User name"; "Enter user name as FIRST LAST"; "");

adjName := @Right(inputName; " ") + ", " + @Left(inputName; " ");

phoneNumber := @DbLookup("Notes" : "NoCache"; "85255AD6:006AE971"; "People"; adjName; 2);

@Prompt([OK]; "Office phone number"; inputName + "s office phone is " + phoneNumber)

3. 该样例在本地通讯录的“群组”视图中查找一个群组的成员。

groupName := @Prompt([OKCANCELEDIT]; "Group name"; "Enter group name"; "");

members := @DbLookup("Notes" : "NoCache"; "" : "NAMES"; "Groups"; groupName; "Members");

@Prompt([OKCANCELLIST]; "Group members"; "Members of " + groupName; ""; members)

4. 该样例在给出办公室电话号码的情况下,取得与该号码有关的人员的姓名。设计这个例子是为了在号码与人员一一对应的情况下使用的。由于数据库没有按电话号码排序的视图,所以此样例使用 @DbColumn 来获得所有电话号码(列 2)和所有人员(列 1),然后查找与号码对应的人员。

phone := @Prompt([OKCANCELEDIT]; "Phone number"; "Enter phone number"; "");

phoneList := @DbColumn("Notes" : "NoCache"; "" : "NAMES"; "People"; 2);

nameList := @DbColumn("Notes" : "NoCache"; "" : "NAMES"; "People"; 1);

position := @Member(phone; phoneList);

@If(position = 0; @Do(@Prompt([OK]; "Not listed"; "No listing for " + phone); @Return(" " )); "");

name := @Subset(@Subset(nameList; position); -1);

nameAdj := @Right(name; " ") + " " + @Left(name; ",");

@Prompt([OK]; "Phone number " + phone; nameAdj)

使用函数通过 ODBC 访问外部数据库

以下函数通过 ODBC 访问外部数据库并返回一个值或值的列表:

@DbColumn 返回表的一列中的全部值,或者全部不同的值。

@DbLookup 返回表的一列中通过关键字匹配选定的值。

@DbCommand 将一个命令传递给外部 DBMS 并返回结果。

@DbColumn 与 @DbLookup 都只能提取数据。它们不能增加、删除、修改数据或执行其他操作。@DbCommand 能提取数据或发送其他可以改变数据的 SQL 语句。LotusScript 提供了一种更广泛的能力,包括更新外部数据库的能力。

前四个参数对于三个函数是同样的,通过 ODBC 建立访问。这些参数是:

"ODBC" 是字符串常量;或者 "ODBC" : "NoCache"

数据源的名称,定义在数据源表格中(在 Windows 中的 ODBC.INI)

用户标识符,两个用户标识符列表,或者一个空串,依外部数据源而定

口令,两个口令的列表,或者一个空串,依外部数据源而定

(@DbColumn 和 @DbLookup)要访问的表名称

(@DbCommand) 要执行的命令字符串

(@DbColumn 和 @DbLookup)要访问的列名称

处理由数据源返回的空数据的选项

(@DbLookup) 包含关键字的列名

(@DbLookup) 适当数据类型的关键字值,或者是一个列表

(@DbColumn 和 @DbLookup)两个元素的列表:“Distinct”作为关键字或空串;“Ascending”或“Descending”作为一个关键字

在需要用户标识符和口令的地方,您可以指定空串并让用户在执行函数时提供它们。

样例:使用函数通过 ODBC 访问外部数据库

1. 该公式取得 MANUALS 表中的 PARTNO 列。

@DbColumn("ODBC";"Oracle";"";"";"MANUALS";"PARTNO";"":"Ascending")

2. 该公式从 MANUALS 表的行中取得 TITLE,在该行中 PARTNO 是 17-895A 。

@DbLookup("ODBC";"Oracle";"";"";"MANUALS";"TITLE";"PARTNO";"17-895A")

3. 该公式从 MANUALS 表中 ONHAND 列的数字值小于100 的每行取得 PARTNO 列值。

@DbCommand("ODBC";"Oracle";"";"";"SELECT PARTNO FROM MANUALS WHERE ONHAND <100")

转贴:http://bbs.chinalotus.com/attachment.php?aid=2888
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值