综合使用JavaScript、LotusScript Agent和Formula的技巧

访问用户环境

用户环境是包含数据库的服务器或工作站,数据库包括以下内容: 复制公式、由新邮件到达时或定时触发的代理、选择公式或列公式。否则,用户环境是用户运行公式的 Notes 工作站。
用户名可以是专有名称也可以是非专有名称,专有名称可以是规范或缩写的,使用 @Name 可更改用户名的格式。
以下函数返回或处理用户环境的信息。
函数 描述
@UserName 返回用户名或服务器名。
@Name([key]; name) 更改用户名的格式。关键字包含 [CN] 以从一个专有名字中解析出公共名,[Abbreviate] 缩写规范格式的专有名字,[Canonicalize] 与上述作用相反,[ToKeyword] 将名字各部分按相反顺序排序,用反斜杠分开(用于分类视图)。
@UserRoles 对于服务器上的数据库,返回当前用户的角色列表。
@MailDbName 返回用户邮件数据库的服务器名和路径名。该 @function 计算出一个包含两元素的列表。
@OptimizeMailAddress(address) 从地址中删除无用的网络域。
@Platform 返回用户当前运行的平台:Macintosh、 NetWare、 OS2V1、 OS2V2、 UNIX、 Windows/16 或 Windows/32。
@Version 返回正在运行的 Notes 版本(字符串)。
@Password(string) 对字符串加密。加密后别人无法从中得到最初的字符串。
访问当前数据库和视图

可以直接访问正在运行公式的数据库(便捷图标除外,因为它没有数据库环境)。也可以在视图环境中直接访问正在运行公式的视图。同样,在文档环境中可直接访问打开文档的视图。
数据库和视图属性
下表列出返回数据库和视图属性的函数。
函数 描述
@DbManager 返回当前对数据库有“管理者”权限的用户、群组和服务器。返回一个列表。
@DbName 返回当前 Notes 服务器和数据库的名称。返回二个元素的列表。
@ViewTitle 返回当前视图的标题。
窗口标题和列公式 @function
许 多 @function 提供了关于视图的答复层次和其他方面的信息。在视图中,主文档以 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) 同上,只是返回 Frue 代替星号。
@IsCategory(True; False) 同上,但是如果没有分类域,则返回 False。
@IsExpandable 如果当前行是可展开的,则返回一个加号。
@IsExpandable(True) 同上,只是返回 True 代替加号。
@IsExpandable(True; False) 同上,但是如果当前行是不可展开的,则返回 False。

使用 @function 通过 LS:DO 访问外部数据库

以下 @function 通过 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”作为一个关键字
在需要用 IDS 和口令的地方,您可以指定空串并让用户在执行函数时提供它们。

使用 @function 通过 LS:DO 访问外部数据库

1. 该公式取得 MANUAL 表中的 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″)

转换数据类型

在对数据操作时类型必须是正确的。以下的函数用来转换数据和测试数据类型。
函数 描述
@Text(value) 将一个值转换为文本字符串。
@Text(value; format) 根据指定的格式将一个数字或时间-日期值转换成文本字符串。
@TextToNumber(string) 将文本字符串转换成一个数字。
@TextToTime(string) 将文本字符串转换成一个日期-时间值。
@IsText(value) 如果值是文本字符串或文本字符串列表,则返回“真”值 (1)。
@IsNumber(value) 如果值是数字或数字列表,则返回“真”值 (1)。
@IsTime(value) 如果一个值是时间-日期或时间-日期列表,则返回“真”值 (1)。
@Char(number) 将一个 IBM 代码页 850 代码转换为对应的字符。

连接、比较和判定长度
运算符 + 用来连接字符串。运算符 =、<>、!=、=!、><、<、>、<= 和 >= 用来比较字符串。以下的函数用来判定字符串的长度和比较字符串:
函数 描述和用法
@Length (string) 以字符为单位返回字符串的长度。
@Length(stringlist) 以字符为单位,返回字符串列表中每个元素的长度。
@Matches (string; pattern) 判定两个字符串是否匹配。可以用通配符来扩展比较的范围。
@Like (string; pattern) 判定两个字符串是否匹配。遵循 ANSI SQL 标准。
@Like(string; pattern; esc) 与上面的一样只是多了一个转义字符。
@Matches @Matches 用“?”来匹配任意一个单独的字符,用“*”来匹配任意的字符序列,@Matches 使用“\”作为转义字符。
@Like 按照 ANSI X3.135-1992 标准,使用“_”(下划线)来匹配任意一个单独的字符,用“%”(百分号)来匹配任意的字符序列。

