表达式经常用于报表来控制内容和报表外观。 表达式是在 Microsoft Visual Basic 中编写的,可以使用内置函数、自定义代码、报表和组变量以及用户定义的变量。 表达式通常以等号 (=) 开头。 有关表达式编辑器和可包含的引用类型的详细信息,请参阅报表中的表达式使用(报表生成器和 SSRS),以及添加表达式(报表生成器和 SSRS)。
重要
启用 RDL 沙盒后,在报表发布时,只能在表达式文本中使用某些类型和成员。 有关详细信息,请参阅 “启用和禁用 RDL 沙盒”。
本主题提供可用于报表中常见任务的表达式示例。
Visual Basic 函数 日期、字符串、转换和条件 Visual Basic 函数的示例。
报表函数 聚合和其他内置报表函数的示例。
报表数据的外观 更改报表外观的示例。
性能 用于设置报表项属性以控制格式或可见性的示例。
参数 在表达式中使用参数的示例。
自定义代码 嵌入式自定义代码的示例。
有关特定用途的表达式示例,请参阅以下主题:
有关简单和复杂表达式的信息,表达式可用于何处,以及表达式中可以包含哪些引用类型,请参阅报表生成器和 SSRS下的主题“表达式”。 有关用于计算聚合的表达式的上下文的详细信息,请参阅总计、聚合和内置集合的表达式范围(报表生成器和 SSRS)。
若要了解如何编写使用本主题中表达式示例也使用的许多函数和运算符的表达式,但在编写报表的上下文中,请参阅 教程:表达式简介。
表达式编辑器包含内置函数的分层视图。 选择函数时,“值”窗格中会显示一个代码示例。 有关详细信息,请参阅“表达式”对话框或“表达式”对话框(报表生成器)。
功能
报表中的许多表达式都包含函数。 可以使用这些函数设置数据的格式、应用逻辑和访问报表元数据。 可以编写表达式,这些表达式使用 Microsoft Visual Basic 运行时库和命名空间中的ConvertMath函数。 您可以从其他程序集或自定义代码中向函数添加引用。 还可以使用 Microsoft .NET Framework 中的类,包括 System.Text.RegularExpressions。
Visual Basic 函数
可以使用 Visual Basic 函数来处理文本框中显示的数据或用作参数、属性或报表其他部分的数据。 本部分举例说明了其中的一些函数。 有关详细信息,请参阅 Visual Basic Runtime Library Members (Visual Basic 运行时库成员)。
.NET Framework 提供许多自定义格式选项,例如,特定日期格式。 有关详细信息,请参阅 MSDN 上的 格式设置类型 。
数学函数
- 该
Round函数可用于将数字舍入到最接近的整数。 以下表达式将 1.3 舍入为 1:
= Round(1.3)
还可以编写表达式,将值舍入到指定的倍数,类似于 MRound Excel 中的函数。 将数值乘以一个使其变为整数的倍数,舍入该整数,然后再除以相同的倍数。 例如,若要将 1.3 舍入到最接近的 .2(1.4)倍数,请使用以下表达式:
= Round(1.3*5)/5
日期函数
- 该
Today函数提供当前日期。 此表达式可用于在文本框中显示报表上的日期,或在参数中根据当前日期筛选数据。
=Today()
- 该
DateAdd函数可用于提供基于单个参数的日期范围。 以下表达式提供一个日期,该日期位于名为 StartDate 参数的六个月之后。
=DateAdd(DateInterval.Month, 6, Parameters!StartDate.Value)
- 该
Year函数显示特定日期的年份。 可以使用此选项将日期组合在一起,或将年份显示为一组日期的标签。 此表达式可以提供一组给定的销售订单日期的年份。 函数Month和其他函数还可用于处理日期。 有关详细信息,请参阅 Visual Basic 文档。
=Year(Fields!OrderDate.Value)
- 您可以在表达式中组合函数,以自定义格式。 下面的表达式将“月-日-年”的日期格式更改为“月-周-周数”。 例如,2009 年 12 月 23 日到 12 月 3 周:
=Format(Fields!MyDate.Value, "MMMM") & " Week " &
(Int(DateDiff("d", DateSerial(Year(Fields!MyDate.Value),
Month(Fields!MyDate.Value),1), Fields!FullDateAlternateKey.Value)/7)+1).ToString
当此表达式在数据集中用作计算字段时,您可以在图表上使用该表达式来按每个月内的周聚合值。
- 以下表达式将 SellStartDate 值的格式设置为 MMM-YY。 SellStartDate 字段是日期时间数据类型。
=FORMAT(Fields!SellStartDate.Value, "MMM-yy")
- 以下表达式将 SellStartDate 值的格式设置为 dd/MM/yyyy。 SellStartDate 字段是日期时间数据类型。
=FORMAT(Fields!SellStartDate.Value, "dd/MM/yyyy")
- 该
CDate函数将值转换为日期。 该Now函数根据系统返回包含当前日期和时间的日期值。DateDiff返回一个 Long 值,该值指定两个 Date 值之间的时间间隔数。
以下示例显示当前年份的开始日期
=DateAdd(DateInterval.Year,DateDiff(DateInterval.Year,CDate("01/01/1900"),Now()),CDate("01/01/1900"))
- 以下示例根据当前月份显示上一个月的开始日期。
=DateAdd(DateInterval.Month,DateDiff(DateInterval.Month,CDate("01/01/1900"),Now())-1,CDate("01/01/1900"))
- 以下表达式生成介于 SellStartDate 和 LastReceiptDate 之间的间隔年。 这些字段在两个不同的数据集内,即 DataSet1 和 DataSet2。 First 函数(报表生成器和 SSRS)是一个聚合函数,它返回 DataSet1 中 SellStartDate 的第一个值和 DataSet2 中 LastReceiptDate 的第一个值。
=DATEDIFF("yyyy", First(Fields!SellStartDate.Value, "DataSet1"), First(Fields!LastReceiptDate.Value, "DataSet2"))
- 该
DatePart函数返回一个 Integer 值,该值包含给定日期值的指定组件。以下表达式返回 DataSet1 中 SellStartDate 的第一个值的年份。 由于报表中有多个数据集,因此指定了数据集范围。
=Datepart("yyyy", First(Fields!SellStartDate.Value, "DataSet1"))
- 该
DateSerial函数返回一个 Date 值,该值代表指定的年份、月和日,时间信息设置为午夜。 以下示例根据当前月份显示前一个月的结束日期。
=DateSerial(Year(Now()), Month(Now()), "1").AddDays(-1)
- 以下表达式根据用户选择的日期参数值显示各种日期。
| 示例说明 | 示例: |
|---|---|
| 昨天 | =DateSerial(Year(Parameters!TodaysDate.Value),Month(Parameters!TodaysDate.Value),Day(Parameters!TodaysDate.Value)-1) |
| 两天前 | =DateSerial(Year(Parameters!TodaysDate.Value),Month(Parameters!TodaysDate.Value),Day(Parameters!TodaysDate.Value)-2) |
| 一个月前 | =DateSerial(Year(Parameters!TodaysDate.Value),Month(Parameters!TodaysDate.Value)-1,Day(Parameters!TodaysDate.Value)) |
| 两个月前 | =DateSerial(Year(Parameters!TodaysDate.Value),Month(Parameters!TodaysDate.Value)-2,Day(Parameters!TodaysDate.Value)) |
| 一年前 | =DateSerial(Year(Parameters!TodaysDate.Value)-1,Month(Parameters!TodaysDate.Value),Day(Parameters!TodaysDate.Value)) |
| 两年前 | =DateSerial(Year(Parameters!TodaysDate.Value)-2,Month(Parameters!TodaysDate.Value),Day(Parameters!TodaysDate.Value)) |
字符串函数
- 通过使用连接运算符和 Visual Basic 常量组合多个字段。 以下表达式返回两个字段,它们分别位于同一文本框的不同行中:
=Fields!FirstName.Value & vbCrLf & Fields!LastName.Value
- 使用
Format函数设置字符串中的日期和数字的格式。 下面的表达式以长日期格式显示 StartDate 和 EndDate 参数的值:
=Format(Parameters!StartDate.Value, "D") & " through " & Format(Parameters!EndDate.Value, "D")
如果文本框仅包含日期或数字,则应使用文本框的 Format 属性应用格式设置,而不是文本框中的 Format 函数。
- 和
RightLenInStr函数可用于返回子字符串,例如,仅将 DOMAIN\用户名剪裁为用户名。 以下表达式将字符串的一部分返回到名为 User 的参数的反斜杠 (\) 字符的右侧:
=Right(Parameters!User.Value, Len(Parameters!User.Value) - InStr(Parameters!User.Value, "\"))
以下表达式与前一个表达式的结果相同,使用 .NET Framework String 类的成员而不是 Visual Basic 函数:
=Parameters!User.Value.Substring(Parameters!User.Value.IndexOf("\")+1, Parameters!User.Value.Length-Parameters!User.Value.IndexOf("\")-1)
- 显示多值参数的所选值。 以下示例使用函数将
Join参数 MySelection 的选定值连接到单个字符串中,该字符串可以设置为报表项中文本框的值的表达式:
= Join(Parameters!MySelection.Value)
以下示例与上面的示例相同,在所选值列表之前显示文本字符串。
="Report for " & JOIN(Parameters!MySelection.Value, " & ")
-
Regex.NET Framework System.Text.RegularExpressions 中的函数可用于更改现有字符串的格式,例如设置电话号码的格式。 以下表达式使用Replace函数将字段中十位电话号码的格式从“nnn nnn- nnnn”更改为“(nnn-) nnn-nnnn”:
=System.Text.RegularExpressions.Regex.Replace(Fields!Phone.Value, "(\d{3})[ -.]*(\d{3})[ -.]*(\d{4})", "($1) $2-$3")
注释
验证 Fields!Phone.Value 的值没有多余的空格并且类型为 String。
查找
- 通过指定键字段,可以使用
Lookup函数从数据集中检索一对一关系的值,例如键值对。 鉴于要匹配的产品标识符,以下表达式显示数据集(“Product”)中的产品名称:
=Lookup(Fields!PID.Value, Fields!ProductID.Value, Fields!ProductName.Value, "Product")
LookupSet
- 通过指定键字段,可以使用
LookupSet函数从数据集检索一对多关系的一组值。 例如,一个人可以有多个电话号码。 在下面的示例中,假定数据集 PhoneList 在每一行中包含一个人员标识符和电话号码。LookupSet返回一个值数组。 以下表达式将返回值合并为单个字符串,并显示 ContactID 指定的人员的电话号码列表:
=Join(LookupSet(Fields!ContactID.Value, Fields!PersonID.Value, Fields!PhoneNumber.Value, "PhoneList"),",")
转换函数
可以使用 Visual Basic 函数将字段从一种数据类型转换为另一种数据类型。 转换函数可用于将字段的默认数据类型转换为计算所需的数据类型或合并文本。
- 下面的表达式将常量 500 转换为类型 Decimal,以便将其与筛选器表达式的 Value 字段中的 Transact-SQL money 数据类型进行比较。
=CDec(500)
- 以下表达式显示为多值参数 MySelection 选择的值数。
=CStr(Parameters!MySelection.Count)
决策函数
- 该
Iif函数会返回两个值之一,具体取决于表达式是否为真。 下面的表达式使用Iif函数返回一个布尔值True(如果值LineTotal超过 100)。 否则返回False:
=IIF(Fields!LineTotal.Value > 100, True, False)
- 使用多个
IIF函数(也称为“嵌套 IIF”)根据PctComplete的值返回三个值中的一个。 可以将以下表达式置于文本框的填充颜色中,以根据文本框中的值更改背景色。
=IIF(Fields!PctComplete.Value >= 10, "Green", IIF(Fields!PctComplete.Value >= 1, "Blue", "Red"))
大于或等于 10 的值显示为绿色背景,值在 1 和 9 之间的显示为蓝色背景,小于 1 的值显示为红色背景。
- 获取相同功能的不同方法使用函数
Switch。 当你有三个或更多条件进行测试时,该Switch函数非常有用。 该Switch函数返回与序列中第一个表达式关联的值,该表达式的计算结果为 true:
=Switch(Fields!PctComplete.Value >= 10, "Green", Fields!PctComplete.Value >= 1, "Blue", Fields!PctComplete.Value = 1, "Yellow", Fields!PctComplete.Value <= 0, "Red",)
大于或等于 10 的值显示为绿色背景,1 到 9 之间的值显示为蓝色背景,等于 1 的值显示为黄色背景,小于或等于 0 的值显示为红色背景。
- 测试字段的值
ImportantDate,如果字段超过一周,则返回“Red”,否则返回“Blue”。 此表达式可用于控制报表项中文本框的颜色属性:
=IIF(DateDiff("d",Fields!ImportantDate.Value, Now())>7,"Red","Blue")
- 测试
PhoneNumber字段的值,如果值为null(在 Visual Basic 中为Nothing),则返回“无值”;否则返回电话号码值。 此表达式可用于控制报表项中的文本框的值。
=IIF(Fields!PhoneNumber.Value Is Nothing,"No Value",Fields!PhoneNumber.Value)
- 测试
Department字段的值,并返回一个子报表名称或null(在 Visual Basic 中为Nothing)。 此表达式可用于条件钻取子报表。
=IIF(Fields!Department.Value = "Development", "EmployeeReport", Nothing)
- 测试字段值是否为 null。 此表达式可用于控制
Hidden图像报表项的属性。 在以下示例中,仅当字段的值不为 null 时,字段 [LargePhoto] 指定的图像才会显示。
=IIF(IsNothing(Fields!LargePhoto.Value),True,False)
- 该
MonthName函数返回一个字符串值,该值包含指定月份的名称。 以下示例会在“月份”字段中显示“NA”,当该字段的值为 0 时。
IIF(Fields!Month.Value=0,"NA",MonthName(IIF(Fields!Month.Value=0,1,Fields!Month.Value)))
报告功能
在表达式中,可以添加引用额外的报表函数来处理报表中的数据。 本部分举例说明了其中两个函数。 有关报表函数和示例的详细信息,请参阅聚合函数参考(报表生成器和 SSRS)。
总和
- 该
Sum函数可以汇总组或数据区域中的值。 此函数在组的组头或组尾中非常有用。 下面的表达式显示 Order 组或数据区域中的数据之和:
=Sum(Fields!LineTotal.Value, "Order")
- 还可以将
Sum函数用于条件聚合计算。 例如,如果数据集具有名为 State 的字段,其可能值为“未启动”、“已启动”、“已完成”,则放置在组标头中时,以下表达式仅计算已完成值的聚合总和:
=Sum(IIF(Fields!State.Value = "Finished", 1, 0))
行号
- 该
RowNumber函数在数据区域中的文本框中使用时,显示表达式所在的文本框的每个实例的行号。 此函数可用于为表中的各行编号。 还可以用于更复杂的情况,如根据行数插入分页符。 有关详细信息,请参阅本主题中的 分页符 。
您为 RowNumber 指定的范围控制重新编号开始的时间。 关键字 Nothing 指示该函数将在最外层数据区域中的第一行开始计数。 若要在嵌套数据区域中开始计数,可使用该数据区域的名称。 若要开始在组中计数,请使用组的名称。
=RowNumber(Nothing)
报表数据的外观
您可以使用表达式来控制数据在报表中的显示形式。 例如,可以在一个文本框中显示两个字段的值,显示报表的相关信息,或设置报表中分页符的插入方式。
页眉和页脚
设计报表时,可能需要在报表页脚中显示报表的名称和页码。 为此,可以使用以下表达式:
- 下面的表达式提供报表的名称及其运行时间。 可以将该表达式放置在报表表尾或表体的文本框中。 使用用于短日期的 .NET Framework 格式字符串来格式化时间:
=Globals.ReportName & ", dated " & Format(Globals.ExecutionTime, "d")
- 下面的表达式放置在报表表尾的文本框中,提供报表的页码和总页数:
=Globals.PageNumber & " of " & Globals.TotalPages
下面的示例说明如何在表头中显示页面中的第一个值和最后一个值,类似于目录列表的形式。 该示例假定数据区域包含一个名为LastName的文本框。
- 以下表达式位于页面页眉左侧的文本框中,提供页面上文本框的第一个值
LastName:
=First(ReportItems("LastName").Value)
- 以下表达式位于页面页眉右侧的文本框中,提供页面上文本框的最后一个值
LastName:
=Last(ReportItems("LastName").Value)
下面的示例说明如何显示页总页数。 该示例假定数据区域包含一个名为Cost的文本框。
- 位于页眉或页脚中的以下表达式提供页面文本框中的值
Cost的总和:
=Sum(ReportItems("Cost").Value)
注释
对于表头或表尾中的每个表达式,只能引用一个报表项。 还可以引用表头和表尾表达式中的文本框名称,但不能引用文本框中的实际数据表达式。
分页符
在某些报表中,你可能希望在指定数量行的末尾插入分页符,而不仅仅在组或报表项中插入分页符。 为此,请创建一个组,其中包含所需的组或详细信息记录,向组添加分页符,然后将组表达式添加到按指定的行数进行分组。
- 下面的表达式放置在组表达式中,为每 25 行指定一个编号。 为组定义分页符时,此表达式每 25 行产生分页符。
=Ceiling(RowNumber(Nothing)/25)
若要允许用户为每页的行数设置值,请创建一个名为 RowsPerPage 的参数,并基于此参数设置组表达式,如以下表达式所示:
=Ceiling(RowNumber(Nothing)/Parameters!RowsPerPage.Value)
有关如何为组设置分页符的更多信息,请参阅添加分页符(报表生成器和 SSRS)。
性能
表达式不仅用于在文本框中显示数据。 还可以用于更改将属性应用于报表项的方式。 您可以更改报表项的样式信息,或更改其可见性。
格式化
- 以下表达式在文本框的 Color 属性中使用时,会根据字段的值
Profit更改文本的颜色:
=Iif(Fields!Profit.Value < 0, "Red", "Black")
此外,还可以使用 Visual Basic 对象变量 Me。 此变量是另一种引用文本框的值的方法。
=Iif(Me.Value < 0, "Red", "Black")
- 以下表达式用于数据区域中的报表项的 BackgroundColor 属性时,会使每行的背景颜色在浅绿色和白色之间交替变化:
=Iif(RowNumber(Nothing) Mod 2, "PaleGreen", "White")
如果对指定范围使用表达式,则可能需要指示聚合函数的数据集:
=Iif(RowNumber("Employees") Mod 2, "PaleGreen", "White")
注释
可使用的颜色来自 .NET Framework KnownColor 枚举。
图表颜色
若要指定形状图表的颜色,可以使用自定义代码来控制颜色映射到数据点值的顺序。 这有助于对具有相同类别组的多个图表使用一致的颜色。 有关详细信息,请参阅对多个形状图指定一致的颜色(报表生成器和 SSRS)。
能见度
您可以使用报表项的可见性属性来显示和隐藏报表中的项。 在诸如表的数据区域中,可以根据表达式中的值在一开始隐藏详细信息行。
- 以下表达式在用于组中详细信息行的初始可见性时,显示
PctQuota字段中所有销售额超过90%的详细信息行:
=Iif(Fields!PctQuota.Value>.9, False, True)
- 在表的 Hidden 属性中设置时,以下表达式仅在表的行数超过 12 行时显示该表:
=IIF(CountRows()>12,false,true)
- 在列属性中
Hidden设置的以下表达式仅在从数据源检索数据后报表数据集中存在字段时才显示该列:
=IIF(Fields!Column_1.IsMissing, true, false)
网址
可以使用报表数据自定义 URL,还可以有条件地控制是否将 URL 添加为对文本框的操作。
- 以下表达式用作文本框的作时,将生成一个自定义 URL,该 URL 将数据集字段
EmployeeID指定为 URL 参数。
="http://adventure-works/MyInfo?ID=" & Fields!EmployeeID.Value
有关详细信息,请参阅向 URL 添加超链接(报表生成器和 SSRS)。
- 下面的表达式可以有条件地控制是否要在文本框中添加 URL。 此表达式取决于一个名为
IncludeURLs的参数,该参数允许用户决定是否在报表中包含活动 URL。 此表达式设置为一个对文本框的操作。 通过将参数设置为 False,然后查看报表,您可以将报表导出至 Microsoft Excel,并且不包含超链接。
=IIF(Parameters!IncludeURLs.Value,"http://adventure-works.com/productcatalog",Nothing)
报表数据
您可使用表达式来处理报表中所使用的数据。 可以引用参数和其他报表信息。 甚至可以更改用于检索报表数据的查询。
参数
您可以在参数中使用表达式来更改参数的默认值。 例如,可以根据用于运行报表的用户 ID,使用参数来筛选某个特定用户的数据。
- 下面的表达式如果用作参数的默认值,可以收集运行报表的用户的 ID:
=User!UserID
- 若要引用查询参数、筛选器表达式、文本框或其他报表区域中的参数,请使用
Parameters全局集合。 此示例假定参数的名称为 Department:
=Parameters!Department.Value
- 可在报表中创建参数,但需要设置为隐藏。 报表在报表服务器上运行时,参数不会显示在工具栏中,报表读取器无法更改默认值。 您可以将设置为默认值的隐藏参数用作自定义常量。 可以在任何表达式中使用此值,包括字段表达式。 下面的表达式标识由 ParameterField参数的默认参数值指定的字段:
=Fields(Parameters!ParameterField.Value).Value
自定义代码
您可以在报表中使用自定义代码。 自定义代码可以嵌入到报表中或存储在用于报表的自定义程序集。 有关自定义代码的详细信息,请参阅 报表设计器(SSRS)中的表达式中的自定义代码和程序集引用。
将组变量用于自定义聚合
您可以初始化特定组作用域的本地组变量的值,然后在表达式中包含对该变量的引用。 可以将组变量和自定义代码一起使用的方法之一是实现自定义聚合。 有关详细信息,请参阅 Reporting Services 2008 中用于自定义聚合的组变量。
有关变量的详细信息,请参阅报表和组变量集合引用(报表生成器和 SSRS)。
在运行时隐藏空值或零值
处理报表时,表达式中某些值的计算结果可能为 Null 值或未定义。 这可以创建运行时错误,导致 #Error 在文本框中显示,而不是计算表达式。 该IIF函数对此行为特别敏感,因为与 If-Then-Else 语句不同,在传递给测试true或false的例程之前,会评估IIF语句的每个部分(包括函数调用)。 如果Fields!Sales.Value为 NOTHING,则语句=IIF(Fields!Sales.Value is NOTHING, 0, Fields!Sales.Value)将在生成的报表中呈现 #Error。
若要避免此情况,请使用以下策略之一:
- 如果字段 B 的值为 0 或未定义,则将分子设置为 0,将分母设置为 1;否则,将分子设置为字段 A 的值,将分母设置为字段 B 的值。
=IIF(Field!B.Value=0, 0, Field!A.Value / IIF(Field!B.Value =0, 1, Field!B.Value))
- 使用自定义代码函数返回表达式的值。 下面的示例返回当前值和先前值之间的百分比差异。 这可用于计算任意两个连续值之间的差异,并处理首次比较的边界情况(即没有前一个值的情况),以及处理无论是前一个值还是当前值为
null的情况(在 Visual Basic 中为Nothing)。
Public Function GetDeltaPercentage(ByVal PreviousValue, ByVal CurrentValue) As Object
If IsNothing(PreviousValue) OR IsNothing(CurrentValue) Then
Return Nothing
Else if PreviousValue = 0 OR CurrentValue = 0 Then
Return Nothing
Else
Return (CurrentValue - PreviousValue) / CurrentValue
End If
End Function
以下表达式演示如何从文本框调用此自定义代码,以用于“ColumnGroupByYear”容器(组或数据区域)。
=Code.GetDeltaPercentage(Previous(Sum(Fields!Sales.Value),"ColumnGroupByYear"), Sum(Fields!Sales.Value))
这有助于避免运行时异常。 现在,可以使用类似于文本框属性中的表达式=IIF(Me.Value < 0, "red", "black")Color根据值是否大于或小于 0 有条件地显示文本。