LotusScript 教程:从入门到精通
目录
-
(图片来源网络,侵删)- 什么是 LotusScript?
- 为什么学习 LotusScript?
- 开发环境简介:Notes/Domino Designer
- 第一个 "Hello, World!" 程序
- 代码注释
-
- 变量声明 (
Dim) - 基本数据类型
- 变量命名规范
- 常量 (
Const)
- 变量声明 (
-
- 算术运算符
- 比较运算符
- 逻辑运算符
- 连接运算符
-
- 条件判断:
If...Then...Else和Select Case - 循环结构:
For...Next,Do...While,Do...Until
- 条件判断:
-
(图片来源网络,侵删)- 什么是 Notes 对象模型?
NotesSession会话对象NotesDatabase数据库对象NotesDocument文档对象NotesView视图对象NotesItem项目对象- 其他重要对象简介
-
- 子过程 (
Sub) - 函数 (
Function) - 参数传递
- 作用域 (
Public,Private)
- 子过程 (
-
On Error GoTo语句Err对象Exit Sub/Function
-
- 需求分析
- 创建代理
- 编写代码
- 测试与调试
-
(图片来源网络,侵删)- 官方文档
- 在线社区与论坛
- 书籍推荐
- 开发最佳实践
第一部分:LotusScript 基础
什么是 LotusScript?
LotusScript 是一种为 IBM Lotus Notes 和 Domino 应用程序设计的编程语言,它与 Visual Basic for Applications (VBA) 语法高度相似,这使得熟悉 VB 的开发者能够快速上手,LotusScript 的核心优势在于它与 Notes/Domino 平台的深度集成,可以方便地操作数据库、文档、视图、邮件等所有 Notes 对象。
为什么学习 LotusScript?
- 自动化任务:自动处理文档、发送邮件、管理数据库等,将重复性工作交给脚本。
- 增强应用功能:在 Notes 表单、视图、代理中嵌入复杂的业务逻辑,实现标准功能无法满足的需求。
- 数据集成:与外部系统(如关系型数据库、Web 服务)进行数据交换。
- 用户交互:创建自定义对话框、消息框,改善用户体验。
- 维护与管理:编写管理脚本,批量处理数据库、修复设计等。
开发环境简介:Notes/Domino Designer
你的所有 LotusScript 代码都将写在 Designer 客户端中,你可以将代码放在以下位置:
- 代理:最常用的位置,可以手动触发,也可以设置为定时触发。
- 表单:在表单的
QueryOpen,QuerySave,PostOpen等事件中编写代码,控制文档的行为。 - 视图:在视图的
QueryAddToFolder,QueryModeChange等事件中编写代码。 - 按钮:放在表单或页面上的按钮,点击后执行代码。
- 共享代码:在
Script Libraries中编写可重用的代码模块。
第一个 "Hello, World!" 程序
-
打开 Domino Designer。
-
创建一个新的 代理,在 "代理" 视图中,点击 "新建代理"。
-
给代理命名,"HelloWorld"。
-
在 "目标" 中选择 "无" 或 "所有文档"。
-
确保 "库" 中选择了 "LotusScript"。
-
点击 "确定"。
-
在打开的代码窗口中,你会看到一个默认的
Sub,在Sub和End Sub之间输入以下代码:Sub Initialize ' 使用 Messagebox 函数显示一个弹窗 Messagebox "Hello, World!", 0, "我的第一个脚本" End Sub -
保存代理。
-
在 Notes 客户端中,打开任意一个数据库,右键点击导航窗格,选择 "代理",然后选择 "HelloWorld" 并运行,你应该会看到一个弹窗。
代码注释
注释是代码中解释性、非执行性的文本,用于方便自己和他人理解代码。
- 单行注释:使用单引号 开头。
' 这是一个单行注释 Dim db As NotesDatabase ' 这也是注释,解释变量的用途
- 多行注释:使用
Rem关键字(不常用)或通过 来实现。' 这是一个多行注释 ' 它可以跨越多行 ' 解释一段复杂的逻辑
第二部分:数据类型与变量
变量声明 (Dim)
变量是存储数据的容器,在使用变量前,最好先声明它。
Dim myVariable As String
Dim是声明变量的关键字。myVariable是变量名。As String指定了变量的数据类型。
基本数据类型
| 数据类型 | 描述 | 示例 |
|---|---|---|
String |
字符串,用于存储文本。 | "Hello" |
Integer |
16 位整数,范围从 -32,768 到 32,767。 | 123 |
Long |
32 位整数,范围更大。 | 123456 |
Single |
单精度浮点数,用于存储小数。 | 14 |
Double |
双精度浮点数,精度更高。 | 1415926 |
Variant |
万能类型,可以存储任何类型的数据,是 LotusScript 的默认类型,尽量避免使用,因为它会影响性能和代码可读性。 | 123 或 "ABC" |
NotesDateTime |
Notes 日期时间对象。 | New NotesDateTime(Now) |
NotesDocument |
Notes 文档对象。 | doc As NotesDocument |
变量命名规范
- 以字母或下划线开头。
- 可以包含字母、数字和下划线。
- 不能使用空格或特殊字符。
- 不区分大小写,但建议采用一致的命名风格(如
CamelCase或PascalCase)。 - 使用有意义的名称,
userName而不是x。
常量 (Const)
常量是一个其值在程序运行期间不会改变的变量。
Const PI = 3.14159 Const MAX_ITEMS = 100 ' 在代码中使用常量 Dim circumference As Double circumference = 2 * PI * 10
第三部分:运算符与表达式
算术运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
| 加法 | 5 + 2 结果为 7 |
|
| 减法 | 5 - 2 结果为 3 |
|
| 乘法 | 5 * 2 结果为 10 |
|
| 除法 (浮点) | 5 / 2 结果为 5 |
|
\ |
除法 (整数) | 5 \ 2 结果为 2 |
Mod |
取模 (余数) | 5 Mod 2 结果为 1 |
^ |
乘方 | 2 ^ 3 结果为 8 |
比较运算符
比较运算符的结果为 True 或 False。
| 运算符 | 描述 | 示例 |
| :--- | :--- | :--- |
| | 等于 | (5 = 5) 结果为 True |
| <> | 不等于 | (5 <> 5) 结果为 False |
| > | 大于 | (5 > 3) 结果为 True |
| < | 小于 | (5 < 3) 结果为 False |
| >= | 大于或等于 | (5 >= 5) 结果为 True |
| <= | 小于或等于 | (5 <= 5) 结果为 True |
逻辑运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
And |
逻辑与,两个条件都为真时,结果为真。 | (True And False) 结果为 False |
Or |
逻辑或,两个条件中有一个为真时,结果为真。 | (True Or False) 结果为 True |
Not |
逻辑非,将布尔值取反。 | Not (True) 结果为 False |
连接运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
& |
连接两个字符串 | "Hello" & " World" 结果为 "Hello World" |
也可以用于连接字符串,但 & 更清晰 |
"Hello" + " World" 结果为 "Hello World" |
第四部分:流程控制
条件判断: If...Then...Else
根据条件的真假来执行不同的代码块。
Dim age As Integer
age = 25
If age >= 18 Then
Messagebox "你已经成年了。", 0, "提示"
Else
Messagebox "你还未成年。", 0, "提示"
End If
' 可以使用 ElseIf 处理多个条件
If age < 13 Then
Messagebox "你是儿童。", 0, "提示"
ElseIf age < 18 Then
Messagebox "你是青少年。", 0, "提示"
Else
Messagebox "你是成年人。", 0, "提示"
End If
Select Case
当需要对一个变量的多个不同值进行判断时,Select Case 比 If...ElseIf 更清晰。
Dim dayOfWeek As Integer
dayOfWeek = 3 ' 假设 3 代表星期三
Select Case dayOfWeek
Case 1
Messagebox "星期一", 0, "星期"
Case 2
Messagebox "星期二", 0, "星期"
Case 3
Messagebox "星期三", 0, "星期"
Case 4 To 7 ' 也可以使用范围
Messagebox "工作日的后半段", 0, "星期"
Case Else ' 其他所有情况
Messagebox "无效的星期数字", 0, "错误"
End Select
循环结构
For...Next
当你知道循环需要执行多少次时,使用 For 循环。
' 从 1 循环到 5
Dim i As Integer
For i = 1 To 5
Messagebox "当前循环次数: " & i, 0, "For 循环"
Next i
' 可以使用 Step 来改变步长
For i = 0 To 10 Step 2
Messagebox "当前数字: " & i, 0, "For 循环 (Step)"
Next i
Do...While 和 Do...Until
当你希望在某个条件为真(或为假)时持续循环,但不确定具体次数时,使用 Do 循环。
Do...While: 当条件为 True 时,继续循环。
Dim count As Integer
count = 1
Do While count <= 5
Messagebox "Count is: " & count, 0, "Do While"
count = count + 1
Loop
Do...Until: 当条件为 True 时,停止循环。
Dim count As Integer
count = 1
Do Until count > 5
Messagebox "Count is: " & count, 0, "Do Until"
count = count + 1
Loop
Do 循环也可以先执行一次再判断条件,只需将 While 或 Until 放在 Loop 后面即可。
第五部分:核心对象模型
这是 LotusScript 的灵魂,让你能够与 Notes/Domino 平台交互。
什么是 Notes 对象模型?
它是一系列相互关联的类(对象),代表 Notes 中的各种元素(如会话、数据库、文档等),通过创建这些对象的实例,你可以读取和操作它们。
NotesSession 会话对象
代表当前 Notes 客户端或 Domino 服务器的会话,它是访问所有其他对象的起点。
Dim session As New NotesSession Dim userName As String userName = session.CommonUserName ' 获取当前用户的完整姓名 Messagebox "当前用户是: " & userName, 0, "会话信息"
NotesDatabase 数据库对象
代表一个 Notes 数据库。
Dim session As New NotesSession
Dim db As NotesDatabase
Dim dbPath As String
' 获取当前打开的数据库
Set db = session.CurrentDatabase
' 或者通过路径打开一个特定的数据库
' dbPath = "CN=MyServer/O=MyOrg!!names.nsf"
' Set db = session.GetDatabase("", dbPath)
If Not db.IsOpen Then
Call db.Open()
End If
Messagebox "数据库名称: " & db.Title & vbCrLf & _
"数据库路径: " & db.FilePath, 0, "数据库信息"
NotesDocument 文档对象
代表 Notes 数据库中的一个文档,这是最常用的对象之一。
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim view As NotesView
Set db = session.CurrentDatabase
Set view = db.GetView("($All)") ' 获取一个视图,($All) 视图
' 获取视图中的第一个文档
Set doc = view.GetFirstDocument()
If Not doc Is Nothing Then
' 读取文档的 "Subject" 字段
Dim subject As String
subject = doc.Subject(0) ' 使用 (0) 获取字段第一个值
' 读取文档的 "Form" 字段
Dim formName As String
formName = doc.Form(0)
Messagebox "表单: " & formName & vbCrLf & _
"主题: " & subject, 0, "文档信息"
' 修改文档并保存
doc.Subject = "新的主题 " & Now()
Call doc.Save(True, True) ' (True, True) 表示提示用户并保存到磁盘
End If
NotesView 视图对象
代表数据库中的一个视图。
GetFirstDocument(): 获取视图中的第一个文档。GetNextDocument(doc): 获取指定文档的下一个文档。GetDocumentByKey(key): 根据视图列的值查找文档。
NotesItem 项目对象
代表文档中的一个字段。
Dim item As NotesItem
Set item = doc.GetFirstItem("Subject")
If Not item Is Nothing Then
Messagebox "字段名: " & item.Name & vbCrLf & _
"字段类型: " & item.Type & vbCrLf & _
"字段值数量: " & item.Values, 0, "项目信息"
End If
第六部分:子过程与函数
将代码封装成可重用的模块。
子过程 (Sub)
执行一系列操作,但不返回值。
Sub LogAction(action As String)
' 这是一个简单的日志记录过程
Dim session As New NotesSession
Messagebox "[" & Now() & "] - " & action, 0, "操作日志"
End Sub
' 调用子过程
Call LogAction("用户打开了文档")
函数 (Function)
执行一系列操作,并返回一个值。
' 计算两个数的和并返回结果
Function AddNumbers(num1 As Long, num2 As Long) As Long
AddNumbers = num1 + num2
End Function
' 调用函数
Dim sum As Long
sum = AddNumbers(10, 25)
Messagebox "计算结果是: " & sum, 0, "函数调用"
参数传递
- 按值传递:
ByVal,函数/过程内部对参数的修改不会影响外部的变量,这是默认方式。 - 按引用传递:
ByRef,函数/过程内部对参数的修改会直接影响外部的变量。
作用域 (Public, Private)
Private:只能在声明它的模块(如代理、表单)内被调用。Public:可以在整个数据库中被调用(需要放在 Script Library 中)。
第七部分:错误处理
健壮的代码必须包含错误处理机制,以防止程序意外崩溃。
On Error GoTo 语句
当发生运行时错误时,程序会跳转到你指定的标签行。
Sub ProcessDocument
On Error GoTo ErrorHandler ' 如果发生错误,跳转到 ErrorHandler 标签
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Set db = session.CurrentDatabase
Set doc = db.CreateDocument() ' 尝试创建一个新文档
' 假设这里有一个会引发错误的操作
' 给一个不存在的视图添加文档
Call doc.PutInFolder("一个不存在的文件夹")
Call doc.Save(True, True)
Exit Sub ' 如果一切正常,在此处退出,避免执行下面的错误处理代码
ErrorHandler:
' Err 对象包含了错误信息
Dim errorMsg As String
errorMsg = "发生错误 #" & Err & ": " & Error(Err)
' 使用日志记录错误
Call LogAction(errorMsg) ' 假设我们有一个 LogAction 过程
' 向用户显示友好的错误信息
Messagebox "处理文档时出错,请记录此信息并联系管理员。" & vbCrLf & errorMsg, 16, "严重错误"
End Sub
第八部分:实战演练:创建一个简单的代理
需求:创建一个代理,它会遍历当前数据库中所有 "Memo" 表单的文档,并将 "Subject" 字段的内容加上 "[已处理]" 的前缀。
-
创建代理:
- 在 Designer 中,选择一个数据库。
- 点击 "代理" 视图,点击 "新建代理"。
- 名称:
ProcessMemos - 目标:
所有文档 - 库:
LotusScript - 共享:勾选(这样所有用户都能运行它)
-
编写代码: 将以下代码粘贴到代理的代码窗口中。
Sub Initialize ' 错误处理 On Error GoTo ErrorHandler ' 1. 获取必要的对象 Dim session As New NotesSession Dim db As NotesDatabase Dim view As NotesView Dim doc As NotesDocument Set db = session.CurrentDatabase ' 2. 获取要处理的视图,这里我们使用 ($All) 视图 Set view = db.GetView("($All)") If view Is Nothing Then Messagebox "找不到 ($All) 视图!", 16, "错误" Exit Sub End If ' 3. 遍历视图中的所有文档 Set doc = view.GetFirstDocument() While Not doc Is Nothing ' 4. 检查文档的表单是否为 "Memo" If doc.Form(0) = "Memo" Then ' 5. 获取并修改 Subject 字段 Dim subject As String subject = doc.Subject(0) If Not subject = "" Then ' 确保主题不为空 doc.Subject = "[已处理] " & subject ' 6. 保存修改 Call doc.Save(True, False) ' (True, False) 表示不提示用户,保存到磁盘 End If End If ' 7. 移动到下一个文档 Set doc = view.GetNextDocument(doc) ' 8. 循环结束 Wend ' 9. 显示成功消息 Messagebox "处理完成!", 64, "成功" Exit Sub ' 正常退出,避免进入错误处理 ErrorHandler: ' 错误处理逻辑 Dim errorMsg As String errorMsg = "代理运行时发生错误 #" & Err & ": " & Error(Err) ' 记录错误到日志或显示给用户 Messagebox "代理执行失败!" & vbCrLf & errorMsg, 16, "严重错误" ' 如果需要,可以在这里添加代码将出错的文档信息记录下来 End Sub -
测试与调试:
- 保存代理。
- 在 Notes 客户端中,打开同一个数据库。
- 右键点击导航窗格,选择 "代理"。
- 选择
ProcessMemos并运行。 - 运行后,打开几个 "Memo" 表单的文档,检查它们的 "Subject" 字段是否已被成功修改。
第九部分:进阶学习资源与最佳实践
官方文档
- IBM Domino Designer 帮助:在 Designer 中按
F1,搜索 "LotusScript" 或具体的对象/方法,这是最权威的参考资料。
在线社区与论坛
- Stack Overflow:搜索
lotuscript标签,有大量历史问题。 - The Notes/Domino Forum:IBM 官方社区,有专家和同行解答问题。
- DominoPower:一个老牌的 Notes 开发者社区,有很多文章和资源。
书籍推荐
- 《LotusScript 编程指南》:经典的入门书籍。
- 《Mastering LotusScript》:更深入的内容。
开发最佳实践
- 始终使用
On Error GoTo:养成处理错误的好习惯。 - 使用有意义的变量名:提高代码可读性。
- 添加注释:解释复杂的逻辑和代码的用途。
- 模块化设计:将通用功能封装到
Sub或Function中,最好放在 Script Library 中实现代码复用。 - 测试,测试,再测试:在测试环境中充分测试你的代码,特别是代理,因为它可能会影响大量数据。
- 善用
Debug.Print:在开发过程中,可以将变量值输出到 Notes 客户端的状态栏,方便调试(需要开启状态栏)。
这份教程为你打下了坚实的基础,学习编程最好的方式就是多写、多练、多思考,从简单的代理开始,逐步尝试更复杂的功能,你会很快掌握 LotusScript 的精髓,祝你学习愉快!
