要在数据环境设计器中创建一个简单的层次结构游标,请按照下列步骤执行: 创建一个新的“标准 EXE”工程。
在“工程”菜单上,单击“添加 Data Enviroment”向工程中添加一个设计器。如果设计器没有在“工程”菜单上列出,则单击“部件”。单击“设计器”选项卡。并单击“数据环境”把设计器添加到菜单上。 
注意 最初为项目加载的四种ActiveX设计器在“工程”菜单上列出。如果加载了超过四个设计器,后面的设计器可以从“工程”菜单的“更多 ActiveX 设计器”子菜单中获得。 在“数据链接属性”对话框上单击“Microsoft Jet 3.51 OLE DB Provider”,这是为访问 Jet 数据库选择正确的 OLE DB 供应商。
单击“下一步”按钮进入“连接”选项卡。
单击第一个文本框旁边的省略按钮(…)。
用“选择 Access 数据库”对话框浏览到 nwind.mdb 文件,它被安装在 Program Files\Microsoft Visual Studio\Vb98 目录下。
单击“确定”关闭对话框。
右键单击“Connection1”图标,单击“重命名”,把图标名改为“Northwind”。
右键单击“Northwind”图标,然后单击“添加命令”显示“Command1”对话框。在对话框中,如下所示设置属性: 属性 设置值 
Command Name  Customers 
Connection  Northwind 
DataBase Object  Table 
Object Name  Customers 
单击“确定”结束对话框。
右键单击“Customers”命令,并单击“添加子命令”显示“Command2”对话框。在对话框中,如下所示设置属性: 属性 设置值 
Command Name  Orders 
Connection  Northwind 
DataBase Object  Table 
Object Name  Orders 
单击“关联”选项卡。应该选中“与父命令对象相关联”复选框。“父”框应该包含“Customers”;“父字段”和“子字段/参数”框都应该包含“CustomerID”。 
在设计关系数据库时,对于链接字段,习惯上相关的表要使用相同的名字。在这种情况下,链接字段都被命名为 CustomerID。数据环境设计器自动地在对话框中匹配这样的对。单击“添加”。单击“确定”关闭对话框。 
单击“添加”按钮向 Command 对象添加关系。在关闭了对话框之后,数据环境设计器通过把两个命令显示为一个层次结构来反映关系。该层次结构将被用于创建数据报表。根据下面的设置值设置工程和设计器的属性,然后保存工程: 对象 属性 设置值 
Project Name PrjNwind 
DataEnvironment Name DeNwind 
Form Name FrmShowReport 
创建数据报表
一旦创建了数据环境设计器,就可以创建一个数据报表。因为并不是数据环境中所有的字段在一个数据报表中都有用,这一系列的主题创建一个受限制的报表,只显示几个字段。要创建一个新的数据报表,请按照下列步骤执行: 在“工程”菜单上,单击“添加 Data Report”,Visual Basic 将把它添加到您的工程中。如果设计器不在“工程”菜单上,单击“部件”。单击“设计器”选项卡,并单击“Data Report”把设计器添加到菜单上。 
注意 为工程加载的前四种 ActiveX 设计器在“工程”菜单上列出。如果加载了多于四个设计器,后面的设计器可以从“工程”菜单的“更多 ActiveX 设计器”子菜单中获得。根据下面的表设置 DataReport 对象的属性: 属性 设置值 
Name rptNwind 
Caption Northwind Data Report 在“属性”窗口上,单击“数据源”,然后单击“deNwind”。然后单击“DataMember”并单击“Customers”。 
重点 要把 DataSource 属性设置为 deNwind,数据环境设计器必须为打开的。如果数据环境设计器是关闭的,按下 CTRL+R 键显示“工程”窗口,然后双击数据环境图标。右键单击数据报表设计器,并单击“检索结构”。 
您已经向设计器添加了一个新的分组。每一个分组都同数据环境中的 Command 对象有“一对一”对应关系;在这种情况下,新的分组与客户的 Command 对象相对应。同时也要注意分组标头有一个与之匹配的分组注脚部分。注意 如果某个 Command 对象有多于一个的子对象 — 相互“平行”的子 Command 对象,则 Data Environment 使您可以创建该 Command 对象的层次结构。Data Report 设计器,却没有那么灵活,在同一时间不能显示多于一个的子对象。此时,当执行一个 Retrieve Structure Command命令时,Data Report 将只显示第一个子 command,其他的都不显示。所以,您应该避免创建带有“平行”子 command的 Command 层次结构。从数据环境设计器,把“CompanyName”字段(在“Customers”命令下)拖到分组标头(Customers_Header)部分。 
分组标头部分可以包含 Customers 命令的任何字段,然而,出于演示目的,此时只显示 Customer 名。删除名为“Label1”的 Label 控件(rptLabel)。 
如果不希望 Label 控件包括在 TextBox 控件中,可以在数据环境设计器的“选项...”对话框的“字段映射”选项卡上撤消对“Drag and Drop Fields Caption”选项的选择。从数据环境设计器中,把“OrderDate”字段(在Orders命令下)拖到细节(Orders_Detail)部分。删除Label控件。 
细节部分表示最内层的“重复”部分,因而与数据环境层次结构(OrdersCommand对象)中最底层的 Command 对象相对应。重新调整数据环境设计器部分的大小,使之与下面的插图类似: 
重新调整细节部分的高度,使它尽可能的矮是很重要的,因为高度将会与为每一个 CompanyName 返回的 OrderDate 相乘。OrderDate 文本框下面或上面的任何多余位置将在最后的报表中导致不必要的空间。保存工程。 
使用 Show 方法预览数据报表
既然数据环境和 Data Report 对象已经创建,就几乎准备好运行工程了。还剩下一步:写代码以显示数据报表。要在运行时显示数据报表,请按照下列步骤执行: 在“工程资源管理器”窗口上,双击“frmShowReport”图标,显示窗体设计器。
在“工具箱”上,单击“通用”选项卡。 
当把一个数据报表设计器添加到工程时,数据报表设计器的控件被添加到名为“Data Report”的选项卡上。要使用标准的 Visual Basic 控件,必须切换到“通用”选项卡。单击“CommandButton”图标并在窗体上绘制一个“CommandButton”。
根据下面的表设置 Command1 控件的属性: 属性 设置值 
Name CmdShow 
Caption Show Report 
在按钮的 Click 事件中,粘贴下面的代码。 
Private Sub cmdShow_Click()
rptNwind.Show
End Sub
保存并运行工程。
单击“显示报表”,在打印预览方式中显示报表。 
可选的—将数据报表作为启动对象设置
在没有代码的情况下,也可以显示报表。 在“工程”菜单上,单击“prjNwind”属性。
在“启动对象”框中,选择“rptNwind”。
保存并运行工程。 
注意 如果使用这种方法,可以从工程中把Form对象删除。

