RequisitePro能够很容易地被扩展以协助支持你的项目过程。本文将展示如何使用脚本快速地开始工作,这个脚本用来自定义需求管理工具。 
              
              RequisitePro能够很容易地被扩展以协助支持你的项目过程。本文将展示如何使用脚本快速地开始工作,脚本用来自定义需求管理工具。这些脚本可以用来收集度量、自动化日常的活动,或者同其它应用程序交换信息,等等。
              可扩展架构概述
                有两个部件用来扩展 RequisitePro。第一个是 RequisitePro Extensibility 
                server,RPX。RPX用来访问工程、包、需求和用户等。
              第二个是RqGUIApp 
                library。它用来控制RequisitePro用户界面,它也可以提供对Microsoft Word文档的一些控制功能。
              
                
                   
                    |  | 
                   
                    | 图 
                      1: 可扩展性架构 | 
                
              
               
              RPX
                RPX是RequisitePro的可扩展性接口。它的核心组件为 ReqPro.dll,这个dll可以通过COM接口访问。RPX包含用来读取或者修改已存在的RequisitePro工程的类。
              要想看关于RPX对象模型,包括类图等的信息,参见RequisitePro 
                Extensibility Interface Help,它已经随着RequisitePro安装。
              下面是一些可以通过RPX访问的内容的例子:
              
                - 需求模型的语义,如应用、工程、包、需求、文档、关系、讨论、属性值等。 
                
- 管理项,如用户和用户组。 
                
- 视图 
                
- Meta-data,如属性类型,需求类型、文档类型。这些项不能通过RPX访问 
                
- 文档内容(看RqGUIApp节有关如何处理文档的内容) 
                
- 工程创建
 
              开始
                一旦你安装了RequisitePro,你就可以开始使用RPX写代码。所有提供的例子都使用Microsoft Visual Basic 
                6语法。如果你使用Visual Basic,你需要添加RPX (RequisitePro Extensibility Interface)到你的工程引用中。
              你也需要一个RequisitePro工程以便用它工作。你可以创建一个新的工程进行试验,也可以使用samples文件夹中提供的工程。
              如果你通过RPX修改了对象,确保在关闭工程前使用了你调用的对象的Save方法。这将永久把你的改变保存到数据库中。
              使用RPX打开工程
                打开工程需要两步。第一步是创建一个新的Application对象的实例。第二步是调用Application.OpenProject。OpenProject方法用来打开它的文件路径中的工程:
              
                
                   
                    | 
                        
                           
                            | 'open a project 
Private Sub OpenProject() 
Dim a_oReqPro As ReqPro40.Application 
Dim a_oProject As ReqPro40.Project 
Dim a_sProjectName As String 
'start the server 
Set a_oReqPro = New ReqPro40.Application 
If Not a_oReqPro Is Nothing Then 
'open a learning project by filename 
a_sProjectName = a_oReqPro.ServerInformation.Path & _ 
"\..\samples\Learning_Project-Traditional\LEARNING - TRADITIONAL.rqs" 
'a user id is required 
Set a_oProject = a_oReqPro.OpenProject( _ 
a_sProjectName, _ 
eOpenProjOpt_RQSFile, _ 
"AnyUserID", _ 
"") 
'close the project 
a_oReqPro.CloseProject a_oProject, eProjLookup_Object 
End If 
Set a_oProject = Nothing 
Set a_oReqPro = Nothing 
End Sub
 |  | 
                   
                    | 清单 
                      1:通过文件名打开工程 | 
                
              
              每个用户都有一个最近打开工程的列表。工程也可以从这个列表中打开:
              
                
                   
                    | 
                        
                           
                            | 'open a project from the catalog 
Private Sub OpenProjectFromCatalog() 
Dim a_oReqPro As ReqPro40.Application 
Dim a_oProject As ReqPro40.Project 
Dim a_oCatalog As ReqPro40.Catalog 
Dim a_oCatalogItem As ReqPro40.CatalogItem 
Dim a_sProjectName As String 
'start the server 
Set a_oReqPro = New ReqPro40.Application 
If Not a_oReqPro Is Nothing Then 
Set a_oCatalog = a_oReqPro.PersonalCatalog 
If Not a_oCatalog Is Nothing Then 
'look up the first project in the catalog 
Set a_oCatalogItem = a_oCatalog.Item(1, eCatLookup_Index) 
'a user id is required 
Set a_oProject = a_oReqPro.OpenProject( _ 
a_oCatalogItem, _ 
eOpenProjOpt_Object, _ 
"AnyUserID", _ 
"") 
'close the project 
a_oReqPro.CloseProject a_oProject, eProjLookup_Object 
End If 
End If 
Set a_oCatalog = Nothing 
Set a_oCatalogItem = Nothing 
Set a_oReqPro = Nothing 
End Sub
 |  | 
                   
                    | 清单 
                      2: 从最近工程列表中打开工程 | 
                
              
              注意:一旦一个工程被打开,在访问它的数据时它就必须保持打开状态。当你的脚本完成后,可以保存和关闭工程。
              在工程中访问需求
                一旦打开了工程,其中的需求就可以被访问。如果你想要产生一份报告或者把信息导出到其它应用中时,这一点非常有用。下面的清单展示了如何从一个已经打开的工程中找到需求:
              
                
                   
                    | 
                        
                           
                            | 'print all requirements 
