导航

SSRS 表达式

Posted on 2011-12-17 10:58  Rainbow.ding  阅读(8483)  评论(1编辑  收藏  举报
表达式示例(Report Builder 3.0 和 SSRS)

表达式通常在报表中使用,以控制报表的内容和外观。表达式以 MicrosoftVisual Basic 编写,可以使用内置函数、自定义代码、报表变量和组变量以及用户定义的变量。表达式通常以等号 (=) 开头。有关表达式编辑器和可以包括的引用类型详细信息,请参阅使用表达式(Report Builder 3.0 和 SSRS)如何添加表达式(Report Builder 3.0 和 SSRS)

本主题提供了一些可用于报表中常见任务的表达式的示例。

有关特定用途的表达式示例,请参阅以下主题:

有关简单表达式和复杂表达式、使用表达式的位置、以及表达式中可以包含的引用类型的详细信息,请参阅表达式(Report Builder 3.0 和 SSRS)下的主题。有关计算聚合计算表达式时所处上下文的详细信息,请参阅了解总计、聚合和内置集合的表达式作用域(Report Builder 3.0 和 SSRS)

若要了解如何编写使用许多本主题中的表达式示例也使用的函数和运算符的表达式,请参阅教程:表达式简介

表达式编辑器还包含内置函数的层次结构视图。选择函数时,“值”窗格中会显示代码示例。有关详细信息,请参阅“表达式”对话框“表达式”对话框 (Report Builder 3.0)

如果您使用报表模型查询设计器来设计使用报表模型作为数据源的数据集查询,则将使用公式而不是表达式。这些公式通过使用已集成到特定查询(指定要从报表模型数据源返回的数据)中的自定义计算,帮助指定报表数据。有关详细信息,请参阅在报表模型查询中使用公式(Report Builder 3.0 和 SSRS)

注意注意

在 Business Intelligence Development Studio 中,您可以在 Report Builder 3.0 和报表设计器中创建和修改报表定义 (.rdl)。每个创作环境提供了不同的方式来创建、打开和保存报表和相关项。有关详细信息,请参阅 Web 上 microsoft.com 中的“在报表设计器和 Report Builder 3.0 中设计报表 (SSRS)”。

函数

报表中的许多表达式都包含函数。您可以使用这些函数来设置数据格式、应用逻辑和访问报表元数据。您可以编写使用 MicrosoftVisual Basic 运行时库、System..::..Convert 和 System..::..Math 命名空间中的函数的表达式。您可以从其他程序集或自定义代码中向函数添加引用。还可以使用 Microsoft.NET Framework 中的类,其中包括 System.Text.RegularExpressions

Visual Basic 函数

您可以使用 Visual Basic 函数来处理文本框中所显示的数据,或者处理参数、属性或报表其他区域中所用的数据。本部分举例说明了其中的一些函数。有关详细信息,请参阅 MSDN 上的 Visual Basic 运行时库成员

.NET Framework 提供了很多自定义格式选项,例如,特定日期格式。有关详细信息,请参阅 MSDN 上的格式化类型

数学函数

  • Round 函数可用于将数字舍入为最接近的整数。下面的表达式将 1.3 舍入为 1:

    = Round(1.3)

    您也可以编写表达式以将某个值舍入到您指定的倍数,类似于 Excel 中的 MRound 函数。用某个生成整数的因子乘以该值,对数字进行舍入,然后除以同一因子。例如,若要将 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)
  • 您可以在表达式中组合函数,以自定义格式。下面的表达式将“月-日-年”的日期格式更改为“月-周-周数”。例如,将“12/23/2009”更改为“December Week 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

    当此表达式在数据集中用作计算字段时,您可以在图表上使用该表达式来按每个月内的周聚合值。