查找并提取子串

样例
以下函数查找并提取子串:
函数 描述
@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,其中单词是在指定的分隔符之间的文本。
修剪、重复、添加新行,并改变大小写

样例

以下函数修剪字符串、重复字符、添加新行(回车),并改变大小写:
函数 描述
@Trim(string) 从字符串中删除开头、结尾和多余的空格。
@Trim(list) 从字符串列表的每个元素中删除开头、结尾和多余的空格,并从列表中删除空白元素。
@Repeat(string , number) 将字符串重复若干次。
@NewLine 在文本字符串中插入一个新行(回车)。
@LowerCase(string) 将字符串中所有的大写字符转换成小写。
@UpperCase(string) 将字符串中所有的小写字符转换成大写。
@ProperCase 将字符串中每个单词的第一个字符转换成大写,并将其余的字符转换为小写。

执行算术运算

乘、除、加、减运算符(*/+-)。乘法和除法运算符的优先级高于加法和减法;运算顺序是从左到右。但可以使用括号更改运算顺序。以下列出的是算术运算函数。
函数 描述
@Abs(number) 计算一个数的绝对(无符号)值。
@Sign (number) 对于正数返回 1,对于负数返回 -1,对于零则返回 0。
@Sum(num; num; …) 计算数字和数字列表的和。
@Integer(number) 去掉数字的小数部分,使它成为整数。
@Integer(numlist) 去掉数字列表所有元素的小数部分,使它们成为整数。
@Round(number) 对一个数字进行四舍五入。
@Round(number; factor) 以一个指定的因子规整数字。
@Round(numlist) 对数字列表中的每个数字进行四舍五入。
@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) 计算常用(以 10 为底)对数。
@Ln(number) 计算自然(以 e 为底)对数。
@Exp(number) 计算以 e 为底的指数。
@Random 返回一个 0 到 1 之间的随机数。
@Sin(angle) 计算角度的正弦(弧度)。
@Cos(angle) 计算角度的余弦(弧度)。
@Tan(angle) 计算角度的正切(弧度)。
@Asin(sine) 反正弦函数。
@Acos(cosine) 反余弦函数。
@Atan(tangent) 反正切函数。
@Atan2(x; y) 计算以 y/x 作为正切值的反正切函数。

答复列的公式

仅用于答复的列需要公式来生成总结答复文档的文本。
包含作者的信息
讨论数据库可以使用如下答复列的公式来显示答复文档的作者、日期和主题:
From + ” added this comment: ” + Subject + ” (” + @Text(@Created) + “)”
按以下方式显示答复:
Stephanie Mahar added this comment: Great job! (10/10/97 04:43:15 PM)
跟踪文档状态
在雇员信息数据库中,答复列可以显示新雇员以及离职雇员的调查信息,作为“按雇员姓名”视图中常规的“雇员记录”的答复文档。下面公式根据答复文档使用的表单的不同,显示不同的消息,并且显示文档的邮递状态。
@If(Form = “Exit”; “Exit Form, “; “New Hire Information, “) + @If(Mailed = “Yes”; “mailed to employee ” + @Text(@Date(PostedDate)); “not yet mailed”)
如果答复文档使用 Exit 表单,那么答复行显示也许如下:
Exit Form, mailed to employee 08/26/97
如果答复文档使用 New Hire Information 表单,那么答复行显示也许如下:
New Hire Information, not yet mailed
跟踪答复的数目
可以使用 @DocDescendants 跟踪答复文档的数目,以便作者迅速知道收到多少答复文档。下面的主文档列(不是答复列)公式对于答复样式的视图非常有用。
Subject + ” (” + @Name([CN]; From) + @DocDescendants(”)”; “, % response)”; “, % responses)”)
如果是主文档,那么列显示 Subject 域的内容、作者名称、答复以及答复的答复文档的数目。如果文档有一个答复,那么列显示“response”;否则显示“responses”。主文档行可作如下显示:
Need Help with Trade Show (Indy Montoya, 1 response)
Changing the Product Name (Sandy Braun, 2 responses)