Sub PrintAllRequirements(oProject As ReqPro40.Project) 
Dim a_oReqs As ReqPro40.Requirements 
Dim a_oReq As ReqPro40.Requirement 
'retrieve all requirements 
Set a_oReqs = oProject.GetRequirements("", eReqsLookup_All) 
'iterate through requirements 
While Not a_oReqs.IsEOF 
Set a_oReq = a_oReqs.ItemCurrent 
'print out tag and text to the debug window 
Debug.Print a_oReq.Tag & " " & a_oReq.Text 
a_oReqs.MoveNext 
Wend 
Set a_oReq = Nothing 
Set a_oReqs = Nothing 
End Sub
 |  | 
                   
                    | 清单 
                      3: 打印需求信息 | 
                
              
              下面的例子演示了一种导出信息到另一个应用程序方法:
              
                
                   
                    | 
                        
                           
                            | 'print requirements to Microsoft Excel 
Sub PrintAllRequirementsToExcel(oProject As ReqPro40.Project) 
Dim a_oReqs As ReqPro40.Requirements 
Dim a_oReq As ReqPro40.Requirement 
Dim a_oExcelApp As Object 
Dim a_oWorkbook As Object ' Excel.Workbook 
Dim a_oSheet As Object ' Excel.Worksheet 
Dim a_lRow As Long 
Set a_oExcelApp = CreateObject("Excel.Application") 
Set a_oWorkbook = a_oExcelApp.Workbooks.Add 
a_oExcelApp.Visible = True 
Set a_oSheet = a_oWorkbook.ActiveSheet 
a_oSheet.Name = "ReqPro" 
a_oSheet.Cells(1, 1).Value = "Tag" 
a_oSheet.Cells(1, 2).Value = "Requirement" 
a_lRow = 2 
'retrieve all requirements 
Set a_oReqs = oProject.GetRequirements("", eReqsLookup_All) 
'iterate through requirements 
While Not a_oReqs.IsEOF 
Set a_oReq = a_oReqs.ItemCurrent 
a_oSheet.Cells(a_lRow, 1).Value = a_oReq.Tag 
a_oSheet.Cells(a_lRow, 2).Value = a_oReq.Text 
a_lRow = a_lRow + 1 
a_oReqs.MoveNext 
Wend 
Set a_oReq = Nothing 
Set a_oReqs = Nothing 
End Sub
 |  | 
                   
                    | 清单 
                      4: 导出需求到Microsoft Excel | 
                
              
              需求也可以通过RPX创建。下面是一个如何自动化一个日常活动的例子。它在完成从其它来源导入需求信息的工作时非常有用。
              下面的例子演示如何创建一个新的需求。需求类型必须首先定义。
              
                
                   
                    | 
                        
                           
                            | 'create a requirement 
Private Sub CreateRequirement(oProject As ReqPro40.Project) 
Dim a_oReqs As ReqPro40.Requirements 
Dim a_oReq As ReqPro40.Requirement 
'get all requirements of type "PR" 
Set a_oReqs = oProject.GetRequirements("PR", eReqsLookup_TagPrefix) 
'add a requirement to the collection of PR requirements 
Set a_oReq = a_oReqs.Add( _ 
"requirement_name", _ 
"This is a root PR requirement.", _ 
"PR", eReqTypesLookups_Prefix) 
'commit this to the database by doing a save on the requirement 
a_oReq.Save 
Set a_oReq = Nothing 
Set a_oReqs = Nothing 
End Sub
 |  | 
                   
                    | 清单 
                      5: 通过RPX创建新的需求 | 
                
              
              RPX也能够用来维护需求之间的可跟踪性。你可以访问关系的集合,也可以创建新的关系。下面的例子演示如何创建一个新的跟踪关系。
              
                
                   
                    | 
                        
                           
                            | 'create a trace-to relationship 
