您的位置:首页 > Web前端 > JavaScript

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

2007-03-08 12:55 615 查看
该视图操作样例从用户那里取得一个数字,并将它和 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 @All3 (@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 @All4 (@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 - CostOfSales2. 该代理样例在当前文档中的两个域上执行数学运算,并将结果指定给第三个域。这两个被引用的域必须存在;GrossSales 域可以是新的。FIELD GrossSales := TotalSales - CostOfSales;SELECT @All3. 该代理公式在当前文档中的两个域上执行数学运算,并将一个数值放到第三个域中或者发送一个邮件信息。第一个语句初始化 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 @All4. 该列公式样例判定文档是否包含 KeyThought 域。如果文档不包含一个 KeyThought 域,则它的缺省值为 Topic。DEFAULT KeyThought := Topic;KeyThought5. 这是另一种实现上例的方法。@If(@IsAvailable(KeyThought); KeyThought; Topic)6. 该代理样例删除 GrossSales 域。@If (@IsUnavailable(GrossSales); @Return(""); "");FIELD GrossSales := @DeleteField;SELECT @All7. 该代理样例计算 GrossSales 域,然后显示结果,而且不标记文档为更新。作为结果,保存的文档未发生任何变化。如果忽略了 @DocMark 或者指定了“@DocMark([Update])”则变化被保存。FIELD GrossSales := TotalSales - CostOfSales;@Prompt([OK]; "Gross sales for " + Subject; @Text(GrossSales));@DocMark([NoUpdate]);SELECT @All8. 该样例显示当前文档中的全部域。@Prompt([OKCANCELLIST]; "Fields"; "Fields in document"; ""; @DocFields);SELECT @All9. 该窗口标题公式为一个新文档显示“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") | @AllDescendants12. 该表单操作公式显示所有文档附件的名称和长度,或者如果文档没有附件的话,则显示“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")
版权所有2001
首页-->LOTUS文章-->强迫WEB用户重新登录的方法(两种)
我们知道在Web应用中,一旦我们曾经输入过一次用户口令,那么,系统将会一直使用当前Web用户与Domino HTTP服务器连接。如果我们希望以另一名Web用户访问此服务器,只好关闭浏览器,再重新连接服务器时,重新输入其他用户的名程和口令。(这是我们不愿意作的。)如何不关闭浏览器,强迫浏览器显示登陆窗口呢?关于如何强迫一个Web用户输入登录口令的方法,在此列出两个:1。Java Servlet程序2. Domino URL 命令这两种方法都是强迫浏览器显示登陆窗口,以使用户可以其他用户名登陆。实际上不能注销当前已连接Web用户,除非在登陆窗口输入错误的用户名和口令或者不同于当前已连接的Web用户的正确的用户名和口令。注释:这段程序有一段逻辑错误,本人已经对其更正这段程序可以使用Domino URL命令代替,功能完全相同。在R5中试验可行,4.6估计可行。比如:http://host/anydatabase.nsf?login注意这里一定要写一个数据库的名字,可以是任何一个数据库,甚至是不存在的数据库。请注意格式。你可以试试,有结果您可以写信给我。-------丁香书 1999.8.13=====================================问题5:怎么使一个Web用户注销登录?来自:http://dingxiang.163.net更新:1999.8.14解答:How do you add a logoff button for web users?Using the username:password@www.company.com URL does not work because the browser thinks your realm is "username:password@www.company.com" instead of "www.company.com".<P>You can use a Java servlet to pass a 401 exception to the browser to log someone off of TestRealm (in most cases, this is "www.company.com"): <P>// From Terry Courtneyimport java.io.*;import javax.servlet.*;import javax.servlet.http.*;public class LogOff extends HttpServlet { public void init(ServletConfig config) throws ServletException { super.init(config) ; } public void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String auth ; // get output streem ServletOutputStream out = res.getOutputStream() ; // get authorization from header auth = req.getHeader("Authorization") ;// if (auth == null) { //It's a logic Error,rem by dingxiang if (auth != null) { // force prompt of login res.setContentType("text/html"); res.setHeader("WWW-Authenticate", "WWW-Authenticate: basic realm=/"/TestRealm/"") ; res.setStatus(401, "401 Unauthorized") ; } out.println("Hi") ; } // end doGet} // end class LogOffWhen you call this servlet w/ a URL of http://www.company.com/LogOff, it will send the right HTTP headers back to the browser to trick the browser into thinking that the user did not authenticate with this Realm.<P>This servlet can also be written as a LotusScript agent.  
版权所有2001
首页-->LOTUS文章-->自动切换用户ID
Sub Initialize%REM 切换用户ID本程序的作用是:1、从指定的目录中搜索所有ID文件,2、然后提供用户选择3、再从注册用户时保存在names.nsf数据库中的密码进行校对看是否相同。4、再通过用户选择的ID文件更换操作员ID本程序有以下缺陷:1、取得特殊指定目录下的ID文件2、无法判断获得的ID文件是用户ID,还是Server.id,cart.id3、用户密码需要保存在names.nsf中,首先进行密码核对,造成安全泄露。但不这样做,无法截获用户输入密码错误,程序不好处理。4、因此此公式仅适合单机用户。tndahttp://notes.363.net%END REMREM 首先搜索指定目录下的所有ID文件Dim ss As New notessessionxx = ss.UserNameListIDPath = ss.GetEnvironmentString("Directory",True)IDFileAll = IDPath+"/*.id"'没有方法遍历所有目录,所以假定所有ID文件在此目录下fileName = Dir(IDFileAll, 0)num = 0Do While fileName <> ""num = num + 1fileName = Dir()LoopIf num = 0 Then Exit Sub '没有找到ID文件就退出程序Redim ids(1 To num) num = 1fileName = Dir(IDFileAll, 0)Do While fileName <> ""ids(num) = Left(filename,Instr(1,filename,".")-1)num = num + 1fileName = Dir()LoopDim uiw As New notesuiworkspaceIDuser = uiw.Prompt( PROMPT_OKCANCELLIST,"更换操作员","请选择一个操作员:","",ids)If IDuser = "" Then Exit SubREM 从names.nsf中获取密码 Dim ndb As notesdatabaseSet ndb = ss.getdatabase("","names.nsf")Dim nvi As notesviewSet nvi = ndb.getview("People")Dim pdoc As notesdocumentSet pdoc = nvi.getdocumentbykey(IDuser)pass = pdoc.comment(0)For i = 1 To 3IDpass = uiw.Prompt( PROMPT_PASSWORD,"输入密码","请输入您的密码:")If pass = IDpass Then Exit For NextIf pass <> IDpass Then Exit SubDim idfile As Stringidfile = IDPath+"/"+IDuser+".id"Dim newreg As New NotesRegistration Call newreg.SwitchToID( idfile,pass )Messagebox "当前操作员是:"+IDuser,64,"更换成功"Exit SubEnd Sub  
版权所有2001
首页-->LOTUS文章-->RTF域全接触
RTF域完全掌握 1、RTF域是Notes中最重要的域,由于它能够保存文本、声音、图片、动画、附件以及按钮操作、链接等多媒体信息资料,是Notes不同于普通关系型数据库的重要特征。2、RTF域的存储容量仅受机器硬盘限制,可以任意大的文件和程序。3、当存储各种类型的RTF域,改变域类型成为文本类型时,仅其中的文本字符能够保存,其他的图片、附件等不能保存在文本类型域中。4、RTF域在编程中,是不能通过公式函数来计算处理的,只能通过LotusScript来对其进行复制操作。5、以下是用LotusScript复制、添加RTF域内容,经测试无误。Sub Click(Source As Button)%REM RTF域复制操作作者:tnda 2000.3.5http://notes.363.net mail:notes@363.netRTF域值在程序中编辑修改后,只能调用doc.save(false,true)不能调用uidoc.save,也不能在文档中单击保存按钮,否则后台修改无效。并且其修改的内容当前不能显示,只有不保存退出文档,再打开才能显示。因为RTF域只能通过后台LotusScript修改。%END REM Dim uiw As New notesuiworkspaceDim uidoc As notesuidocumentDim doc As notesdocumentSet uidoc = uiw.currentdocumentSet doc = uidoc.document '获得当前文档Dim rtitem1 As NotesRichTextItemSet rtitem1 = doc.GetFirstItem( "aaaa" )If rtitem1 Is Nothing Then Exit SubIf rtitem1.Type <> RICHTEXT Then Exit Sub'文档没有保存以前,无法发现RTF域Call rtitem1.AppendText( "这是第一个域值内容" ) Dim rtitem2 As NotesRichTextItemSet rtitem2 = rtitem1.CopyItemToDocument( doc,"bbbb")Call rtitem2.AppendText( "这是第二个域新内容" ) Call doc.Save( False, True )End Sub
版权所有2001
首页-->LOTUS文章-->域公式
  域公式本节主要介绍域在何处需要使用公式,具体公式编程,下章介绍。可以使用域公式的事件有:域选择公式、域隐含公式、域初始值和计算公式、域校验公式、域刷新公式、域事件公式等。域选择公式:在选择域类型为对话框列表、复选框、单选框、列表框、组合框时,需要输入域可以选择的选项。选择项:对于固定不变的选择项,如:性别、学历等,可以手动输入。对于可能会变化,或者说无法确定的选择项目,如:毕业学校、所学专业等,需要使用公式获得。手动输入的方法为:在选择项目输入框内,输入男|1女|2“|”前面的“男”,为显示内容,即用户可以看见的,“|”后面的“1”,为实际内容,即当用户选择了“男”时,实际上此域保存的内容是“1”。因此,此域在表单中显示为“男”,但在视图中显示为实际值“1”,如果希望显示和保存的内容一致,则放弃使用“|”,即可,如:男女注意:“1”是文本字符,不是数字类型,利用选择项输入的域类型一律是文本类型。一行为一个选择项目,如果选择项内容需要空值,直接回车,在一行中不要输入任何内容即可。公式选择项的方法为:1、从视图读取:需要使用公式:@DbColumn,此公式的作用是从任何服务器上的数据库中,读取指定的视图中的指定的列。@DbColumn( class : "NoCache" ; server : database ; view ; columnNumber )· class:输入空值,或"Notes" · "NoCache":不从缓冲区读取 · server:指定的服务器,本地服务器,可以使用空值"" · database:指定的数据库名称,如果找不到则报错,如果是当前数据库则为空值 · view:指定的视图,可以为隐含视图, · columnNumber:指定视图中的第n列,可以是隐含列,从视图的左数第N个列,包括隐含列。 · 注意:如果视图的第N列有重复内容,则选择项目中也会有重复内容供选择,需要第N列排序分类即可。 如:@DbColumn("";"";"aaaa";1),读取当前数据库的aaaa视图的第1列值。2、从其他文档读取:可以从其他文档读取一个多值域,作为选择项目,如可以将公司的部门输入指定配置属性文档中,供选择。使用公式@DbLookup,此公式的作为是从指定的文档中读取一个域值内容。@DbLookup( class : "NoCache" ; server : database ; view ; key ; fieldName )· key:根据此值,从视图中的第一列选择指定的文档,如果key是多值列表,如:"男":"团员",则视图第一列性别必须排序分类,第二列政治面貌必须排序,依此类推。 · filedName:指定文档中的域名称,函数将返回此域的值。如果输入数字N,则表示读取视图中指定文档的第N列值,建议使用域名称。 · 注意:如果没有找到文档,系统将定位为此视图的第一个文档,如果视图中没有文档,则出错。 如:@DbLookup("";"" ;"aaaa"; "abc" ; "City" ),返回从当前数据库中aaaa视图,根据aaa值定位的文档的City域值。返回内容必须是多值域,如果是单值域,则仅有一个选项。使用视图对话框的方法:选择项目可以使用视图来选择,可以使用函数:@PickList,其作用是显示一个视图对话框,可以从中选择一个或几个文档,并返回指定的域值。@PickList( [Custom] : [Single] ; server : file ; view ; title ; prompt ; column ; categoryname )· [Custom]用户自定义选项 · [Single]:选择此项表示返回单值,否则可以返回多值 · title:对话框标题 · prompt:对话框显示提示 · column:返回第N列域值 · categoryname:5.0新增功能,表示视图仅显示此参数指定的分类文档。 · 此函数功能比较多,具体请参阅帮助数据库 使用地址对话框的方法:显示names.nsf的人员视图供选择使用存取权限框的方法:显示当前数据库存取权限指定的人员供选择如果选择了域属性“可以使用不在列表中的数值”,则可以从选择项目中选择的同时,可以输入新建内容。域隐含公式:域隐含公式必须返回@True或@False,来根据逻辑对或错判断域是否隐含。如:aaa = "",表示域aaa的值为空时隐含域初始值和计算公式:根据公式返回一个指定的值,返回的值类型必须和域类型一致,否则出错。公式位置为:Default Value如:文档创建时间域初始公式可以为,@New,表示返回当前工作站时间域校验公式:判断域值输入是否正确,仅编辑类型可以使用。公式位置为:Input Validation如:数量域值大于0,小于100,其公式为@If(ShuLian > 0 & ShuLiang < 100 ; @Success ; @Failure("数量输入范围是0 ~100"))· @Success:返回正确,表示此域内容符合要求。 · @Failure:返回错误,表示此域内容不符合要求,并显示提示内容,且输入光标会自动进入此域输入框中。。 域刷新公式:当表单刷新时,会根据此公式返回的值改变域值内容,仅编辑类型可以使用。公式位置为:Input Translation如:如果在省份输入的内容是“广东”则自动将其内容转化为“广东省”@If(@Right(ShengFen;1) = "省" ; ShengFen ; ShengFen + "省" )此公式判断ShengFan域内容,最后一个字符是否是“省”,如果不是,则加入,否则返回原值。域事件公式:根据域触发的事件运行一段程序,事件有:· Entering:进入编辑域,即此域获得输入焦点,激活此事件,一般可以设置动态初始值。 · Exiting:退出编辑域,即此域失去输入焦点,激活此事件,一般可以校验域,或根据域内容改变其他域内容。 · Initialize:域调入内存时,激活此事件 · Terminite:域从内存中退出时,激活此事件
版权所有2001
首页-->LOTUS文章-->代理调试方法
在notes编程中,尤其web开发中,代理是很常用的,但是,相对而言,代理的调试也很不方便。下面就我的经验,列出几种常用的方法,欢迎大家指正和补充。(这里讨论的都是lotussript代理)  1.notes端跟踪法  使用notes开发客户端时,对于那些在客户端运行的代理(与服务器端运行相对)可以直接跟踪代理的运行。  方法:选中菜单中“文件-〉工具-〉调试lotusscript”后再运行代理即可。  优点:调试直观,代理可以单步跟踪、设置断点(使用stop语句或者在调试窗口中双击需要加断点的语句)、观察该中断时刻的各种变量和对象的值等。所以使用这种调试方法可以很快地知道问题的所在。  缺点:只适用于客户端运行的代理,而且有些web客户端运行的代理也无法调试。 一些调试技巧:  可以把那些在服务器端运行的代理的核心代码先在客户端调试通过后,再改回服务器端运行,这样有时可以节省很多调试时间。有些web端运行的代理也可照此方法调试。  2.输出调试信息  对于那些在服务器端运行的代理,或在web端运行的代理,可以利用print命令来输出一些关键的信息来帮助你了解问题的所在。  方法:在代理中怀疑有问题的地方或分支点附近加入print命令来打印一些关键信息,从而帮助了解问题的所在。  a.对于处于非调试状态下的notes客户端而言,print的信息将显示在客户端下部的状态条中。  b.对于处于调试状态下的notes客户端而言,print的信息将显示在客户端下部的状态条中和调试窗口的输出窗口中。  c.对于web应用而言,print的信息将直接输出到浏览器中。(但请注意,位于表单的webqueryopen代理中的print输出都将被忽略)  d.对于服务器端运行的代理,print的信息将保存在NOTES.LOG文件中  附带说一句,当代理产生错误时,一般都会在domino的命令窗口中产生一个错误信息,说明错误的类型,可能的话,先看看这些信息,了解一下错误的类型,可能会比一上来就盲目地跟踪要好一些。当然,在程序编码的同时,利用on error来建立一些错误报告机制,也有助于更快地分析错误的类型与所在。  3.代理日志  建立一个代理日志,这恐怕是最通用的方法了,但也相对较繁琐。 方法:在代码的头部加入如下代码(xxxx为一随意的日志名,mylog为日志对象的名称,可以自定):dim mylog as new noteslog("xxxx")call mylog.openagentlog在代码需要调试的部分加入下面的语句call mylog.logaction(description$)description$ 是一个字符串常量或变量,内容根据调试的需要而定。这些内容将会写到代理的日志中。  日志的察看方法:  a.在designer中打开数据库的代理窗口。  b.在制定的代理上面点击鼠标的右键  c.在弹出的菜单中选择日志即可  注意,代理一旦重新保存,代理日志就会被清空。代理每次运行,新产生的代理日志会覆盖上一次的日志。
版权所有2001
  某食堂管理系统,希望根据不同的用户身份,进入相应的页面。下面就是实现这种功能的一段代理的Initialize代码: Sub InitializeOn Error Goto errorsDim session As New notessessionDim note As notesdocumentDim result As VariantDim i As IntegerDim viewname As StringDim querystring As StringDim doc As notesdocumentDim view As notesviewDim normaluserday As VariantDim useridday As Variantnormaluserday=Evaluate("@If(@Weekday(@Today)=1;@Adjust(@Today;0;0;-6;0;0;0);@Adjust(@Today;0;0;2-@Weekday(@Today);0;0;0))")Const notesmcro$=|@ismember("[manager]";@userroles)|'format后的normaluserday是字符串型useridday=Format(normaluserday(0),"yyyy-mm-dd")Set db=session.currentdatabaseSet view=db.getview("vshipu")Set doc=view.getdocumentbykey(useridday)Set note=session.documentcontextresult=Evaluate(notesmcro$)If result(0)=1 Then 'administratorPrint "[/"+getdbpath+"/myview?openform&view=vshipu]"Else 'normal userIf (doc Is Nothing) ThenPrint "本周食谱还未制订,请下次再来,谢谢合作."End IfPrint "[/"+getdbpath+"/vshipu/"+doc.universalid+"?opendocument]"End IfExit Suberrors:Print ErrExit SubEnd Sub
版权所有2001
Notes R5同外部邮件系统路由的设置
 
我们知道NOTES作为内部邮件系统是非常简单易行的,很受大家欢迎,但习惯于使用
OUTLOOK的用户还是喜欢使用POP3邮件格式,尤其是要和外界的POP3用户交流信息,其实
,NOTES不仅提供了POP3服务,而且还能通过SMTP(简单邮件传输协议)和其他的POP3邮
件系统进行通讯。本文主要介绍如何和其他POP3邮件系统交换信息。
  目标:
  1、使NOTES能够同外部邮件系统通讯(包括接收和发送外来和外出邮件);
  2、为组织内的非应用用户提供NOTES的邮件服务,这些用户无须安装NOTES客户端软
件,就可以使用NOTES的邮件系统。
  配置服务器需要:
  1、为服务器 启用"在本地 Internet 网络域外部发送消息时所用的 SMTP"
  2、为服务器 启用 SMTP侦听 任务
  3、正确设置 DNS 将 DNS服务器 设置为合适的邮件连接服务器。
  具体步骤:
  一、设置到本地 Internet 网络域外部的 SMTP 路由
  必须启用 SMTP 路由在本地 Internet 网络域外部发送消息(如 Internet 或其他
私有网络)。
  启用到本地 Internet 网络域外部的 SMTP 路由:
  1.确保已准备好发送邮件到 Internet 的系统。
  2.确保已经配置了服务器的"配置设置"文档。
  3.在 Domino Administrator 中,单击"配置"附签,然后展开"消息处理"区段。
  4.选择"配置"。
  5.选中"配置设置"文档,然后单击"编辑配置"。
  6.在"路由器/SMTP"下的"基本"附签,完成以下域,并保存文档:
  域 (在本地 Internet 网络域外部发送消息时所用的 SMTP)
  输入 (启用,使用 SMTP 将邮件路由到 Internet)
  二、设置服务器接收通过 SMTP 路由发送的邮件
  要设置服务器接收 SMTP 路由的消息,必须启用"侦听程序"。然后,服务器则可以
"侦听"TCP/IP 端口(通常端口为 25)上的 SMTP 通信量,并可接收 MAIL.BOX 数据库
中的 SMTP 消息。
  注释: 不要将 SMTP 作为任务添加到 Notes .INI 文件中的任务列表中,否则此功
能将无法工作。
  启用"侦听程序":
  1.在 Domino Administrator 中,单击"配置"附签,然后展开"服务器"区段。
  2.选择要编辑的"服务器"文档,然后单击"编辑服务器"。
  3.在"基本"附签,完成以下域,然后保存文档:
  域 (SMTP 侦听 任务)
  输入 ("启用",打开侦听程序,以便服务器可以接收通过 SMTP 路由路由的消息)
  三、网络域命名服务 (DNS) 和邮件路由
  在网络域名服务器上设置Domino邮件服务器的 A记录和MX记录,使得Domino邮件服
务器能够接收外来邮件;在网络域名服务器上设置非Domino邮件服务器的 A记录和MX记
录,使得Domino邮件服务器能够发送外出邮件。
  示例:
  该示例实现了两个Domino邮件服务器的邮件路由。
  1、首先要确认两台服务器能够互相PING通;
  2、要确认两台服务器内部邮件收发畅通;
  3、对Domino服务器进行上述修改;
  4、在网络域名服务器上设置上设置A记录和MX记录。
Domino服务器1的A记录为:
apps.salmon.forward.com. IN A 147.25.8.17
Domino服务器1的MX记录为:
salmon.forward.com. IN MX apps.salmon.forward.com.
Domino服务器2的A记录为:
mail.ntserver.nmg.gov.cn. IN A 147.25.8.66
Domino服务器2的MX记录为:
ntserver.nmg.gov.cn. IN MX mail.ntserver.nmg.gov.cn.
  注:
  1、在邮递失败和 Domino 发送无法邮递消息之前,消息在服务器之间所能传送的最
大次数默认是25次。
  2、服务器在重试将消息传送到另一台服务器之前应等待的分钟数。如果再次失败,
Domino 将增加等待时间。缺省为 15 分钟。
  环境介绍:
  1、邮件服务器
  2、DNS服务器设置
首页-->LOTUS文章-->如何在Notes开发的程序中实现修改留痕
如何在Notes开发的程序中实现修改留痕Notes 的一项很强大的功能是能够实现工作流审批,但是如何能使每个审批人在对原文进行修改后留下他们的修改痕迹呢?本人写了一段程序在Notes中嵌入word 97实现了该功能,希望对网友有所帮助。具体实现如下:首先在表单中创建一个RTF域body,以嵌入word 97,再做一按钮,该按钮实现对修改的留痕。其源程序为:Dim db As New notesdatabase(servername,"jswfw")Dim handle As Variant Dim doc As NotesDocumentSet doc=source.documentDim rtitem As VariantDim object As NotesEmbeddedObject Set rtitem = doc.GetFirstItem( "Body" )Dim session As New NotesSessionDim user As Stringuser = session.commonUserNameIf ( rtitem.Type = RICHTEXT ) ThenSet object = rtitem.GetEmbeddedObject_( "Microsoft Word 文档" )Set handle=object.activate(False)handle.showgrammaticalerrors=Falsehandle.showspellingerrors=Falsehandle.TrackRevisions = Truehandle.PrintRevisions = Truehandle.ShowRevisions = Truehandle.parent.UserName = userhandle.parent.UserInitials = userhandle.parent.UserAddress = ""handle.save End If 起草人在起草了文章后,单击该按钮,以后对该文章的所有修改都将保留痕迹。
首页-->LOTUS文章-->Notes文档查询的研究
Notes文档查询的研究 合肥工业大学管理系 张录娥 ---- Lotus Notes/Domino是一种基于Internet/Intranet技术为构架的群件系统,是构造企业信息网主要工具之一。信息检索技术作为 LotusNotes/Domino的一个主要技术,为用户提供了包括全文检索、按关键字查询、视图和文件夹等多种方式, 本文结合在实际开发中的经验体会,对Notes应用中文档查询进行讨论。 文档的查询 ---- 在LotusNotes中,信息是以文档男问奖4嬖谑菘庵械模桓鑫牡迪嗟庇诠叵敌褪菘庵械囊桓黾锹肌?也就是说,在NOTES应用中,对信息的查询就是对文档的查询,对文档的查询主要有以下几种方式:视图、文件夹、全文检索。下面我们来一一探讨他们的特点。 ---- 1. 视图 ---- 视图是 LotusNotes中文档的主要浏览窗口,每一视图都包含符合一定条件的文档。当一个视图的选择条件给定以后,通过该视图所看到的文档就是符合条件的文档,如某一视图的选择条件为:Select form="请假单"; 则打开该视图后,我们所看到的文档都是请假单。视图除了有选择条件外,还可以按不同的特性将文档进行分类和排序,使得我们可以及其快捷地导航到要查找的文档。对于简单的查询,可以不编写任何程序,而通过把视图按合理的方式进行分类和排序就可以了。 Notes视图设计是应用程序设计过程中较快的一步,如果数据库第一次就设计正确,拥有在正确文档中可用的全部必需的字段,那么设计视图应是一个容易的过程,且对用户来说是直观的,可打印输出屏幕上显示的视图。 ---- 2. 文件夹 文件夹也是文档的浏览窗口之一,但是和视图不同的是,文件夹没有选择条件,它里面的文档是通过Putinfolder来放进的,必须通过RemoveFromFolder来将其中的文档移开。 ---- 3. 全文检索 ---- 全文检索是 LotusNotes提供的基于数据库全文索引的搜索工具,它能根据给定的检索关键字在整个数据库中搜索,并把搜索结果显示在该视图的顶端。 ---- 4. 按关键字查询 ---- 好的查询设计应是对用户的查询给于准确快速的响应,准确,灵活地显示用户所需的数据。为满足用户多条件的组合查询,开发人员一般为用户设计一种"按关键字查询"方式,需要编写程序使用户可以输入一个或多个查询条件进行组合条件查询,找满足条件的文档。但是由于NOTES无法直接显示结果,一般的解决方法是:将查询结果存放到文件夹中,最后,打开文件夹显示查询结果。 文件夹方式存在的缺陷及解决方法 ---- 由于LotusNotes的文档是可以共享的,文件夹也可以共享,也就是说,你可以用这个文件夹来存放你的检索结果,我也可以用这个文件夹来存放我的查询结果,而且LotusNotes应该保证互相不冲突。然而遗憾的是,LotusNotes不作这个保证,导致的结果是大家互相影响,产生访问冲突。为了解决这一问题我们提出两种方法: ---- 1、建立私有文件夹 ---- 所谓私有文件夹,是指文件夹属于一人私有,其他人看不见这个文件夹。可以通过创建一个"启动后私有"文件夹,每个用户使用该文件夹后,系统立即根据这个启动后私有文件夹创建一个新的属于该用户的文件夹。这样,每个用户都有一个结构完全相同而且互相不干扰的文件夹。这种解决方法保证冲突不会产生,但系统为每个用户保存一个文件夹,会导致系统维护上的困难。如果系统的用户太多,情况会更坏。如果用户注销,它的私有文件夹不会自动删除。 ---- 2、改进的视图方法 ---- 视图一般是大家共享的,我们可以通过改进视图的选择条件,将视图作为我们存储查询结果的地方,就能避免文件夹方式产生的问题。我们提出解决问题的思路是:把满足某一用户查询条件的文档作选择标记,创建一个共享视图,用视图选择公式来显示该用户的查询结果,显示或打印完成后,删除选择标记。具体实现方法如下: ---- (1) 在要查询的数据库文档表单上创建一个可编辑多值的隐含?quot;SelectedUserName"用于存放查询该文档的用户名。 ---- (2) 创建一个共享视图vwSelect,视图公式为: ---- SELECT Form = "frmFormName" & ---- @Contains(SelectedUserName;@UserName) ---- 用于显示该用户查到的文档 ---- (3) 创建一个显示视图的导航器"nvgQueryResult",其初始视图为vwSelect。 ---- (4) 用Sript语言,利用FTSearch函数进行组合条件查询,查找满足条件的文档。 编程实现 ---- (1) 查询显示 ---- 功能:完成按关键字条件查询,显示查询结果. Dim session As New NotesSessionDim db As NotesDatabaseDim doc As NotesDocumentDim view As NotesViewSet db = session.CurrentDatabaseitemvalues=item1.valuesCondition=itemvalues(0)For i=Lbound(itemvalues)+1 to Ubound(itemvalues)Condition=Condition+itemvalues(i)'记载用户输入的全部查询条件NextCount=view.FTSearch(Condition,0) '完成全文查找If count〈〉0 ThenMessagebox"本数据库中共有:"+Str(Count) + "个记录满足条件!",0+64,"提示信息" For j=1 To countSet doc=dc.getnthdocument(j)Set item = doc.GetFirstItem( "SelectedUserName" ) Call item.AppendToTextList( session.UserName ) '在域SelectedUserName中Call doc.Save( True, True )'追加用户名NextServerName = session.GetEnvironmentString("ServerName")DirName = session.GetEnvironmentString("DirectionName")DatabaseName=DirName+"DBName.nsf" '打开导航器调用视图,即显示查询结果Call workspace.OpenDatabase ( ServerName,DatabaseName,"nvgQueryResult" )ElseMessagebox "没有满足条件的记录!",0 +48,"提示信息:"End Ifend(2) 退出显示 功能:清除用户的选择标记 Dim session As New NotesSessionDim db As NotesDatabaseDim doc As NotesDocumentDim view As NotesViewSet db = session.CurrentDatabase ' ViewName = session.GetEnvironmentString("envViewNa")Set view = db.GetView(vwSelect)Set doc = view.GetFirstDocumentUserName=session.UserName'取现用户名到变量:UserNameWhile Not (doc Is Nothing ) TempValue=doc.SelectedUserName '清除文档域"SelectedUserName"中doc.SelectedUserName=""'自己的用户名;Call doc.save(True,False) '同时保留其他用户的用户名.Set item=doc.getfirstitem("SelectedUserName") Forall x In TempValue If x〈〉 UserName Then Call item.AppendToTextList(x ) Call doc.save(True,False) End If End Forall Set doc = view.GetFirstDocument Wend end主要技术要点: ---- 以上应用设计主要运用了以下技术要点来保证显示结果的准确性和数据的共享性. ---- (1) 要查询的数据库文档表单上创建的可编辑多值的隐含域"SelectedUserName" . 域是构成表单的重要元素,对一个NOTES数据库来说,外部数据的录入要通过域, 库内存放数据显示也要依靠域。我们这里创建域"SelectedUserName"的作用是:存放查询该文档的用户名作为选择标志。 选择标志的确定: ---- 使用用户名作为选择标志主要因为在Notes中用户名是唯一的,不同的用户有不同的用户名,不会存在两个相同的用户名。这样,该域记住了有哪几个不同用户查询选择了此文档。为用视图显示文档做准备. 域的主要属性是: ---- 可编辑:数据可以通过按钮执行Formulas或Script来产生。 ---- 隐含的:只作存储,没有显示作用。显示文档时不显示该域的数据准许多值,准许用户存入多个值,保证该域记录下选择该文档所有的用户名。因为在共享数据状态下,同一个文档同时可被多个用户查询选择,你必须记住所有选择该文档的用户名。这一点对于多用户下显示数据十分重要。 ---- (2) 视图及视图选择公式: ---- 我们设计了一个共享视图vwSelect,视图公式为: ---- SELECT @Contains(SelectedUserName;@UserName) ---- 视图功能:显示所有域SelectedUserName中含有当前的用户名的文档。 ---- @UserName:返回当前的用户名。 ---- @Contains(SelectedUserName;@UserName): ---- 用于判断是否文档域SelectedUserName中含有当前的用户名; 因为在查询时,那些满足条件文档的域"SelectedUserName"中已被加入了用户名作为选择标志,所以该视图选择显示那些域SELECTEDUSERNAME中包含用户名的文档。 ---- 在视图的设计时,使用"打开后废弃索引"选项。 小结 ---- 综上所述,LousNotes为查询应用程序开发提供了灵活快速的环境,本文所述的几种方式都能实现对数据文档的查询检索,但是,它们的实现方法和满足的目的要求不尽相同。尽管还有不足之处需要完善, 但是仍然说明了一些能结合到你的应用程序中去的Notes技术,同时,我们必须清醒地认识到它与传统关系型数据库应用程序开发系统有很大的差别,查询设计有其独特的方式,一个应用程序能很快地被设计出来并且达到可用状态。试图将传统的应用程序开发技术映射到Notes环境中的开发人员,将很难获得Notes应用程序的优点。  
版权所有2001
LotusNotes4.5是一个很好的群件工作平台,它有很好的电子邮件系统,领先的全文检索和复制功能。它还具有极强的安全措施,可以可靠地保证信息安全性。但它在解决事务处理问题上功能较弱,这时就需要传统的关系型数据库管理系统来协助解决。如何把现有的关系型数据库信息转移到Notes数据库中,以利用Notes的许多良好性能共享数据,就是本文要讨论的问题。本文以Foxpro数据库为例,介绍LotusNotes访问异种数据库的一种实现方法。LotusNotes访问异种数据库的途径LotusNotes使用ODBC标准存取异种数据库信息。通过Notes里内嵌的公式或Script语言,可在Notes文档中引入非Notes数据库信息,把现成的数据转换成Notes数据库。Notes提供以下方法来存取外部数据:1.在Notes公式里利用@Db函数Notes提供@DbColumn、@DbLookup及@DbCommand三个函数,这三个函数的第一个参数用“ODBC",就可访问异种数据库信息。但它有一个缺陷:只能按列存取信息,而不能按记录存取信息。2.。利用LotusScript数据对象LSX兼容模块使用LotusScript语言来编写存取外部数据的函数,Notes的ODBCConnection、ODBCQuery及ODBCResultSet三个类为Notes提供了用ODBC标准存取异种数据库的属性和操作。实例:1.定义数据源在存取外部数据之前,必须定义一个数据源,以便让ODBC驱动程序管理器知道怎样获取数据。一个数据源把一个特定的ODBC驱动程序和要存取的数据联系在一起,并包括要存取的数据,它与服务器或目录、后台DBMS以及网络平台相联系,这些信息都记录在一个注册文件中(在Winows95中是ODBC.INI),可采用Windows的管理工具注册数据源。在Windows95中操作步骤如下:打开Windows控制面板,按ODBC图标,击Add按钮;选择需要的驱动程序,击OK按钮;输入数据源名称、描述信息以及所需要的其它信息;有些驱动程序还需要其他一些信息,输入这些必需的信息,并击OK按钮;击Close按钮关闭ODBC配置。2.LotusNotes访问Foxpro的一种实现方法实现Notes访问Foxpro数据库的基本编程思想是:对Foxpro的一个数据库,按其结构相应地在Notes数据库里建立一个同样结构的表单,以便把Foxpro字段的信息经转换后存入Notes表单相应字段中;建立一个代理,用Script语言编写转换程序;再创建一个视图运行这个代理,以实现异种数据库信息向Notes数据库转换。现有一个Foxpro数据库BMZBK.DBF,其结构如下:字段名类型宽度说明codeCharacter7指标编码nameCharacter40指标名称fullnameCharacter60指标全称unitCharacter12计量单位3.把这个库的所有信息转换到Notes库中的实现步骤如下:1.在Notes中新建一个数据库,取名为Convert.nsf,在这个数据库里创建一个表单,取名为codelib,其内容如下:域名类型说明code文本可编辑指标编码name文本可编辑指标名称fullname文本可编辑指标全称unit文本可编辑计量单位0在Convert.nsf库中建立一个代理,取名为vfpagent,定义如下:运行此代理的时间设定为:人工选择“操作”菜单执行;指定代理操作的文档设定为:视图中所有文档。2.此代理要执行的操作,用Script编写两个事件:(1)Option事件作如下编程:OptionPublicUselsx"*LSXODBC"'存取ODBC类库的全局对象(2)Initialize事件作如下编程:SubInitializeDimsessionAsNewNotessessionDimdbAsNotesdatabaseDimdocAsnotesdocumentSetdb=session.currentdatabaseSetdoc=Newnotesdocument(db)doc.form="codelib"DimconnAsNewODBCConnectionDimqryAsODBCQueryDimresultAsODBCResultSetCallconn.Disconnect()Setqry=NewODBCQuerySetresult=NewODBCResultSet'VFR是ODBC里注册好的数据源Ifconn.ConnectTo("VFP")ThenSetqry.Connection=connqry.SQL="SELECT*fromBMZBK"'发送查询请求Setresult.Query=qryCallresult.Execute()columns=result.Columns'取出结果集,并存入Notes相应的字段中DoUntilresult.IsEndOfDatadoc.code=Trim$(result.getvalue(1))doc.name=Trim$(result.getvalue(2))doc.fullname=Trim$(result.getvalue(3))doc.unit=Trim$(result.getvalue(4))Calldoc.save(True,True)Setdb=session.currentdatabaseSetdoc=Newnotesdocument(db)doc.form="codelib"Callresult.nextrow()LoopCallconn.Disconnect()'与数据源断开连接ElseMessagebox("Couldnotconnecttoserver")EndIfEndSub3.在Convert.nsf库中建立一个视图,取名为DemoView,在此视图里创建一个操作,标题为“转换”,运行方式为简单操作:运行“vfpagent"代理。这样在打开Convert.nsf数据库时,点击DemoView视图,就会在屏幕上方出现“转换”操作按钮,点击这个按钮,就可把Foxpro一个数据库BMZBK.DBF的所有信息转换成Notes数据库了。

转载地址:http://bbs.chinalotus.com/viewthread.php?tid=12106&extra=page%3D1&page=1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: