页面树结构
转至元数据结尾
转至元数据起始

子报表是包含在另一个报表(主报表)中的某个字段中的常规报表。子报表通常被设计在一个主从应用场景中,用来基于主报表中的一个当前值显示详细的信息。在接下来的示例中,主报表包含了分组而位于内容区域的子报表包含当前分组的产品详细信息。

为了基于Categories 和Products数据表生成一个主从报表,您需要创建一个Categories(主视图)报表和一个Products 报表(详细视图)。

步骤一:创建主报表

  1. 1.使用C1Report向导创建一个基本的报表定义。
    1. 从Northwind数据库选择(位于"ComponentOne Samples\Common"目录下的Nwind.mdb)Categories数据表。
    2. 包含CategoryName和Description字段至报表。
  2. 在C1ReportDesigner应用程序中,单击Close Print Preview按钮以开始编辑报表。
  3. 设置页眉和报表页眉报表节的Visible属性的值为False。
  4. 在内容区域,选择DescriptionCtl并将其直接移动至CategoryNameCtl下方。
  5. 通过属性窗体改变外观设置(字体和前景色)。注意,在本示例中,我们向内容区域添加了一个渐变字段。关于渐变字段的更多信息,请参见"添加渐变字段"章节。
  6. 单击预览按钮,Categories报表现在应当看起来如下图所示:

步骤二:创建详细报表

  1. 在C1ReportDesigner应用程序中,通过单击新建报表按钮使用C1Report向导创建一个基本的报表定义。
    1. 从Northwind数据库选择Products数据表。
    2. 包含以下字段至报表:ProductName,QuantityPerUnit,UnitPrice,UnitsInStock,以及UnitsOnOrder。
  2. 在报表设计器中,单击Close Print Preview以开始编辑报表。
    1. 设置页眉和报表页眉报表节的Visible属性的值为False。
    2. 在内容区域,排布所有的控件,使其对齐到相关的标题标签。使用属性窗体改变外观设置。

步骤三:创建子报表字段

现在C1ReportDesigner程序拥有了两个独立的报表,Categories报表和Products报表。下一步是创建一个子报表:

  1. 在设计器的报表列表中,选择Categories(主报表)。
  2. 在设计模式下,从Design标签页的Fields分组,单击AddSubreport按钮,并从下拉菜单选择Products报表。

  1. 在报表的Detail区域,单击并拖拽鼠标指针创建一个子报表区域:

步骤四:将子报表链接到主报表

主从关系由子报表字段的Text属性进行控制。该属性应当包含一个表达式,该表达式可以计算出一个筛选子报表数据源的条件。
报表设计器可以为您自动生成这个表达式。尝试完成以下步骤:

  1. 右键单击子报表字段,并从菜单上选择Link Subreport。

  1. 弹出的对话框允许您选择通过哪些字段进行链接。

  1. 完成选择,并单击OK,报表设计器将生成链接表达式并将其设置给子报表字段的Text属性。在本示例中,生成的表达式为:"[CategoryID] = '" & [CategoryID] & "'" 您同样也可以通过以下步骤链接子报表到主报表:

1. 在属性窗体,单击子报表的Text属性,并选择位于下拉列表上的ScriptEditor。

  1. 在VBScript编辑器中输入以下表达式:"[CategoryID] = '" & [CategoryID] & "'"

  2. 单击OK关闭VBScript编辑器以生成表达式。

预览并打印报表从设计器窗体左侧的报表列表选择报表,并单击预览按钮,以预览一个报表,该按钮出现在每一个Ribbon标签页上:

同样,也可以从菜单选择View | Preview。报表在右侧面板显示,如下面的屏幕截图所示:

主窗体具有一个预览导航工具栏,上面有按钮可以按页查看整个文档并选择缩放模式。在这里,您可以通过单击打印按钮打印报表:

导出并发布报表
除了打印报表,您也许希望导出报表成为一个文件,并以电子文档方式共享给客户或者同事。设计器支持以下导出格式:

格式

描述

分页式HTML (*.htm)

为报表中的每一个页面创建一个HTML文件。这些HTML页面包含链接,用户可以使用此链接在报表的各个页面中导航。

钻取式 HTML (*.htm)

创建一个单一的HTML文件,各个报表节可以通过单击收起或展开。

普通HTML (*.htm)

创建一个单一的HTML文件,不具有收起或者展开功能。

使用系统字体的PDF (*.pdf)

创建一个可以在装备了Adobe Acrobat阅读器或者浏览器插件的任意电脑上查看的
PDF文件。

带有内嵌字体的PDF (*.pdf)

创建一个具有内嵌字体信息的PDF文件,具有更好的可移植性。该选项将显著增大
PDF文件的尺寸。

RTF (*.rtf)

创建一个RTF格式的文本,可以被大多数流行的字处理软件打开(例如,Microsoft
Word,WordPad)。

具有固定位置信息的RTF (*.rtf)

创建一个具有固定的位置信息的RTF格式的文本,可以被大多数流行的字处理软件打开(例如,Microsoft Word,WordPad)

Microsoft Excel 97 (*.xls)

创建一个XLS格式的文件,该文件可以被Microsoft Excel打开。

Microsoft Excel 2007/2010 Open
XML (*.xlsx)

创建一个XLS格式的文件,该文件可以被Microsoft Excel2007或者更新的版本打开。

TIFF (*.tif)

创建一个多页面的TIFF(标记图像文件格式)文件

文本文件(*.txt)

创建一个纯文本文件。

单页面文本文件(*.txt)

创建一个单页面的纯文本文件。

压缩的元文件 (*.txt)

创建一个压缩的元文件的文本文件。

为创建一个导出文件,从菜单选择File | Export,并通过文件保存对话框选择希望创建的文件类型,并设定其文件名和保存位置。

注意:注意:当文档导出至RTF或者DOCX格式,同时选择了"保留分页信息"选项时,文档将被放在不同的文本框中,结果文档中的重新文档流排布功能可能会受到限制。

管理报表定义文件
一个报表定义文件可能包含若干报表。有时,您可能需要从一个文件复制或者移动报表到另一个。
打开两个不同的C1ReportDesigner应用程序的实例,并从一个实例拖拽报表到另一个可以实现从一个文件移动报表到另一个。如果在这一过程中您按下了CTRL键,该报表将被复制。否则,将移动该报表。
您同样可以在一个文件中复制一个报表。这将创建报表的一个新的实例,这在开始设计一个新的和现有报表相似的报表时是一种非常有效的技巧。
注意,报表文件保存为XML格式,因此您可以通过任何文本编辑器编辑和管理它们。

导入Microsoft Access报表

!MISSING PHRASE 'Show All'!
!MISSING PHRASE 'Hide All'!
C1ReportDesigner应用程序众多强大的功能之一是能够导入MicrosoftAccess创建的报表。该功能需要在确保电脑上安装了Access。一旦报表被导入设计器中,将不再依赖Access程序。

单击Application按钮并从菜单选择Import。将会显示一个对话框,提示您选择希望导入的文件名。
选择一个MicrosoftAccess文件(MDB或者ADP),之后设计器将扫描该文件,并显示一个对话框。您可以选择希望导入的报表:

该对话框允许您指定是否设计器在开始导入过程之前需要清除全部当前定义的报表。
导入过程将处理源报表的大部分元素,除了一些列外:

  • 事件处理器代码

Access报表可以使用VBA,宏以及表单以动态格式化报表。C1Report可以做同样的事情,但是只能够使用VBScript。正因如此,全部的报表代码需要手动翻译并迁移。

  • 面向表单的字段类型

Access报表可能包含一些特定的字段,这些字段不会被设计器的导入过程处理。以下字段类型不被支持:Chart,CommandButton,
ToggleButton,OptionButton,OptionGroup,ComboBox,ListBox,TabCtl,以及CustomControl。

  • 使用了VBScript保留字的报表

由于Access不支持VBScript,因此可能在之前设计报表的时候用到了VBScript保留关键字做为报表对象的标识符或数据集字段的名称。
这将使得当VBScript引擎尝试解析并计算表达式的时候遇到问题,并会导致报表不能正确地呈现。
不应当作为标识符使用的保留关键字包括Date,Day,Hour,Length,Minute,Month,Second,Time,TimeValue,Value,
Weekday,以及Year。关于保留关键字的全部列表,请参见"VBScript参考"

  • 按照季度(或者周,月份等等)对日期排序的报表