Private Sub CreateTraceRelationship(oProject As ReqPro40.Project) 
Dim a_oReqs As ReqPro40.Requirements 
Dim a_oReq1 As ReqPro40.Requirement 
Dim a_oReq2 As ReqPro40.Requirement 
Dim a_oRel As ReqPro40.Relationship 
'get all requirements 
Set a_oReqs = oProject.GetRequirements("", eReqsLookup_All) 
'lookup the requirements that you would like 
'to be a part of the relationship 
Set a_oReq1 = a_oReqs.Item("PR1", eReqLookup_Tag) 
Set a_oReq2 = a_oReqs.Item("SR1.6", eReqLookup_Tag) 
If Not a_oReq1 Is Nothing Then 
Set a_oRel = a_oReq1.TracesTo.Add(a_oReq2, eReqLookup_Object) 
End If 
'commit this to the database by doing a save on the requirement 
a_oReq1.Save 
Set a_oReq1 = Nothing 
Set a_oReq2 = Nothing 
Set a_oRel = Nothing 
Set a_oReqs = Nothing 
End Sub
 |  | 
                   
                    | 清单 
                      6: 创建跟踪关系 | 
                
              
              RequisitePro也可以被扩展以访问需求的属性信息。可以创建新的属性,也可以更新属性值。一个属性的值甚至可以从其它属性的值计算出来。
              
                
                   
                    | 
                        
                           
                            | 'modify requirement attribute values 
Private Sub ModifyAttributeValue(oProject As ReqPro40.Project) 
Dim a_oReqs As ReqPro40.Requirements 
Dim a_oReq As ReqPro40.Requirement 
Dim a_oAttrValues As ReqPro40.AttrValues 
Dim a_oAttrValue As ReqPro40.AttrValue 
'get all requirements 
Set a_oReqs = oProject.GetRequirements("", eReqsLookup_All) 
Set a_oReq = a_oReqs.Item("PR1", eReqLookup_Tag) 
If Not a_oReq Is Nothing Then 
Set a_oAttrValues = a_oReq.AttrValues 
If Not a_oAttrValues Is Nothing Then 
'cycle through each AttrValue object and modify the value 
'based on the attribute's specific data type. 
For Each a_oAttrValue In a_oAttrValues 
Select Case a_oAttrValue.DataType 
Case ReqPro40.eAttrDataTypes_Text 
a_oAttrValue.Text = "RequisitePro Example" 
Case ReqPro40.eAttrDataTypes_List 
'Rather than using the Value property of a List 
'Attr, we need to use the ListItemValues 
'property, which returns a collection of 
'ListItemValue objects. 
'Once we have a ListItemValue object reference, 
'we can then query its Text property, 
'and set its Selected property. 
Dim a_oListItemValues As ListItemValues 
Dim a_oListItem As ListItemValue 
Set a_oListItemValues = a_oAttrValue.ListItemValues 
For Each a_oListItem In a_oListItemValues 
If a_oListItem.Text = "Low" Then 
a_oListItem.Selected = True 
End If 
Next a_oListItem 
End Select 
Next a_oAttrValue 
End If 'Not a_oAttrValues Is Nothing 
End If 'Not a_oReq Is Nothing 
' Commit this to the database by doing a save on the requirement 
a_oReq.Save 
Set a_oReq = Nothing 
Set a_oAttrValues = Nothing 
Set a_oAttrValue = Nothing 
Set a_oListItemValues = Nothing 
Set a_oListItem = Nothing 
Set a_oReqs = Nothing 
End Sub
 |  | 
                   
                    | 清单 
                      7: 更新一个属性的值 | 
                
              
               
              使用包
                项目的包结构可以协助保持需求、文档和视图的组织化。当创建一个新的单元时,通常需要把它们从缺省位置--根包--移动到其它位置。下面的例子演示了如何创建一个新的包。
              
                
                   
                    | 
                        
                           
                            | 'create a package 
Sub CreatePackage(oProject As ReqPro40.Project) 
Dim a_oRootPackage As ReqPro40.RootPackage 
Dim a_oPackage As ReqPro40.Package 
'retrieve the root package 
Set a_oRootPackage = oProject.GetRootPackage 
'create a package at the root level (Don't need to call save. 
CreatePackage will persist the package) 
Set a_oPackage = a_oRootPackage.CreatePackage("Package Name1", _ 
"My Package") 
Set a_oRootPackage = Nothing 
Set a_oPackage = Nothing 
End Sub
 |  | 
                   
                    | 清单 
                      8: 创建一个新的包 | 
                
              
              下面的例子给出了一个例子,它在一个包中而不是在根包中创建一个新的需求。
              
                
                   
                    | 
                        
                           
                            | 'move a requirement 
