存档在 ‘Ribbon/RibbonX’ 分类中.
RibbonX:自定义Office 2007功能区
第4章 介绍VBA阅读笔记
对于有一定VBA基础的人来说,本章较简单。因此,我的笔记相对也较简单,只是对内容进行粗略地概述,或者记下需要注意的事项及关键点。
—————————————-
编写自已的代码
1、命名约定
使用约定的规则命名,将使他人和您更容易阅读和理解代码;降低了使用预留字或特定字符的风险;避免对象之间的命名冲突;更容易向他人解释代码。
此外,当多人共同为一个项目工作或者需要与他人共享代码时,遵守标准的命名约定是有利的。
本书为XML代码采用的命名约定为:
(1)前缀:为功能区定制代码使用rx以区分其他VBA代码。
(2)标记:采用RVBA标记系统来标记功能区控件。例如,在VBA中label控件的标记为lbl,而在这里的功能区命名约定中使用rxlbl。这样,让我们知道该标签来自于功能区而不是VBA工程内的标签控件。
(3)基本的名称:即控件的描述。例如,有一个功能区控件并定义其前缀和标记为rxbtn,然而该控件做什么呢?如果是一个演示按钮,则将其命名为rxbtnDemo,使之更有意义。
(4)事件后缀:已经有一个按钮,但当用户单击该按钮后会发生什么?将触发事件,此时使用通用的VBA事件后缀来描述该行为。因此,如果Demo按钮附加了onAction属性,那么过程名为rxbtnDemo_click。
(5)共享的事件:如上例,Demo按钮有单击事件。然而,如果希望与其他按钮共享该事件,或者其他控件有onAction属性。此时使用一般的标记来指明onAction属性在许多不同的控件中共享。例如:rxshared_click。现在,应该知道单击被许多具有onAction属性的其他控件共享。
(6)Repurpose后缀:前面已提到使用事件后缀来匹配VBA的事件。然而,当使用内置命令时,可能希望使用onAction属性重新使用其行为。由于onAction返回click后缀,不能让代码阅读者知道其是一个被重新使用的内置命令。此时,在rx前缀后面跟随控件的idMso属性作为基本的名称,然后加上下划线和单词“Repurpose”表示其为重新使用的内置命令。例如:rxFileSave_Repurpose表示重新FileSave命令来执行某些其他操作。
2、数据类型
包括Byte、Boolean、Integer、Long、Single、Double、Currency、Decimal、Date、Object、String、Variant、User-Defined。
3、处理事件
Excel、Access和Word都能控制许多不同类型的事件。事件通常与常使用的对象相关联。
(1)工作簿事件
例如,工作簿的SheetBeforeRightClick事件:
Private Sub Workbook_SheetBeforeRightClick(ByVal Sh As Object, _
ByVal Targe As Range,Cancel As Boolean)
If Union(Target.Range(“A1”),Range(“A1:C25”)).Address= _
Range(“A1:C25”).Address Then Cancel=True
End Sub
其中,参数sh引用发生右击的工作表,参数Target引用右击的目标区域,参数Cancel决定是否取消右击的结果。正常情况下,右击时将获得一个弹出菜单,但当Cancel设置为True后,将取消该弹出菜单。
上述代码对工作簿中所有工作表都有效。
一些有用的工作簿事件:BeforeClose、BeforeSave、NewSheet、Open、SheetActivate、SheetBeforeRightClick、SheetChange。
(2)工作表事件
当必须处理某工作表上的事件时,使用该工作表自身的事件。下面举一个实用的解决方案。
假设需要验证A列接受不重复的值,只要用户在每个单元格中输入数据而不在单元格区域中复制和粘贴,那么一切都正常。关键是,如果用户复制并粘贴数据,那么所有的验证都是徒劳。此时,应该使用事件过程。
使用Change事件来检查在列中发生了什么,如果用户粘贴数据,则该过程验证粘贴值以便确定撤销在该列中的粘贴操作。如下面的代码:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngSelected As Range
Dim rngValue As Range
Dim lngCount As Long
‘当检查发生时禁用事件
Application.EnableEvents = False
‘监控的单元格区域
If Union(Target.Range(”A1″), Range(”A1:A1048576″)).Address = _
Range(”A1:A1048576″).Address Then
On Error Resume Next
‘设置所选择的区域
Set rngSelected = Selection
‘统计所有粘贴的值的重复数
For Each rngValue In rngSelected
lngCount = WorksheetFunction.CountIf(Range(”A1:A1048576″), _
rngValue)
‘如果重复数大于1
If lngCount > 1 Then
‘显示错误消息
MsgBox “列A仅接受唯一值.” _
& “这些值您已经输入.”, vbCritical, _
“在列A复制的值”
‘撤销粘贴操作
Application.Undo
Application.CutCopyMode = xlCut
Exit For
End If
Next rngValue
End If
‘启用事件以使继续监控
Application.EnableEvents = True
End Sub
注意,因为代码也导致工作表中的变化,所以必须临时禁用事件。此外,在过程结束前,必须启用事件。
一些有用的工作表事件:Activate、BeforeDoubleClick、BeforeRightClick、Change、SelectionChange。
(3)在Access中的窗体和报表事件
假设用户打开某报表,但什么也没看到,即在报表中没有放置数据。空的报表将给人在过程中出现错误的印象,而不是报表中没有数据。此时,使用NoData事件来确定是否取消报表,来避免这些问题和混淆
Private Sub Report_NoData(cancel As Integer)
MsgBox “目前没有可用的数据。报表将被删除…”
cancel=-1 ‘也可以使用True代替数字1
End Sub
另一个有用的事件是Open事件,使用该事件确保显示报表前装载了重要的元素。示例略。
一些有用的报表和窗体级事件:Click、Close、Current、Load、NoData、OnFormat、Open。
(4)在Word中的文档级事件
在Word中,需要为特定的文档创建类模块来处理事件。也能应用该方法到全局模板或者制作加载项来控制应用程序级的事件。
使用WithEvents关键词声明能在工程中使用的公共的Word对象。
首先,需要在工程中添加一个类模块并将其命名,本例中为clsEvents。然后,打开代码窗口,输入下面的代码:
Public WithEvents appWrd As Word.Application
Private Sub appWrd_DocumentChange()
End Sub
第一行代码指定Word应监控的事件。下面的过程表明应该监控文档变化。
事实上,此时并不会发生什么。然而,可以使用文档级的Open事件来为Word设置应用程序级事件。
Dim mappWrd As New clsEvents
Private Sub Document_Open()
Set mappWrd.appWrd = Application
End Sub
一旦这样处理后,准备使用在类模块clsEvents中的事件。记住,必须首先编写所有的事件,否则类将被中止,因为没有监控的事件。
下面添加一段实用的事件代码,用来追踪某文档的打印:
Private Sub appWrd_DocumentBeforePrint(ByVal Doc As Document, _
Cancel As Boolean)
If Doc = ThisDocument Then
‘code
Else
‘code
End If
End Sub
注意,WithEvents变量appWrd将监控整个Word应用程序,因此当试图只监控包含代码的文档时,应该创建代码使之仅在正确的文档中执行。在示例中,使用ThisDocument对象来确保仅在包含代码的文档中有效。
(5)应用程序级事件
正如在Word中所见,如果打算配置应用程序级的事件,则需要使用类模块。因此,这里所有的示例都使用类模块。并且,使用标准的名称clsEvents。
第一个示例演示如何监控特定的工作簿的打印,并且仅允许打印指定的工作簿。
(1)打开Excel,在VBE中添加一个新的类模块。
(2)在类模块的代码窗口中,输入下面的代码:
Public WithEvents appXL As Excel.Application
Private Sub appXL_WorkbookBeforePrint(ByVal Wb As Workbook, _
Cancel As Boolean)
If Not Wb.Name = “AllowedWorkbook.xlsm” Then
MsgBox “不允许打印,除非是工作簿AllowedWorkbook.xlsm”, vbCritical
Cancel = True
End If
End Sub
(3)在应用程序的Open事件中,输入下面的代码:
Dim mappXL As New clsEvents
Private Sub Workbook_Open()
Set mappXL.appXL = Application
End Sub
此时,将只允许指定的工作簿被打印。
第二个示例在Access中,在数据输入到表之前提供一种验证数据的方式。假设一个文本框用于输入数据到某字段,并且仅包含正值,因此,如果该文本框出现在多个窗体中时,可能试图为每个文本框编写验证代码。然而,可以在类模块中编写简单的过程然后将其在工程中使用,从而节省时间。代码如下:
Public WithEvents clsTextBox As TextBox
Private Sub clsTextBox_AfterUpdate()
With Me
If .clsTextBox.Value<0 Then
MsgBox “该字段不允许输入负值……”,vbCritical
.clsTextBox.Value=0
End If
End With
End Sub
创建类模块后,需要从使用文本框的任何窗体调用该模块。注意,在每个窗体中文本框必须有相同的名称。从设计视图中打开一个可用的窗体并输入下面的代码:
Dim mtxtbox As New clsTextBoxEvents
Private Sub Form_Load()
Set mtxtbox.clsTextBox=Me.txtValue
End Sub
Private Sub txtValue_AfterUpdate()
‘该过程没有使用,仅确保执行类
End Sub
现在,应该能够在工程中的任何地方重复使用该类而无须重复编写相同的代码。这是一项非常有用的技术,能应用到许多解决方案中。
4、对象浏览器
(1)找到对象及其属性、方法和事件的最好方式是使用对象浏览器。
(2)在VBE中,按F2键即可快速打开对象浏览器。
5、引用库
一旦引用相应的库之后,就能够查看其对象模型获得帮助,也能够使用该库的对象及其属性和方法。
使用VBE菜单“工具”─—“引用”,打开“引用”对话框,其中列出了所有可引用的库。
(1)介绍早期绑定和后期绑定
当使用外部对象时,也就是说使用不属于正处理的对象模型中的对象时,必须创建该外部对象的实例。即使用早期绑定或后期绑定。
当首先安装对其他库的引用时,使用的是早期绑定。早期绑定不仅加速了编写代码的过程(现在所有关于该库的对象包括其属性和方法都公开),而且改善了代码的性能。缺点是使用该程序代码的用户也需要已经注册了所引用的库。如下面的代码:
Dim olEmail As Outlook.MailItem
后期绑定不依赖于先引用库,而且首先简单地声明普通的对象并使用其属性和方法,在运行时再调用相关的库。例如下面的代码:
Dim appOL As Object
Dim Email As Object
Set appOL=CreateObject(“Outlook.Application”)
Set Email=appOL.CreateItem(olMailItem)
CreatObject函数总是创建对象的新实例,如果已经打开了该对象的一个实例,那么将创建另一个实例。如果不希望由于创建应用程序对象新实例而耗尽资源,可以使用GetObject函数:
Set appWrd=GetObject(,”Word.Application”)
如果已经打开则该代码将获取Word的application对象,因而不需要创建该应用程序的另一个实例。当然,如果该应用程序的实例不存在,那么代码将返回错误。可以使用下面的代码进行处理并避免错误:
On Error Resume Next
Set appWrd=GetObject(,”Word.Application”)
If appWrd Is Nothing Then Set appWrd=CreateObject(“Word.Application”)
使用On Error Resume Next忽略可能没有已经运行的实例而产生的错误。如果发生错误,则不会设置该对象并且仍然是Nothing。因此,随后的语句检查是否是nothing,如果是则创建该对象的一个新实例。
调试代码
(1)Debug.Print和Debug.Assert
Debug对象用于向立即窗口输出结果,它有两个方法:
Print:用于在立即窗口打印输出结果。
Assert:当预料的结果应该评估为True时,用于断言在运行时评估为False的条件。当感到代码应该返回true值或者基于true的假设,但事实上返回false值,则当其评估为false时可以断言该代码,并停留在该断言行,如下例所示:
Sub debugAssert()
Dim lngRow As Long
Dim blnAssertNotEmpty As Boolean
lngRow = 1
Do Until IsEmpty(Cells(lngRow, 1))
blnAssertNotEmpty = Not (IsEmpty(Cells(lngRow + 1, 1)))
lngRow = lngRow + 1
Debug.Assert blnAssertNotEmpty
Loop
End Sub
本例中,将在工作表指定的单元格中循环,检查是否下一个单元格是空。当遇到空单元格时,Boolean值将为False,代码停止在断言行。
(2)Stop语句
Stop语句用于执行代码时在特定的点挂起。假设希望在打开工作簿、文档、报表或窗体时停止代码。可以添加MsgBox并输入在显示消息之后的代码。然而,这会导致不期望的中断,在每次执行该行代码时不得不处理消息框。此时,一种更好的选择是使用Stop语句,避免消息框。
使用Stop语句将延缓执行,能使您分析代码。例如,下面的代码包括Stop语句,在设置Ribbon对象之前中止过程。如果在这里停止执行,那么UI仍然会装载,但Ribbon对象将不可用:
Sub rxIRibbonUI_onLoad(ribbon As IRibbonUI)
Stop
Set grxIRibbonUI = ribbon
End Sub
注意,使用Stop与在代码中添加断点有相似的效果。然而,当文件关闭后,断点也失效了。
(3)立即窗口
立即窗口是一个有价值的工具,可以:1)测试所编写的代码或者调试代码中的问题;2)查询或更改变量的值;3)当中止执行时,查询或更改变量的值;4)为变量赋新值;5)查询或更改属性值;6)运行子过程或函数;7)查看调试输出。
(4)本地窗口
本地窗口用于显示正执行过程的变量值和对象。如果需要监控多个变量、值或对象,那么使用本地窗口可能是最好的方式之一。
(5)监视窗口
监视窗口是调试代码的另一个极好的工具,能够指定监视某对象的值的指令,例如变量、表达式、函数调用,等等。当条件满足或者正监视的变量改变时,监视窗口将暂停代码的执行。
错误处理
有一些简单的方式来处理未解决的或不可预知的问题,错误处理技术就是一种,能够帮助您建立更健壮的代码。
(1)On Error Resume Next
这是最简单且最频繁使用的错语处理语句。该语句将简单地忽略发生错误的语句并继续执行下面的代码。但是,如果其他代码行依赖于该行出错的语句,那么程序将会出现一连锁的错误反应,因而得不到正确的结果。
建议保守地使用这种错误处理的方法。
(2)On Error GoTo
这种形式的错误处理有:
On Error GoTo 0或On Error GoTo <label>,label代表选择的标记,如ErrHandler或Err_Handler。
Sub OnErrorGoTO()
On Error GoTo Err_Handler
‘这里是过程/函数的主体
Exit Sub ‘或Exit Function
Err_Handler:
‘这里是错误处理代码
Resume Next
End Sub
处理数组
数组基本上是一组被索引的数据,VBA将其作为单个的变量。例如:
Dim InflationRate(2000 To 2007) As Double
索引值是2000至2007之间的年份。
(1)确定数组的边界
使用LBound和UBound函数确定数组的上边界和下边界(上限和下限)。
(2)调整数组的大小
即创建动态数组。此时,使用ReDim关键字来调整数组的大小。
但是,如果数组已经包含值,那么使用ReDim调整数组的大小将会清除数组内容。如果想保留数组中以前的信息,则可以在ReDim关键字后再使用Preserve关键字,例如:
ReDim Preserve InflationRate(StartingYear To EndingYear)
Dim InflationRate() As Double
Dim varArray As Variant
Sub RunExampleArray()
Call ExampleArray(1990, 2000)
Call ExampleArray2(1980, 2007)
End Sub
Sub ExampleArray(ByVal StartingYear As Long, _
ByVal EndingYear As Long)
ReDim InflationRate(StartingYear To EndingYear)
InflationRate(1990) = 2.4
InflationRate(2000) = 1.9
varArray = InflationRate()
End Sub
Sub ExampleArray2(ByVal StartingYear As Long, _
ByVal EndingYear As Long)
ReDim InflationRate(StartingYear To EndingYear)
InflationRate(1990) = varArray(1990)
InflationRate(2000) = varArray(2000)
Debug.Print LBound(InflationRate)
Debug.Print UBound(InflationRate)
Debug.Print InflationRate(1990)
Debug.Print InflationRate(2000)
End Sub
下一章:回调的具体细节。
RibbonX:自定义Office 2007功能区
第4章 介绍VBA阅读笔记
对于有一定VBA基础的人来说,本章较简单。因此,我的笔记相对也较简单,只是对内容进行粗略地概述,或者记下需要注意的事项及关键点。
————————————————————
使用XML可以自定义功能区,然而,要创建真正的自定义解决方案,需要添加功能,此时就需要VBA啦。
开始学习VBA
学习VBA的一些基本原理和编程规则。
一般而言,在Excel和Word中VBA过程的一组指令称作宏。然而,Access同时有称作宏的对象,提供了一些预先确定的在工程中容易使用的指令。因此,不应该将Excel和Word的宏与Access的宏相混淆。此外,在Excel和Word中有宏录制器,而Access则没有。然而,Access 2007有一个非常好的宏设计器,包括为用户提供的宏名、条件、动作、参数、批注等字段。并且,从Access 2007开始,Access向导产生宏代替VBA代码。
虽然VBA不是用于编程Ribbon的唯一语言(也可以使用诸如C#、C++、VB.Net和VB),但本书只探讨VBA,因为VBA不仅强大,而且对拥有Microsoft Office的每个人都是可用的。
1、什么是VBA
VBA是一种编程语言,能够使人们处理使用内置工具不可能完成的功能,并且VBA常用于改进和自动化某项任务。
一般说来,对于Excel和Word,VBA能够被分成两类代码:可录制的代码和不可录制的代码。这两类代码不会应用到Access,因为它没有提供宏录制功能。此外,虽然Access向导产生宏,但向导没有联系到Ribbon定制。因此,使用Access的讨论和示例大多数取决于VBA,但也有一些示例展示如何使用Access宏对象。
2、启用宏的文档
在需要代码的功能区定制中,由于需要允许运行宏,因此应该将Excel工作簿和Word文档保存为启用宏的文档。
3、使用Visual Basic Editor(VBE)
在VBE中编写VBA代码。VBE窗口中重要的元素包括:
(1)代码窗口─—输入VBA代码的地方或者放置录制的代码的地方。每个主要的对象都有自已的代码窗口。标准模块和类模块也有自已的代码窗口。
(2)代码窗口关闭按钮─—使用该按钮关闭一个打开对象的代码窗口。
(3)代码窗口最大化/恢复按钮─—使用该按钮最大化/恢复某对象的代码窗口。
(4)代码窗口最小化按钮─—使用该按钮最小化打开对象的代码窗口
(5)立即窗口─—使用立即窗口调试按钮。从代码中发送结果到这个窗口或者可以直接在窗口中输入指令
(6)菜单栏─—VBE菜单栏仍然保留与以前版本相同,不仅是内容而且外观
(7)工程资源管理器─—工程对象的容器
(8)属性窗口─—显示当前对象的可用属性
(9)标题栏─—如果不清楚代码窗口指向的对象,看看标题栏,这里有它的名称
(10)工具栏─—包含有用的命令,帮助更容易编写代码
(11)VBE关闭按钮─—使用该按钮关闭VBE工作环境
(12)VBE最大/恢复按钮─—使用该按钮来最大化/恢复VBE工作环境
(13)VBE最小化按钮─—使用该按钮最小化VBE工作环境
为Excel和Word录制宏
了解Excel或Word对象模型最好的方式是录制宏。
录制宏时在Excel和Word之间一个重大的区别是,当录制操作时Excel允许使用鼠标,相反Word仅录制输入。这意味着虽然能够在Excel中使用鼠标选择文本,然后执行对文本的某种操作,并且这些过程将被录制,但是在Word中录制宏时不能在文档窗口使用鼠标。
虽然在文档中不能使用鼠标执行操作,但是可以使用鼠标选择功能区中的命令和/或选择UI中的元素。
1、一个录制示例
本节介绍一个录制宏的简单示例。假设在Excel中有某项计算,总要插入一个特定的批注。可以录制与插入批注相关的操作,然后重复利用该宏,而不需要每次都输入相同的批注。
(1)在“开发工具”选项卡的“代码”组中,单击“录制宏”,打开“录制新宏”对话框。
(2)输入宏名,这里使用“InsertComment”。
(3)指定快捷键,这里使用Ctrl+Shift+C。
(4)单击“确定”开始录制。
(5)选择需要插入批注的单元格。
(6)单击“审阅”选项卡的“批注”组中的“新建批注”。
(7)输入批注,这里是“This is the comment!”。
(8)完成后,单击“开发工具”选项卡的“代码”组中的“停止录制”。
现在,应该在VBE中看到如下图所示的窗口:
2、编辑录制的宏
录制的宏将总是在单元格C4中插入批注,而现在想将批注插入到所选择的单元格中。并且,将试图覆盖已存在的批注时,将会产生错误。
因此,现在需要修改录制的代码,使代码为重复使用切实可行。此时,需要:(1)在添加新批注之前删除旧的批注;(2)确保批注总是可见的。代码如下:
Sub InsertComment()
‘ InsertComment Macro
‘ 快捷键: Ctrl+Shift+C
Range(”C4″).Comment.Delete
Range(”C4″).AddComment
Range(”C4″).Comment.Visible = True
Range(”C4″).Comment.Text Text:=”fanjy:” & Chr(10) & “This is a comment!”
End Sub
由于在单元格C4中已经存在批注,因此在插入新批注前使用Comment对象的Delete方法将之清除。然而,如果在该单元格中没有批注,则会产生错误(后面将会介绍错误处理)。要在活动单元格中放置批注,则在代码中使用ActiveCell替换Range(“A1”)。
注意,Comment对象没有Add方法,而是AddComment方法。可以直接使用该方法添加批注,如:Range(“A1”).AddComment (“fanjy:” & Chr(10) & “This is a comment!”)
3、在录制后编辑宏选项
在Excel和Word中稍有不同。在Word中需要调用“Word选项”中的“自定义”选项卡。
子过程和函数
1、对象模型(OM)
(1)最高级别的对象是Application对象,通常称之为根对象。
(2)对象模型基本上是一组对象和对象的集合,公开用于执行各种各样操作的属性和方法。
(3)为使用对象模型,理解概念和语法是重要的。
(4)例如,假设希望在Word文档中添加一个表格,必须包含从根对象到希望使用的对象的完整路径:
Application.Documents(“Document1”).Tables.Add
(5)也能够使用低层级对象的Parent属性,从底层级的对象到高层级的对象。例如:
MsgBox ThisWorkbook.Parent
将在消息框中显示“Microsoft Excel”。
2、子过程
子过程主要是一组指令,用来完成某项任务或者一系列任务。例如,在Access中创建打开报表的过程或者在Excel中创建将公式转换为文本的过程。
下面是三个示例。
(Excel示例)
Sub WorkingWithCell()
ThisWorkbook.Windows(1).ActiveCell.ClearContents
ThisWorkbook.Windows(1).ActiveCell.Value=Now()
ThisWorkbook.Windows(1).ActiveCell.NumberFormat=”dd-mm-yyyy hh:mm:ss”
End Sub
(Access示例)
Private Sub cmdExit_Click()
CloseCurrentDatabase
End Sub
(Word示例)
Sub TableFit()
ThisDocument.Tables(1).AllowAutoFit=True
End Sub
第一个示例处理单元格。第二个示例数据库。第三个示例处理表格。看了这三个示例后,您将认识到一些重要的对象:
(1)ThisWorkbook:本身指Excel,引用包含代码的工作簿。有许多其他方式引用工作簿,但是如果需要处理工作簿级别的元素,则使用该对象。(ThisWorkbook也是Application对象的属性,返回一个Workbook对象)
(2)ThisDocument:使用该对象意味着访问包含代码的文档的相关属性和方法。
(3)CurrentProject:用于获取包含代码的数据库项目的重要信息,例如连接字符串、路径等等。
例如,使用ThisWorkbook来识别工作簿的作者:
Sub ThisWB()
MsgBox ThisWorkbook.BuiltinDocumentProperties(“Author”)
End Sub
使用下面的代码从数据库项目中获取完整的连接资料:
Sub connectionDetails()
MsgBox CurrentProject.Connection
End Sub
3、函数
与过程不一样,函数通常用于返回值。例如,如果希望获得计算的结果,那么使用函数。
Function nthRoot(number As Double,nth As Integer) As Double
nthRoot=number ^ (1/nth)
End Function
能够直接地或者间接地使用函数。意味着能够在窗体或者工作表中使用函数计算值,或者能够从VBA工程里的另一个过程中调用函数。
VBA编码技术
1、循环语句
(1)For-Next循环
语法:
For counter=start To end [Step step]
[statements]
[Exit For]
[statements]
Next [counter]
注意:不能指定一个Boolean型或者数组作为counter。step可以是负值。
语法:
For Each element In group
[statements]
[Exit For]
[statements]
Next [element]
注意,element代表用于遍历集合或数组中的元素。对于集合,element可以仅为Variant型变量或者任何特定的对象变量(如Worksheet、Document、Database)。对于数组,element仅为Variant变量。
例如,在对Windows Script Hosting模型引用后,下面的过程读取Excel工作簿所在文件夹中的每个文件,并在当前工作表中列出:
Sub listFileNames()
Dim fsoObj As New FileSystemObject
Dim fsoFolder As Folder
Dim fsoFile As File
Dim lngRow As Long
Dim strPath As String
strPath=ThisWorkbook.Path
Set fsoFolder=fsoObj.GetFolder(strPath)
lngRow=1
For Each fsoFile In fsoFolder.Files
ActiveSheet.Cells(lngRow,1)=fsoFile.Name
lngRow=lngRow+1
Next fsoFile
Set fsoFile=Nothing
Set fsoObj=Nothing
End Sub
注意,此时必须先保存该工作簿。
(2)Do-While/Do-Until循环
在进入循环之前指定条件,语法为:
Do [{While | Until } condition]
[statements]
[Exit Do]
[statements]
Loop
在执行循环后判断条件,语法为:
Do
[statements]
[Exit Do]
[statements]
Loop [{While | Until } condition]
这两类循环在希望进行循环直到满足某条件时是有用的,例如:
Sub DoUntilLoop()
Dim lngRow As Long
lngRow=1
Do Until IsEmpty(ActiveSheet.Cells(lngRow,1))
lngRow=lngRow+1
Loop
Msgbox ActiveSheet.Cells(lngRow,1).Address
End Sub
上面的循环将一直发生,直至到达活动工作表第一列中第一个空单元格,然后在消息框中显示该单元格的地址。
下面的示例应用于Access(如果Excel和Word访问记录集并遍历时,则也能应用于这两个应用程序):
Sub DoWhileLoop()
Do While (Not(rst.EOF))
rst.MoveNext
Loop
End Sub
当没有到文件结尾时上述循环一直发生。
Do While循的一种变体如下:
While (Not(rst.EOF))
rst.MoveNext
Wend
(3)With … End With语句
当需要对单个的对象或用户自定义类型执行一系列语句时,该语句相当有用。语法为:
With object
[statements]
End With
其中,object表示对象名称或用户自定义类型。当对相同的对象或属性执行一系列语句时,With语句的优势时不需要重复对象名称。
例如,重写上面的WorkingWithCell过程如下:
With ActiveCell
.ClearContents
.Value=Now()
.NumberFormat=”dd-mm-yyyy hh:mm:ss”
End With
使用With语句,不仅节省输入代码时间,并且结构化代码使之层次分明,因而使代码更容易阅读和理解,并且能使代码执行得更快。
(4)If…Then…Else…End If语句
根据满足的条件,执行相应的语句。语法为:
If condition Then [statements] [Else elsestatements]
或:
If condition Then
[statements]
[ElseIf condition-n Then
[elseifstatements]
[Else
[elsestatements]]
End If
例如,下面的代码比较字符串:
Function isLike(varValue As Variant,strLike As Variant) As Boolean
If varValue Like strLike Then
isLike=True
Else
isLike=False
End If
End Function
在过程中调用函数:
Sub compare()
MsgBox isLike(“robson”,”rob*”)
End Sub
(5)Select Case语句
使用该语句能够使多条件判断更简洁。语法为:
Select Case testexpression
[Case expressionlist-n
[statements-n]
[Case Else
[elsestatements]]
End Select
其中,expression-n有下列形式:expression,expression To expression,Is comparison operator expression。
注意:(1)表达式文本与Case后的值必须正确匹配,并且区分大小写。
(2)如果表达式文本与多个Case后的值匹配,则只执行第一个匹配的Case后的语句。
(3)当没有匹配值时,执行Case Else后的语句。
RibbonX:自定义Office 2007功能区
第三章 理解XML学习笔记
————————————-
核心的XML框架
每个定制都以customUI和Ribbon元素开始,取决于是否决定从头开始创建自已的UI、对内置的控件顺序作小的调整、或者创建两者的组合。
除了已经列出的元素外,也将研究tabs、tab和group元素,几乎在所有的定制中都将使用这些元素。
customUI元素
要创建格式良好的XML文档,实质上包含一个且唯一一个“最外层的元素”,嵌套所有其他的元素。最外层的元素被称为“根元素”。在功能区定制中,该元素是customUI元素。
打开CustomUI Editor,输入下面的代码:
<customUI xmlns=”http://schemas.microsoft.com/office/2006/01/customui“>
<!– All other instructions go here –>
</customUI>
然后,单击“validate”验证代码。注意,验证代码是一个好习惯。
1、customUI元素必需的属性
每个customUI标签必须指定xmlns属性,如下表所示。
表:customUI元素必需的属性
静态属性 允许值
Xmlns http://schemas.microsoft.com/office/2006/01/customui
2、带有回调签名的可选的静态和动态属性
这些属性不一定在XML中使用。
表:为customUI元素可选的属性
静态属性 动态属性 允许值 默认值 对动态属性的VBA回调签名
xmlns:Q (none) 1至1024个字符 (none) (none)
(none) onLoad 1至1024个字符 (none) Sub onLoad(Ribbon as IRibbonUI)
(none) loadImage 1至1024个字符 (none) Sub loadImage(imageID as string,ByRef returnedVal)
添加onLoad属性的代码如下:
<customUI
xmlns=”http://schemas.microsoft.com/office/2006/01/customui“
onLoad=”rxiRibbonUI_onLoad”>
<!– All other instructions go here –>
</customUI>
注意,onLoad属性只是嵌套在与customUI元素相同的<>括号内,对其他可选属性也是如此。
3、customUI元素的子对象
customUI标签是一个容器,能包含其他对象:
commands
ribbon
ribbon元素
要修改功能区,则要在customUI标签内嵌套ribbon元素,如下所示:
<customUI xmlns=”http://schemas.microsoft.com/office/2006/01/customui“>
<ribbon>
<!– All other instructions go here –>
</ribbon>
</customUI>
1、ribbon元素必需的属性
ribbon元素没有任何必需的属性。
2、可选的静态属性
ribbon元素有一个非常特别的属性,如下表所示。
表:ribbon元素的可选属性
静态属性 动态属性 允许值 默认值 对动态属性的VBA回调签名
startFromScratch (none) true,false,1,0 false (none)
startFromScratch属性能够隐藏整个内置的功能区。
因为该属性默认值为false,所以前面的示例代码中都忽略了该属性。下面的XML取得相同的结果:
<customUI xmlns=”http://schemas.microsoft.com/office/2006/01/customui“>
<ribbon startFromScratch=”false”>
<!– All other instructions go here –>
</ribbon>
</customUI>
3、ribbon元素允许的子对象
ribbon对象可能仅包含下列元素之一:
contextualTabs
officeMenu
qat
tabs
tabs元素
这是另一个容器,必须嵌套在功能区块中,代码如下:
<customUI xmlns=”http://schemas.microsoft.com/office/2006/01/customui“>
<ribbon>
<tabs>
<!– All other instructions go here –>
</tabs>
</ribbon>
</customUI>
tabs标签的目的是集中要引用、创建或修改的每个元素和单个的选项卡。
1、tabs元素必需的属性
tabs元素是要使用的最容易的元素之一,没有单个的属性。
2、tabs元素允许的子对象
tabs元素是一个容器元素,用于包含特定引用的(或创建的)选项卡控件。
tab元素
tab元素在tabs容器中,用于创建或引用功能区中单个选项卡。
理解tabs对象和tab对象之间的不同是非常重要的。tabs引用整个选项卡集合,而tab指定特定的选项卡。
1、tab元素必需的属性
tab对象是需要id属性的层级中的第一个元素。必须从下表中选择其中一个:
表:tab元素的id属性
属性 何时使用
id 当创建自已的选项卡时
idMso 当使用现有的Microsoft选项卡时
idQ 当创建在命名空间之间共享的选项卡时
为什么需要id属性的原因很简单:如果选项卡没有id属性,那么如何引用该选项卡呢?
2、带有回调签名的可选的静态和动态的属性
tab元素提供了几个可选的静态属性。如果要设置选项卡相对于其他任何现有的选项卡的位置,则使用下表列出的insert属性之一:
表:对tab控件可选的insert属性
insert属性 允许值 默认值 何时使用
insertAfterMso 有效的Mso选项卡 在最近的选项卡之后插入 在Microsoft选项卡之后插入
insertBeforeMso 有效的Mso选项卡 在最近的选项卡之后插入 在Microsoft选项卡之前插入
insertAfterQ 有效的选项卡idQ 在最近的选项卡之后插入 在共享的命名空间选项卡之后插入
insertBeforeQ 有效的选项卡idQ 在最近的选项卡之后插入 在共享的命名空间选项卡之前插入
注意,如果没有指定insert属性,那么选项卡将被添加到最后一个选项卡之后,而不管是自定义选项卡还是内置选项卡。
tab控件也接受下表显示的任何或所有的属性:
表:tab控件的可选属性和回调
静态属性 动态属性 允许值 默认值 对动态属性的VBA回调签名
keytip getKeytip 1至3个字符 (none) Sub GetKeytip(control As IRibbonControl,ByRef returnedVal)
label getLabel 1至1024个字符 (none) Sub GetLabel(control As IRibbonControl,ByRef returnedVal)
tag (none) 1至1024个字符 (none) n/a
visible getVisible true,false,1,0 true Sub GetVisible(control As IRibbonControl,ByRef returnedVal)
注意,动态回调用于在使用文件时动态修改功能区,使用了VBA代码来运行。
3、tab元素允许的子对象
tab对象可包含同组元素,例如内置的剪贴板组或者自已制作的自定义组。
内置的选项卡
当在功能区中处理选项卡时,有两种类型的选项卡:内置的和自定义的。
1、引用内置选项卡
每个内置选项卡有自已唯一的idMso属性,通过调用该属性引用这个选项卡,因此应确定idMso属性。
下表显示了Excel、Access和Word的一些最通用选项卡名称,注意大小写。
表:最常用的内置选项卡名称
选项卡名称 idMso(Excel) idMso(Word) idMso(Access)
开始 TabHome TabHome TabHomeAccess
插入 TabInsert TabInsert (none)
页面布局 TabPageLayoutExcel TabPageLayoutWord (none)
公式 TabFormulas (none) (none)
数据 TabData (none) (none)
视图 TabReview TabReviewWord (none)
创建 (none) (none) TabCreate
外部数据 (none) (none) TabExternalData
数据库工具 (none) (none) TabDatabaseTools
2、修改内置选项卡
(1)打开Excel 2007创建一个新的工作簿,由于不需要任何动态回调,因此将该文件保存为Excel的默认工作簿格式(xlsx)。
(2)关闭Excel,然后在CustomUI Editor中打开该工作簿。
(3)输入下面的XML代码:
<customUI xmlns=”http://schemas.microsoft.com/office/2006/01/customui“>
<ribbon startFromScratch=”false”>
<tabs>
<tab idMso=”TabHome” visible=”false”>
</tab>
</tabs>
</ribbon>
</customUI>
(4)验证代码并保存,关闭CustomUI Editor。
(5)在Excel中打开该工作簿文件,此时“开始”选项卡没有了。
此时,关闭该工作簿文件,将使“开始”选项卡重新出现。
自定义选项卡
1、创建自定义选项卡
创建自定义选项卡时,不需要引用idMso,而是为新选项卡指定一个唯一的id属性。
继续上面的练习,在Excel中关闭工作簿文件,在customUI Editor中重新打开该文件,输入下面的代码:
<customUI xmlns=”http://schemas.microsoft.com/office/2006/01/customui“>
<ribbon startFromScratch=”false”>
<tabs>
<tab id=”rxtabDemo” label=”Demo”>
</tab>
</tabs>
</ribbon>
</customUI>
验证代码并关闭该文件,然后在Excel中重新打开该工作簿,此时在功能区中将增加一个新的自定义选项卡,如下图所示。

2、放置自定义选项卡
例如下面的代码,将自定义选项卡放置在“开始”选项卡之后。
<customUI xmlns=”http://schemas.microsoft.com/office/2006/01/customui“>
<ribbon startFromScratch=”false”>
<tabs>
<tab id=”rxtabDemo”
label=”Demo”
insertAfterMso=”TabHome”>
</tab>
</tabs>
</ribbon>
</customUI>
如下图所示:
注意,当插入多个控件时,将按照在XML代码中编写的顺序插入。
group元素
group元素的作用是为实际的按钮、复选框、菜单和其他允许在功能区中配置的命令创建占位符。
1、group元素必需的属性
与tab元素一样,每个组需要一个唯一的id属性,如下表所示。
表:group元素的id属性
属性 何时使用
id 当创建自已的组时
idMso 当使用现有的Microsoft组时
idQ 当在共享的命名空间之间创建组时
2、带有回调签名的可选的静态的和动态的属性
要设置某个组相对于任何其他现有的组的位置,需要指定下表列出的insert属性之一。
表:group控件可选的insert属性
insert属性 允许值 默认值 何时使用
insertAfterMso 有效的Mso组 最近的组之后插入 Microsoft组之后插入
insertBeforeMso 有效的Mso组 最近的组之后插入 Microsoft组之前插入
insertAfterQ 有效的组idQ 最近的组之后插入 共享的命名空间组之后插入
insertBeforeQ 有效的组idQ 最近的组之后插入 共享的命名空间组之前插入
group控件也接受下表所列出的任何或所有的属性。
表:group控件可选的属性和回调
静态属性 动态属性 允许值 默认值 对动态属性的VBA回调签名
image getImage 1至1024个字符 (none) Sub GetImage(control As IRibbonControl,ByRef returnedVal)
imageMso getImage 1至1024个字符 (none)同上
keytip getKeytip 1至3个字符 (none) Sub GetKeytip(control As IRibbonControl,ByRef returnedVal)
label getLabel 1至1024个字符 (none)Sub GetLabel(control As IRibbonControl,ByRef returnedVal)
screentip getScreentip 1至1024个字符 (none) Sub GetScreentip(control As IRibbonControl,ByRef returnedVal)
supertip getSupertip 1至1024个字符 (none) Sub GetSupertip(control As IRibbonControl,ByRef returnedVal)
tag (none) 1至1024个字符 (none) (none)
visible getVisible true,false,1,0 true Sub GetVisible(control As IRibbonControl,ByRef returnedVal)
3、group元素允许的子对象
group元素能够包含下列对象的任意组合:
box
button
buttonGroup
checkBox
comboBox
control
dialogBoxLauncher
dropdown
editBox
gallery
labelControl
menu
separator
splitButton
toggleButton
下面是创建一个自定义组的XML代码:
<customUI xmlns=”http://schemas.microsoft.com/office/2006/01/customui“>
<ribbon startFromScratch=”false”>
<tabs>
<tab id=”rxtabDemo”
label=”Demo”
insertAfterMso=”TabHome”>
<group id=”rxgrpDemo”
label=”Demo Group”
keytip=”D”
screentip=”This is my screentip”
supertip=”This is my supertip”>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
结果如下图所示:

注意,在上面的XML中,仅label属性的值出现在功能区中。大多数可选的属性例如imageMso,在组控件中将没有可见的效果。因此,经调试后,可以忽略一些可选的属性。
内置组
使用内置组,仍然能够提供内置功能。也提供了将经常使用的控件组合在一起的功能。
1、引用内置组
与选项卡相似,通过引用其id属性识别自定义组,通过引用其idMso属性识别内置组。
下表列出了Excel、Access和Word中的一些内置组。
表:在Excel、Access和Word中通用的组
显示的名称 idMso名称
剪贴板 GroupClipboard
字体 GroupFont
形状 GroupShapes
例如,隐藏Word中的剪贴板组的XML如下:
<customUI xmlns=”http://schemas.microsoft.com/office/2006/01/customui“>
<ribbon startFromScratch=”false”>
<tabs>
<tab idMso=”TabHome”>
<group idMso=”GroupClipboard”
visible=”false”>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
结果如下图:
2、在自定义选项卡中使用内置组
能够在自已的选项卡中使用内置组,这是Office 2007的一项关键功能。
Microsoft虽然花费了大量的人力和财力研究用户的使用习惯,但默认的控件顺序不会总是满足特定的需求。因此,使用重复使用Microsoft内置组的能力,可以很容易地在单个选项卡中放置最常用的命令,这样更方便于使用且随时可见,避免在功能区选项卡之间来回切换。
在许多场合,创建一个自定义且经过整理的选项卡能够节省无数次的键击并极大地提高生产力。
例如,下表列出了在Excel中一些经常需要的组。
表:在Excel中常用的审核工具的位置
组名 默认的选项卡 名称
剪贴板 开始 GroupClipboard
字体 开始 GroupFont
公式审核 公式 GroupFormulaAuditing
批注 审阅 GroupComments
编辑 开始 GroupEditingExcel
现在,创建一个包含上述组的自定义选项卡,其XML代码如下:
<customUI xmlns=”http://schemas.microsoft.com/office/2006/01/customui“>
<ribbon startFromScratch=”false”>
<tabs>
<tab id=”rxtabMyTools”
label=”My Tools”
insertBeforeMso=”TabHome”>
<group idMso=”GroupClipboard”/>
<group idMso=”GroupFont”/>
<group idMso=”GroupFormulaAuditing”/>
<group idMso=”GroupComments”/>
<group idMso=”GroupEditingExcel”/>
</tab>
</tabs>
</ribbon>
</customUI>
注意,在上面的代码中,group元素没有使用单独的结束标签,而是在行尾使用/>结束。这样的编写非常简洁。此时,结果如下图所示。
注意,在自定义组中引用的内置组只是原来组的副本,内置组仍然在原来的位置。
自定义组
1、创建自定义组
与tab元素一样,通过指定一个唯一的id属性来创建自定义组。而不是引用内置组的idMso。
继续上面的示例,关闭Excel文件,在CustomUI Editor中重新打开该文件,在最后的一个group标签之后,添加下面的XML代码:
<group id=”rxgrpMyGroup”
label=”My Group”>
</group>
注意,上述代码并没有在同一行中开始和结束代码。这样,方便在其中添加其他控件,例如按钮、复选框或动态菜单。
验证代码后保存文件并关闭CustomUI Editor。再打开Excel,此时,添加了一个空组,如下图所示。
2、放置自定义组
有时,可能想让自定义的组放置在指定的位置或按指定的顺序排列。
(1)在XML代码中,按想要显示的顺序编写代码。
(2)使用insertBeforeMso属性或insertAfterMso属性。
3、在内置选项卡中的自定义组
以Word 2007为例。
(1)创建一个新的Word文档并保存,然后关闭该文档。
(2)在CustomUI Editor中打开该文档,并输入下面的代码:
<customUI xmlns=”http://schemas.microsoft.com/office/2006/01/customui“>
<ribbon startFromScratch=”false”>
<tabs>
<tab idMso=”TabHome”>
<group id=”rxgrpMyGroup”
label=”My Group”
insertBeforeMso=”GroupFont”>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
(3)验证代码并保存代码,然后关闭CustomUI Editor。
(4)在Word中重新打开该文件,现在看到在“开始”选项卡中有一个自定义组,如下图所示。
此时,在内置的“开始”选项卡中添加了自定义组“My Group”,并且将该组放置在第二位,即“字体”组之前。然后,您可以在自定义组中添加想要的控件了!
RibbonX:自定义Office 2007功能区
第三章 理解XML学习笔记
————————————————————
这里的学习内容包括如何创建访问和操纵内置功能区所需的核心XML框架。
什么是XML,为什么需要XML
XML是Extensible Markup Language的缩写,最初由W3C发布。XML不是编程语言,它缺乏执行操作的任何机制。XML是一组规则,其意图是简化跨平台的数据共享。
Office 2007文件以Microsoft的OpenXML格式配置,是包含几个XML文件的一个简单的压缩容器。
(1)XML节省空间。
(2)结构化数据后,能够快速地被索引,因而能使其他程序为特定的字符串或其他项目搜索索引。
(3)对于开发者来说,能够链接某个应用程序里的XML架构来验证XML而确保像意料中的那样工作。例如前一章中介绍的CustomUI Editor和XML Notepad,如果没有这些架构,CustomUI Editor将不能验证代码,XML Notepad不能提供智能感知功能。
现在我们关心XML,是因为XML是Ribbon的核心。要定制Office 2007用户界面,必须编写XML代码,虽然VBA在定制中也能起到关键的作用,但它不是必需的。而XML在定制中几乎总是必需的,但也有例外。例如弹出式菜单和一些出现在加载项选项卡中的VBA定制。
本章下面的内容将集中介绍如何从头开始创建XML框架,引导您通过必需的XML创建和修改功能区。
基本的背景知识
即,XML的构成及如何编写XML。
1、标签(Tags)
例如,下面的代码片断:
<group id=”rxgrpTest”>
<button idMso=”Bold”/>
<button idMso=”Italic”/>
<splitButton id=”rxsbtnTest”>
<button idMso=”Underline”/>
</splitButton>
</group>
看看上面代码的结构,注意<、>和/号的使用,指示了标签的开始和结束。例如开始的标签和结束的标签之间的内容包含了在功能区中显示的组。
此外,注意到按钮的代码,其中/号位于标签的结尾,不需要单独的标签来关闭元素。
其实,上面演示了使用标签的两种方法。您需要理解并使用这些方法来创建自定义UI的结构。如下面的表格所示:
表:开始和关闭标签的形式
开始和关闭标签分开 <element attribute(s)=”Value”></element>
开始和关闭标签未分开 <element attribute(s)=”Value”/>
(1)在XML中,每个标签至少包含一个元素和通常至少一个属性
(2)在处理代码时,涉及的每个项目都被称作对象(object)。例如,对象包括功能区中的组、按钮、复选框、甚至是菜单。当某控件有子控件时,将该控件称为父控件。
注意,父对象通常(但不总是)有不同类型的子对象。选项卡有一个或多个组对象作为子对象,并且一个组可能有按钮、复选框和动态菜单子对象的组合。其中,dynamicMenu对象除了其他子对象类型外,还有dynamicMenu子对象。某些父对象甚至有完整的子对象群,称之为集合(collection)。
每个子对象也能够成为它自已的子对象的父对象。每个子对象控件必须嵌套在其父对象的开始和结束标签中。
(3)为了创建格式良好(有效的)XML,必须理解:
所有标签,无论是元素还是必属,都区分大小写,即SPLITBUTTON元素与splitButton元素不相同。
属性值必须被放置在单引号或双引号内。
在父元素中的子元素的嵌套必须准确。每个开始标签必须与其结束标签相匹配。
2、元素(Elements)
当处理功能区的XML时,可以看到每个元素指定功能区控件(或结构)的特定部分。
group是一个元素,而<group>是一个标签。因此,标签实质上是通过<和>符号识别代码块的标志。
每个标签必须包括一个且唯一一个元素。此外,元素总是XML标签的第一部分。告诉编译器希望开始处理或停止处理的特定项目。
3、属性(Attributes)
标签告诉编译器要处理的对象,而属性告诉编译器该对象的属性,包括对象的名称、在屏幕中显示的标题以及是否对象可见。
与元素不同的是,在所给标签内可以为对象设置多个属性。例如,下面的代码片断显示了带有多个属性的标签示例:
<button id=”rxbtnProtectAll”
size=”normal”
label=”Protect All Sheets”
imageMso=”ReviewProtectWorkbook”
onAction=”rxbtnProtectAll_click”/>
上面的代码提供给按钮一个唯一的id并指定了大小、标签和图像,此外也提供了一个onAction回调签名,当单击该按钮时启动相应的VBA过程。
(1)id属性
在创建额外的对象之前,需要讨论如何在代码中识别这些对象。而id属性用于识别在自定义XML代码内指定的对象,为其提供名称,使得后面能够使用该名称引用该对象。这是引用对象的唯一方法。在下列容器中每个对象都需要id属性:
contextualTabs
officeMenu
qat
tabs
id属性有几种不同的类型并且每一个都有不同的使用。下表描述了id属性的不同类型及其主要用途。
表:id属性表
属性 何时使用
id 用于唯一地标识控件。如果动态地装载项目,其属性将被赋值
idMso 用于唯一地标识内置控件、选项卡、命令,等等。使用该属性与内置对象交互
idQ 用于跨共享的命名空间引用对象。
为了识别某对象,简单地在开始标签中添加id属性,例如:
<tab id=”rxtab”
<!– Other tab attributes would go here! –>
</tab>
同样地,如果试图引用内置的字体(Font)组,使用下面的XML:
<group idMso=”Font”
<!– Other group attributes would go here! –>
</group>
注意,所有的id和idQ属性都是唯一的。如果使用已存在的id,或者由Microsoft保留的id,将会导致错误并阻止UI装载。
为了避免与内置的控件相冲突,建议所有自定义控件使用标准的命名约定加上前缀。
(2)label属性
即用户能够在屏幕上读取的内容,不必是唯一的,但应该是合乎逻辑、简洁明了且一致。Label属性为用户提供清晰的向导。要添加标签,如下面的代码:
<tab id=”rxtab”
label=”My Custom Tab”>
</tab>
4、布置XML代码的技巧
使用硬回车或制表符将代码分成逻辑块,容易阅读和解释。下面是一段示例代码,更容易阅读:
<group
id=”rxgrp”
label=”My First Group”>
<button
id=”rxbtn1″
imageMso=”Italic”
label=”Large size button”
size=”large”
onAction=”rxbtn1_Click”/>
<button
id=”rxbtn2″
imageMso=”Bold”
label=”Normal size button”
size=”normal”
onAction=”rxbtn2_Click”/>
<button
id=”rxbtn3″
imageMso=”WrapText”
label=”Normal size button”
size=”normal”
onAction=”rxbtn3_Click”/>
<button
id=”rxbtn4″
imageMso=”ConditionalFormatting”
label=”Normal size button”
size=”normal”
onAction=”rxbtn4_Click”/>
</group>
5、在XML代码中创建注释
注释能够使自已或他人清楚代码的作用。放置注释的方法是:在开始处放置一个小于号(<),然后输入感叹号(!),随后是两个连字号(–),结束注释需要两个连字号加一个大于号(>)。
<!– This is a comment –>
如果注释很长,可能需要几行,如下所示:
<!–
This is a comment that has become extremely long.Since you decided that
you do not want to have short,one line comments to describe what you
are doing, you let it run over several lines.
–>
在<!–和–>之间的被当作连续的注释。
此外,不能够将注释放置在一块开始的XML代码的中间。下面的示例来进行演示:
<!– This is my first button –>
<button id=”rxbtn”
label=”This is my button”
imageMso=”HappyFace”
size=”large”
onAction=”rxbtn_Click”/>
或:
<button id=”rxbtn”
label=”This is my button”
imageMso=”HappyFace”
size=”large”
onAction=”rxbtn_Click”>
<!– This is my first button –>
</button>
上述两段代码都是正确的,但下面的代码会产生错误:
<button id=”rxbtn”
<!– This is my first button –>
label=”This is my button”
imageMso=”HappyFace”
size=”large”
onAction=”rxbtn_Click”/>
上面的问题在于注释被插入到了未关闭的代码块中。