视图小程序编程
通过使用一些 @commands 命令可以对视图小程序编程。有以下命令:
@command 描述
ViewCollapse 折叠所选文档
ViewExpand 展开所选文档
ViewCollapseAll 折叠所有文档
ViewExpandAll 展开所有文档
ViewRefreshFields 刷新视图。
刷新时,视图小程序不删除标记为已删除的文档
MoveToTrash 使当前所选文档标记为已删除
EmptyTrash 永久删除标记为已删除的文档
Folder 将所选文档移动或拷贝到文件夹
RemoveFromFolder 从当前文件夹删除所选文档。

用新建表单增强Notes打印功能中央财经大学 邹龙泉
02-1-31 下午 01:56:09

Lotus公司推出的Lotus Domino/Notes作为办公自动化系统的平台近年来在国内得到了广泛的应用,许多的政府主管部门、金融单位、企事业单位都使用了Notes以及在Notes上开发的各种办公系统,工作效率得到了极大的提高。
在 实际的应用中,为了存档以及供没安装Notes系统的部门传阅,许多在Notes系统中流转的电子文档需要打印出来。不幸的是,Notes提供的打印功能 很弱,一个文档只能按照给定表单的版式进行打印。但在实际的使用中,如政府部门,内容相同的一个文档,其上行公文和下行公文的版式是不一样的,这就需要将 同一文档用多种样式打印。最直接的想法当然是在Designer中修改表单的版式,但由于应用系统一般是隐藏设计的,表单无法修改。还有就是最终用户的计 算机水平有限,直接修改表单从技术上讲也行不通。
这时一个可行的做法就是:用VC++给用户提供一个“所见即所得”的编辑界面,并列出Notes 文档中各部分的内容,让用户以拖放的方式将相关内容放到适当的位置上,同时还可以加入文字、图片等修饰内容,然后按照最终的版式在Notes外部直接生成 一个Notes表单,并用此表单进行打印。这种方法既绕过了隐藏设计的障碍,又降低了对最终用户的技术要求。当然这一切都得益于Notes提供的API函 数。
由于只需一个NSFItemScan函数就能收集到Notes文档中所有的域,而又有多种灵活的方式实现“所见即所得”的排版功能,因此在提出上述的思路后,本文将主要介绍如何构造Notes表单。

一、Notes表单结构简介
一个表单中有三个必需的域:$TITLE、$INFO和$BODY,辅助性的还有$FIELDS域及属性为placeholder的各域。
1.$TITLE域
$TITLE 域的类型为TYPE_TEXT,其中保存表单的名称,Notes客户端窗口中“创建”菜单下列出的各表单名即为各表单note中$TITLE域的值。在 Notes提供的C API头文件“stdnames.h”中有预定义的常量ITEM_NAME_TEMPLATE_NAME代表表单note的名称域,为保证程序的向后兼 容,建议使用常量而避免直接使用$TITLE。
2.$INFO域
由于表单和 文档的创建有关,$INFO域定义了通过此表单创建的文档的一 些属性。实际上$INFO域中存储的是一个名为CDDOCUMENT的结构体,对生成文档属性的设定就是通过对该结构体中各分量的不同赋值实现的。结构体 CDDOCUMENT 的定义及说明见Lotus C API 的参考文档。
$INFO域的类型为TYPE_COMPOSITE,对应的预定义常量为ITEM_NAME_DOCUMENT。
3. $BODY域
$BODY 域是表单note中的核心域,整个表单显示和打印时的格式,还有通过此表单生成的文档所包含的域及其类型,都是在本域中定义的。由于$BODY域的结构非 常复杂,本文将在第二部分专门介绍。$BODY域也是TYPE_COMPOSITE类型的,名称预定义常量为ITEM_NAME_TEMPLATE。
4. $FIELDS域
$FIELDS域是一个TYPE_TEXT_LIST类型的域,其中包含了用此表单生成的文档包含的所有域。但专为打印生成的表单中可以没有此域。
5. “placeholder”域
对$BODY域中定义的将来文档中要含有的每一个域,在表单中都对应一个类型为TYPE_INVALID_OR_UNKNOWN而标志为ITEM_PLACEHOLDER的域,域名和$BODY域中定义的一样,而其值为NULL。
标志为ITEM_PLACEHOLDER的域将被加入到“域名表”中,这样当用户选择了客户端中的“设计”菜单中的“视图”子菜单后,在弹出的对话框中选择“添加域”时,该域名才会被显示出来。
同样,这些域在打印的表单中不是必需的。

