Lotus Domino WEB 开发技术积累

xinli_chen

贡献于2012-08-02

字数:288240 关键词: Web框架

 Lotus Domino WEB 开发技术积累 目录: 1. 选取视图的列的内容 @Trim @DbColumn 6 2. 隐藏判断常用的命令 6 3. 判断当前用户是否是“某个组”的成员,然后来显示和隐藏 6 4. 在Lotus Domino 中显示图 6 5. 链接JS文件 6 6. 删除文档的方法 7 7. $$return 域的使用 8 8. 将表单设计为视图或导航器模板 9 9. 为 Web 定制“表单已处理”确认信息 10 10. 定制出错信息 11 11. $$HtmlHead几种常用的技巧 11 12. Domino Designer 模板表 12 13. 角色判断 13 14. 判断文档是否正在被修改 13 15. 在只读的方式下返回($$return 13 16. 刷新表单 14 17. 怎样在文档里存照片? 14 18. 后台lotusscript如何取得前台表单中复选框所选择的项目列表(b/s结构) 15 19. 试图的列公式:附件下载 15 20. 有没有好一点的分页处理代码 16 21. 同一用户重复登录 18 22. Return to sender 19 23. Agent to copy values from 1 form to another 在同一个数据库中进行 22 24. 超越OLE – 通过COM结合MS Office与Notes应用 23 25. 读写关系数据库资料 28 26. 视图---excel,表单---word 32 27. 关于Web上的检索问题 35 28. 如何使用Notes与关系数据库进行信息交互? 37 29. 如何在IE里面实现notes中的 对话框列表? 39 30. LotusDomino环境下编写Web浏览器多数据库检索程序 40 31. WINAPI函数 44 32. 用PowerBuilder访问Lotus Notes数据库 55 33. 如何在表单中加入计数器 58 34. 实现两个数据库间的数据追加 C/S 结构 60 35. 如何防止他人使用旧id和旧口令访问Domino服务器? 61 36. 在你的WEB站点上使用DOMINO群集 62 37. 在你的DOMINO WEB站点中插入.SWF文件 73 38. DOMINO R5的域搜索功能在WEB上的实现 77 39. Display Rich Text fields in a view 86 40. Auto-Launch a file attachment 87 41. Showing a response count without showing the responses 89 42. 常用的几个按钮收集 91 43. 在WEB上从视图删除文档技巧 93 44. 在Domino Designer中使用XML数据 96 45. 在Domino Designer上执行XML 100 46. Show single category view, the next stage 107 47. Checkboxes in a list box 108 48. Formatting a Notes view in HTML table for WEB 109 49. Jump to the end of a view (web agent) 111 50. Disabling actions until a page finishes loading 114 51. Web-based, fully customizable search 115 52. 从复选框中删除文档Deleting selected docs on Web 120 53. Debugging LotusScript Agents 121 54. Displays the contents of the Subject field in the first document in theExamples view. 124 55. Example: GetLastDocument method 125 56. Examples: GetNextDocument method 125 57. Example: GetFirstDocument method 126 58. Examples: FTSearch method 127 59. Examples: DeleteDocument method 128 60. Example: Deleting a document 129 61. Example: Creating a document 129 62. Examples: Locating documents within a view or folder 130 63. Example: Adding a document 135 64. Export to Excel 136 65. 连接ODBC 138 66. 特效 140 67. notes和Excel交换数据 141 68. NOTES的ODBC:(LS:DO) 142 69. Managing JavaScript "popup" windows 第一稿 144 70. HEAD元素使用集锦 147 71. 主页javascript特效19则 148 72. 关于创建、删除、编辑、打开和保存文档的 URL 命令 156 73. Domino URL 命令 158 74. 在打开有下面这段代码的页面时将会跳出一个468x60大小的小窗口 160 75. javascript的容错脚本 161 76. Web search with JavaScript 162 77. 如何防止他人使用旧id和旧口令访问Domino服务器 164 78. Fixing the Domino CheckBox Bug 165 79. Managing JavaScript "popup" windows 172 80. Quick, easy, foolproof field level help 175 81. Quick edit document link 176 82. Managing JavaScript "popup" windows 178 83. Svg: Pie-Eyed 181 84. Recebt Entries 182 85. Xin Calendar Mods 183 86. 答复文档 186 87. 公式语言 187 88. Resuable way to get URL parameters into fields 199 89. JSHeader 使用 201 90. JavaScript 帮助 201 91. Examples: Collecting documents by searching 207 92. 关于DOcumentContext 的属性 209 93. About data types 关于lotus Domino 的数据类型 210 94. CLng function 212 95. Using the DOM to replace "No documents found" 213 96. What you need and want to know about errors 217 97. Processing multiple documents from a view 221 98. Forcing attachments to always download 225 99. ODBCExample: GetValue method 247 100. ODBCResultSet class 248 101. Create a "Login" anchor link 251 102. 分类视图的开发技巧 253 103. 公式语言 255 104. Copy documents from one database to another 267 105. 定制搜索表单 268 106. UserName的属性及使用 275 107. Dynamic Content for Popup Windows 277 108. Shortcut when printing from a Java Agent 278 109. Lotus Script: Write # statement 279 110. Lotus Script: Input # statement 280 111. 使用代理生成 XML 284 112. 使用视图生成 XML 286 113. 执行算术运算 288 114. Keep URLs simple by making them relative 292 115. Quick, easy, foolproof field level help 294 116. Hiding attachments (without noscript tag!) 295 117. Listing search results in groups 296 118. 如何在表单中加入计数器? 300 119. 怎样限制一个WEB用户只有登陆才能使用数据库 302 120. Complete control when printing HTML from an agent 304 121. Simple multi-lingual forms using Domino 306 122. Stop double form submissions 308 1. 选取视图的列的内容 @Trim @DbColumn 备注 程序代码 @Trim(@DbColumn("":"nocache";@DbName;"bjialist";1)) 2. 隐藏判断常用的命令 备注 程序代码 @IsDocBeingEdited|!@IsMember("[admin]";@UserRoles) 3. 判断当前用户是否是“某个组”的成员,然后来显示和隐藏 备注 程序代码 @IsMember("names.nsf中的用户组";@UserNamesList) 4. 在Lotus Domino 中显示图 备注 程序代码 img:="

"; @If(@AttachmentNames!="";img;" ") 5. 链接JS文件 备注 程序代码 "" 6. 删除文档的方法 备注 程序代码 REM "Do not show delete link on a new document"; @If(@IsNewDoc; ""; "Delete Document...") REM "Do not show delete link on a new document"; @If(@IsNewDoc; ""; "") 7. $$return 域的使用 备注 程序代码 返回到另外的一个页面 "[http://www.lotus.com]" 增加到另外页面的链接 "Lotus" 个人化信息 "

谢谢您的文档,"+@name{[cn];@userName}+"!


" 返回到文档,查询刚才输入的信息 Rem "Anchors to document view" " " + "查询输入的内容"+"" 在$$Return域中使用JavaScript : back2:=”” back3:=”” @if(@IsNewdoc;back2;back3) Create a view (All) with all documents of your db.In your form create a computed field called Doc_ID with formula @Text(@DocumentUniqueId) and a $$Return field with: dominoserver:=@Name([CN];@Subset(@DbName;1)); filename:=@Subset(@DbName;-1); Doc_Id:=Doc_Id; "[http://"+dominoserver+"/"+filename+"/All/"+Doc_Id+"?opendocument]". 8. 将表单设计为视图或导航器模板 备注 程序代码 在 Web 应用程序中,要创建表单与视图或导航器之间的关联,可为表单指派一个保留名称。用户打开视图或导航器时 Domino 将表单用作模板。这对于在站点上创建视图和导航器的标准显示来说是一种好方法。 使用以下保留表单名称创建表单与视图或导航器之间的关联。 请注意 Domino 要求表单上必须有嵌入视图或 $$ViewBody 域,但可以不考虑其值。 表单名称 必需的设计元素 注释 $$ViewTemplate for viewname 嵌入视图或 $$ViewBody 域 将表单与特定视图关联。表单名包括 viewname,即视图的别名,如果没有别名,就包括视图的名称。 $$NavigatorTemplate for navigatorname 嵌入导航器或 $$NavigatorBody 域 将表单与特定导航器关联。表单名包括 navigatorname,即导航器名称。例如:被命名为 "$$NavigatorTemplate for World Map" 的表单将与 World Map 导航器关联。 Domino 忽略在表单上创建和读取存取列表。 $$ViewTemplateDefault 嵌入视图或 使该表单成为所有与另一表单不关联的 Web 视图的模板。 $$ViewBody 域 $$NavigatorTemplateDefault 嵌入导航器或 $$NavigatorBody 域 使该表单成为所有与另一表单不关联的 Web 导航器的模板。 9. 为 Web 定制“表单已处理”确认信息 备注 程序代码 Web 用户提交文档后,Domino 使用缺省的“表单已处理”的确认信息回应用户。要重新设置缺省答复,可将计算文本域添加到表单中,给此域命名为 $$Return,并使用 HTML 作为计算值来创建定制的批准。 显示个人化答复 下面的 $$Return 公式返回答复“Thank you”,并附加上用户姓名: who:= @If(@Left(From; " ") = ""; From; @Left(From; " ")); @Return("

Thank you, " + who + "


Main View"); 显示定制的错误消息 要定制显示给 Web 用户的错误消息外观,向数据库中添加定制的错误消息表单。如果发生错误条件,且其定制表单存在,则 Domino 使用定制表单来显示错误消息。否则,Domino 使用缺省错误消息表单。添加到数据库的消息表单将覆盖由管理员设置的服务器范围内的消息。 要在表单和错误条件之间创建关联,创建拥有下列名称之一的表单。然后创建名为 MessageString 的可编辑的文本域来保存错误消息。添加要与错误消息一起显示的其他文本、链接以及其他表单对象。 表单名称 条件 $$ReturnAuthenticationFailure 不能校验用户名称和口令。 $$ReturnAuthorizationFailure 用户对该数据库没有足够的存取级别。 $$ReturnDocumentDeleted 成功删除文档。 $$ReturnGeneralError 出现了其他错误条件。 链接到另一页面 根据提交文档中的域值,在 HTML 中包括链接到另一页面的 URL。下面的 $$Return 公式根据用户选择的范围返回答复。例如:如果用户选择欧洲,则消息“在意大利访问我们的站点”将显示一个链接,可链接到意大利的 Web 站点(假定公式中的“stdAnswer”和“stdFooter”已预先定义。)。 @If(Region="Asia"; stdAnswer + "

Visit our site in Japan

" + stdFooter; Region="Europe"; stdAnswer + "

Visit our site in Italy

" + stdFooter; stdAnswer + stdFooter); 返回另一页面 要跳转到不同的 Web 页面,可将页面的 URL 用括号括起来放入页面。当用户提交文档时,Web 客户机将显示引用的文档。例如:下面的 $$Return 公式显示 Lotus 日本站点的主页。 "[http://www.japan.lotus.com]" 10. 定制出错信息 备注 程序代码 要想在发生一个错误之后,向用户返回定制的出错信息,可以使用如下的表单: 表单名称 描述 $$ReturnDocumentDeleted 用户成功删除了文档 $$ReturnAuthenticationFailure 用户的名称和密码无法验证 $$ReturnAuthorizationFailure 用户没有足够高的权限来访问数据库 $$ReturnGeneralError 发生了任何其他类型的错误 11. $$HtmlHead几种常用的技巧 备注 程序代码 自动刷新WEB页面: a http-equiv=\”refresh\” content=2>” 自动链接到另外的页面: URL:=”http://www.lotus.com”; “” 例子: url:="http://190.2.40.220/jjxmxx.nsf/jjxmxx_view?OpenForm"; "" 12. Domino Designer 模板表 备注 程序代码 模板在开发流程的后期被更新。当 Domino Designer 可以使用时,下表列出的模板可能已经改变,或者附加了一些可用模板。 如果使用 Domino Designer 安装模板,则可以在 Notes 程序目录下找到它们。 数据库标题 文件名及设计模板名 面向对象 描述 讨论- Notes & Web (R5.0) (*) discsw50.ntf StdR50Disc Notes 的一般用户和 Web 浏览器用户 电子会议室。 特性: 具有内置用户简要表来自动邮寄感兴趣的项目链接的线程化讨论。 匿名答复、归档和创建公用/私有线程。Web 浏览器用户的多导航器、备用视图模板和热点操作。 文档集-Notes & Web (R5.0) doclbw50.ntf Notes 的一般用户和 文档存储。 (*) StdR50WebDocLib Web 浏览器用户 特性:评阅工作流程(串行和并行)和归档。 Microsoft Office 文档集 (R5.0) doclbm50.ntf StdR50DocLibMS Notes 的一般用户 为此应用程序套件开发的文档集的特殊版本。 自动装载 OLE 对象并将 OLE 对象放大到窗口大小;并存储和支持文档(由套件创建)的评阅流程。 个人日志 (R4) journal4.ntf StdR4Journal Notes 的一般用户 电子日记,用户可使用它来记录个人想法和个人文档。其中包括定制设计的指令。 站点注册 5.0 siregw50.ntf StdSite50Reg Web 浏览器用户 一个样例,演示如何为基于 Domino 的应用程序注册 Web 用户。不用手动干涉用户即可自动创建帐号。 工作室 (R5.0) (*) teamrm50.ntf StdR50TeamRoom Notes 的一般用户和 Web 浏览器用户 工作组协同工作的模型。 维护若干文档交流类型来提交会议、讨论和操作项目。功能并行, 评阅进程、归档和新闻简报。 13. 角色判断 备注 程序代码 !@IsMember("admin"; @UserRoles) 14. 判断文档是否正在被修改 备注 程序代码 @Isdocbeingedited 15. 在只读的方式下返回($$return 备注 程序代码 比如修改$$return 再比如在按钮里面写公式: jspath:="/"+@ReplaceSubstring(@Subset(@DbName;-1);"\\";"/"); @Command([FileSave]);@URLOpen(jspath+"/0/"+docid+"?opendocument") 16. 刷新表单 备注 程序代码 calling _doClick('$Refresh', this, '_self') through javacript will refresh the form and reloads the tables 17. 怎样在文档里存照片? 备注 程序代码 建一个域(RTF),将该域设置成热点,然后对其click编写如下公式: @command([FileImport];"文件类型";"所在目录") 其中文件类型对于图片可以是gif/jpeg格式的,可以省略 所在目录,可选 18. 后台lotusscript如何取得前台表单中复选框所选择的项目列表(b/s结构) 备注 程序代码 Dim DQsessionnew As New notessession Dim workspace As New NotesUIWorkspace Dim DQdocument As Notesdocument Dim DQdatabase As Notesdatabase Dim Dqitem As NotesItem Dim DQuid Set DQdatabase = DQsessionnew.CURRENTDATABASE Set DQuid = workspace.CurrentDocument Set DQdocument=DQuid.document Set DQitem = DQdocument.GetFirstItem("A") Forall v In DQitem.Values Messagebox( v ) End Forall A为复选域名 同意 gwmdj(gw) ; 最好将 A为复选域名 改为$$SelectDoc 19. 试图的列公式:附件下载 备注 程序代码 _docRef := "0/" + @Text(@DocumentUniqueID); _attachRef := @ReplaceSubstring(@AttachmentNames; " "; "+"); _href := _docRef + "/$File/" + _attachRef + "?OpenElement"; _aTag := "" +"  "+ title + ""; _html := "[" + @Implode(_aTag; ", ") + "]"; @If(@Attachments = 0; title; _html) 20. 有没有好一点的分页处理代码 备注 程序代码 在clpclub上看到的 该代理在webqueryopen里面打开 文章主题:RE: 有没有好一点的分页处理代码?呵呵 :) 狂雷天牢 2002-03-15 11:43:26 -------------------------------------------------------------------------------- Sub Initialize Dim s As New NotesSession Dim doc As NotesDocument Set doc=s.DocumentContext Dim db As NotesDatabase Set db=s.CurrentDatabase Dim view As NotesView Set view=db.GetView(doc.v_view(0)) If view Is Nothing Then Msgbox "view is Nothing!" Goto bz End If Dim viewdc As NotesViewEntryCollection If doc.v_keysort(0)<>"" Then Set viewdc=view.GetAllEntriesBykey(doc.v_keysort(0)) Else Set viewdc=view.AllEntries End If Dim numdoc,rowsperpage As Integer numdoc=viewdc.count rowsperpage=Val(doc.v_rowsperpage(0)) If (numdoc Mod rowsperpage)=0 Then doc.v_pagenum=numdoc/rowsperpage Else doc.v_pagenum=Int(numdoc/rowsperpage)+1 End If Dim start As Variant start=Evaluate({@middle(query_string;"start=";"&")},doc) If start(0)<>"" Then doc.v_currentpage=Int(Val(start(0))/rowsperpage)+1 Else doc.v_currentpage="1" start(0)="1" End If Dim item As NotesItem Set item=doc.GetFirstItem("v_dispage") If Cstr(doc.v_gopage(0))<>"" Then start(0)=(doc.v_gopage(0)-1)*rowsperpage+1 End If For i=Int(Val(start(0))/rowsperpage)-4 To Int(Val(start(0))/rowsperpage)+4 If i>=0 Then If i>=doc.v_pagenum(0) Then Exit For End If If i=Int(Val(start(0))/rowsper page) Then Call item.AppendToTextList("当前第"+Cstr(i+1)+"页") Else Call item.AppendToTextList("[["+Cstr(i+1)+"]]") End If End If Next bz: Print {} Print {} End Sub 21. 同一用户重复登录 备注 程序代码 var ConflictResult=document.forms[0].ConflictResult.value; if ((ConflictResult.indexOf("同一用户重复登录!")!=-1) || (ConflictResult.indexOf("文档锁定!")!=-1)){ while(ConflictResult.indexOf("\\n")!=-1) ConflictResult=ConflictResult.replace("\\n","\n"); alert(ConflictResult); } document.forms[0].ConflictResult.value=""; 就是用户对于同一份文档重复登录时,提示此文档已被锁定,由某用户正在编辑。仅供参考。 Remind:此消息由justle在08-15 14:50:08做过手脚,呵呵…… 22. Return to sender 备注 This Lotus developer was trying to come up with a clever solution to forward incoming emails to recipients' text enabled mobile phones. Instead he ended up setting off a mail bomb on himself and his ASP. The following story is a good example of how a clever idea can blow up in your face, or your inbox. 程序代码 This Lotus developer was trying to come up with a clever solution to forward incoming emails to recipients' text enabled mobile phones. Instead he ended up setting off a mail bomb on himself and his ASP. The following story is a good example of how a clever idea can blow up in your face, or your inbox. I was doing some development work to create an agent that would run when a new mail arrives and send a summary to the mobile phone text service (SMS). I had set the agent to run on new mail received but for each mail received it sent summaries of all e-mails in my DB! Anyway the poor ASP that was forwarding my sms's had a limit of 100 per day so any subsequent sms was rejected with an e-mail, which in turn triggered another flood of emails which in turn resulted in a stream of rejections which in turn... well you get the picture. I left this running overnight!!!! The result: Some 40,000 e-mails outbound with a similar number inbound and a very cranky ASP. I was very red-faced then next morning to return to the office with a lot of phone messages from ASP. It was an easy fix though, but now I have lifetime ban from the ASP, I have now fixed the agent (below) which looks in the calendar profile for details of SMS email address the Agent is set to run 'AfterNew mail Has Arrived' on Newly Received Mail Documents. Code: 'Options Option Public Option Declare Sub Initialize Dim session As New NotesSession Dim dbCurrent As NotesDatabase Dim collUnprocessed As NotesDocumentCollection Dim docCurrent As NotesDocument Dim itemBody As NotesItem Dim strPriority As String, strImportance As String Dim varBody As Variant Dim strSendTo As String Dim m_calprofile As notesdocument Dim sendsms As String Set dbCurrent = session.CurrentDatabase Set m_calprofile = dbCurrent.GetProfileDocument("CalendarProfile") strSendTo = M_calprofile.SMSAddress(0) 'Celluar pager address sendsms = M_calprofile.SMSOwner(0) If sendsms = "Yes" Then 'I want to be notified If (dbCurrent Is Nothing) Then 'Nothing to Process Else Set collUnprocessed = dbCurrent.UnprocessedDocuments If collUnprocessed.Count < 1 Then Else Set docCurrent = collUnprocessed.GetFirstDocument If (docCurrent Is Nothing) Then 'No handle for Current Doc Else Do strPriority = docCurrent.DeliveryPriority(0) strImportance = docCurrent.Importance(0) If ((docCurrent.Form(0) = "Memo") And (strPriority = "H" Or strImportance = "1")) Then 'Need to create new memo & send to pager. Dim docPagerMemo As New NotesDocument(dbCurrent) Dim varFrom As Variant, strSubject As String, strBodyText As String docPagerMemo.SendTo = strSendTo varFrom = Evaluate({@Name([CN]; From)}, docCurrent) strSubject = docCurrent.Subject(0) Set itemBody = docCurrent.GetFirstItem ("Body") If (itemBody Is Nothing) Then 'Body can not be read docPagerMemo.Body = "Text can not be read. Check your email. | From: " & varFrom Else 'If Body can be read, return only 200 characters strBodyText = "Fr: " & varFrom(0) & " : " & Left(itemBody.Abstract(1000,1,0), 200) docPagerMemo.Subject = strSubject docPagerMemo.Body = strBodyText docpagermemo.inetfrom = "b2b" End If Call docPagerMemo.Send(False) Call session.UpdateProcessedDoc(docCurrent) End If Set docCurrent = collUnprocessed.GetNextDocument(docCurrent) Loop Until (docCurrent Is Nothing) End If End If End If Else 'No I dont want to be notified Exit Sub End If End Sub 'End of Agent Regards, George 23. Agent to copy values from 1 form to another 在同一个数据库中进行 备注 程序代码 First, create two views: Form1 Selection formula: SELECT form = "Form1" Form2 Selection formula: SELECT form = "Form2 Put the following in the querysave of Form1 form: '======================================= dim session as New NotesSession dim ws as New NotesUIWorkspace dim uidoc as NotesDocument dim db as NotesDatabase dim view as NotesView dim doc1 as NotesDocument, doc2 as NotesDocument set uidoc = ws.CurrentDocument set doc1 = uidoc.Document set view = db.GetView("Form2") set doc2 = view.GetFirstDocument ' you now have a handle on both documents 'now do this... doc2.FieldA = doc1.FieldA call doc2.save(true,true) '======================================= that was all done without testing, so you might have to tweak something here or there, but that is the idea. - Matt 24. 超越OLE – 通过COM结合MS Office与Notes应用 备注 程序代码 COM技术在Notes程序中的运用,极大丰富了Notes应用的功能和应用范围,本文对该技术的具体使用方面作一介绍。 要在Domino Designer中使用MS Office COM对象,你必须确认使用了正确的对象库,当安装了Office后,这些库就能在Domino Designer自动显示出来,虽然这些不是准确意义上的OLE类,它们还是显示在了Domino Designer设计界面“参考”附签中的“OLE classes”分类下。其中,Word 8.0 对应Office97, Word 9.0 对应Office2000。 为了确保该集成应用能正确运行,用户应在本地注册表中正确注册了相应的Windows应用程序(如Word 或 Excel)。 在使用MS Word的COM接口之前,你必须先理解MS Word对象层次关系结构,如你有些VB的编程经验的话,你已经或多或少接触了该层次结构。具体内容可在MS Office帮助中“Visual Basic入门指南”下的“Microsoft Word对象”一节中查阅。比如你要对Document对象进行操作,可查到Document对象的所有方法和属性,再进行相应的编程。 操作对象的两个基本步骤: 1、 为该对象定义一个Notes变量,类型为Variant; 2、 创建该对象。 代码如下: Dim officeApp as Variant Set officeApp = CreateObject( “Word.Application.9” ) ‘ 对应Office 2000 可以定义MS Word对象层次关系结构中各层的对象,如: Dim officeDocs as Variant Set officeDocs = officeApp.Documents Dim officeMainDoc as Variant Set officeMainDoc = officeDocs.Open( “c:\training.doc” ) 本文的例子中,我们将把选中的多个Notes文档中的客户信息合并到一个Word文档中,并按照Word文档中设定的格式进行信封打印,这些都是通过COM对象来完成的。 本示例中,假定有一个简单的数据库,其中存放有客户信息,如公司信息和客户个人信息等,数据库视图有三个操作:Envelopes, MailingLabels, MailMerge.这实际上是通过三个代理来完成的。当某个操作被执行时,对应的代理完成如下步骤: 1、 把选中的客户文档收集到一文档集合中; 2、 在后台打开一个Word session; 3、 把文档集中的文档某些内容合并到一个为本例设计的Word文档中; 4、 打印该文档; 5、 清空该Word 文档(模板)内容(准备下一次的合并)。当然你在清空之前也可以保存该结果文档。 你事先要按Word结果文档的要求建立一个Word 格式文件,其中包含与Notes文档中对应的多个域,两边的域名称不一定要相同,如本例中Notes文档内公司名为“CompName”,而Word中为“Company”。在本例的Word 文件中相应的6个域为:Company, Address, ZipCity, Country, Date, Regarding. 如何构建MailMerge代理? Sub Initialize Dim officeApp As Variant Dim offic eMainDoc As Variant Dim officeSel As Variant Dim officeFields As Variant Dim x As Integer Dim domDoc As NotesDocument Dim domColl As NotesDocumentCollection Dim domSes As New NotesSession Dim domDb As NotesDatabase ' Setting Notes environment Set domDb = domSes.CurrentDatabase Set domColl = domDb.UnprocessedDocuments Set domDoc = domColl.GetFirstDocument ' Setting Word enviornment Set officeApp = CreateObject("Word.Application.9") Set officeMainDoc = officeApp.Documents.Open("c:\MergeMe.doc") Set officeFields = officeMainDoc.FormFields While Not (domDoc Is Nothing) With domDoc officeFields.Item("Company").Result=.CompName(0) & Chr$(13) & .ContName(0) officeFields.Item("Address").Result=.CompAddress(0) officeFields.Item("Zipcity").Result=.CompZip(0) & " " & .CompCity(0) officeFields.Item("Country").Result=.CompCountry(0) officeFields.Item("Today").Result=Str$(Today) officeFields.Item("Regarding").Result=.ContInterest(0) End With ' Print-out Call officeMainDoc.PrintOut(True) Set domDoc = domColl.GetNextDocument(domDoc) Wend ' Quit Application / Close the connection ' Wait for all print jobs to finish Print "Waiting for print jobs. No. of pending print jobs: " & Cstr(officeApp.BackgroundPrintingStatus) While officeApp.BackgroundPrintingStatus > 0 ' Wait Wend P rint " " ' to delete the earlier print sentence Call officeApp.Quit(False) End Sub 如何编写Envelopes代理? Sub Initialize Dim officeApp As Variant Dim officeMainDoc As Variant Dim officeEnvelope As Variant Dim domDoc As NotesDocument Dim domColl As NotesDocumentCollection Dim domSes As New NotesSession Dim domDb As NotesDatabase Dim ToAddress As String Dim FromAddress As String ' Setting Notes environment Set domDb = domSes.CurrentDatabase Set domColl = domDb.UnprocessedDocuments Set domDoc = domColl.GetFirstDocument ' Setting Word enviornment Set officeApp = CreateObject("Word.Application.9") Set officeMainDoc = officeApp.Documents.Add() Set officeEnvelope = officeMainDoc.Envelope Call officeEnvelope.Insert() officeEnvelope.DefaultSize="B4" officeEnvelope.ReturnAddress="Lotus Development Corp." & Chr$(13) & "55 Cambridge Parkway"  & Chr$(13) & "Cambridge, MA 02142" While Not (domDoc Is Nothing) With domDoc officeEnvelope.Address=.CompName(0) & Chr$(13) & .ContName(0) & Chr$(13) & .CompAddress(0) & Chr$(13)  & .CompZip(0) & " " & .CompCity(0) & Chr$(13) & .CompCountry(0) End With ' Print-out Call officeEnvelope.PrintOut(True) Set domDoc = domColl.GetNextDocument(domDoc) Wend ' Quit Application / Close the connection ' Wait for all print jobs to finish Print "Wai ting for print jobs. No. of pending print jobs: " & Cstr(officeApp.BackgroundPrintingStatus) While officeApp.BackgroundPrintingStatus > 0 ' Wait Wend Print " " Call officeApp.Quit(False) End Sub 如何编写MailingLabels代理? Sub Initialize Dim officeApp As Variant Dim officeDoc As Variant Dim officeLabelDoc As Variant Dim officeCustomLabelDoc As Variant Dim domDoc As NotesDocument Dim domColl As NotesDocumentCollection Dim domSes As New NotesSession Dim domDb As NotesDatabase Dim TmpAddress As String ' Setting Notes environment Set domDb = domSes.CurrentDatabase Set domColl = domDb.UnprocessedDocuments Set domDoc = domColl.GetFirstDocument ' Setting Word enviornment Set officeApp = CreateObject("Word.Application.9") Set officeDoc = officeApp.Documents.add() Set officeLabelDoc=officeApp.MailingLabel Set officeCustomLabelDoc = officeLabelDoc.CustomLabels.add("MyLabel") ' Set a custom label officeCustomLabelDoc.NumberAcross=2 officeCustomLabelDoc.NumberDown=5 While Not (domDoc Is Nothing) With domDoc ' Print-out / print one page with each label ' Use the last attribute on PrintOut to determine the paper tray ' You can use an attribute on PrintOut - to printout only one label Call officeLabelDoc.PrintOut("MyLabel", .CompName(0) & Chr$(10) & .ContName(0) & Chr$(10)  & .CompAddress(0) & Chr$(10) & .CompZip(0) & " " & .CompCity(0) & Chr$(10) & .CompCountry(0)) End With Set domDoc = domColl.GetNextDocument(domDoc) Wend ' Quit Application / Close the connection ' Wait for all print jobs to finish Print "Waiting for print jobs. No. of pending print jobs: " & Cstr(officeApp.BackgroundPrintingStatus) While officeApp.BackgroundPrintingStatus > 0 ' Wait Wend Print " " Call officeApp.Quit(False) End Sub 本文因篇幅所限,不能对每个过程详细解释。如想得到文中提及的示例数据库和Word模板,可与我联系。希望能对各位有用。 25. 读写关系数据库资料 备注 程序代码 在Notes数据库中,可以通过公式函数和Script读写其他关系数据库资料,本文就是举例讲解如何通过程序读写关系数据库,为了方便,以通过ODBC访问TXT文件数据库格式举例。 一、 设置ODBC数据源 Notes是通过ODBC数据源来访问关系数据库,但其他特殊数据库,如DB2,ORACLE等,有特殊的形式,不再此处解释。 1、 在操作系统的控制面板中,打开“ODBC数据源”。 2、在“用户DSN”中单击“添加”,增加一个新的数据源。 3、选择数据源的驱动程序,本例选择“Microsoft Text Driver(*.txt,*.csv)”,单击“完成”。 4、在“ODBC文本安装中”输入: 数据源名称:此名称将是Notes访问ODBC数据库的识别名称,区分大小写,本例使用“TESTXT”。  描述:解释说明,可以缺省  目录:指定数据库的表单位置。本例为“c:\txt”  注:真正的数据库文件应该是一个包括若干表单的文件数据资料库,如*.nsf数据库文件,而*.TXT,*.DBF等文件不能叫数据库,只能是属于数据库中的一个表单。因此需要指定其文件所属的数据库文件,即目录地址,表示此目录下的所有*.txt文件都属于此数据库中的表单。  5、在定义格式中,需要指定*.txt文件字段之间的分隔符,此例为"Tab" 6、在指定*.txt表单的字段名称,本例为: Field_Char:字符类型,10位  Fidle_Int:整数类型  7、全部完成后,在“用户DSN”中可以看到“TESTXT”,表示ODBC数据库设置完成。 8、在“c:\txt”目录中新建一个"abc.txt"文件,需要使用英文文件名称,数字有些问题,内容为 "aa"    1(用TAB分隔) "bb"    2 二、利用Notes函数访问数据库 1、@DbColumn:检索指定的DBMS、表和列,并返回该列的所有值。参见此函数的使用方法。 本例返回所有记录中的字段Table_Char的值: @DbColumn("ODBC" : "NoCache" ; "TESTXT" ; "";"";"ABC.TXT" ;"Table_Char" ) 返回"aa":"bb" 2、@DbLookup:检索指定的 DBMS,表和列,并对那些关键字列的值和指定的关键字匹配的记录返回该列的值。参见此函数的使用方法。     本例搜索字段Table_Char = "aa"的记录,并返回其字段Table_Int的值:     @DbLookup("ODBC":"NoCache";"TESTXT";"";"";"ABC.TXT";"Table_Int";"";"Table_Char";"aa")     返回:1 说明:这两条公式函数都能返回数据库,可以在域初始值的计算公式中使用,建议最好使用LotusScript来代替这两个函数,因为这两个函数对访问错误比较难捕获和处理。 三、利用Script读取数据库 使用LotusScript访问数据库的完整函数: 注意:使用LotusScript访问数据库一定要在(Options)中加入Uselsx "*LSXODBC"命令 Sub Click(Source As Button)                     Dim con As New ODBCConnection '定义ODBC连接对象     Dim qry As New ODBCQuery '定义ODBC执行对象     Dim result As New ODBCResultSet '定义ODBC结果处理对象     On Error Goto errorHandler '如果有错误,就显示错误信息     Set qry.Connection = con     Set result.Query = qry     con.ConnectTo("TXTEST") '激活连接TESTXT数据库     qry.SQL = "SELECT Table_Chat,Table_Int FROM ABC.TXT" '决定对表单的“ABC.TXT”的字段Table_Char,Table_Int进行处理     result.Execute  '执行SQL命令     maxrow = result.MaxRows '获得表单的记录数     Call result.FirstRow '定位第一条记录     Do         aa = result.GetValue("Table_Char")         bb = result.GetValue("Table_Int")         Print aa,bb '将返回的值,打印显示         Call result.NextRow '继续下一条记录     Loop While maxrow > result.CurrentRow '如果搜索到最后条记录,退出循环     result.Close(DB_CLOSE)     con.Disconnect Exit Sub errorHandler:     Messagebox result.GetExtendedErrorMessage,, result.GetErrorMessage     Exit Sub End Sub 四、利用Script写入数据库 使用LotusScript访问数据库的完整函数: 本函数仅加入了一条记录,你可以使用循环,将Notes数据库中的值加入到ODBC中。 Sub Click(Source As Button)                     Dim con As New ODBCConnection '定义ODBC连接对象     Dim qry As New ODBCQuery '定义ODBC执行对象     Dim result As New ODBCResultSet '定义ODBC结果处理对象     On Error Goto errorHandler '如果有错误,就显示错误信息     Set qry.Connection = con     Set result.Query = qry     con.ConnectTo("TXTEST") '激活连接TESTXT数据库     qry.SQL = "SELECT Table_Chat,Table_Int FROM ABC.TXT" '决定对表单的“ABC.TXT”的字段Table_Char,Table_Int进行处理     result.Execute  '执行SQL命令     result.AddRow '增加一行记录     Call result.SetValue("Table_Char","cc")     Call result.SetValue("Table_Int",3)     result.UpdateRow '将增加的记录更新到数据库文件中     result.Close(DB_CLOSE)     con.Disconnect '关闭数据库,断开连接 Exit Sub errorHandler:     Messagebox result.GetExtendedEr rorMessage,, result.GetErrorMessage     Exit Sub End Sub 26. 视图---excel,表单---word 备注 程序代码 你的网站很好,交流的气氛很浓,我从中获得不少益处。 我近几天解决了“视图---excel","表单---word"的问题。相信你对notes视图打印有同样的不满。我无个人网站,加之我的程序也是从网上抄的,版权不详,希望你能试试,然后告诉更多人。我个人已试成功。 《视图---excel》也可作成后台代理 Sub Click(Source As Button) Dim session As New NotesSession  Dim db As NotesDatabase  Dim view As NotesView  Dim doc As NotesDocument  Dim excelApplication As Variant  Dim excelWorkbook As Variant  Dim excelSheet As Variant  Dim i As Integer  '--- Dim selection As Variant Set excelApplication = CreateObject("Excel.Application")  excelApplication.Visible = True  '找到excel的位置 path = session.getenvironmentstring("directory",True) gzpath=path+"\"+"th.xls" ' execelApplication.excel.open(gzpath) Set excelWorkbook = excelApplication.Workbooks.Add  Set excelSheet = excelWorkbook.Worksheets("Sheet1")  '定义excel的列植 excelSheet.Cells(1,1).Value = "姓名"  excelSheet.Cells(1,2).Value = "年龄"  i = 1  Set db = session.CurrentDatabase  '定义打印的视图 Set view = db.GetView("打印")  Set doc = view.GetFirstDocument  While Not(doc Is Nothing)  i = i + 1  '定义域名为“姓名” excelSheet.Cells(i,1).Value = doc.姓名(0) excelSheet.Cells(i,2).Value = doc.年龄(0)  Set doc = view.GetNextDocument(doc)  Wend  '选择a到d列 excelSheet.columns("a:d").select  'excelSheet.Columns(A:g).Select  excelSheet.Columns("A:d").EntireColumn.AutoFit  ' excelSheet.Columns("A:d").EntireColumn.AutoFit '加上表格线 excelsheet.PageSetup.PrintGridlines = True '输出到打印机 excelWorkbook.printout '保存的位置,防止退出提问(可能可以用excel的模版解决的更好) excelWorkbook.SaveAs("Script 内容") excelApplication.Quit  Set excelApplication = Nothing  End Sub 《表单---word》 Sub Click(Source As Button) ' Sub print(printvar() As String,arrnum As Integer) Dim session As New notessession path =session.getenvironmentstring("Directory",True) 'notes工作路径 'word application Dim mark As String Dim wordapp As Variant Set wordapp=createobject("word.application") wordapp.visible=True wordapp.changefileopendirectory(path) gzpath=path+"\"+"workpage.dot" wordapp.documents.Open(gzpath) Dim workspace As New notesuiworkspace Dim uidoc As notesuidocument Dim doc As notesdocument Set uidoc = workspace.currentdocument Set doc = uidoc.document Dim printvar() As String Dim arrnum As Variant arrnum = 10 For i=1 To 2 '在word中先定义书签,mark为书签名 mark=Trim("bookmark"+Trim(Str(i))) wordapp.activedocument.bookmarks(mark).select '可改进下面一句,使得内容添近来 ' wordapp.wordbasic.insert(printvar(i)) wordapp.wordbasic.insert("test luck test 20") Next wordapp.Activedocument.printout flag=Msgbox("工作票打印已经结束。",MB_OK,"提示") If flag=1 Then wordapp.acti vedocument.close(wdnotsavechanges) wordapp.quit(wdnotsavechanges) End If 'End Sub  End Sub 27. 关于Web上的检索问题 备注 程序代码 notes的检索功能很强大,是notes很吸引用户的一个特点。   将Notes应用移植到Web上时,最简单的提供检索的方法是使用@command([viewshowsearchbar]);此命令在Notes端时,会显示搜索条,而在浏览器上,会显示一个搜索页面。R5中文版显示的搜索页面使用的html是位于domino\data\domino\icons里的srchzhcn.htm和schbzhcn.htm。Domino引用这两个页面的样式和内容来生成URL搜索语句,可以直接修改这两个页面来定制搜索的界面。   上面的这种检索方法实际上是利用url命令SearchView来实现的,它有两个方面的不足:   1、不够灵活、用户输入较复杂的检索条件比较困难(需要自己输入searchview的参数query,例如要检索域名为yourfield中包含xxx的文档时,需要输入“field yourfield contains xxx”)。   2、不是即时的,因为全文索引不是即时更新的。   要解决上面的问题,可以自己在数据库中定制检索表单,用户可以在检索表单上制定复杂的检索条件,例如对上面的情况,由检索代理根据用户输入来生成Searchview命令 http:// yourhost/view?Searchview & query= field + yourfield + contais + xxx。 另外,可以在检索代理中加入以下代码,确保更新索引: If(db.isftindexed)Then If(db.lastftindexed找到"+Cstr(iNum)+"个符合条件的文档
" Print || For i=1 To iNum Set ResultDoc=targetview.getnthdocument(i) Print || Print || Print || Next Print |
|+Cstr(i)+|| Print ResultDoc. biaoti(0)+|
| 28. 如何使用Notes与关系数据库进行信息交互? 备注 程序代码 在Notes环境下,可通过公式、函数和Script与其他关系数据库进行信息交互。  一、设置ODBC数据源 Notes可通过ODBC驱动程序访问关系数据库。 1、在操作系统的控制面板中,打开“ODBC数据源”。 2、在“用户DSN”中单击“添加”,增加一个新的数据源。 3、选择数据源的驱动程序。 4、定义数据源等驱动参数。     二、利用Script读取数据库 注意:使用LotusScript访问数据库一定要在(Options)过程中加入Uselsx "*LSXODBC"命令  On Error Goto err '如果有错误,就转到相应错误处理程序 Dim con As New ODBCConnection '定义ODBC连接对象 Dim qry As New ODBCQuery '定义ODBC查询对象 Dim result As New ODBCResultSet '定义ODBC结果处理对象 Set qry.Connection = con '将ODBC查询对象和相应连接对象挂靠 Set result.Query = qry '将ODBC查询对象和相应结果处理对象挂靠 con.ConnectTo("ABC") '使用ODBC数据源ABC连接上相应数据库 qry.SQL = "SELECT * from test" '定义ODBC查询对象所使用的查询SQL语句 result.Execute '执行该SQL语句 rows = result.MaxRows '返回结果记录数 Call result.FirstRow '定位第一条记录 Do a1 = result.GetValue("1") '获得该条记录1字段中的值 a2 = result.GetValue("2") '获得该条记录2字段中的值 Print a1,a2 '将返回的值,打印显示 Call result.NextRow '继续下一条记录 Loop While maxrow > result.CurrentRow '如果搜索到最后条记录,退出循环 result.Close(DB_CLOSE) '关闭结果集 con.Disconnect '断开数据库连接 Exit Sub errorHandler: Messagebox result.GetExtendedErrorMessage,, result.GetErrorMessage '显示发生错误的消息 Exit Sub     三、利用Script写入数据库 On Error Goto err '如果有错误,就转到相应错误处理程序 Dim con As New ODBCConnection '定义ODBC连接对象 Dim qry As New ODBCQuery '定义ODBC查询对象 Dim result As New ODBCResultSet '定义ODBC结果处理对象 Set qry.Connection = con '将ODBC查询对象和相应连接对象挂靠 Set result.Query = qry '将ODBC查询对象和相应结果处理对象挂靠 con.ConnectTo("ABC") '使用ODBC数据源ABC连接上相应数据库 qry.SQL = "SELECT * from test" '定义ODBC查询对象所使用的查询SQL语句 result.Execute '执行该SQL语句 result.AddRow '增加一行记录 Call result.SetValue("1","AA") '给该记录字段1赋值"AA" Call result.SetValue("2",3) '给该记录字段2赋值3 result.UpdateRow '将增加的记录写入数据库 result.Close(DB_CLOSE) '关闭结果集 con.Disconnect '断开数据库连接 Exit Sub errorHandler: Messagebox result.GetExtendedErrorMessage,, result.GetErrorMessage '显示发生错误的消息 Exit Sub  29. 如何在IE里面实现notes中的 对话框列表? 备注 程序代码 如何在IE里面实现notes中的 对话框列表? (即可以添加新的项目的列表框) 答:在notes中这种列表框是系统自身就有的,实现起来比较容易,但这个功能不 被IE所支持,要在IE中实现该功能只能是采用另一种方式来仿效这种效果。 在IE中实现时,首先要把对话框列表的属性设置为不可添加新内容。(否则在IE 中不能显示为列表框,而是编辑框),其次再增加一个文本编辑域。这个域用来输入 新的项目,那么怎么才能让新的项目加入到列表框中去呢?这里用到一个小技巧,这 个技巧首先被Notes开发人员所使用:列表框中的项目要动态的从一个视图中提取它的 一个已经分类的列,这个列实际上就是你的新输入项目所间接存取的域。 具体操作方法是: 一、对应于要在IE中实现的某个对话框列表域name,你再建一个对话框列表域web_name, 但要把它的属性设置为不可添加新内容。 二、再建一个文本编辑域web_new_name。在name的属性设置中你要设置为“为选 项使用公式”并把公式写为: @If(!@IsNewDoc & @IsDocBeingLoaded;@Unavailable; @DbColumn(“”:”nocache”; “”; “视图名字”;1)) 三、在name的 input translation事件中 输入公式 @If(@ClientType = “Notes”;  @Trim(name); if(@Trim(web_new_name)=””;@Trim(Web_name);@Trim(web_new_name))) 四、在web_name的属性设置中你要设置为“为选项使用公式”并把公式写为 @DbColumn( “”:”nocache”; “”; “v_bulletin_classsel”;1) 五、在notes中隐藏web_name和web_new_name域。   30. LotusDomino环境下编写Web浏览器多数据库检索程序 备注 程序代码 LotusDomino环境下编写Web浏览器多数据库检索程序    随着计算机技术的日益普及,Internet/Intranet技术得到了更加广泛的应用,在世 界范围的大量Web网点上以及公司内部的Web服务器上,都存放着大量的信息。为使这些信 息得到的合理使用,Web服务器管理员应该为用户提供方便的信息检索方法。作为群件代 表的Lotus Domino  4.5集成了邮件处理、群件应用和Internet出版等功能,是Notes技术向Internet/ Intranet融合开放的里程碑式的产品。在继承以往产品全部优点与功能的基础上,Domino 将原先的Notes服务器提升为用途更广泛、使用更方便的Internet/Intranet服务器。在 Domino的帮助下用户能够快速 构建安全可靠的Web网点,开发出管理和控制Internet/Intranet的应用程序,并通过Web 浏览器实现对各类数据和服务器的交互式访问。Domino还为用户提供了多种检索信息的方  法,而且用户甚至不必编程。本文所要讨论的是通过简单编程实现在Web浏览器上对任意 多个数据库同时进行检  索的一种方法。    下面给出具体的实现方法:    1、创建数据库SiteSearch.NSF。    2、在数据库SiteSearch.NSF上创建Form名称为 SearchForm。    3、在SearchForm上创建Field,内容如下:    (1)DatabaseNames:类型为关键字,可编辑,允许多值,范围为:每行输入一个关  键字。关键字列表框内输入允许搜索的数据库列表。    假设有五个数据库允许用户检索,它们分别是:讨论板(Discuss.NSF)、规章制度  (Institution.NSF)、技术论文(TechDocuments.NSF)、公司最新动态(  CompanyNews.NSF)、简报及公告(Bulletin.NSF),则在DatabaseNames关键字列表框内  可输入:    讨论板 | Discuss.NSF    规章制度| Institution.NSF    技术论文| TechDocuments.NSF    公司最新动态 | CompanyNews.NSF    简报及公告 | Bulletin.NSF    (2)SearchString:类型为文本,可编辑。    (3)$$QuerySaveAgent :类型为文本,显示时计算,数值为textSearchQuerySaveA  gent,隐藏。    (4)SaveOptions:类型为文本,可编辑,默认值为“0”,隐藏。    4、创建代理TextSearchQuerySaveAgent。运行代理时间指定为:从“操作”菜单中  选择执行。指定代理操作的文档为:运行一次(可能使用@命令)。    代理程序的内容如下:    Sub Initialize     Dim ArrNsf As Variant     Dim item As NotesItem     '获得文档 context,因为此代理是一个$$QuerySaveAgent,所以$$QuerySaveAgent  可以访问 Context文档上的项目。     Dim sess As New NotesSession     Dim doc As NotesDocument     Set doc = sess.DocumentContext     '输出HTML页面的头部和标题:     Print {}     Print { }     Print {}     Print {}     Print "多数据库搜索"     Print {}     Print {}     '设置HTML页面的背景颜色:     Print {}     '获得欲检索的数据库,存放在数组ArrNsf内:     ArrNsf= doc.DatabaseName     '如果没有输入检索条件,则输出提示信息:     If Trim(Cstr(doc.Query(0)))="" Then     Goto EmptyQuery     End If     Dim MatchDoc As NotesDocument     Dim db As NotesDatabase,     Dim collection As NotesDocumentCollection     '下列循环从数组ArrNsf中取得欲检索的数据库进行处理:     For nsfCount=0 To Ubound( ArrNsf )     SearchDB=ArrNsf(nsfCount)     Set db = sess.GetDatabase("",SearchDB)     '出现错误则转向:     On Error Goto BadQuery     '获得满足查询条件的记录集:     Set collection = db.FTSearch(doc.Query(0),0)     On Error Goto 0     '输出数据库标题:     Print "
"     Print db.title     Print "
"     '输出该数据库中满足条件的记录个数:     Print "There are " & Str$(collection.Count) & " matching  documents
"     '下列循环从满足条件的记录集中读取记录并输出:     For i% = 1 To collection.Count     Set MatchDoc = collection.GetNthDocument(i%)     Print {
}     Print ""     '如果文档包含Subject或Title,则输出Subject或Title:     Set item =MatchDoc.GetFirstItem( "Subject" )     If ( item Is Nothing ) Then     Set item = MatchDoc.GetFirstItem( "Title" )     End If     If Not (item Is Nothing) Then     Print " " & item.Name & ": " & item.Text     End If     '如果文档包含Categories,则输出Categories:     Set item = MatchDoc.GetFirstItem( "Categories" )     If Not (item Is Nothing) Then     Print item.Name & ": " & item.Text     End If     '输出文档产生日期和作者:     createDate = MatchDoc.Created     Print "Document create date:" &createDate     Print " Authors: "     Forall aAuthor In MatchDoc.Authors     Print aAuthor     End Forall     Print "
"     Next     Next    Out:     Print {}     Exit Sub    EmptyQuery:     Print {Search query can not be empty }     Resume Out    BadQuery:     Print {Query is not understandable: "} & doc.Query(0) & {"}     Resume Out    End Sub    在本例中使用的FTSearch搜索查询内容是一个符合 Notes 全文检索规则的字符串,  搜索内容可以是一个字词或多个字词。搜索内容可以包括 ? 和 * 通配符,并且可以由  ! (not)、& (and)、|(or)  操作符混合。所检索的数据库可以有全文索引,也可以没有全文索引。如果没有全文索引  ,则搜索速度会慢一些。运行本程序时,应先从浏览器中输入URL:http://homeURL/Site  Search.NSF/SearchForm?OpenForm,然后选择欲检索的数据库并输入检索条件,单击  Submit按钮,则将列出所有  符合检索条件的文档。 31. WINAPI函数 备注 程序代码 一、网络函数二、打印函数三、文件处理函数四、菜单函数五、绘图函数六、硬件与系统函数七、文本和字体函数八、设备场景函数九、WINDOWS消息函数十、进程和线程函数十一、控制与消息函数十二、位图、图标和光栅运算函数十三、内存、字符串、结构及资源函数 Win95系统API函数大揭秘 何发武      Win95以其崭新精致的外观、简便快捷的操作方式,让你尽享操作平台之乐趣。同属Microsoft公 司的Visual Basic不仅仅是一门计算机语言,还是一个集应用程序开发、测试、查错功能于一体的功能 强大的集成式开发环境, 数百万的程序员受益于此。 Visual Basic一个强大的特性是它具有调用驻留在动态连接库(DLL)文件中的函数功能,其中包 括由Windows提供和使用的所有函数。对几百个函数以及DLL所包含的其它函数的存取将Visual Basic 的功能进行了大大的扩充,其功能远远超出其它语言,真有种“信手拈来”之神韵,毕竟Visual Basic 是Microsoft公司的“嫡系部队”。 你可以在你的应用程序中利用WINDOWS API提供的数百个API接口 函数进行扩充,加速应用程序的建立,减少程序开发的重复性(比尔.盖茨找你打版权官司可不关我事! ——喔喔!)      所谓API就是“应用程序接口”(Application Programing Interface),是一些用C语言编写由操作系统 自身调用的函数。Windows API函数由许多“动态连接库”或DLL组成。在32位Windows中,核心的Windows API DLL有如下一些: gdi32.dll--------图形显示界面的API kernel32.dll-----处理低级任务(比如内存和任务管理)的API user32.dll-------处理窗口和消息(Visual Basic程序员能把其中一些当作事件访问)的API 还不断有新的API出现,处理新的操作系统扩展,比如E-MAIL、联网和新的外设。 由于Windows API函数不是Visual Basic内部函数,所以在使用它们之前必须显式地加以声明。要 想得到正确格式化的函数声明,可以访问WINAPI目录下的文件WIN32API.TXT。     本文只对Win95系统API函数加以说明并调用Win95内置功能。例如,我们可以直接调用标准化的“重 新启动”、“磁盘格式化”、调用并更改标准“关于窗口”、查看“属性”、 设置“墙纸”、 建立快捷键、 确定内存、读写“注册表”、在建立状态栏图标等。     ? 重新启动 有些应用程序安装完毕要求重新启动一次,以使设置生效,可利用ExitWindowsEx函数实现。 Private Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long Private Sub Command1_Click() ExitWindowsEx &H43, 0 End Sub ? 磁盘格式化 当鼠标右键单击“3.5软盘A”并选择“格式化”时,则弹出标准的“磁盘格式化”窗口。我们 也可以在应用程序中利用函数轻松调用Windows 95标准的“磁盘格式化”窗口,以实现对磁盘相应 的操作功能。 窗体加入如下代码: Private Sub Form_Click() FormatFloppy End Sub 加入代码如下的模块: Public Const WM_CLOSE = &H10 Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Any, ByVal lpWindowName As Any) As Long Declare Function GetWindowsDirectory Lib "kernel32" Alias "GetWindowsDirectoryA" (ByVal lpBuffer As String, ByVal nSize As Long) As Long Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal X As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long Declare Function GetDesktopWindow Lib "user32" () As Long Declare Function LockWindowUpdate Lib "user32" (ByVal hwndLock As Long) As Long Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Type RECT         Left As Long         Top As Long         Right As Long         Bottom As Long End Type Type POINTAPI         X As Long         y As Long End Type Const SWP_NOSIZE = &H1 Const SWP_NOZORDER = &H4 Public Sub FormatFloppy() Dim sBuffer As String, Windir As String, Procs As String, X Dim lResult As Long sBuffer = String$(255, 0) lResult = GetWindowsDirectory(sBuffer, Len(sBuffer)) Windir = Trim(sBuffer) Procs = Left(Windir, lResult) & "\rundll32.exe shell32.dll,SHFormatDrive"     Call CenterDialog("Format - 3? Floppy (A:)")     X = Shell(Procs, 1)     Call CenterDialog("Format - 3? Floppy (A:)") k = LockWindowUpdate(0) End Sub Public Sub CenterDialog(WinText As String) DoEvents On Error Resume Next Dim D3 As Long D3 = LockWindowUpdate(GetDesktopWindow()) Dim wdth% Dim hght% Dim Scrwdth% Dim Scrhght% Dim lpDlgRect As RECT Dim lpdskrect As RECT Dim hTaskBar As Long hTaskBar = FindWindow(0&, WinText)     Call GetWindowRect(hTaskBar, lpDlgRect)     wdth% = lpDlgRect.Right - lpDlgRect.Left     hght% = lpDlgRect.Bottom - lpDlgRect.Top     Call GetWindowRect(GetDesktopWindow(), lpdskrect)     Scrwdth% = lpdskrect.Right - lpdskrect.Left     Scrhght% = lpdskrect.Bottom - lpdskrect.Top      X% = (Scrwdth% - wdth%) / 2     y% = (Scrhght% - hght%) / 2     Call SetWindowPos(hTaskBar, 0, X%, y%, 0, 0, SWP_NOZORDER Or SWP_NOSIZE) DoEvents End Sub ? 调用“关于”窗口 在“帮助”菜单选择“关于XXX”会弹出标准“关于”窗口,利用ShellAbout函数不但可以调用 标准“关于”窗口,还可以随意更改其中内容呢! ShellAbout声明如下: HWnd设置窗口句柄,szApp设置窗口的“Caption”, szOtherStuff 在“版权所有”和“使用权” 之间的空白处增加额外说明。 Private Declare Function ShellAbout Lib "shell32.dll" Alias "ShellAboutA" (ByVal hWnd As Long, ByVal szApp As String, ByVal szOtherStuff As String, ByVal hIcon As Long) As Long Private Sub Form_Load() Call ShellAbout(hWnd, "何发武天使工作室!", "调用标准的关于窗口" & vbCrLf & "上帝与你同在! 阿弥陀佛!", 0) End Sub     你还可以通过对注册表信息“动手术”来改变系统的“版权信息”运行REGEDIT,按照如下路径: HKEY_LOCAL_MACHINE →SOFTWARE → Microsoft→Windows→  CurrentVersion →Version,就会找到 你计算机中“关于”版本的通用设置,你可以把Version的内容改为你心仪的设置,如“何发武天使工 作室”、“ 何发武野狼工作室”等。 ? 查看“属性”     Win95中增加了一个全新的概念——“属性”,每个对象都拥有自己的“属性”,在“属性”窗口里 是关于对象的详细描述, 并且不同的对象“属性”窗口的说明是不同的。我们可以用ShellExecuteEX函 数直接调用“属性”标准窗口。下述程序功能相当于当鼠标右键单击根目录下的“autoexec.bat”并选 择“属性”时,则弹出标准的“属性”窗口。 窗体加入如下代码: Private Sub FORM_Click()   Dim r As Long   Dim FileName As String   FileName = "c:\autoexec.bat"   r = ShowProperties(FileName, Me.hwnd)   If r <= 32 Then MsgBox "Error"   End Sub 加入代码如下的模块: Option Explicit Type SHELLEXECUTEINFO     cbSize        As Long     fMask         As Long     hwnd          As Long     lpVerb        As String     lpFile        As String     lpParameters  As String     lpDirectory   As String     nShow         As Long     hInstApp      As Long lpIDList      As Long      lpClass       As String    hkeyClass     As Long      dwHotKey      As Long      hIcon         As Long      hProcess      As Long      End Type Public Const SEE_MASK_INVOKEIDLIST = &HC Public Const SEE_MASK_NOCLOSEPROCESS = &H40 Public Const SEE_MASK_FLAG_NO_UI = &H400 Declare Function ShellExecuteEX Lib "shell32.dll" Alias "ShellExecuteEx" _ (SEI As SHELLEXECUTEINFO) As Long Public Function ShowProperties(FileName As String, OwnerhWnd As Long) As Long     Dim SEI As SHELLEXECUTEINFO     Dim r As Long     With SEI         .cbSize = Len(SEI)         .fMask = SEE_MASK_NOCLOSEPROCESS Or SEE_MASK_INVOKEIDLIST Or SEE_MASK_FLAG_NO_UI         .hwnd = OwnerhWnd         .lpVerb = "properties"         .lpFile = FileName         .lpParameters = vbNullChar         .lpDirectory = vbNullChar         .nShow = 0         .hInstApp = 0         .lpIDList = 0     End With     r = ShellExecuteEX(SEI)     ShowProperties = SEI.hInstApp   End Function ? 设置墙纸 墙纸是显示在桌面的图片或图像,是Win95的一个重要窗口。你可以通过改变列表中的文件来选择多 姿多采的墙纸。墙纸为Win95蒙上了一披美丽的面纱,我们可以利用SystemParametersInfo函数来揭开 它的“神秘面纱”并亲手为她营造异样的风采。 在窗体中增加List1控件,窗体加入如下代码: Option Explicit Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As Any, ByVal fuWinIni As Long) As Long Const SPI_SETDESKWALLPAPER = 20 Const SPIF_UPDATEINIFILE = &H1    'update Win.ini Constant Const SPIF_SENDWININICHANGE = &H2 'update Win.ini and tell everyone Private Sub Form_Load()   Dim Temp As String   Temp = InputBox("Please Input A Directory", "Changer", "C:\WINDOWS\")   If Temp = "" Then End 'Cancel clicked   If Right$(Temp, 1) <> "\" Then Temp = Temp + "\"   List1.Tag = Temp   Temp = Temp + "*.bmp" 'Set the file filter (path + *.BMP)   Temp = Dir$(Temp)   Do While Temp$ <> ""     Temp = Dir$         If Temp = "" Then Exit Do      List1.AddItem Temp   Loop   List1.AddItem "(None)"   Show   List1.SetFocus   List1.ListIndex = 0 End Sub Private Sub list1_dblclick()   Dim Temp As String   Dim BMPFile As String   Temp = Tag     If List1.Text = "(None)" Then     BMPFile = "(none)"   Else     BMPFile = Temp + (List1)   End If    SystemParametersInfo SPI_SETDESKWALLPAPER, 0, ByVal BMPFile, SPIF_UPDATEINIFILE End Sub Private Sub List1_KeyPress(KeyAscii As Integer)     If KeyAscii = 13 Then list1_dblclick End Sub 马上试试,当场把你的墙纸改变啦(不变不收钱)!爽吧! ? 建立快捷键 Win95中快捷方式提供了对常用程序和文档的访问捷径,你可以为桌面或文件夹中的任何程序、文档 或打印机添加快捷方式。VB5中利用fCreateShellLink函数可以为常用程序和文档快速建立建立快捷键。 fCreateShellLink的声明为: Private Declare Function fCreateShellLink Lib "STKIT432.DLL" (ByVal lpstrFolderName As String,  ByVal lpstrLinkName As String, ByVal lpstrLinkPath As String, ByVal lpstrLinkArgs As String)  As Long LpstrFolderName设置快捷方式的文件夹名称,lpstrLinkName设置快捷方式的标题名称,lpstrLinkPath 设置快捷方式所指向的应用程序的目录及文件名。简而言之,如下格式:  fCreateShellLink(Destinationpath, Shortcutname, SourcepathAppName, "") 如下代码在“桌面”上为“d:\path\appname.exe”应用程序建立名为"Shortcut Title"的快捷方 式。 Private Declare Function fCreateShellLink Lib "STKIT432.DLL" (ByVal lpstrFolderName As String,  ByVal lpstrLinkName As String, ByVal lpstrLinkPath As String, ByVal lpstrLinkArgs As String)  As Long Private Sub Form_Click() lResult = fCreateShellLink("....\WINDOWS\DESKTOP", "Shortcut Title", "d:\path\appname.exe",  "") End Sub 技巧: 如果想在“桌面”上建立快捷方式,则建立目标目录应该为“....\WINDOWS\DESKTOP”; 如果想在 “开始”菜单中建立快捷方式,则建立目标目录应该为“....\WINDOWS\Start Menu”; 如果想在“程 序”菜单中建立快捷方式,则建立目标目录应该为相应的“....C:\WINDOWS\Start Menu\Programs”中, 以此类推。 ? 确定内存 我们经常要访问Windows管理的内存。对应用程序性能影响最大的因素是可用的内存容量,访问系 统内存在处理类似于位图文件之类的大文件时非常有用,因为程序通过交换文件(Swap)的方法,可以 获得比实际可用内存更大的内存。知道内存如何分配后,就可以读入内存值并操作大型数字文件。可以 用丰富的Win32 API函数确定Windows 的全局内存并操作数据文件,这些对于确定程序能否正常工作非 常有用。 dwLength 数据结构的长度 dwMemoryLoad 内存使用百分比 dwTotalPhys 实际内存总字节数 dwAvailPhys 可用的实际内存字节数 dwTotalPageFile 分页文件总字节数 dwAvailPageFile 分页文件可用字节数 dwTotalVirtual 虚拟内存的总字节数 dwAvailVirtual 可用的虚拟内存字节数 加入代码如下的模块: Type MEMORYSTATUS dwLength As Long dwMemoryLoad As Long dwTotalPhys As Long dwAvailPhys As Long dwTotalPageFile As Long dwAvailPageFile As Long dwTotalVirtual As Long dwAvailVirtual As Long End Type Declare Sub GlobalMemoryStatus Lib "kernel32" (lpBuffer As MEMORYSTATUS) 窗体中加入如下代码: Private Sub Form_Click() Dim m As MEMORYSTATUS m.dwLength = Len(m) GlobalMemoryStatus m Print "数据结构的长度", m.dwLength Print "内存使用百分比", m.dwMemoryLoad Print "实际内存总字节数 ", m.dwTotalPhys Print "可用的实际内存字节数", m.dwAvailPhys Print "分页文件总字节数", m.dwTotalPageFile Print "分页文件可用字节数", m.dwAvailPageFile Print "虚拟内存的总字节数", m.dwTotalVirtual Print "可用的虚拟内存字节数", m.dwAvailVirtual End Sub ? 读写注册表 Win95及NT的注册表数据库(Registry)是系统中非常重要的组成部分,它设置了Win95及NT的参数, 包括用户信息、系统硬件配置和应用程序等信息。注册表系统代替了旧版Windows中的多个INI文件。(警 告:如果你对注册表不熟悉,不要随意修改它。如果注册表项目出错,会使机器崩溃,甚至破坏操作系 统本身。) Win32 API中Reg函数处理对注册表数据库一般的读写过程如下:  1、使用RegOpenKey或RegCreateKey打开或创建一个键; 2、如果上一步成功,使用RegQueryValue(或RegQueryValueEx)读取子键的值,使用RegSetValue(或 RegvSetValueEx)设置子键值,使用RegEnumKey获得所有子键,使用RegDeleteKey删除一个键; 3、完成操作后使用RegCloseKey关闭键。 下述应用程序演示了如何生成键、存放值并取得注册表数据。在HKEY_LOCAL_MACHINE键下面生成三 个子键Test\Mastering vb5、 Windows Width、Windows Height,用于存放上次执行时的窗体尺寸。 Private Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA" (ByVal hKey As  Long, ByVal lpSubKey As String, phkResult As Long) As Long Private Declare Function RegDeleteKey L ib "advapi32.dll" Alias "RegDeleteKeyA" (ByVal hKey As  Long, ByVal lpSubKey As String) As Long Private Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" (ByVal hKey  As Long, ByVal lpValueName As String) As Long Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal  hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, lpData  As Any, lpcbData As Long) As Long ' Note that if you declare the lpData parameter as  String, you must pass it By Value. Private Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey  As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, lpData As  Any, ByVal cbData As Long) As Long ' Note that if you declare the lpData parameter as  String, you must pass it By Value. Const ERROR_SUCCESS = 0& Const ERROR_BADDB = 1009& Const ERROR_BADKEY = 1010& Const ERROR_CANTOPEN = 1011& Const ERROR_CANTREAD = 1012& Const ERROR_CANTWRITE = 1013& Const ERROR_REGISTRY_RECOVERED = 1014& Const ERROR_REGISTRY_CORRUPT = 1015& Const ERROR_REGISTRY_IO_FAILED = 1016& Const HKEY_CLASSES_ROOT = &H80000000 Const HKEY_CURRENT_USER = &H80000001 Const HKEY_LOCAL_MACHINE = &H80000002 Const regkey = "Test\Mastering vb5" Private Sub Form_Load() Dim retValue As Long Dim result As Long Dim keyValue As String Dim keyId As Long Dim subKey As String Dim bufSize As Long Label6.Caption = regkey retValue = RegCreateKey(HKEY_LOCAL_MACHINE, regkey, keyId) If retValue = 0 Then subKey = "Windows Width" retValue = RegQueryValueEx(keyId, subKey, 0&, reg_sz, 0&, bufSize) If bufSize < 2 Then keyValue = Me.Width retValue = RegSetValueEx(keyId, subKey, 0&, reg_sz, ByVal keyValue, Len(keyValue) + 1) Else keyValue = String(bufSize + 1, "") retValue = RegQueryValueEx(keyId, subKey, 0&, reg_sz, bykeyvalue, bufSize) keyValue = Left$(keyValue, bufSize - 1) Me.Width = keyValue End If Label4.Caption = subKey Label5.Caption = Me.Width subKey = "Widows Height" retValue = RegQueryValueEx(keyId, subKey, 0&, reg_sz, 0&, bufSize) If bufSize < 2 Then keyValue = Me.Height retValue = RegSetValueEx(keyId, subKey, 0&, reg_sz, ByVal keyValue, Len(keyValue) + 1) Else keyValue = String(bufSize + 1, "") retValue = RegQueryValueEx(keyId, subKey, 0&, reg_sz, ByVal keyValue, bufSize - 1) Me.Height = keyValue End If Label8.Caption = subKey Label7.Caption = Me.Height End If End Sub Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) Dim keyValue As String Dim retValue As Long Dim keyId As Long retValue = RegCreateKey(HKEY_LOCAL_MACHINE, regkey, keyId) keyValue = Me.Width retValue = RegSetValueEx(keyId, "Windows Width", 0&, reg_sz, ByVal keyValue, Len(keyValue) +  1) keyValue = Me.Height retValue = RegSetValueEx(keyId, "Windows Height", 0&, reg_sz,  ByVal keyValue, Len(keyValue)  + 1) End Sub ? 在“状态区”中建立图标 Win95中如“音量”、“日期”、“屏幕”等可以在Win95的状态栏(Tray)上建立快捷图标。如果鼠 标停留在图标上,会显示出相应的工具提示(ToolTip),当用户在图标上单击(或双击)鼠标左键时,软 件会实现相应的功能,单击右键时会实现其简捷的功能。  Tray也称作SysTray、TrayIcon、NotifyIcon、Status Area等,它是Win95/NT的任务条上一个特殊区 域,许多软件运行时在Tray中加入自己的图标,这个区域的另一个特殊之处在于你可以从资源管理器内 拖文件然后放在这个区域。正是由于这些特性,Tray编程在Win95/NT中有特殊的地位。 Tray编程比较特殊,主要包括三个主要方面:图标、工具提示和消息。它属于Shell编程的一部分, 主要是利用Shell API中的Shell_NotifyIcon函数完成的。Shell_NotifyIcon函数是这样声明的:  Type NOTIFYICONDATA cbSize As Long 结构所占的字节数 hwnd As Long 接受TRAY托盘图标消息的窗口句柄 uID As Long 由应用程序定义的图标识别符 uFlags As Long 标志 uCallbackMessage As Long 由应用程序定义的消息 hIcon As Long TRAY图标句柄 szTip As String * 64 工具提示字符串 End Type Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias " Shell_NotifyIconA" (ByVal dwMessage As Long,  lpData As NOTIFYICONDATA) As Long 这个结构中的uFlags很重要,它有三种取值:NIF_ICON、NIF_MESSAGE和NIF_TIP,分别表示 hIcon、uCallbackMessage和szTip参数有效,用来修改图标、消息和工具提示。这三个取值可以同时使 用(三个参数相或),也可以单独使用。为了实现对用户鼠标操作的响应,需要在程序中处理 uCallbackMessage所定义的消息,该消息的长参数lParam包含Win32所定义的鼠标消息,如果有多个图 标,短参数wParam表示图标识别符。 在vb光盘中\TOOLS\UNSUPPRT\SYSTRAY目录下有SYSTRAY的工程,经编译后生成 SYSTRAY.OCX控件。 现在我们应用SYSTRAY.OCX控件进行Tray编程。 首先建立一个“工程”,依次:“工程”——“部件”(或者在“工具箱”上单击鼠标右键选择“部 件”),再复选SYSTEM TRAY CONTROL CSYSTRAY,CSYSTRAY控件即出现在“工具箱”中。 SYSTRAY.OCX控件拥有MouseDblClick、MouseDown、MouseMove、MouseUp四个事件,响应先 后为MouseMove、MouseDown、MouseUp、MouseDblClick。下面编程很清楚地说明他们的响应时间次 序。 Private Sub cSysTray1_MouseDblClick(Button As Integer, Id As Long) MsgBox "Hei!You have DblClick the mouse!" End Sub Private Sub cSysTray1_MouseDown( Button As Integer, Id As Long) If Button = 2 Then MsgBox "Hei!You have clicked me in right button!" End If End Sub Private Sub cSysTray1_MouseMove(Id As Long) MsgBox "Hello!I am here!" End Sub Private Sub cSysTray1_MouseUp(Button As Integer, Id As Long) MsgBox "Hei!You clicked me just now!" End Sub Private Sub Form_Load() cSysTray1.TrayTip = "Hello! I am the King of the world!" cSysTray1.InTray = True cSysTray1.TrayIcon = "c:\fittings\F ACE.ico" End Sub SYSTRAY控件还拥有InTray、Name、TrayIcon、TrayTip、Parent、Index、Object、Tag属性。InTray 设置是否在Win95的状态栏Tray上建立一个快捷图标;Name设置SYSTRAY控件的名称;TrayIcon设 置在Tray上所建立快捷图标的外观;TrayTip设置如果鼠标停留在图标上所显示的工具提示(ToolTip)内 容;Tag储存程序所需要的附加数据。 通过实践发现,在使用VB开发应用程序时,灵活使用API 函数,会更大地发挥VB 的作用,使开 发的软件更专业,功能更强大。本文仅仅是介绍了一下API函数在Win95中的使用方法,以作抛砖引玉 之用。真正的应用API 函数,还需要更详尽的资料和读者更大的努力。  上述程序在中文Windows 98和 VB5.0中文企业版下调试通过。 32. 用PowerBuilder访问Lotus Notes数据库 备注 程序代码 摘 要 Notes库是由PowerBuilder提供的开发Lotus Notes应用的工具,本文介绍了Notes库的安装、组成、服务,并以一个实际应用说明如何在PowerBuilder下用Notes库访问Lotus Notes数据库。 关键词 PowerBuilder Lotus Notes 库   Lotus Notes是美国Lotus公司于90年代推出的群组工作软件(群件),现已被广泛应用于办公自动化、协同工作环境、工作流控制等方面,它提供了功能强大的多媒体共享文档数据库和电子邮件系统,是工业界的群件标准。 开发Notes应用系统,除了Notes自身的开发环境外,开发者还可根据自己的技术、经验,以及工作环境来决定使用第三方厂商提供的开发工具,Powersoft公司的Notes库就是其一。 我们知道,PowerBuilder(以下简称为PB)是客户/服务器计算环境下优秀的客户端开发工具,它所提供的数据窗口、面向对象的编程语言等特点一直深受广大程序员的喜爱。有了PB下的Notes库,就可利用数据窗口访问Notes数据库,并将其放入PB应用程序中,利用PB的特点开发出更完美的Notes应用程序。 一、 Notes库安装 在安装Notes库之前,应已安装好Notes的客户端软件。 主要步骤如下: (1) 运行PB安装程序 (2) 选择Custom安装 (3) 在Product Available窗口,选中Library for Lotus Notes,并单击窗口右边的Details按钮选择安装16位或32位的Notes库。这主要取决于PB的版本,对16位的PB,只能选择16位的Notes库;对32位的PB,还要根据Notes的客户端软件决定使用哪个库。 Notes库安装完毕,将Notes客户端软件所在路径和Notes库的路径加到DOS的搜索路径中。 在Notes库目录下,主要有以下两个程序: Notes库QNOTES.PBL提供访问Notes数据库的服务;Notes数据窗口构造程序QNOTEFE.EXE,用于创建访问Notes数据库的数据窗口,为方便使用该程序,可将其加入PB的工具栏。 二、 Notes库 Notes库主要提供以下服务: (1) 选择Notes服务器、数据库及其中的表单(Form)或视图(View)。 (2) 创建模拟表单或视图的数据窗口。 (3) 查询Notes数据库。 (4)在数据库中插入新表单,利用模拟表单的数据窗口进行检索、修改、删除操作。 (5)创建、打开、检索、修改、删除数据库中的文档及响应文档。 对以上服务,都是由Notes库中一组用户对象提供的,最主要的是以下三个: (1) 服务对象N_CST_NOTES_SERVICE:非可视化用户对象。含有用户定义函数,为应用程序提供访问Notes数据库的所有服务,。 (2) Notes对象N_NOTES_OBJECT:标准可视化用户对象,由数据窗口对象派生。在该对象的Constructor事件中,创建一个服务对象的实例,并在服务对象中注册数据窗口。这样,只要把该对象放在窗口中,将一个用Notes数据窗口构造程序创建的数据窗口之相联,就可得到Notes库提供的全部服务。 (3) 选择器对象U_SELECTOR:标准可视化用户对象,由树型视图(TreeView)派生。在该对象的Constructor事件中,创建一个服务对象的实例。该对象提供浏览Notes服务器和数据库的功能。 三、 Notes数据窗口构造程序 用Notes数据窗口构造程序QNOTEFE.EXE,可方便地创建模拟表单或视图的数据窗口和对数据库的查询。对创建的数据窗口,可放入Notes对象N_NOTES_OBJECT中,以访问Notes数据库。运行后主窗口如图1所示。 图1 各按钮功能如下: (1)SELECT:打开Notes Selection对话框,显示可访问的Notes 服务器。可选择服务器,数据库,用于创建数据窗口的表单和视图,以及查询。 (2)RETRIEVE:对为视图或查询创建的数据窗口,按该按钮可从数据库中检索数据。 (3)CANCEL:关闭程序。 (4)SAVE DATAWINDOW:保存创建的Notes数据窗口。 四、 访问Notes数据库的应用程序 在Notes服务器上有数据库MYDB,其中含有个人通讯录文档,视图VNAME按名字显示通讯录,表单ADDRBOOK用于创建、修改文档。在PB下利用Notes库编写应用程序NOTESTEST访问该数据库,取出通讯录信息。主窗口如图2所示。 图2 按检索按钮,左边的数据窗口模拟视图VNAME显示数据库MYDB的文档,右边的数据窗口模拟表单显示选中文档的具体内容。 步骤如下: (1) 创建应用程序库NOTESTEST.PBL,注意将Notes库QNOTES.PBL加入库的搜索路径。 (2) 创建主窗口W_MAIN。 (3) 用Notes数据窗口构造程序创建访问数据库MYDB中视图VNAME的数据窗口D_VIEW_VNAME,并保存到NOTESTEST.PBL中。 (4) 在W_MAIN中左边放置用户对象U_NOTES_OBJECT,该对象名设为DW_LIST,数据窗口设为D_VIEW_VNAME。 (5) 在W_MAIN中右边放置用户对象U_NOTES_OBJECT,该对象名设为DW_ADDRBOOK。 (6) 在W_MAIN的OPEN事件中,加上语句: dw_list.of_registerform(dw_addrbook,true) 这样,DW_ADDRBOOK就成为视图数据窗口DW_LIST的表单。 (7) 在表单数据窗口DW_ADDRBOOK的CONSTRUCTOR事件中,加上语句: this.of_setautocreate(true) this.of_setautoretrieve(true) 在视图数据窗口DW_LIST中,每选中一行时,表单数据窗口DW_ADDRBOOK就自动创建相对应文档的表单,并自动检索数据。 (8) 在W_MAIN中放置检索按钮以检索视图VNAME的内容,在按钮的CLICKED事件中,加上语句: dw_list.Retrieve() (9) 保存窗口W_MAIN,在应用程序NOTESTEST的OPEN事件中,加上语句: Open(w_main) (10) 运行应用程序NOTESTEST,就可从Notes数据库中检索通讯录文档。 33. 如何在表单中加入计数器 备注 程序代码 Lotus 的Domino 服 务 器 不 仅 是Notes 服 务 器,  还 是 一 个HTTP 服 务 器, 当 你 使 用 Domino 服 务 器 作 为 你 的Web 站 点 时,  你 可 能 想 在 你 的 主 页 上 增 加 一 个 计 数 器, 告 诉 用 户 是 第 及 个 访 问 者,  并 且 你 也 可 以 把 它 作 为 统 计 你 的Web 站 点 访 问 情 况 的 一 个 重 要 数 据。 目  前, 在 标 准 的 Web 服 务 器 上, 计 数 器 通 常 都 是 通 过CGI 程 序 来 实 现 的。 本 文 将 告 诉 你, 如 何 通 过 Notes ---- Designer for Domino 来 实 现 计 数 器。 ---- 下 面 简 要 的 介 绍 一 下 Domino Web 服 务 器 工 作 原 理: Domino 能 把 Notes 构 件( 如 导 航 器, 视 图, 表 单, 文 档, 链 接) 自 动 地 转 换 成 在 Web 浏 览 器 上 能 显 示 的 HTML 。  您 只 需 简 单 地 在 Notes 中 开 发 Web 应 用 程 序, 由 Domino 完 成 余 下 的 工 作。 设 计 你 站 点 的 主 页 表 单, 在 其 中 加  入 一“Count” 计 算 域, 用 来 显 示 此Web 页 面 的 访 问 次 数,  计 算 公 式 为“Count”。 设 计 一 个 代 理, 用 于 在 该 表 单 在 被 打  开 前 执 行, 我 们 用Notes 的Profile 文 档 来 存 放 页 面 被 访 问 的 次 数,  表 单 页 面 每 一 次 打 开 之 前, 都 要 先 读 取Profile 文 档 中 存 放 页 面 访 问 的 次 数,  加 一 后, 赋 给 表 单 的Count 域, 并 把 新 值 存 回 到Profile 文 档 中; 如 果 站 点 是 第 一  次 被 访 问,Profile 文 档 不 存 在, 这 时 只 需 表 单 的Count 域 赋 为1, 把1 存 回 到Profile 文 档 中。 ---- 1、 选 择 创 建- > 设 计- > 代 理 ---- 2、 把 新 建 的 代 理 命 名 为“Counter” ---- 3、 设 置 代 理 属 性 为“ 共 享 代 理”, 运 行 此 代 理 的 时 间 设 为“ 从< 操 作 > 菜 单 选 择 执 行”, 指 定  代 理 操 作 的 文 档 设 为“ 运 行 一 次( 可 能 使 用@ 命 令)” ---- 4、 选 中“Script”, 在Initialize 事 件 中 输 入 如 下 代 码 Sub Initialize Dim Session As New NotesSession Dim ProfileDoc As NotesDocument Dim doc As NotesDocument Dim CountNum As Double Dim CountString As String '得到当前数据库的句柄 Set db = Session.CurrentDatabase '获得名为"CounterProfile"的Profile文档,如还不存在,GetProfileDocument '新建一个名为"CounterProfile"的 Profile文档。 Set ProfileDoc = db.GetProfileDocument ("CounterProfile") '得到驻留内存文档 Set doc = Session.DocumentContext '从Profile文档的取得Web页面已被访问次数 CountString =ProfileDoc.Count(0) If CountString < > "" Then CountNum = Cdbl(CountString) + 1 Else '第一次访问该站点 CountNum = 1 End If ProfileDoc.Count = Cstr(CountNum) '新值存回到Profile文档中 Call profiledoc.save(False,False) '将当前Web页面已被访问次数传递给文档中的Count条目 doc.Count = CountNum End Sub 5、 保 存 该 代 理 ---- 回 到 主 页 表 单, 在 该 表 单 的 WebQueryOpen 事 件 中, 加 入 下 列 代 码 @Command([ToolsRunMacro]; "< Counter >") ---- 我 们 知 道 在Notes 中 有QueryOpen 事 件, 在 当 前 文 档 被 打 开 前 发 生。WebQueryOpen 事 件 是 在 Domino 将 文 档 转 换 为 HTML 并 且 发 送 到 浏 览 器 之 前 运 行 代 理。 ---- 如 果 你 使 用 的 是Notes 早 期 版 本, 其  中 可 能 没 有WebQueryOpen 事 件, 那 么 你 可 以 在 表 单 中 填 加 一 $$QueryOpenAgent 的 计 算 域, 把  其 缺 省 值 置 为 "Counter", 与 使 用WebQueryOpen 事 件 一 样。 在 公 用 通 讯 录 的 服 务 器 文 档 的 代 理 管 理 者 区 段, 把 你 的 加 入 到 运 行 受 限 LotusScript/Java 代 理 中。 ---- 做 完 上 述 步 骤 后, 一 个 简 单 的 计 数 器 就 已 设 计 完 成, 这 样 每 当 一 个 用 户 访 问 你 的 页 面 时, 他 就  能 看 到 此 页 面 被 访 问 过 的 次 数。 ---- 你 可 以 点 击 浏 览 器 上 的 刷 新 按 钮, 你 将 看 到 每 刷 新 一 次, 访 问 次 数 将 回 加1。 你 可 以 把 它 们 加 入 到 你 用Notes 开 发 好 的Web 应 用 中 去。 34. 实现两个数据库间的数据追加 C/S 结构 备注 程序代码 请问两个数据库之间如何进行数据追加? 问题: 例如: > 数据库A中有 BM,DWMC,BMMC等域,表单名TEST1 > 数据库B中也有 BM,DWMC,BMMC等域,但有部分域数据库A中没有,表单名TEST2 > 在数据库A中录入文档,进行一个操作同时完成两个事件(1.数据库A保存文档 2.向数据库B中追加 > 一条纪录) 答复: REM 本程序可以放在数据库A的表单TEST1中的操作或postsave保存事件中 dim uiw as new notesuiworkspace dim uidoc as notesdocument set uidoc = uiw.currentdocument dim doc as notesdocument set doc = uidoc.document   '获得当前文档 dim ss as new notessession dim db as notesdatabase set db = ss.getdatabase("服务器名称","数据库B") '获得数据库B REM 在数据库中创建文档,将在数据库A中创建的文档追加到数据库B中 dim newdoc as notesdocument set newdoc = db.createdocument newdoc.form = "TEST2" newdoc.aaaa = doc.aaaa(0) newdoc.bbbb = doc.bbbb(0) REM 如果有的域是多值域需要 newdoc.cccc = doc.cccc call newdoc.save(true,true) REM 程序结束 35. 如何防止他人使用旧id和旧口令访问Domino服务器? 备注 程序代码 我们知道,在Domino系统中,个人ID文件十分重要,就象身份证一般。因为ID文件中保存了大量用户私人信息,比如:用户名、私有密钥等等。但大家要注意一点,这就是ID文件的口令实际上并未存储在ID文件中。口令和文件是通过某种复杂的数学运算联系在一起的。 在实际应用当中,系统管理员经常可以发现用户将其ID文件到处拷贝和共享,这样如果其它人获得了他的ID文件,并知道了这个ID文件的口令,那么其它人就有可能以他的身份登陆系统,造成安全方面的隐患,并且该ID文件口令不会因为用户后来的口令修改而发生改变。 那么怎么预防这种安全问题的出现呢? Domino提供了两种手段: 1、口令跟踪:该功能可以让服务器跟踪用户修改口令,使服务器仅接受使用最新口令的ID的用户登陆,也就防止了他人使用旧ID和旧口令访问服务器。 设置步骤如下: A、管理端——配置——服务器配置文档——安全性——启动“检验NOTES标识符口令” B、针对需要进行口令跟踪的用户修改其个人文档——管理——启用“检查口令” C、重新启动服务器 D、如果需检查是否生效,可以个人文档——管理——口令摘要是否有内容为准。如果有,则已经生效;反之,则没有生效。 2、公用密钥跟踪:该功能可以让服务器在用户登陆时,将其ID中公用密钥和其个人文档中的公用密钥作比较。如相同,则允许访问。 设置步骤如下: A、管理端——配置——服务器配置文档——安全性——启用“与保存在通讯录中的NOTES公用密钥比较” B、重新启动服务器 使用方法如下: 用户:A、文件——工具——用户标识符——其它——新建公用密钥 B、将信息发给系统管理员 管理员:打开所收邮件——验证——返回信息给用户 用户:打开所收邮件——接受信息 注意:以上两种方法均针对个人,不能针对群体。 适用版本:4.6、R5 36. 在你的WEB站点上使用DOMINO群集 备注 程序代码 [Editor's Note: First published in Oct. 1997, this article marked the beginning of our regular columns on exposing how the Notes.net site is run. The article explains how to set up a Domino server cluster for your Web site. This update also now includes information on how we use Cisco Systems' LocalDirector for load balancing, and details on the new clustering features in Domino R5.] So, you've got a great Web site with an edge -- everyone's talking about it, and everyone wants to see it. A Webmaster's dream? Maybe -- if you've got the tools to handle it. In this article, you'll learn how you can use Domino server clusters to make sure that your great Web site can actually be appreciated. A cluster is a way to group up to six Domino servers together to ensure high availability of your site, and to balance the workload between the servers. Domino includes the real-time Cluster Replicator, which ensures that all data changes are continuously replicated around the servers in the cluster. No matter how popular your Web site is right now, a cluster is a good investment, because it allows you to grow your system as the number of hits to your site increases. In the rest of this article, we'll introduce you further to Domino clusters. You'll learn why clusters are a good idea for your Web site -- so good, that we use them here at Notes.net. Then, we'll walk through the steps for setting up a basic cluster. An introduction to clusters Clusters were first available for R4 servers as part of the Notes for Public Networks, an offering for telecommunication and Internet service providers. Then, Lotus released clusters for general customer usage as part of the Domino Advanced Services in R4.5. One of the big selling points of clusters is that they provide high availability to data, because you can access the same data from any of the servers in the cluster. For more information on this high availability, please see the article "Lotus Domino Advanced Services: High Availability Powered by Notes." In addition to high availability, a Domino cluster for a Web site also offers the following advantages: o Fault tolerance: You can now have a site that responds gracefully to an unexpected hardware or software failure. Clustering means more servers (up to six) are capable of responding to client requests to your Web servers. o Scalability: You can easily add servers to the cluster as your Web site becomes more popular. o Workload balancing: You can distribute user accounts across the cluster and balance workloads to optimize performance. The load balancing is almost instantaneous because of a single virtual address for all the servers. o Ease of multi-server administration: You can use the real-time Cluster Replicator to keep site design and site content synchronized across the servers in the cluster. Because the Cluster Replicator is event driven, any changes to a database or to the cluster membership itself, are immediately passed to other databases or servers in the cluster. You can have multiple replicators on a clustered site. o Analysis tools: You can use the Cluster Analysis tools to determine what is happening in the cluster and what you should do to optimize the performance of the cluster. Prior to Domino R5, clusters provided load balancing and automatic failover only for Notes clients. To do this for Web clients, you needed to use an alternative method, such as round-robin DNS or another software or hardware-based solution. In the DNS method, a linear rotation distributes the Web user requests across the server cluster. You simply assign multiple IP addresses to a single DNS name. The Domain Name Server then responds to Web user requests by rotating through the IP addresses of the physical servers in the list. Domino's real-time cluster replication ensures that the servers in the cluster are identical to one another. A drawback to this approach is that you rotate to a server regardless of its state. Plus, other site DNS servers and/or Proxy servers tend to cache URL references, which hinders your ability to turn off DNS rotation for a particular server. In some cases, it may take one to two days before this information is properly updated by other sites. To overcome the drawbacks of the DNS method, you can use another software or hardware-based solution. These solutions work like a traffic cop. They "sit" in front of your server cluster and appear as the final destination Web server for all Web client requests. But really, they're a "virtual" server with a virtual IP address assigned via DNS. When a request comes in, they distribute the request to one of the "real" servers -- servers with a real IP address that reside in the cluster. The benefit is that now you can add and remove servers from the cluster, and not worry about cached references out on the Internet. You can do this with a proxy-software package, such as Netscape's or Microsoft's Proxy Server, or a hardware solution, such as Cisco Systems' LocalDirector. For more information on your different load balancing options, see the excellent article in Web Techniques magazine on "Load balancing your Web site." Now, with Domino R5, you don't need to use these alternatives -- clusters provide load balancing for both Notes and Web clients. Domino R5 includes a new cluster component called the Internet Cluster Manager (ICM), which is like the software solutions we just described above but better, because it's Domino-aware. The ICM maintains information on the availability of the servers in a Domino cluster, and also maintains information about the distribution of databases on the servers. Then, when a request comes in from a Web client, the ICM determines the best server to receive that request. For more information on the ICM, see the article "Domino R5: The Domino Internet Cluster Manager." Putting clusters to work at Notes.net Now that you understand more about Domino clusters, let's look at how we use them at Notes.net. The following diagram is an overview of how we have a Domino cluster set up for the Notes.net site. Because we're still using Domino R4.x servers, we use Cisco Systems' LocalDirector to provide load balancing for the site. All Web requests first go to the LocalDirector, which has the virtual IP address of www.notes.net. Then, the LocalDirector distributes the request to one of our "real" servers with real IP addresses: www1.notes.net, www2.notes.net, or www3.notes.net. Of course, as our site migrates to R5, we'll investigate using the Domino Internet Cluster Manager for load balancing. Each server contains replicas of all the databases in the cluster. Net1 is the administration server for the cluster and the replication hub, so it handles all replication with the rest of the servers in the domain and all agent execution. Although our scheduled replication is set for every five minutes, Domino's real-time cluster replication is crucial for keeping our Iris Cafe discussions and Public Address Book synchronized. For example, it's possible that a user could create a topic, decide to edit it, and return to a server that has not replicated yet with the original server. If the discussion database replicates in real time, this time lapse is prevented. Similarly, the registration process and creating users in the Public Address Book is processed more efficiently. If an edit to an entry is required, the real-time replicator forces the change immediately. To maintain performance for the site, cluster replication is enabled only for the Notes.net Public Address Book and discussion databases. Components of a Domino cluster Before you begin setting up your Domino Web cluster, it might be helpful to get some background on the specific components that make up a Domino cluster. As with most things in Domino, a server cluster has its roots in the Public Address Book (NAMES.NSF). The Public Address Book is where you create a cluster, and then add or delete servers from that cluster. When you add a server to a cluster, the Administration Process (ADMINP) adds the Cluster name to the Server document. For the actual day-to-day operations of the cluster, Domino uses the following components: o Cluster Administration Process (CLADMIN) -- This server task is responsible for the correct operation of all cluster components. On clustered servers, the process runs automatically at server startup and whenever the cluster membership changes. o Cluster Analysis -- Available from the administration panel, this tool enables you to analyze the configuration of a cluster and determine whether it has been set up correctly. By default, it stores the results in the Cluster Analysis database (CLUSTA4.NSF). o Cluster Database Directory Manager (CLDBDIR) -- This server task tracks all the databases on each server in a cluster, and stores the database information in the Cluster Database Directory (CLDBDIR.NSF). o Cluster Manager -- The Cluster Manager tracks all members in a cluster. It keeps a list of which servers in the cluster are currently available and maintains information about the workload on each server. o Cluster Replicator (CLREPL) -- This server task is responsible for synchronizing databases and their replicas in a cluster. The Cluster Replicator uses the Cluster Database Directory to determine which local databases have replicas on other cluster members. Then, whenever a change occurs to a database, the Cluster Replicator pushes the change to the other replicas in the cluster. Note: The Cluster Replicator only handles replications within the cluster. The standard replicator task (REPLICA) is still responsible for replicating changes to and from servers outside of the cluster. As mentioned earlier, the Internet Cluster Manager (ICM) is a new Domino R5 cluster component that provides failover and workload balancing for Web clients. For more information on the ICM, see the article "Domino R5: The Domino Internet Cluster Manager." Setting up your Web cluster Each server that you want to include in your Domino Web cluster, must have the following: o TCP/IP support o Domino 4.5 or later (any supported platform) o The Domino Advanced Services License o A hierarchical server ID (required by the Administration Process) In the following steps, we assume that you have at least two existing Domino servers that share a Public Address Book -- that is, the servers are in the same domain. The servers should also be able to successfully replicate with each other. You can set up database replicas before or after you create the cluster. Part I. Planning for the Web cluster Before you begin to create your cluster, you must first complete the following steps. 1. Verify that each server for the cluster has a hierarchical server ID. To do this, choose File - Tools - User ID. Select the Basics icon, and check that the ID type is hierarchical. If you are using an existing server that has a flat name ID, you must convert to a hierarchical ID. For the conversion steps, please see the Administration Help. 2. Make sure that the Administration Process (ADMINP) is set up for your domain. To do this, you must first define an administration server for the Public Address Book. Note: With Release 4.6, when you set up your first Domino server, it automatically becomes the administration server for the Public Address Book. However, you must complete these steps if you're upgrading to Release 4.6. -- From the workstation of the server, open the local copy of the Public Address Book. -- Choose File - Database - Access Control, and select the Advanced icon. At the top of the dialog box, click Server and select the name of the server that will be the administration server. Don't enable "Modify All Reader and Author fields." -- Then, make sure that ADMINP is running correctly on each server. For more information on the Administration Process, please see the article "Setting up the Administration Process in your Domain." 3. Install or upgrade to the Lotus Domino Advanced Services license on each server. -- From the Install Options dialog box, select "Customize features - Manual install" and select the same directories as for your original server install. -- On the Advanced Services tab, select Advanced Services and Advanced Services Data. Click Yes when prompted whether you purchased the Advanced Services license. (You do not need to install the Domino Partitioned Server.) Part II. Creating the cluster If possible, you should use the administration server for the Public Address Book to create the cluster, and add servers to the cluster. This administration server does not have to actually be part of the cluster. 1. Open the server copy (rather than local copy) of the Public Address Book. Choose File - Database - Open, select the server, and type the filename names.nsf. (If you are denied access, try switching to your administrator's ID.) 2. From the Server - Servers view, select the servers you want to add to the cluster, and click "Add to Cluster." Click Yes when prompted if you want to add the selected servers to a cluster. (You can have only up to six servers in a cluster.) 3. Select Create New Cluster, then type the new cluster name. Click OK. You are then prompted that your request to add the servers to the cluster has been successfully submitted to the Administration Requests database (ADMIN4.NSF). Congratulations -- You've created your cluster! The rest of the steps in this section are optional, because they simply help you verify that the components of your cluster are now set up. 4. Run the Administration Process (ADMINP). -- If you are using the administration server of the Public Address Book to create the cluster, ADMINP immediately runs and adds the cluster name to the Server document(s). -- If you are not using the administration server, your request to create the cluster is queued in the Administration Requests database. When this request is replicated to the Administration Requests database on the administration server, ADMINP executes the request to update the appropriate Server document(s). After ADMINP makes changes to the Server document in the administration server's Address Book, the changes replicate to the servers. (You can also force replication between the administration server and the added servers.) 5. On the server you just added to the cluster, open the server copy of the Public Address Book. Verify that ADMINP added the cluster name to the server's Server document. The Server - Clusters view should also show the cluster, and the servers you just added to the cluster. 6. Again, from the added server, verify that the Cluster Administration Process (CLADMIN) created the Cluster Database Directory (cldbdir.nsf). Choose File - Database - Open, select the server, and type the filename cldbdir.nsf. All databases on the server should be listed in this directory. 7. Now, check that the Cluster Administration Process (CLADMIN) loaded the Cluster Replicator task (CLREPL). -- From the server console, enter "Show tasks". The Cluster Replicator should be listed as Idle. -- If the Cluster Replicator is not listed, enter "Load CLREPL" to load the task. When you add a server to a cluster, Domino automatically adds the server tasks CLDBDIR and CLREPL to the ServerTasks entry in the NOTES.INI file. This entry means that these tasks will start automatically whenever you re-start the server. 8. From the server console, enter "Show cluster" to show the status of the cluster. For example, you can now see the members of the cluster, and if they're available. (Optional) Part III. Selecting databases for cluster replication When you create a cluster, each database in the cluster is set to replicate in real time (that is, the "Cluster replication" field for each database is "Enabled" in the Cluster Database Directory). However, real-time cluster replication is only necessary for databases that you expect to change often. For example, the administration server for Notes.net has more than 100 databases, but only the Public Address Book and discussion databases are enabled to replicate in real time. Note: Disabling cluster replication in this way only prevents event-driven replication changes -- that is, replication changes made by the Cluster Replicator. Any standard, scheduled replication (REPLICA) will continue to be performed both from and to the databases. 1. From the administration server for the Public Address Book, open the server copy of the Cluster Database Directory (CLDBDIR.nsf). Open any of the database documents, and notice that the Cluster replication field is enabled. 2. Choose Create - Agent. Then, name the agent, and select for it to run "Manually from the Actions Menu" and on "Selected documents." 3. Select for the agent to run "Simple actions," and click Add Action. Select to modify the Cluster Replicate field, and replace the value with 0. Save the action. 4. Select the databases that you want to disable, and run your new action from the Actions menu. To easily see which databases have replication enabled, sort the Databases by Pathname view by the Cluster Replication column. Conclusion Domino clusters are an excellent way to ensure that data on your Web site is current and dynamic -- so you don't lose your edge. Creating your cluster is just the beginning. You should check out the following sources for details about cluster tasks, how to set up workload balancing, and how to use the Cluster Analysis database for better performance for your Web servers: o The "Iris Today" articles "Fine points of configuring a cluster," "Workload balancing with Domino clusters," and "Domino R5: The Domino Internet Cluster Manager" o The Domino Administration Help o The Domino Cluster Zone on the Lotus Web site o IBM Redbooks on Domino clustering 37. 在你的DOMINO WEB站点中插入.SWF文件 备注 程序代码 Have you ever wondered how to add some spice to your Web site? You may not realize that Domino can serve up much more than plain HTML. This article will explain how to add Shockwave files to your Web site, so you can "shock" your site with sound, animation, links, and more. We'll briefly describe what Shockwave is, walk through the steps for adding Shockwave files to your Domino Web site, and then show you how EntreVision, Inc. "shocked" their fictitious Chile Pepper site. (EntreVision,a dynamic groupware consulting firm and Lotus Premium Partner, designed the fictitious Chile Pepper site to showcase the power of Domino on the Web.) The techniques in this article work with Domino 4.5 or later. What is Shockwave? Shockwave is an interactive, dynamic file type that you can embed into your Domino Web pages. Shockwave files can have sound, animation and links, and are a popular solution for Web site design with the entertainment, advertising, learning, and design industries. You can create Shockwave files by using Macromedia's Authorware, Director, or Flash. For more information on these products and how to create Shockwave files, see the Macromedia Web site at http://www.macromedia.com. To view your "shocked" site, users need to have the Shockwave plug-in, which is available free of charge from Macromedia. The first time users try to view a Web page that contains a Shockwave file, their browser searches its plug-ins directory for the Shockwave plug-in. What happens if the browser can't find the plug-in? If they are using Internet Explorer 3.x or 4.x, the browser immediately downloads and installs the plug-in (using Active X) from the Macromedia Web site. If they are using Netscape Navigator 3.x or 4.x, the browser notifies them that the plug-in is required, and asks whether they want to get it. (You can still see the site without the plug-in; however, the elements that use the plug-in will appear as broken icons.) In addition to the Shockwave plug-in, you can download Macromedia's Streaming Shockwave player, which lets animation and sound files start playing immediately while the remainder of the file downloads in the background. For more information on downloading the Shockwave plug-in or player, see http://www.macromedia.com/shockwave/download/. Adding Shockwave files to your Domino Web site Once you've got your Shockwave files created, use the following steps to add them to your Domino Web site: 1. Add Shockwave definitions to your Domino configuration file, httpd.cnf, so Domino can display them correctly. For example, if you created the files with Director, add the following entries: AddType .dcr application/x-director binary 1.0 # Shockwave for Director AddType .dir application/x-director binary 1.0 # Shockwave for Director AddType .dxr application/x-director binary 1.0 # Shockwave for Director These types are now included in the httpd.cnf files in Domino 4.6; however, you might still need to add them if you upgraded from an earlier release of Domino. Definitions for other Macromedia Shockwave products, such as Authorware, Freehand, Flash, and others, can be found at http://www.macromedia.com/support/config.html. 2. Copy the Shockwave files into the html directory, which resides in the notes/data/domino directory. (Alternatively, you can store these files in a Notes database as document attachments and use the $file directive to retrieve them. For more information on this technique, see the article "Notes.Net Exposed: Using a database to store Web site graphics.") 3. Add the Shockwave file to your Web page by using passthru HTML. (Enter the code, highlight it, and then choose Text - Pass-Thru HTML.) The code should be in the format : For a complete listing of the HTML parameters you can use with the Shockwave file, see the sidebar "Shockwave parameters." 4. Save the page. If you are using Release 4.6, you can preview how the page will look in a browser by choosing Actions - Preview in Web Browser. (To preview forms or navigators, choose Design - Preview in Web Browser. For views, choose View - Preview in Web Browser.) Note: To use the Web browser preview, you must have selected the Toolbox option when installing the Notes Designer client. Also, you must have an Internet browser selected in your Location document, and you should have at least Default access in the database's ACL. Shocking the Chile Pepper site For example, Entrevision uses the following code to "shock" their Chile Pepper site, served by Domino. (See http://chilepepper.lotus.com/ and go to the Chile Life section to view this code as it appears on the Web.) /sw1 to sw8 are user-definable parameters that provide a /generic way to pass URL parameters from HTML to the /Shockwave file. Notice that the code uses the height and width tags for cropping the Shockwave file, and sw tags for linking URLs to the Shockwave file. "One of the biggest challenges we faced was building a Shockwave file in a way where we did not have to hard code the URLs, which can cause more work when you want to make changes later," explains Peter Carroll, a partner at EntreVision, Inc. "We met this challenge by using the generic sw tags as they let us easily pass information to the Shockwave file in a more efficient manner." The future of Shockwave Macromedia has developed a new product called Universal Media Initiative, which brings its products, such as Shockwave for Director and Flash onto a Java-based delivery system. With this method, Web developers can build interactivity using the Macromedia products, with the intention of them being delivered with the Shockwave plug-in. Then, if the end user does not have the plug-in installed, a Java applet with the plug-in code and the Shockwave file, are downloaded instead. This Java version is slower, but is still a good alternative in certain situations. "The Universal Media Initiative is something that I am very excited about as a designer," says Bryon McInroy, an Interface Designer at EntreVision, Inc. "Added functionality with plug-ins are nice to add to Web sites or applications. The possibility of an end user not having a given plug-in installed can be a deterrent for relying on Shockwave or other plug-in technologies for functionality. But with the Universal Media Initiative, developers and clients have two levels of assurance, the plug-in and then Java." So, Shockwave will remain a good option for spicing up your Domino Web site. ABOUT THE AUTHOR Larry Kovner is a technical writing consultant in the Domino/Notes UA group. Larry has BS in Communications from Emerson College and a Master in Professional Writing from Northeastern University. When not immersed in computer technology, he enjoys music, theatre, and having karaoke parties. Larry would like to thank Peter Carroll and Bryon McInroy of EntreVision for their help with this article. EntreVision Inc., a dynamic groupware consulting firm and Lotus Premium Partner, uses Lotus Domino groupware technology to solve complex organizational challenges associated with building enterprise Web sites 38. DOMINO R5的域搜索功能在WEB上的实现 备注 程序代码 With the new Domain Search feature introduced with Domino R5, the ability to search for content in a domain has become a reality. The new Domain Search capabilities allow you to search every server in your domain for any information located in virtually any document, whether it's in a Domino database or a public file system. You can search for the information from a Web browser or the Notes client. Domain Search combines the ease of searching on the Web with the power and security of Notes. The benefits of Domain Search include: o Easy searching. You don't need to know where the data you're looking for is located to be able to execute a search. You can search everything from one place. o Security. Domain Search uses database access control lists (ACLs) to ensure that users receive only the results they're allowed to see. In addition, if a document has a Reader field, the user must be listed in that field to gain access to that document via the search results. o Central administration. You control what gets indexed. To find out more about Domain Search features, read the Iris Today article Domino R5: Domain Search. In the Notes R5 client, the Search button provides access to Domain Search: You can also use Domain Search from your Web browsers, but access to it is a trickier because there are no user interface elements within Web browsers to search against a Domain Search index. This article explains how to integrate Domain Search with Microsoft Internet Explorer 5 (IE5) so that Domain Search is always readily available. This article assumes you have some understanding of the following technologies: o HTML o JavaScript o Windows Registry It also assumes you have already set up Domain Search in your Domino R5 system. For instructions on doing so, see Domino 5 Administration Help. The integration of Domain Search with Internet Explorer relies on a feature introduced with IE5 called Explorer Bars. This article shows you how to implement a horizontal Explorer Bar to access Domain Search. Because users can be looking for information within the enterprise (via the R5 Domain Search index) or on the Internet, the Explorer Bar will let users choose the search engine they want to use to execute the search request. The implementation steps are: o Use HTML and JavaScript to create the Domain Search Explorer Bar. o Modify the Windows Registry to include references to the Domain Search Explorer Bar. Creating the Domain Search Explorer Bar You can use the following HTML code as a starting point to create the Explorer Bar. Use any text editor, such as Notepad, to create and save this HTML file. Domain Search Explorer Bar

Search Query: Search Server:

At this point, when you bring up this page in a browser, the Search Server field is empty. You need to add a little bit of logic to this page, which you can do with JavaScript. The following JavaScript code, which you add after the header information in your new HTML file, will load the Search Server field with a set of selections including Domain Search and some popular Internet search engines. (You can, of course, decide to choose other Internet search engines you want to include in your Explorer Bar.) Reload the HTML file to see the results: Now that you've populated the Search Server field, you need to: o Build the appropriate search URL based on the search query and the syntax used by the search engine selected by the user. o Create a new window to display the results. The following JavaScript accomplishes both these tasks. The buildurl function constructs the appropriate query for the selected search engine, and the keyword "_main" in the window.open function is used to display the result set in the main window. You can add this JavaScript to your HTML file, directly after the Search Server JavaScript but before the closing tag. Note that in in the sample code below, we assume that Domino R5 Domain Search is running on a server called search.acme.com. You should replace this with the host name of your Domino R5 Domain Search server. function buildurl (server, query){ switch (server) { case "Domino R5": url="http://search.acme.com/catalog.nsf/ SearchResults?SearchDomain&query= "+query+"&start=1&count=50" var resultwin= window.open(url,"_main") break case "Altavista": url="http://www.altavista.com/cgi-bin/query?pg=q&q "+query+"&kl=XX&stype=stext" var resultwin= window.open(url,"_main") break case "Open Directory": url="http://search.dmoz.org/cgi-bin/osearch?search "+query+"&start=1&so=1&fo=0" var resultwin= window.open(url,"_main") break case "Google": url="http://www.google.com/search?q="+query var resultwin= window.open(url,"_main") break case "Yahoo": url="http://search.yahoo.com/bin/search?p="+query var resultwin= window.open(url,"_main") break } } You have defined all the JavaScript functions you need, so now you have to start using them within the HTML page. The LoadSeach() function has to be executed while the page is loading. This is done with an onload statement associated with the Body tag. The last step is to invoke the buildurl function. This function has two arguments: o The value of the Search Query field, which is represented by: document.forms[0].query.value o The name of the search engine selected by the user, which is represented by: document.forms[0].engine.options[document.forms[0] .engine.selectedIndex].text The buildurl function is called via the onSubmit event associated with the Search form, as follows:
With the HTML and JavaScript complete, we're ready to add this as an IE5 Explorer Bar. (To see the complete HTML/JavaScript file, see the article sidebar.) Integrating the Explorer Bar with Internet Explorer 5.0 The first step in integrating the new Explorer Bar with IE5 is to move the HTML file to a Web server accessible to all users. The file can be hosted by any HTTP sever, such as a Domino, Microsoft IIS, or Apache server. For this article, we'll assume the URL for accessing the Explorer Bar is: w3.acme.com/iesearch.htm Of course, you'll need to replace this URL with the one you choose within your organization. Next, you need to create a valid globally unique identifier (or GUID) for the Explorer Bar. You can use the UUIDGEN utility provided with most of Microsoft's development tools to create the GUID, or you can simply use {77BD6998-BBC8-44f6-ADD6-D411DED7ED6C}, which is the GUID we will use as an example. To complete the integration of the Explorer Bar, you use the regedit utility in Windows. 1. Open the regedit utility by typing regedit at the operating system prompt. 2. Expand HKEY_CLASSES_ROOT and find CLSID. You need to create new keys and assign string values to some of them. The following screen shows the hierarchy of the new keys under HKEY_CLASSES_ROOT\CLSID when you have finished. Follow the steps below to create these keys and assign string values. 1. Create a new key under HKEY_CLASSES_ROOT\CLSID for by right-clicking CLSID, choosing New - Key, and typing the GUID for the new Explorer Bar. For example, type: {77BD6998-BBC8-44f6-ADD6-D411DED7ED6C} 2. Set the default string value for this key by right-clicking Default, choosing Modify, and typing the name for the Explorer Bar in the Edit String dialog box. For example, set the string value to R5 Domain Search. 3. Create a new key by right-clicking {77BD6998-BBC8-44f6-ADD6-D411DED7ED6C}, choosing New - Key, and typing Implemented Categories. 4. Create a new key under ImplementedCategories for the CATID that makes the Explorer Bar a horizontal bar. The horizontal CATID is: {00021494-0000-0000-C000-000000000046} Note: If you want to implement a vertical Explorer Bar you would need to use the following CATID instead: {00021493-0000-0000-C000-000000000046} 5. Create a new key called InProcServer32 under {77BD6998-BBC8-44f6-ADD6-D411DED7ED6C}, and set the default string value for this key to Shdocvw.dll. 6. Create a new string value for InProcServer32 called ThreadingModel by right clicking InProcServer32, choosing New - String Value, and typing ThreadingModel. Then set its value to Apartment by right-clicking ThreadingModel, choosing Modify, and typing Apartment in the Edit Value dialog box. 7. Create a new key called Instance under {77BD6998-BBC8-44f6-ADD6-D411DED7ED6C}. 8. Create a new string value for Instance called CLSID and set its value to: {4D5C8C2A-D075-11d0-B416-00C04FB90376} 9. Create a new key called InitPropertyBag under Instance. 10. Create a new string value for InitPropertyBag called URL and set its value to the location of the HTML page hosting your Explorer Bar, for example, http://w3.acme.com/iesearch.htm. Finally, you must add the GUID to the Explorer Bars listed under HKEY_LOCAL_MACHINES and specify the size of your new Explorer Bar. 1. Expand HKEY_LOCAL_MACHINES. 2. Create a new key for {77BD6998-BBC8-44f6-ADD6-D411DED7ED6C} under HKEY_LOCAL_MACHINES\SOFTWARE\Microsoft\Internet Explorer\Explorer Bars. 3. Create a new binary value for {7BD6998-BBC8-44f6-ADD6-D411DED7ED6C} called BarSize. You set the value of BarSize to an 8-byte binary value in hexadecimal notation representing the default size of your new Explorer Bar. The value is interpreted in pixels, so for example, the value 4100 00 00 00 00 00 00 is equivalent to setting the size of the Explorer Bar to 65 pixels. Once all of these entries have been added to the Windows Registry, you can launch Internet Explorer and see your Explorer Bar at the bottom of the main window. Use the View - Explorer Bar command to enable or disable the Explorer Bar. By integrating the new Domain Search feature introduced with Domino R5 into IE5 with this Explorer Bar, you have made Domain Search as easy to get to from the browser as it is from a Notes R5 client. This means that for users, their corporate search engine is always just a click away. ABOUT JOEL Joel Demay has worked at Lotus for about 7 years first in Paris France, then in the United States. Joel recently joined Iris Associates as a product manager for Raven, the upcoming knowledge management server. When he is not sailing on the Charles river, Joel is telling stories to his 2 1/2 year old daughter. If you have any questions about this article, contact Joel at 39. Display Rich Text fields in a view 备注 程序代码 First thing to do is to create a Computed field, of type Text, and call it something like "Abstract". The formula for this will be somthing like : @If(@IsAvailable(name_of_the_rt_field); @Abstract( [Abbrev]; 200; ""; " name_of_the_rt_field "); "" ) * This example will take the first two hundred characters of the named rich text field and abbreviate its content. This can then be displayed in views as a kind of intro to the document. Cool hey!? 40. Auto-Launch a file attachment 备注 程序代码 In the Notes Client there is an option when designing a form to tell it to launch the first attachment when a document is opened. How about doing this in the browser? I've thought of two ways of doing it: 1. Meta-Tags 2. JavaScript 1. Meta Tags - Using the Refresh meta-tag we can tell the browser to redirect the page to the chosen attachment. Place the following line in the $$HTMLHead field (or its equivalent in R5) path := @ReplaceSubstring(@Subset(@DBName; -1); "\\"; "/"); file := @ReplaceSubstring(@Subset(@AttachmentNames; 1); " "; "+"); @If(@Attachments; "" ;"") When the page is opened it automatically opens the first attachment. What happens next depends on the browser, the file type and the user's preferences. In IE, if the file is an office document it will probably launch automatically. Text (.txt) files should open on all browsers as should Adobe Acrobat (.pdf) files and standard HTML files. The user also has the option to tell the browser what to do with each type of file. 2. JavaScript This method is number two as it is not as fool proof as the meta-tag method. Place the following somewhere in your header ($$HTMLHead field) and as soon as the browser encounters the JavaScript that is generated it will redirect to the attachment. path := @ReplaceSubstring(@Subset(@DBName; -1); "\\"; "/"); file := @ReplaceSubstring(@Subset(@AttachmentNames; 1); " "; "+"); @If(@Attachments; "" ;"") JavaScript that is generated: Note: This could be done simply by changing the value of location.href but there is a good reason not to. If you simply change the location href then the "redirect" page is still in the browser's history and every time the user hits the back button they will simply re-run the above script and end up back in the page they were already in. Hence, "breaking the back button" = very annoying. Using the replace method tells the browser not to remember the current page and make the back button go to the page they were in before the "redirect" page 41. Showing a response count without showing the responses 备注 程序代码 Source notestips.com Compatible r4.6x, r5.x, r6.x This tip is primarily for use on the web but it could be put to equally good use in the Notes client. Traditionally, in the Notes client a count of response documents might be shown with twisties to expand the sections. On the web I try to avoid twisties, firstly because I hate the view applet so all of my views are HTML. Secondly, and most importantly if you want to treat your view as HTML, twisties don't work to well(or at least not as well as in the client), as a result most views on the web are best presented flat. Counting the number of child documents for a main document is easily achieved using @DocDescendants however for flat views this @function does not work. So the question is how do we include a document count in an HTML view without displaying the responses. The answer is quite simple. Allow the view to display response documents, include a view column to display the response documents and hide it. We now have a view that allows us to use @DocDescendants but all responses are hidden and not displayed. Although this is simple getting it to work is not so simple, certain properties are essential. Creating the View 1. Create your view with a selection formula that includes responses e.g. Form = "Document" | @AllDescendants 2. These are the important properties. Check the view property to allows response documents and make sure the view is set to be collapsed when first opened. 3. Set the view to display as HTML 4. Include a column in the view to show the responses 5. Hide the responses column 6. In another column you can create your HTML to display your documents and use @DocDescendants to get the count of response documents. Mike 42. 常用的几个按钮收集 备注 程序代码 1. Search @Command([ViewShowSearchBar]) 2. Next @DbCommand("Domino"; "ViewNextPage") 3. Previous @DbCommand("Domino"; "ViewPreviousPage") 4. 在视图中显示Attachment Files ,点击后可以打开。 _linkText := @AttachmentNames; _docRef := "0/" + @Text(@DocumentUniqueID); _attachRef := @ReplaceSubstring(@AttachmentNames; " "; "+"); _href := _docRef + "/$File/" + _attachRef + "?OpenElement"; _aTag := "" + _linkText + ""; _html := "[" + @Implode(_aTag; ", ") + "]"; @If(@Attachments = 0; ""; _html) 5. 显示Notes 的内置图标 @If(@Attachments="";0;5) 6. Preventing opening a document from a view In the view's Queryopendocument method, add continue = false but I find that if the document is opened b4(by another view), this method is not work again. 7.

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 8 金币 [ 分享文档获得金币 ]
1 人已下载

下载文档

相关文档