解决方案 »

  1.   

    您可以在 Microsoft 数据报表中用到的控件。注意 虽然在“Visual Basic toolbox”中有 Data Report 设计器控件,但此控件与其他类似的 Visual Basic 控件不一样,它们只能在 Microsoft Data Report 中使用。
    在设计时,您可以在“属性”窗口中更改这些控件的属性。这些可更改的属性包括: ForeColor 和 BackColor
    Caption 和 text
    Fonts
    Size
    Location 和 alignment
    Border color 和 Border style 
    Data Report 设计器控件
     Pointer这是 Microsoft Data Report Toolbox 中唯一一个不会画出控件的项。一旦您选择了这个指针,您将只能改变一个已经画在报表上控件的大小或者移动它的位置。 rptLabel使您能加入不能被更改的文本,例如一副图下面的标题等。Label 控件不能用于显示一个域的内容。 rptTextBox绑定到数据库中的一个域上。设定 DataMember 属性以后,您可以通过设定 DataField 属性来设置域。该控件通常是多行模式。   rptImage从您报表的位图、图标、或元文件显示一个图形图象。 rptLine用于绘制多种样式的线条,以使您能够将报表的各个部分进行分割使其容易阅读。当输出到 HTML 文件时,用水平线作为 HTML <HR> 标记。 rptShape使您能够在报表上绘制多种形状。您可以选择长方形、圆角长方形,正方形、圆角正方形、椭圆形或圆形。 rptFunction您可以选择下列几个内置函数之一来计算并显示结果。这些内置的函数有 Sum、Average、Minimum、Maximum、 Row Count、Value Count、Standard Error 和Standard Deviation。
    在编译了一个报表之后,您或许希望重新使用它,要么作为一个大文档的一部分,要么在 intranet 或 Internet 上发行。数据报表设计器的 ExportReport 方法使您能够完成这些任务。使用 ExportReport 方法,可以将任何报表作为文本文件或 HTML 文件导出。此外,也可以使用任意的 ExportFormat 对象剪裁已导出的文件的内容或外观。重点 ExportReport 方法不支持图像或图形形状导出。ExportFormat 对象
    ExportReport 方法被设计为与 ExportFormat 集合一同使用。集合中的每个 ExportFormat 对象表示一个单独的报表格式。例如,一个 intranet 发行格式的报表可能包含工作组或雇员的名字作为报表标头的一部分;为 Internet 发行的报表,则那些名字将被清除或替换。因此要创建至少两个 ExportFormat 对象,每一个要适应于不同的发行机制。然而,也可能不创建任何 ExportFormat对象就导出一个报表,因为已经为您提供了四个。四个缺省 ExportFormat 对象
    缺省情况下,ExportFormat 集合包含四个成员。下表列出了四个成员以及与其相关联的文件过滤器:对象 文件过滤器 描述 
    ExportFormats(1) *.htm, *.html HTML 
    ExportFormats(2) *.htm, *.html Unicode HTML 
    ExportFormats(3) *.txt Text 
    ExportFormats(4) *.txt Unicode Text 
    如果需要使用任何缺省类型,也可以使用Key属性指定缺省的类型。Key属性值和常数如下所示:对象 关键字 常数 
    ExportFormats(1) key_def_HTML rptKeyHTML 
    ExportFormats(2) key_def_UnicodeHTML_UTF8 rptKeyUnicodeHTML_UTF8 
    ExportFormats(3) key_def_Text rptKeyText 
    ExportFormats(4) key_def_UnicodeText rptKeyUnicodeText 
    假定缺省的成员符合您需要,通过使用四个成员之一,可以不创建另一个ExportFormat对象就导出一个报表。例如,要导出一个按日的HTML报表,可以使用下面的代码:DataReport1.ExportReport rptKeyHTML显示一个对话框是可选的
    编程人员可以决定在导出一个报表时是否显示一个对话框。例如,如果报表在每天早晨自动创建,并写入同一个文件以便在 intranet 上发行,就没有必要显示对话框。只要提供一个有效的文件路径和关键字,并将 Overwrite 参数设置为 True,则不显示对话框。' 作为HTML导出一个报表,覆盖任何已经存在的文件。 导出 
    ' 所有页面到Daily_Report.htm文件。
    DataReport1.ExportReport rptKeyHTML, "C:\Temp\Daily_Report", True, , _
    rptRangeAllPages注意 在上面的代码中,第二个参数看起来象个目录,但实际上是一个文件名。“Daily_Report.htm”是被写的文件名。ExportFormat 对象提供文件扩展名(.htm),因此没有必要把它写在文件名参数中。ExportFormat 提供对话信息
    ExportFormat 对象也包含用户调用 ExportReport 方法时显示的信息。特别的,FileFormatString 属性设置在“导出”对话框的“Save As Type”框中显示的文本。例如,设想一个公司有一个标准的 ExportFormat 对象要用于所有报表。下面的代码将确保 ExportFormat 可以在“导出”对话框的格式类型列表中得到:Dim strTemplate As String' 首先为ExportFormat对象创建一个模板。
    strTemplate = "MyCompany Daily Report" & vbCrLf & rptTagBody' 添加一个ExportFormat对象。FileFormatString决定
    ' 将在“导出”对话框中显示什么内容。
    DataReport1.ExportFormats.Add _
       Key:="StandardReport", _
       FormatType:=rptFmtText, _
       FileFormatString:="Standard Report (*.txt)", _
       FileFilter:="*.txt", _
       Template:=strTemplate' 调用ExportReport方法指定要使用的
    ' 名为StandardReport的ExportFormat。
    DataReport1.ExportReport "StandardReport", , False, True, _
    rptRangeFromTo, 1, 10被调用时,“导出”对话框类似这样:模板代码
    ExportFormat 对象的核心是它的模板。一个模板只是一个字符串,其中包括您想要显示的文本以及表示数据报表多个部分的常数。常数、值和描述如下表所示:常数 值 描述 
    rptTagTitle <!--MSDBRPT_Template_Title--> 表示报表的标题,可在Title属性中找到。 
    rptTagBody <!--MSDBRPT_Template_Body--> 表示报表体。 
    要创建一个只包括作者名,然后是报表体的简单数据报表,其模板类似这样:Dim strT As String
    strT = "Author: " & InputBox("Your name") & vbCrLf & rptTagBody
    drpNwind.ExportFormats.Add "AuExp", rptFmtText, _
    "Author Only Text File", "*.txt", strT打印一个数据报表可以使用下面两种方法之一。用户可以单击“打印预览”中数据报表上的“打印”按钮(使用 Show 方法),也可以通过使用 PrintReport 方法编程打印。如果打印过程中发生错误,将在 Error 事件中捕获。详细信息 请参阅“Data Report事件。”选择显示一个“打印”对话框
    当编程打印一个报表时,有两种选择:通过显示“打印”对话框打印,或不显示对话框打印。要显示“打印”对话框,请按照下列步骤执行: 将一个 CommandButton 添加到窗体。
    在按钮的 Click 事件中,放置下面的代码: 
    DataReport1.PrintReport True“打印”对话框允许用户选择一个打印机、打印到文件、选择要打印的页面范围并指定要打印的份数。注意 要显示打印机选择,打印机必须安装在计算机上。不显示对话框打印
    在有些情况下,您可能希望不需用户干预打印报表。PrintReport 方法也提供这样的选择:选择要打印的页面范围,可以是全部,也可以是一个指定的范围。要不显示对话框地打印,请按照下列步骤执行: 将一个 CommandButton 添加到窗体
    在按钮的 Click 事件中,放置下面的代码: 
    DataReport1.PrintReport False或者,要指定打印的页面范围,请使用下面的代码:DataReport1.PrintReport False, rptRangeFromTo, 1, 2
    象标准的 Visual Basic 窗体一样,数据报表设计器的存在是由某些关键事件标记的。那些事件以及它们发生的顺序,如下表所示:事件 描述 
    Initialize 查询完成之后发生,并且控件位于窗体上。 
    Resize 第一次显示设计器或一个对象的窗口状态更改时发生。 
    Activate 当设计器变为活动窗口时发生。 
    ProcessingTimeout 大约每秒钟发生一次,直到所有处理都已经结束。使用该事件可以决定处理是否占用太长时间,并取消处理。 
    注意 在查询完成之前该事件将不发生。请参阅下面的内容。
     
    [Deactivate] 当设计器不再是活动窗口时发生。使用该事件决定用户是否单击了另一个窗体或设计器。 
    QueryClose 在设计器终止之前发生。设置 Cancel 参数为 True 以取消终止。CloseMode 参数返回引起终止的动作类型。 
    Terminate 当所有对设计器的引用都被设置为0时发生。 
    超时和异步调用事件
    除设计器的存活期事件之外,DataReport 对象也以允许捕获错误和监视同步或异步函数调用的事件为特色。ExportReport和PrintReport:查询、同步和异步处理
    当调用 ExportReport 或 PrintReport 方法时,处理被分为三个阶段——查询、同步处理和异步打印或导出: 查询——当第一次创建数据报表时,发送给数据提供方一个查询。
    处理——查询检索到的数据由 Visual Basic 处理以创建报表。数据被高速缓存在计算机上的一个临时文件中。这一处理是同步的。
    异步打印或导出——在创建报表后,报表就被导出或打印。这一处理是异步的。 
    当Show方法被调用时,数据报表执行查询,然后在显示报表之前在同步处理过程中处理数据。因为这些方法结合了同步和异步处理,有各自的事件监视每种处理。ProcessTimeOut 事件——对于同步函数
    处理一个大的数据报表也许要花费一些时间。如果想要允许您的用户取消过程较长的操作(如 Show、ExportReport 或 PrintReport),可以使用 ProcessingTimeout 事件监视已经过去了多少秒,并按照用户的命令把 cancel 参数设置为True。下面的代码显示了一个示例:Private Sub DataReport_ProcessingTimeout(ByVal Seconds As Long, _
    Cancel As Boolean, ByVal JobType As MSDataReportLib.AsyncTypeConstants, _
    ByVal Cookie As Long)
       Select Case Seconds
       Case 30
          If MsgBox("This has taken " & Seconds & "seconds. Cancel?", _
             vbRetryCancel) = vbCancel Then
                Cancel = True
          End If
       Case 45
          If MsgBox("This has taken " & Seconds & "seconds. Cancel?", _
             vbRetryCancel) = vbCancel Then
                Cancel = True
          End If
       Case 60
          '60秒钟后自动取消。
          Cancel = True
       End Select
    End Sub注意 并不保证在上面指定的间隔会发生 ProcessingTimeout 事件。例如,在后台运行的其他的 Visual Basic 代码可能会阻止这一事件的发生。在那种情况下,将 Case 语句设置为一个范围内的值;当该事件发生时,将一个模块级标志设置为 True,并在随后发生的事件中检查它。Error 事件——对于异步函数
    要捕获在没有 Visual Basic 代码执行(也就是说,一个异步函数)时发生的错误,请使用 Error 事件。例如,如果 PrintReport 或 ExportReport 方法在异步阶段失败,Error 事件将发生。下面的示例捕获异步错误:Private Sub DataReport_Error(ByVal JobType As _
    MSDataReportLib.AsyncTypeConstants, ByVal Cookie As Long, _
    ByVal ErrObj As MSDataReportLib.RptError, ShowError As Boolean)
       Select Case JobType ' The JobType identifies the process.
       Case rptAsyncPrint
          ' 此处捕获 PrintReport 错误。
       Case rptAsyncReport
          ' 此处捕获 ExportReport 错误。
       End Select
    End Sub也可以使用 Error 事件捕获特定的情况,例如计算机上缺少打印机,如下面的代码中所示:Private Sub DataReport_Error(ByVal JobType As _
    MSDataReportLib.AsyncTypeConstants, ByVal Cookie As Long, _
    ByVal ErrObj As MSDataReportLib.RptError, ShowError As Boolean)
       Case rptErrPrinterInfo ' 8555
          MsgBox "A printing error has occurred. " & _
          "You may not have a Printer installed."
          ShowError = False
          Exit Sub
       Case Else
          ' 此处处理其他情况。
          ShowError = True
       End Select
    End SubAsyncProgress 事件
    AsyncProgress 事件不是为捕获错误而设计的,但允许监视异步函数的状态。到这一事件发生时,所有的数据都已经被处理过;这样,事件的两个参数是 PagesCompleted 和 TotalPages。该事件还包括标识异步操作的参数:则 JobType 和 Cookie 参数可以被用于监视任何处理的过程。
    创建一个数据报表的一种方法是: 创建一个包含 Command 对象层次结构的数据环境设计器。
    设置数据报表设计器的 DataSource 属性为数据环境设计器。
    设置 DataMember 属性为最顶层的 Command 对象。
    右键单击数据报表设计器并单击“检索结构”。 
    在检索结构之后,将创建适当数目的分组标头和注脚,而且每一标头/注脚对被指定一个对应于一个 Command 对象的名字。把 Command 对象从数据环境设计器拖到数据报表设计器上的对应部分。 
    Command 对象包含的所有数据字段,都作为 Command 对象被放下的部分中的 TextBox 控件,被自动创建在数据报表上。每一 TextBox 的 DataMember 属性和 DataField 属性都按照 Command 对象及其数据字段设置。从每一个 TextBox 控件创建时所在的部分上将 TextBox 控件拖动到数据报表设计器的不同部分上。
    按照需要将 Function 控件添加到报表。 
    当数据报表被绑定到一个数据环境时,报表上控件的放置规则就不再是立即显现。该主题解释了在数据环境中创建的层次结构是如何与在数据报表中构造的分组标头和注脚系统相关联的。对应于分组标头/注脚或细节部分的Command对象
    除两个例外情况,数据环境中的每一个 Command 对象或对应于一对分组标头和注脚部分,或对应于细节部分。例外的情况在该主题稍后部分讨论。Hierarchy 与标头、注脚和细节
    下面的插图显示包含四个 Command 对象(每一对象都至少与一个其它的对象有父/子关系)的数据环境设计器的一个图解视图。属于表的数据字段未显示。另一方面,数据报表设计器被构造为一系列的部分。并且每一部分可以按照如下四种类型归类:报表标头/注脚、页标头/注脚、分组标头/注脚和细节部分。为便于指导,可以不管报表和页标头/注脚对。这就剩下了分组标头/注脚和细节部分。细节部分,设计器的最内层部分,对应于最低层次的 Command 对象。当在层次结构中逐渐向上时,细节部分则由成对的部分括起来,每一对与一个单个的 Command 对象相关联。下面的插图使 Command 对象和部分相互关联:对应于 Command 对象的部分这样插图显示了数据环境的层次结构实际上对应于一系列括号的扩展,最内层的(细节)部分对应于层次结构中的最低层次,最外层部分对应于最高层次的 Command 对象。控件可以被放置在较低层次的部分中
    控件的放置由它从属的部分(或部分对)管理。简言之,控件可以放置在产生它的部分和比它自身更低层次的所有部分中。例如,如果一个控件属于 Command1 部分对,它也可以被放置在 Commands2、3 和 4 的部分对中。第二个示例是:在部分3中产生的控件也能放置在部分4中,但不能放置在部分1和2中。总而言之,在 Command 4(细节部分)部分中产生的控件不能被放置在除细节部分以外的任何其它位置。放置 Function 控件
    对于以上有关控件位置的指南,Function 控件有三点例外。Function 控件不象 TextBox 控件那样直接绑定到记录集上。相反,Function 控件在报表生成时计算自己的值。因此,Function 控件只能被放置在报表的注脚部分中。Function 控件的第二个例外是:它只能被放置在比自身层次高一级的任何部分对中。例如,如果Command 3 对象包含一个 Quantity 字段,可以把一个合计 Quantity 值的 Function 控件放置到Command 2的注脚部分上,或放置到 Command 1 的注脚部分上。关于 Function 控件的第三个例外是:不象其它的数据绑定控件(TextBox 控件),Function 控件可以被放置在报表注脚部分中。当这样做时,控件的计算范围将扩大到整个报表。例如,放置在报表注脚中用来计算 Quantity 字段合计值的 Function 控件,将计算报表上每一个 Quantity 控件的合计值。例外:分组和总计合计
    有两个例外,数据环境中的每一个 Command 对象对应于一对分组标头和注脚。当您使用数据环境设计器的分组特征时第一个例外发生。分组字段
    当创建分组字段时,数据环境设计器在一个单个的 Command 对象下创建两个文件夹。第一个包含分组字段,另一个包含细节字段。尽管没有为分组字段创建一个新的 Command 对象,必须在数据报表上创建一个新的分组标头/注脚对,并且对这一需要使其成为一个例外。总计合计字段
    当在数据环境中创建一个总计合计字段时发生第二个例外。如同当创建一个分组字段一样,将为 Command 对象创建一个新的文件夹。新文件夹包含任何创建的总计合计字段,并且必须将一个新的分组标头/注脚添加到数据报表。详细信息 有关创建合计字段的详细信息,请参阅“使用 Data Environment 设计器”中的“创建合计”。 检查层次结构
    如果对于数据环境 Command 对象的层次结构存有疑问,有两种方法确保数据报表有正确的分组标头/注脚结构:检索结构——如果还没有在数据报表设计器上放置很多控件,并且可以重新组织报表,可以使用 Retrieve Structure Command 自动创建正确数目的分组标头和注脚。ADO层次结构信息——在数据环境设计器中右键单击最顶层的 Command 对象,并单击“层次结构信息...”显示“层次结构信息”对话框。单击“查看 ADO 层次结构”选项卡查看 Command 对象的层次结构的图形表示。