Sub MoveRequirement(oProject As ReqPro40.Project) 
Dim a_oReqs As ReqPro40.Requirements 
Dim a_oReq As ReqPro40.Requirement 
Dim a_oRootPackage As ReqPro40.RootPackage 
Dim a_oPackage As ReqPro40.Package 
'get all requirements of type "PR" 
Set a_oReqs = oProject.GetRequirements("PR", _ 
eReqsLookup_TagPrefix) 
'add a requirement to the collection of PR requirements 
Set a_oReq = a_oReqs.Add( _ 
"requirement_name", _ 
"This is a root PR requirement.", _ 
"PR", eReqTypesLookups_Prefix) 
'commit this to the database by doing a save on the requirement 
a_oReq.Save 
'retrieve the root package 
Set a_oRootPackage = oProject.GetRootPackage 
'create a package at the root level 
'Don't need to call save, CreatePackage will persist the package 
Set a_oPackage = a_oRootPackage.CreatePackage("Package Name1", _ 
"My Package") 
a_oPackage.AddElement a_oReq, _ 
ePackageLookup_Object, _ 
eElemType_Requirement 
Set a_oReqs = Nothing 
Set a_oReq = Nothing 
Set a_oRootPackage = Nothing 
Set a_oPackage = Nothing 
End Sub
 |  | 
                   
                    | 清单 
                      9: 在包之间移动需求 | 
                
              
               
              访问文档
                尽管文档的内容不能通过RPX进行访问,仍然有一些信息对于进行报告是有用的。下面的例子显示如何在RPX中访问文档,打印这些文档中包含的需求的名字和标签。
              
                
                   
                    | 
                        
                           
                            | 'print all requirements in each document 
Sub PrintAllDocBasedRequirements(oProject As ReqPro40.Project) 
Dim a_oDocs As ReqPro40.Documents 
Dim a_oDoc As ReqPro40.Document 
Dim a_oReqs As ReqPro40.Requirements 
Dim a_oReq As ReqPro40.Requirement 
'retrieve all documents 
Set a_oDocs = oProject.Documents 
For Each a_oDoc In a_oDocs 
'print out document path and name 
Debug.Print a_oDoc.Name & ": " & a_oDoc.FullPath 
'retrieve all requirements in this document 
Set a_oReqs = a_oDoc.Requirements 
'iterate through requirements 
If Not a_oReqs Is Nothing Then 
While Not a_oReqs.IsEOF 
Set a_oReq = a_oReqs.ItemCurrent 
'print out tag and text to the debug window 
Debug.Print vbTab & a_oReq.Tag & " " & a_oReq.Text 
a_oReqs.MoveNext 
Wend 
End If 
Next a_oDoc 
Set a_oDocs = Nothing 
Set a_oDoc = Nothing 
Set a_oReq = Nothing 
Set a_oReqs = Nothing 
End Sub
 |  | 
                   
                    | 清单 
                      10: 打印文档中的需求 | 
                
              
               
              RqGuiApp
                RqGuiApp是 RequisitePro的 GUI应用程序接口。它的核心组件为RqGuiApp.tlb。这个库允许一些对RequisitePro应用的控制,也可以控制在Microsoft 
                Word打开的RequisitePro文档。
              这些接口在RequisitePro Extensibility Interface Help中详细描述,它随着RequisitePro一起安装。
              下面是一些可以通过RqGuiApp使用的操作:
              
                - 打开和关闭工程 
                
- 打开、关闭、创建、保存、定位选择文档 
                
- 创建和更新基于文档的需求 
                
- 打开视图和找到当前选择的需求 
                
- 刷新工程浏览器
 
              开始
                为了与RequisitePro配合使用RqGuiApp,RequisitePro必须运行。下面的例子显示如何找到RequisitePro的运行实例:
              
                
                   
                    | 
                        
                           
                            | Dim a_oRqGuiApp As Object 
'get the current running instance of RequisitePro from Windows 
On Error Resume Next 
Set a_oRqGuiApp = GetObject(, "ReqPro40.GUIApp") 
On Error GoTo 0 
' if not open 
If a_oRqGuiApp Is Nothing Then 
MsgBox "Please open RequisitePro" 
End If
 |  | 
                   
                    | 清单 
                      11: 使用RqGuiApp和RequisitePro一起工作 | 
                
              
              RqGuiApp也可以用来打开RequisitePro应用程序:
              
                
                   
                    | 
                        
                           
                            | Dim a_oRqGuiApp As Object 