二、$BODY域详解
$BODY 域中可以包含各种Notes对象,如文本、域、图像、热点、链接等,还有一些辅助性对象,如段定义、段引用 等。为方便管理,所有这些对象的定义都是通过不同的结构体实现的。Notes中定义对象的结构体都以“CD”开头,如CDTEXT定义静态文本、 CDFIELD定义域等,其他对象的具体定义请查阅Lotus C API 的参考文档。
通常,一个$BODY域的整体结构是这样的:
CDPABDEFINITION
CDPABDEFINITION

CDPARAGRAPH
CDPABREFERENCE
CDTEXT
text

CDPARAGRAPH
CDPABREFERENCE
CDBEGINRECORD
CDFIELD
CDBEGINRECORD

下面对其中的各部分分别予以说明。
1.段落预定义部分
CDPABDEFINITION定义页面上一个段落的属性,在这个结构体中我们可以定义段落的对齐方式、页边距、段间距、行间距等。在后面的某个具体段落中,如果定义了到此段定义的引用,则该段落就具有了此处定义的各属性。
段落的定义可以放在$BODY域的开头,也可以放在中间,只要保证序号PABID不重复就可以了。
2.静态文本的定义
上 述总体结构的中间部分定义了一段文本:CDPARAGRAPH定义一段的开始,类似文本串中的一个回车换行符;CDPABREFERENCE定义一个到段 定义的引用,从而本段就具有了前面定义的各种属性;CDTEXT是文本的头部,包含有文本的长度、字体、颜色等信息;text是实际的文本。
3.域的定义
对域的定义也是以CDPARAGRAPH和CDPABREFERENCE开始,但与文本不同的是,像域、图像等对象的定义,除了有作为头部的结构体外,还要有一对界定结构体CDBEGINRECORD和CDENDRECORD放在对象定义的前后两端。
有时在域的前面还要有一些提示性文字,如一个用于接收姓名的域name,通常在其前面要有“姓名”两个字,以便具体操作者知道此处要输入姓名。具体创建域时,这部分内容以文本形式放在CDBEGINRECORD之前,格式如上一步中所述。
在货币型或数值型的域中,为了对数据的格式进行更进一步的控制,在CDBEGINRECORD和CDFIELD中间还要插入一个CDEXT2FIELD结构,该结构提供了附加的格式定义。
域中的其他元素,如默认值计算公式、输入变换公式、域名、描述字串等放在CDFIELD后面,排列顺序和其长度值在CDFIELD结构体中的位置顺序一致。当然除域名外,其他元素如不是必要可以省略。
在本部分中,以文本和域为例,介绍了$BODY域中各对象的具体定义方式,其他对象与此类似。

三、创建Notes表单
在了解了Notes表单结构的基础上,通过API函数建立表单就很容易了。
首 先打开一个数据库,然后在其中 新建一个空白note,接下来就可以向其中添加各域了。像$TITLE这样的单一类型的域,可以直接调用NSFItemSetText函数创建。而 像$INFO和$BODY这样的复合类型的域,就比较麻烦一些。通常的做法是,先申请一块足够大的内存,然后顺序写入各部分内容,最后调用 NSFItemAppend函数创建域。
在向复合域中写入数据时,文本、域名等一般字符串可以直接写入,而各种结构体需调用ODSWriteMemory函数以Domino规范的形式写入,另外就是域定义中用到的各种公式,在写入前要经过NSFFormulaCompile变换。

四、例程
下面的程序段定义了一个带有默认值公式的名为“TextField”的域:

char TextFieldName[] = “TextField”;
char TextDescription[] = “This is a Simple Text Field”;
char TextDefValFormula[] = “\”Default\”";
char far *pBufferStart, far *pBuffer;
HANDLE hMem;
CDPABREFERENCE CDPabRef;
CDPARAGRAPH CDPara;
CDBEGINRECORD CDBegin;
CDENDRECORD CDEnd;
CDEXT2FIELD CDExt2Field;
CDFIELD CDField;
FONTIDFIELDS *pFontFields;

// 申请内存并锁定内存,获得指向该块内存的指针
OSMemAlloc (0, wCDBufferLength, &hMem);
pBufferStart = (char far *)OSLockObject(hMem);
memset( pBufferStart, 0, (size_t) wCDBufferLength );
pBuffer = pBufferStart;

// 填写 PARAGRAPH 结构
// 结构体的长度
CDPara.Header.Length = (BYTE) ODSLength(_CDPARAGRAPH);
// 结构体的类型
CDPara.Header.Signature = (BYTE)SIG_CD_PARAGRAPH;
// 转换为Domino规范的形式写入申请的内存
ODSWriteMemory( (void far * far *)&pBuffer, _CDPARAGRAPH, &CDPara, 1 );

// 填写 PABREF 结构
CDPabRef.Header.Signature = (BYTE)SIG_CD_PABREFERENCE;
CDPabRef.Header.Length = (BYTE) ODSLength(_CDPABREFERENCE);
// 要引用的段定义的序号
CDPabRef.PABID = wPabDefNumber;
ODSWriteMemory( (void far * far *)&pBuffer, _CDPABREFERENCE, &CDPabRef, 1 );

// 填写CDBEGINRECORD 结构
CDBegin.Header.Length = (BYTE)ODSLength(_CDBEGINRECORD);
CDBegin.Header.Signature = SIG_CD_BEGIN;
CDBegin.Version = 0;
CDBegin.Signature = SIG_CD_FIELD;
ODSWriteMemory( (void far * far *)&pBuffer, _CDBEGINRECORD,(void far *) &CDBegin, 1 );

// 填写CDEXT2FIELD 结构
memset(&CDExt2Field, 0, sizeof(CDEXT2FIELD));
CDExt2Field.Header.Length = (WORD)ODSLength(_CDEXT2FIELD);
CDExt2Field.Header.Signature = SIG_CD_EXT2_FIELD;
ODSWriteMemory( (void far * far *)&pBuffer, _CDEXT2FIELD, (void far *) &CDExt2Field, 1 );

// 填写CDFIELD 结构,定义文本域
CDField.Header.Signature = SIG_CD_FIELD;
CDField.Flags = FEDITABLE;
CDField.DataType = TYPE_TEXT;
CDField.ListDelim = LDDELIM_SEMICOLON;

// 本域中不用数值格式参数,全部清零
CDField.NumberFormat.Digits = 0;
CDField.NumberFormat.Format = 0;
CDField.NumberFormat.Attributes = 0;
CDField.NumberFormat.Unused = 0;

//本域中不用时间格式参数,全部清零
CDField.TimeFormat.Date = 0;
CDField.TimeFormat.Time = 0;
CDField.TimeFormat.Zone = 0;
CDField.TimeFormat.Structure = 0;

// 设定FontID
pFontFields = (FONTIDFIELDS *)&CDField.FontID;
pFontFields->Face = FONT_FACE_ROMAN;
pFontFields->Attrib = 0;
pFontFields->Color = NOTES_COLOR_BLACK;
pFontFields->PointSize = 14;

// 编译默认值公式
NSFFormulaCompile(NULL, 0, TextDefValFormula, (WORD) strlen(TextDefValFormula), &hTextDefValFormula, &wTextDefValFormulaLen, &wdc, &wdc, &wdc, &wdc, &wdc))

// 填写CDFIELD 结构的其余部分,因为DVLength值只有公式编译后才知道
CDField.DVLength = wTextDefValFormulaLen;
CDField.ITLength = 0;
CDField.TabOrder = 0;
CDField.IVLength = 0;
CDField.NameLength = strlen(TextFieldName);
CDField.DescLength = strlen(TextDescription);
CDField.TextValueLength = 0;
CDField.Header.Length = ODSLength(_CDFIELD) +CDField.DVLength +CDField.ITLength +CDField.IVLength +CDField.NameLength +CDField.DescLength +CDField.TextValueLength;