字符串函数

  • 使用串联运算符和 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 函数。

  • RightLen 和 InStr 函数可用于返回子字符串,例如,修整 DOMAIN\username 以便仅返回用户名。下面的表达式从名为 User 的参数返回反斜杠 (\) 字符右侧的字符串部分:

    =Right(Parameters!User.Value, Len(Parameters!User.Value) - InStr(Parameters!User.Value, "\"))

    下面的表达式使用 .NET FrameworkSystem..::..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)
  • .NET FrameworkSystem.Text.RegularExpressions 中的 Regex 函数对更改现有字符串的格式很有用,例如设置电话号码格式。下面的表达式使用 Replace 函数,将字段中的 10 位电话号码格式从“nnn-nnn-nnnn”更改为“(nnnnnn-nnnn”:

    =System.Text.RegularExpressions.Regex.Replace(Fields!Phone.Value, "(\d{3})[ -.]*(\d{3})[ -.]*(\d{4})", "($1) $2-$3")
    注意注意

    验证 Fields!Phone.Value 的值没有多余的空格并且类型为 String

查找

  • 通过指定键字段,您可以使用 Lookup 函数为一对一关系(例如键值对)从数据集检索值。下面的表达式显示来自数据集的产品名称,给出了用于进行匹配的产品标识符:

    =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 函数可根据表达式的计算结果(True 或 False)返回两个值中的一个。下面的表达式使用 Iif 函数在LineTotal的值超过 100 时返回布尔值 True。否则,它将返回 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”。此表达式可用于控制报表项中的文本框的 Color 属性:

    =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)
  • 测试字段值是否为空。此表达式可用于控制图像报表项的 Hidden 属性。在下面的示例中,字段 [LargePhoto] 指定的图像仅当字段值非空时才会显示。

    =IIF(IsNothing(Fields!LargePhoto.Value),True,False)

报表函数

在表达式中,您可以添加对在报表中操作数据的其他报表函数的引用。本部分举例说明了其中两个函数。有关报表函数和示例的详细信息,请参阅聚合函数引用(Report Builder 3.0 和 SSRS)

Sum

  • Sum 函数可以对某个组或数据区域中的值求和。此函数在组的组头或组尾中非常有用。下面的表达式显示 Order 组或数据区域中的数据之和:

    =Sum(Fields!LineTotal.Value, "Order")
  • 还可以使用 Sum 函数进行条件聚合计算。例如,如果数据集包含名为 State 的字段,其可能的值为 Not Started、Started、Finished,则将下列表达式放置在组头中时将只计算 Finished 值的聚合总数。

    =Sum(IIF(Fields!State.Value = "Finished", 1, 0))

RowNumber

  • 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)

    有关为组设置分页符的详细信息,请参阅如何添加分页符(Report Builder 3.0 和 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 FrameworkKnownColor 枚举的可用颜色。

图表颜色

若要指定形状图的颜色,可以使用自定义代码控制颜色映射为数据点值的顺序。这有助于您对具有相同类别组的多个图表使用一致的颜色。有关详细信息,请参阅如何跨多个形状图指定一致的颜色(Report Builder 3.0 和 SSRS)

可见性

您可以使用报表项的可见性属性来显示和隐藏报表中的项。在诸如表的数据区域中,可以根据表达式中的值在一开始隐藏详细信息行。

  • 如果下面的表达式用于组中详细信息行的初始可见性,则可以在PctQuota字段中显示超过 90% 的所有销售的详细信息行:

    =Iif(Fields!PctQuota.Value>.9, False, True)
  • 如果在表的 Hidden 属性中设置下面的表达式,则仅当该表多于 12 行时才会显示:

    =IIF(CountRows()>12,true,false)
  • 如果在列的 Hidden 属性中设置下面的表达式,则仅当从数据源完成数据检索后,该字段存在于报表数据集中时才显示该列:

    =IIF(Fields!Column_1.IsMissing, true, false)

URL

可以使用报表数据自定义 URL,还可以有条件地控制是否将 URL 添加为对文本框的操作。

  • 如果将下面的表达式用作对文本框的操作,则可以生成一个自定义 URL,它可将数据集字段EmployeeID指定为 URL 参数。

    ="http://adventure-works/MyInfo?ID=" & Fields!EmployeeID.Value

    有关详细信息,请参阅如何向 URL 添加超链接(Report Builder 3.0 和 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)

  • 下面的示例调用名为 ToUSD 的嵌入代码方法,该方法可将StandardCost字段值转换为美元值:

    =Code.ToUSD(Fields!StandardCost.Value)
  • 下面的示例显示如何定义某些自定义常量和变量。

    [Visual Basic]

    Public Const MyNote = "Authored by Bob" Public Const NCopies As Int32 = 2 Public Dim  MyVersion As String = "123.456" Public Dim MyDoubleVersion As Double = 123.456

    尽管自定义常量和变量不会出现在“表达式编辑器常量”视图(仅显示内置常量)中,但是可以从任何表达式向其中添加引用,如下面的示例所示。这些引用被作为变量进行处理。

    [Visual Basic]

    =Code.MyNote =Code.NCopies  =Code.MyVersion =Code.MyDoubleVersion

使用组变量自定义聚合

您可以初始化特定组作用域的本地组变量的值,然后在表达式中包含对该变量的引用。可以将组变量和自定义代码一起使用的方法之一是实现自定义聚合。有关详细信息,请参阅 Using Group Variables in Reporting Services 2008 for Custom Aggregation(在 Reporting Services 2008 使用组变量自定义聚合)。

有关变量的详细信息,请参阅使用报表和组变量集合引用(Report Builder 3.0 和 SSRS)

替换运行时字段中的文本

下面的示例调用名为 FixSpelling 的嵌入方法,该方法可使用“Bicycle”替换SubCategory.Value中出现的所有“Bike”文本。

=Code.FixSpelling(Fields!SubCategory.Value)

下面的代码当嵌入报表定义时,可显示 FixSpelling 方法的实现。此示例演示如何引用 .NET FrameworkSystem.Text..::..StringBuilder 类。有关详细信息,请参阅如何向报表添加代码 (SSRS)

Public Function FixSpelling(ByVal s As String) As String    Dim strBuilder As New System.Text.StringBuilder(s)    If s.Contains("Bike") Then       strBuilder.Replace("Bike", "Bicycle")       Return strBuilder.ToString()       Else : Return s    End If End Function

取消运行时的 Null 值或零值

处理报表时,表达式中某些值的计算结果可能会为 Null 值或未定义。这将创建运行时错误,从而导致在文本框中显示 #Error,而不是计算后的表达式。IIF 函数对此行为特别敏感,因为它不同于 If-Then-Else 语句,IIF 语句的每一部分在传递到测试 true 或 false 的例程之前,都要进行计算(包括函数调用)。如果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

    下面的表达式演示如何从文本框调用此自定义代码:

    =Code.GetDeltaPercentage(Previous(Sum(Fields!Sales.Value),"ColumnGroupByYear"), Sum(Fields!Sales.Value))

    这样可以避免运行时异常。您现在可以在文本框的 Color 属性中使用类似=IIF(Me.Value < 0, "red", "black")的表达式,以便有条件地基于这些值是大于还是小于 0 来显示文本。