C1Report使用ADO.NET数据集的Sort属性对分组进行排序。该属性仅按照字段的值对数据集进行排序,不支持表达式。(注意您能够按照任意表达式进行分组,但是不能排序。)一个按照季度对分组进行排序的Access报表将在导入之后按照日期对分组进行排序。为了修正这个问题,您有两种方式:创建一个新的字段,该字段包含希望进行排序的表达式的值;或者改变SQL表达式,创建一个新的数据集并对新的数据集执行排序。
这些限制将影响为数不多的一些报表,不过在导入这些报表之后您应当预览全部的报表,确保它们可以正常工作。
导入Nwind.mdb文件
为了演示设计器如何在一个现实的示例中工作,请尝试导入为了演示设计器如何在一个现实的示例中工作,请尝试导入Nwind.mdb文件。它包含以下十三个报表。(随文件。它包含以下十三个报表。(随C1Report发布的发布的
Nwind.xml文件已经包含了以下全部的改动。)文件已经包含了以下全部的改动。)

    1. Alphabetical List of Products 不需要做任何改动。
    2. Catalog

不需要做任何改动。

    1. Customer Labels

不需要做任何改动。

    1. Employee Sales by Country

该报表包含代码,需要手动转换。以下代码应当设置给Group1 Header 对象的OnPrint属性:
Visual Basic

Visual Basic

If SalespersonTotal > 5000 Then
ExceededGoalLabel.Visible = True
SalespersonLine.Visible = True
Else
ExceededGoalLabel.Visible = False
SalespersonLine.Visible = False
End If

C#

C#

if (SalespersonTotal > 5000) {
ExceededGoalLabel.Visible = true;
SalespersonLine.Visible = true;
} else {
ExceededGoalLabel.Visible = false; SalespersonLine.Visible = false;
}

    1. Invoice

不需要做任何改动。

    1. Products by Category 不需要做任何改动。
    2. Sales by Category

该报表包含一个图表控件,该控件无法被导入。为了向导入的报表添加一个图表,您需要使用一个非绑定的图片字段,之后使用VB事件处理器创建这个图表并做为图片保存到该字段。

    1. Sales by Category Subreport 不需要做任何改动。
    2. Sales by Year


该报表包含一段引用Form对象的代码,该代码需要被手工迁移。为替代Form对象,编辑RecordSource属性以添加一个
[ShowDetails]参数:
Visual Basic


Visual Basic

PARAMETERS (Beginning Date) DateTime 1/1/1994,
(Ending Date) DateTime 1/1/2001, (Show Details) Boolean False; ...

C#

C#

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="0d5e9ed5-79cb-4ca0-b84d-72dd574d18fc"><ac:plain-text-body><![CDATA[

PARAMETERS [Beginning Date] DateTime 1/1/1994,
]]></ac:plain-text-body></ac:structured-macro>
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="a2fb4c73-89f9-477c-83c2-849f7098ac92"><ac:plain-text-body><![CDATA[ [Ending Date] DateTime 1/1/2001, [Show Details] Boolean False; ...

]]></ac:plain-text-body></ac:structured-macro>

Use the new parameter in the report's OnOpen event:
Visual Basic

Visual Basic

Dim script As String = _
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="86817e72-78d8-4bf0-b5a7-e257e2af120c"><ac:plain-text-body><![CDATA[ "bDetails = [Show Details]" & vbCrLf & _
]]></ac:plain-text-body></ac:structured-macro>
"Detail.Visible = bDetails" & vbCrLf & _
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="4ba5beb8-ca10-4884-94c1-3ea3eb898123"><ac:plain-text-body><![CDATA[ "[Group 0 Footer].Visible = bDetails" & vbCrLf & _
]]></ac:plain-text-body></ac:structured-macro>
"DetailsLabel.Visible = bDetails" & vbCrLf & _
"LineNumberLabel2.Visible = bDetails" & vbCrLf & _
"Line15.Visible = bDetails" & vbCrLf & _
"SalesLabel2.Visible = bDetails" & vbCrLf & _
"OrdersShippedLabel2.Visible = bDetails" & vbCrLf & _
"ShippedDateLabel2.Visible = bDetails" & vbCrLf & _ "Line10.Visible = bDetails" c1r.Sections.Detail.OnPrint = script

C#