// 保证CDFIELD域长度为偶数
if (CDField.Header.Length % 2)
CDField.Header.Length++;
ODSWriteMemory( (void far * far *)&pBuffer, _CDFIELD, (void far *)&CDField, 1 );

// 获取指向编译后公式的指针
pTextDefValFormula = OSLock( char, hTextDefValFormula );
// 写入公式内容到内存
memcpy( pBuffer, pTextDefValFormula, wTextDefValFormulaLen );
pBuffer += CDField.DVLength;
// 解锁并释放公式占用的空间
OSUnlockObject(hTextDefValFormula);
OSMemFree(hTextDefValFormula);

// 域名部分,直接写入
memcpy( pBuffer, TextFieldName, CDField.NameLength );
pBuffer += CDField.NameLength;

// 域描述部分,直接写入
memcpy( pBuffer, TextDescription, CDField.DescLength );
pBuffer += CDField.DescLength;

// 保证整个域定义的长度为偶数
if ((pBuffer-pBufferStart) %2)
pBuffer++;

// 填写CDENDRECORD结构
CDEnd.Header.Length = (BYTE)ODSLength(_CDENDRECORD);
CDEnd.Header.Signature = SIG_CD_END;
CDEnd.Version = 0;
CDEnd.Signature = SIG_CD_FIELD;
ODSWriteMemory( (void far * far *)&pBuffer, _CDENDRECORD, (void far *) &CDEnd, 1 );

在web上显示视图的时候,总是不喜欢notes的默认界面,想换成表格的。用表格显示很容易,别让notes生成HTML,全部由你自己定制就成了。但如何交替用颜色显示不同行呢?就是说当view行数是寄数时显示一种颜色,偶数时显示另一种颜色。
原先想用@docnumber去做,但@docnumber产生的值时一个特殊值,无法转换成数字来判断。在www.lotus.com的开发者原地有一篇类似介绍,用的方法是把docnumber直接打印到html里,然后再用javascript来判断,这样虽然可以,但非常的麻烦。
下面有一种比较简便的方法:还是用javascript:
function transformView() {
var tableElements = document.getElementsByTagName(’table’) ;
var table = tableElements[tableElements.length - 1] ;
//上面是你的表格再页面中倒数第几个表格,如果你是倒数第2个,就-2
table.width = ‘100%’ ;
table.cellSpacing = ‘0′ ;
headers = table.getElementsByTagName(”th”) ;
for( i = 0; i < headers.length; i++) {
headers.bgColor = ‘#cccccc’ ;
}
rows = table.getElementsByTagName(”tr”) ;
var counter = 0
for( i = 0; i < rows.length; i++) {
rows.bgColor = (i % 2 ? ‘#efefef’ : ”) ;
}
}
怎么样,是不是很cool?

如何将Domino服务器配置为Internet邮件服务器?
在学习配置之前,我们需要先简单了解一下协议的概念。
在进行Internet邮件收发的时候,我们需要使用到下面两个协议:
SMTP(简单消息传输协议)管理Internet邮件发送
POP3(邮局协议)管理Internet邮件接收
实际上两者的功能划分并不是如此清楚,也就是说两者间关系是相辅相成的,独立任何一方都不可能完成任务。
好了,协议就了解到这里,我们来看看最具体的东西,配置步骤:
1、配置——服务器配置文档——基本中,打开SMTP邮件邮递和SMTP侦听任务选项
2、在服务器配置文档——基本中,定义全限定的Internet主机名,也就是说用户的邮件地址会是:用户名@全限定Internet主机域名,比如用户admin,全限定的Internet主机名为www.flycat.net,那么该用户的邮件地址就是[email protected]

【版权说明】:本网页上有部分内容来源于网上收集,但不能保证资料的完整性和准确性,仅提供参考和学习。如有侵权请立即通知我们,我们将立即删除,谢谢合作!

你可能感兴趣的:(JavaScript,技巧,agent,Formula,LotusScript)