'get the current running instance of RequisitePro from Windows 
Set a_oRqGuiApp = CreateObject("ReqPro40.GUIApp")
 |  | 
                   
                    | 清单 
                      12: 使用RqGuiApp打开RequisitePro | 
                
              
              回调对象
                很多在RqGuiApp中提供的方法需要使用回调对象。回调对象是一个类的实例,它拥有一些对外的预定义的方法。这些方法在RequisitePro 
                Extensibility Interface help中有详细的定义。需要把定义了这些方法的类编译成一个 .dll,然后把这个类的实例放到RqGuiApp中。在 
                RequisitePro 2003中,提供了一个用来封装回调对象的 .dll。
              当RqGuiApp操作完成时(例如,工程打开,文档已经创建等),回调对象将收到通知。
              使用工程工作
                为了打开一个工程,必须使用回调对象。可以从RqGuiApp库中使用回调对象获得工程对象的实例。
              
                
                   
                    | 
                        
                           
                            | ' If another project is open, RequisitePro closes the project 
'(and the appropriate dialog boxes) and opens the specified project. 
Function OpenProjectInGui(oRqGuiApp As Object, _ 
sPath As String, _ 
sUser As String, _ 
sPwd As String) As ReqPro40.Project 
Dim a_bRet As Boolean 
Dim a_oCallback As RqCallback.Callback 
'need to instantiate callback object 
Set a_oCallback = New Callback 
'tell the RequisitePro application to open a project 
a_bRet = oRqGuiApp.OpenProject(sPath, _ 
eOpenProjOpt_RQSFile, _ 
sUser, sPwd, _ 
eProjFlag_Normal, _ 
a_oCallback) 
If a_bRet Then 
'wait until the operation is complete 
While Not a_oCallback.IsDone 
DoEvents 
Wend 
'retrieve the project object 
Set OpenProjectInGui = a_oCallback.GetObject 
End If 
Set a_oCallback = Nothing 
End Function
 |  | 
                   
                    | 清单 
                      13: 使用RqGuiApp打开工程 | 
                
              
               
              使用文档工作
                RqGuiApp 允许控制RequisitePro文档。这些控制允许脚本请求RequisitePro创建、打开和关闭文档。另外,需求可以加到文档中,已经存在的基于需求的文档可以更新到文档中。
              
                
                   
                    | 
                        
                           
                            | ' Creates a RequisitePro document in the current project. 
' The new document is opened in Word, and becomes the active document. 
Public Sub CreateDocument(oRqGuiApp As Object, _ 
sName As String, _ 
sPath As String, _ 
sDocTypeGUID As String, _ 
sDescription As String) 
Dim a_bRet As Boolean 
Dim a_oCallback As RqCallback.Callback 
'need to instantiate callback object 
Set a_oCallback = New Callback 
'the path should be the project's path, including the 
'filename with the proper document type extension 
a_bRet = oRqGuiApp.CreateDocument(sName, _ 
sPath, _ 
sDocTypeGUID, _ 
sDescription, _ 
a_oCallback) 
If a_bRet Then 
'wait until the operation is complete 
While Not a_oCallback.IsDone 
DoEvents 
Wend 
End If 
Set a_oCallback = Nothing 
End Sub
 |  | 
                   
                    | 清单 
                      14: 创建新的文档 | 
                
              
               
              下面是更新文档中存在的需求的例子。
              
                
                   
                    | 
                        
                           
                            | 'Updates requirement text in a document. 
'The document must be saved for the change to take effect. 
Public Sub UpdateRequirementInDocument(oRqGuiApp As Object, _ 
oReq As ReqPro40.Requirement, _ 
sNewText As String) 
Dim a_bRet As Boolean 
Dim a_oCallback As RqCallback.Callback 
'need to instantiate callback object 
Set a_oCallback = New Callback 
a_bRet = oRqGuiApp.UpdateRequirementInDocument(oReq, _ 
sNewText, _ 
a_oCallback) 
If a_bRet Then 
'wait until the operation is complete 
While Not a_oCallback.IsDone 
DoEvents 
Wend 
End If 
Set a_oCallback = Nothing 
End Sub
 |  | 
                   
                    | 清单 
                      15: 创建新的基于文档的需求 | 
                
              
               
              相关读物
              
              
                - 要想得到更多的信息和例子,请参看随RequisitePro提供的RequisitePro Extensibility 
                  Interface Help。
参考资料 
              
                - 您可以参阅本文在 developerWorks 全球站点上的 英文原文。
 
                
                   
                    | 关于作者 Mark Goossen自1996年起就在软件行业工作。在加入Rational Software和IBM之前,他使用Rational产品在机器视觉和广播软件行业工作。
 |