C#

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="238599c0-ac6f-4707-929f-9f1b3d574116"><ac:plain-text-body><![CDATA[

string script = "bDetails = [Show Details]" + "Detail.Visible = bDetails\r\n" +
]]></ac:plain-text-body></ac:structured-macro>
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="fb34d149-ae1b-4cf3-ae3a-e22eb206838e"><ac:plain-text-body><![CDATA[ "[Group 0 Footer].Visible = bDetails\r\n" +
]]></ac:plain-text-body></ac:structured-macro>
"DetailsLabel.Visible = bDetails\r\n" +
"LineNumberLabel2.Visible = bDetails\r\n" +
"Line15.Visible = bDetails\r\n" +
"SalesLabel2.Visible = bDetails\r\n" +
"OrdersShippedLabel2.Visible = bDetails\r\n" +
"ShippedDateLabel2.Visible = bDetails\r\n" + "Line10.Visible = bDetails"; c1r.Sections.Detail.OnPrint = script;

最后,需要转换其他两行代码:
Visual Basic

Visual Basic

Sections ("Detail").OnPrint = _
"PageHeader.Visible = True"
Sections("Group 0 Footer).OnPrint = _
"PageHeader.Visible = False"

C#

C#

Sections ("Detail").OnPrint =
"PageHeader.Visible = true";
Sections("Group 0 Footer).OnPrint =
"PageHeader.Visible = false";

    1. Sales by Year Subreport 不需要做任何改动。
    2. Sales Totals by Amount

此报表包含需要手工迁移的代码。以下代码需要指定给PageHeader的OnPrint属性:
Visual Basic

Visual Basic

PageTotal = 0

C#

C#

PageTotal = 0;

以下代码应当指定给Detail的OnPrint属性:
Visual Basic

Visual Basic

PageTotal = PageTotal + SaleAmount
HiddenPageBreak.Visible = (Counter = 10)

C#

C#

PageTotal = PageTotal + SaleAmount;
HiddenPageBreak.Visible = (Counter = 10);

    1. Summary of Sales by Quarter


该报表具有一个按照季度排序的分组(参见之前第四项)。为了解决这个问题,向源数据集添加一个字段,该字段包含
ShippedDate字段所表达的季度值,然后按照以下方式修改RecordSource属
性:
SELECT DISTINCTROW
Orders.ShippedDate,
Orders.OrderID,
[Order Subtotals].Subtotal,
DatePart("q",Orders.ShippedDate) As
ShippedQuarter
FROM Orders INNER JOIN [Order
Subtotals]
ON Orders.OrderID = [Order
Subtotals].OrderID
WHERE (((Orders.ShippedDate) Is Not Null));
Change the group's <span style="color: #1364c4">GroupBy</span> property to use the new field, ShippedQuarter.
13. Summary of Sales by Year 不需要做任何改动。
归纳一下上表的信息,有十三个报表从Northwind数据库导入:八个不需要做任何改动,三个需要对脚本代码做手工迁移,一个需要对 SQL表达式做改动,还有一个存在无法替换的图表控件。<span style="color: #3f529c">导入水晶报表</span>
C1ReportDesigner应用程序同样可以导入水晶报表定义文件(.rpt文件)。

为了从水晶报表定义文件导入报表:


  1. 单击Application按钮并从菜单选择Import。

将会弹出一个对话框提示希望导入的文件名。

  1. 选择一个水晶报表定义文件(RPT),设计器会将该报表转换为C1Report格式。

导入过程将处理源报表的大部分元素,除了少量的一些例外情况,包括水晶报表的对象模型没有暴露的元素或者
C1Report不支持的元素。这些例外包括图像字段,图表以及跨标签页字段。
报表中的图表
汇总图表是一个功能强大,简单且易于使用的功能。ComponentOne Reports for WinForms通过其可扩展的自定义字段结构支持了图表字段。Chart字段做为一个自定义字段在C1.Win.C1Report.CustomFields.2.dll程序集中实现,该程序集随着报表设计器程序一并安装并做为示例提供了全部的源代码(CustomFields)。以下主题中,您将看到如何通过
C1ReportDesigner程序自定义图表字段。ComponentOne Reports for WinForms 以及ComponentOne Reports for WPF 均安装了C1ReportDesigner程序。简单报表中的图表
创建一个简单的报表非常容易。可以通过以下步骤创建一个简单报表:

  1. 打开C1ReportDesigner应用程序并创建或者打开一个报表定义文件。
  2. 添加一个图表字段至报表,并选中以便在设计器的属性窗体显示其属性。
  3. 设置图表的DataX属性的值为用作显示在X轴(图表类目)内容的字段。
  4. 设置图表的DataY属性的值为用作显示在Y轴(图表值)内容的字段。
  5. 可选地设置其他属性比如ChartType和DataColor。

例如,以下图表基于NorthWind的Products数据表创建。在本示例中,我们设置了以下属性:
DataX = "ProductName"
DataY = "UnitPrice"

注意,对于该图表类型(条形图),数值轴(显示DataY字段的值)是水平方向的那条坐标轴,类目轴是垂直方向那条坐标轴。
在本示例中,我们应用了一个过滤条件到数据层,以便限制显示的数值的个数。如果不加任何筛选条件,图表将包含大量的数据以至于垂直坐标轴无法正常辨识其内容。
其他有用的图表属性
除了之前提到的DataX以及DataY属性之外,图表对象提供了其他的一些常用属性:
ChartType:该属性用作选择显示的图表类型。一共有六个可选项:条形图(水平数据条),柱状图(垂直数据列),散点图(X-Y值对),折线图,面积图以及饼图。
DataColor:该属性选择用作绘制水平数据条,垂直数据列,面积,散点图符号以及饼图中的扇形区域的颜色。
如果一个图表包含多个数据系列,则Chart字段将自动地根据选中的颜色为不同的数据系列应用深浅不同的颜
色。如果您希望为每一个不同的系列应用指定的颜色,请使用Palette属性,并使用分号分隔的颜色序列设置该属性的值(例如"Red;Green;Blue")。
FormatY,FormatX:这些属性用作决定每一个坐标轴显示数值的格式。例如设置FormatY为"c"使得图表字段将
Y轴方向显示的数值格式化为金融货币值。这类似于在常规报表字段上的Format属性的功能。
XMin, XMax, YMin, YMax:这些属性可以指定每一个坐标轴的范围。设置其中任意属性的值为-1将导致图表自动计算此范围。例如,如果设置YMax属性为100,则任何大于100的值将被修剪掉,不会出现在图表中。
这些属性将应用到全部的图表类型。这里还有一些仅应用到饼图类型的额外属性:
ShowPercentages:每一个饼图的扇形区域具有一个图例,显示该扇形的X值。如果ShowPercentages属性设置为 true,该图例项将同时显示一个百分比值,表示该扇形区域的尺寸占整个圆饼的百分比。此百分比的值使用
FormatY属性指定的格式进行格式化。例如,如果设置了FormatY为"p2",那么图例项将包含X值以及带有两位小数的百分比值(例如"North Region(15.23%)")。
RadialLabels:该属性指示具有连接线的标签关联到每一个扇形,而不是在图表右侧显示一个图例区域。这在扇形个数较少的时候工作正常(少于十个)。
图表字段实际上是对C1Chart控件的一个封装,C1Chart控件提供了全部的图表相关的服务并支持了非常丰富的对象模型。如果您希望更进一步地自定义图表字段,您可以通过ChartControl属性通过脚本访问内部的C1Chart对象。
例如,图表字段不支持控制图例区域的属性。但是C1Chart控件本身是支持的,您可以通过ChartControl属性访问这些设置。举个具体的例子,以下脚本将导致图表的图例区域放置在图表下方而不是默认的右侧位置:
' place legend below the chart
chartField.ChartControl.Legend.Compass = "South"
设置脚本给报表的OnLoad属性,则图表看起来如下图所示:

创建这些图表的其他属性设置列举如下:
ChartType = Pie
FormatY = "p1"
ShowPercentage = true
Palette = "Red;Gold;Orange;Beige;DarkGoldenrod;Goldenrod;" 具有多个数据系列的图表
为创建具有多个数据系列的图表,可以简单的设置DataY属性的值为包含每一个数据字段的名称的字符串,不同字段名称之间使用分号分隔。
例如,创建一个图表,显示产品单价和折扣,您应当按照如下方式设置DataY属性的值:
DataY= "UnitPrice;Discount"
如果您希望指定用做显示每一个系列的颜色,请为Palette属性指定一组用分号分隔的颜色。例如,下面的值将使得图表显示"UnitPrice"系列为红色,而"Discount"系列为蓝色:
Palette = "Red;Blue"
使用计算结果当作数据系列
DataY属性不仅仅局限于显示字段名称。指定给系列的字符串实际上将被当作完整的表达式处理,并和报表中其他的常规字段一样进行计算。
例如,您可以按照如下方式设置DataY属性的值,以创建一个显示产品实际价格的字段:
DataY= "UnitPrice * (1 - Discount)" 分组报表中的图表
Reports for WinForms允许创建具有多个分组的报表。例如,除了可以在一个单一的报表中列举全部的产品信息外,还可以按照分类对产品进行分组。每一个分组具有一个页眉和页脚,用作显示该分组的相关信息,比如说标题和副标题。如果添加一个图表至分组页眉区域,则图表仅显示当前分组的数据。而添加一个图表到报表页眉或者页脚区域则会包含报表的全部数据。
为了说明这一点,这里是一幅图,展示了在报表设计器中添加一个图表字段至报表页眉和分组页眉的不同效果:

报表页眉区域位于这里的图表字段在整个报表中仅生成一次。该图表将显示报表数据源的全部数据。

页眉区域页眉区域

分组页眉区域(分组页眉区域(CategoryName))
位于此处的图表字段将为每一个CategoryName的值生成一个图表。每一个图表将显示当前CategoryName对应的数据。

内容区域内容区域

分组页脚区域分组页脚区域 (CategoryName)

页脚区域页脚区域

报表页脚区域报表页脚区域

我们继续回到之前提到的的示例,如果添加一个图表至分组页眉区域并设置DataX属性的值为"ProductName",DataY属
性的值为"UnitPrice",则最终的报表将为每一个分类包含一个图表,每一个图表显示位于当前分组的产品单价。
以下图片显示了上面描述的位于分组页眉区域的图表的屏幕截图,包含少量的示例数据:

以上图表显示了位于"Beverages"分组的产品的单价,以下图表显示了位于"Condiments"分组的产品单价。

DataX = "Product Name"
DataY = "Unit Price"
图表将自动地基于所位于的报表节选择数据范围,因此在分组报表中创建报表相当容易。
总结图表
包含在Reports for WinForms的2009v3版本的图表具有一个强大的新功能叫做"图表自动汇总"。该功能允许您选择一个汇总功能(求和,平均值,标准差等等),然后可以对具有相同分组(DataX)的数据值(DataY)进行自动汇总。
为了演示此功能,假设我们有一个"Invoices"报表,该报表按照国家,客户以及订单ID对数据进行分组。
该报表的结构如下所示:

报表页眉区域报表页眉区域

页眉区域页眉区域

分组页眉区域(分组页眉区域(Country))

分组页眉区域(分组页眉区域(Customer))

分组页眉区域(分组页眉区域(OrderID))

内容区域内容区域

分组页脚区域(分组页脚区域(OrderID))

分组页脚区域(分组页脚区域(Customer))

分组页脚区域(分组页脚区域(Country)))

页脚区域页脚区域

 

报表页脚区域报表页脚区域
假设您希望向每一个Country分组的页眉区域添加一个图表,用做显示当前国家不同客户的订单总金额。
首先请向"Country"的页眉区域添加一个图表字段,并设置DataX以及DataY属性的值如下所示:
DataX= "CustomerName"
DataY= "ExtendedPrice"
这将无法正常工作,每一个国家的数据中,针对每一个用户通常包含若干条记录,而图表会为每一条记录生成一条数据点。图表无法智能推测您实际需要的是将每一个客户的记录累加至一个单一的数据点。
为了解决这种情况,我们为图表字段添加了一个Aggregate属性。该属性告诉图表如何对具有相同分组的数据进行汇总并归并为一个数据点在图表中进行展示。可以设置Aggregate属性对数据执行任何常见的汇总功能:求和、平均值、计数、最大值、最小值、标准偏差以及方差。
继续回到我们的示例,现在我们可以简单地设置图表的Aggregate属性为"Sum"。这将使得图表把属于同一个客户的不同记录的"ExtendedPrice"字段的值累加为一个单独的数据点。结果如下面所示:

请注意每一个客户是如何仅在图表上出现一次的。图表上显示的值和具有相同的"Customer"字段值的记录的"ExtendedPrice"的值之和相关。
由于该图表位于"Country"分组页眉区域,则该图表将为每一个不同的国家重复显示,包含该国家中全部的客户的订单总和信息。
如果将此报表放置在报表页眉区域,则它将对整个报表的全部数据进行汇总。例如,您希望在"Invoices"报表的开始部分放置一个图表用来显示每一个销售人员订单的总金额。为了做到这一点,您需要在报表的页眉部分添加一个图表字段,并设置其属性如下:

由于图表放置在报表的页眉区域,则其显示的值将包括全部的国家以及客户的信息。如果将此图表字段从报表页眉区域移动到"Country"分组的分组页眉区域,您将获取一个按照不同国家显示的一个类似的图表,显示在该国家范围内,不同的销售人员的总销售金额记录。
报表中的地图
ComponentOne Reports for WinForms通过其可扩展的自定义字段的架构设计支持地图字段。Map自定义字段就是这么
一个自定义字段,它使用了两个来自于ComponentOne Studio for WPF产品的程序集:C1.WPF以及C1.WPF.Maps,这些程序集已随着报表设计器程序一起安装。在下文中,您将了解如何通过C1ReportDesigner程序自定义地图字段。
注意,Map自定义字段使用到了来自于ComponentOne Studio for WPF产品包的两个程序集:C1.WPF以及
C1.WPF.Maps。请确保在开始之前这些程序集是可用的,同时您的工程已经添加了对这两个程序集的引用。
完成下列步骤,以便在C1ReportDesigner程序中使用Map自定义字段:

  1. 运行C1ReportDesigner应用程序。具体请参见"从Visual Studio中访问C1ReportDesigner"章节。

确定Map的图标已经显示在C1ReportDesigner的工具栏上。如果尚未包含此图标,您需要添加下面的内容到
C1ReportDesigner.EXE.settings文件的<customfields>部分:
<item value="C1.C1Report.CustomFields.4;C1.C1Report.CustomFields.Map" />

  1. 创建一个新的报表或者打开一个现有的报表。请参见"创建一个基本报表定义"的示例。
  2. 单击Map图标并拖拽其至报表以添加一个Map字段。

这样就OK了!Map字段主要包括:

    • 地图图块和数据层
    • 图例
    • 样式
    • 表达式自动缩放/居中以及数据跟踪
    • 更多信息,请参见以下章节。下章将介绍Map自定义字段的一些重要属性。

图层
地图的主要部分是一个提供表示地球表面或者其一部分的光栅图像的地图图块图层,0或多个层代表着空间数据。
地图图块图层由TileSource属性指定。可以设置为VirtualEarth的地图图块来源(道路、航空或者二者混合显示)。地图图块层可以设置为"none",表示地图上不显示地图图块层。这可能在当其他层,比如说KML,已经为地图展示提供了足够的数据时比较有用。
注意,除非设置地图图块层为"none",否则当报表运行时地图图块将从网络位置加载,这将大大的影响处理速度。除了地图图块层外,其他的图层包含在Layers集合中。目前我们提供了三种不同的图层类型:
标点层。一个标点层允许在地图上以点的方式显示空间坐标数据。标点层将为每一个数据行绘制一个标记。
画线层。画线层允许在表示每一个数据行的点之间绘制一条直线。
KML层。KML(Keyhole标记语言)是一种基于XML的语言,用于描述不同的地理信息。关于KML的更多信息,请参见http://en.wikipedia.org/wiki/Keyhole_Markup_LanguageKML图层允许向地图加载来自于本地或者基于网络的KML文件。

指定图层的数据源

可以为Layers集合中的每一个图层指定RecordSource属性(一个SQL表达式)。如果将其省略,则图层(除了KML图层外)将会从其父报表获取数据(按照当前的分组范围进行过滤)。如果指定了该属性,则会基于父报表的连接字符串使用该RecordSource属性。
目标跟踪
由Map字段显示的地图可以自动地按照显示在地图上的数据将地图居中并缩放。该行为由以下两个因素决定:
为整个Map字段指定的AutoCenter以及AutoZoom属性的值,以及其他相关的属性将微调自动居中和缩放
(AutoZoomPadLon,AutoZoomPadLat,MaxAutoZoom,RoundAutoZoom)。
空间坐标数据由图层呈现,表示该数据被"追踪"。目标跟踪(比如是否一个特定的空间坐标数据片段应当用做自动居中以及缩放)由图层的Track属性来决定。此外,对于KML图层,也可以指定一个表达式,表示是否追踪某一个特定的KML元素。
样式
地图元素的可视属性大部分由样式定义。有以下几种不同的样式类型(点标记样式、线形样式以及KML项目样式);可用的样式由上下文决定,比方说标点图层将使用点标记样式,画线层使用线形样式等等。通常一个样式可以被指定为一个数据驱动的表达式(因此实际的样式将由运行时数据决定),同时也存在一个默认的备用样式。下面将具体说说如何指定样式表达式以及表达式如何求值。
Map自定义字段包含三个样式集合:
MarkerStyles
LineStyles
KmlItemStyles
这些样式可用于该Map上定义的其他图层,同样也可以用于当前报表的其他Map字段。每一个集合中的样式不仅可以按照下标索引获取,更好的办法是通过名称查找(通过Name属性)。当一个样式表达式计算出一个字符串,该字符串将被用做搜索匹配的样式。首先将在当前的地图中搜索,如果搜索失败,则将在当前报表的其他地图字段中进行搜索(仅匹配同类的样式;比方说,对于点标记样式,仅搜索各个MarkerStyles集合,其他样式也一样)。
空间坐标位置标点层和画线层为数据指定空间坐标位置提供了两种不同的方式:做为一个可以在运行时计算为一个经度/纬度值对的表达式对。通常将直接引用存储在数据源中相应的字段(经度和纬度)。
作为一个MapLocation指定,MapLocation指的是一个表达式(或者一个表达式的列表),可以计算出一个字符串,该字符串可以通过外部在线服务(谷歌地图)获取相应的空间坐标位置。如果指定的MapLocation中包含分号,则它将被处理为一个用分号分隔的表达式列表,每一个表达式将分别求值然后结合在一起用做查询。一个典型的MapLocation将类似于如下格式:
"Address;City;PostalCode;Country"
这将从数据源获取Address,City,PostalCode,以及Country字段,并结合在一起通过外部服务进行查询。
请注意由于网络访问速度的影响,使用MapLocation可能会是一个比较耗时的操作。因此在缺省情况下获取到的空间坐标数据将保存在一个本地的磁盘文件中。该文件的路径由Map.GeoCachePath属性指定。默认情况下,该文件名为"geocache.xml",位于报表定义文件同样的目录下。不建议禁用地理信息缓存功能。
标点层
标点层用来显示点位置的标记,数据源每一条记录将显示为一个标记。像上一章节提到的那样,标记的位置可以由一个经纬度值或者由一个MapLocation指定。下面几点是标点层的重点。
数据访问:在运行时处理标点层时,报表的数据源(图层自己的RecordSource,或者在未指定该属性时,由当前的分组筛选的报表记录源)将被挨个遍历,将为每一个数据记录绘制一个标记。
视觉样式:点标记的外观由应用的标记样式决定。标点层提供一个默认的MarkerStyle,用做指定标记的形状、颜色等等。此外,可以为MarkerStyleExpr属性指定一个表达式,这样的话,在运行时将使用每一个数据记录计算这个表达式,如果计算的结果匹配当前地图的MarkerStyles集合中的标记样式,如果查找不到,也会尝试匹配当前报表中的其他地图,匹配到的样式将替代默认样式。(如同前面所提到的那样,样式表达式将计算出一个用做在样式集合中匹配的字符串。) 聚类:当几个点标记的位置相互靠近彼此的时候,它们可以被"聚"在一起成为一个单一的标记。该标记始终显示其表示的聚类在一起的点标记的数量。聚类标记的视觉样式和普通点标记有所不同,并且可能会根据其表示的点的多少有所区别。聚类样式由标点层的ClusterStyles集合指定,如果提供了多个样式,则特定的样式由聚合点的尺寸决定。相关的标点层属性有:ClusterDistance,ClusterDistribution以及ClusterStyles。
追踪:如果Track属性设置为True,则自动居中和缩放将包含图层中全部的点。
画线层
画线层用于在地图上的点之间绘制直线,一条直线连接表示数据记录的两个点。每一个点的空间坐标位置和标点层指定的方式一样:要么使用两个经纬度值对(每一个经纬度值表示直线的一个端点),要么使用两个MapLocation用于从网络服务获取坐标位置。以下几点描述了画线层的几个重要概念:
数据访问:和标点层一样,画线层允许指定其自己的RecordSource,或者使用经过当前分组筛选的报表数据记录。
视觉样式:关于样式的处理过程大体和标点层保持一致,唯一不同的是,这里将使用LineStyles集合而不是
MarkerStyles集合。
追踪:如果Track属性设置为True,则自动居中和缩放将包含图层中全部的线。

  • 无标签