【问题标题】:SSRS Iif Evaluates True and FalseSSRS Iif 评估真假
【发布时间】:2019-12-16 05:51:25
【问题描述】:

MSDN 声明 SSRS 将评估 Iif 语句的真假部分,无论返回哪一个。这似乎使Iif 在避免错误方面完全无用。换句话说,您不能使用Iif 来绕过错误,因此基本上您选择包含的任何操作无论条件如何都必须始终有效。老实说,这有什么好处?

所以我的问题是......除了Iif 之外,SSRS 还有其他评估条件的方法吗?

这是我的例子。我只是希望能够在不抓住比赛的第一个字符的情况下返回 Left。

=Iif
(
    InStr(Fields!SearchField.Value, Fields!Criteria.Value) <= 1,    
    "",             
    Left(Fields!SearchField.Value, InStr(Fields!SearchField.Value, Fields!Criteria.Value)-1)                    
)

但是,这里发生的情况是 InStr(Fields!Criteria.Value, Fields!Criteria.Value)-1 在某些情况下评估为 0,这完全没问题,直到语句的 FALSE 部分尝试从中减去 1 并将其传递给 InStr 函数。 InStr 不能接受 -1 作为要返回的字符数。

对此的过度简化如下。假设您有一种情况,即 Value 永远不会低于 0 而不会引发错误。

Iif (Value > 0, Value = Value -1, 0)

尝试使用Iif 强制值不低于 0 不起作用,因为所有这些语句即使不满足条件也会被评估。

尝试使用InStr 获取匹配项的索引,而Left 基于该索引构建子字符串因此失败。我不知道如何完全避免这种情况。

【问题讨论】:

  • 我认为 SSRS 直到最近才使用短路布尔评估。 IIF() 是一个函数,所有表达式都在进行比较之前进行评估。您可以将表达式放在报告代码中并分配一个值,例如 Code.FormatWhenFoundOrEmpty(x,y)
  • 是我一个人,还是微软的这种做法极其短视?我的意思是,条件语句的整个想法是在满足条件时做某事,否则不做。值得注意的是,这是一个非常违反直觉的情况。遇到它我很惊讶。

标签: reporting-services iif


【解决方案1】:

我也认为Switch 会起作用,但经过测试却没有。据我所知,自定义代码是唯一的出路。我测试了下面的函数,它适用于我的几个测试用例。

Public Function TruncateWord(ByVal str As String, ByVal criteria As String) As String
If str.Contains(criteria) Then
    Return Left(str, InStr(str, criteria) - 1)
Else:
    Return ""
End If
End Function

我用以下5个基本字符串进行测试,搜索“d”,得到如下结果:

+-----------------+
| String | Result |
+-----------------+
| asdf   | as     |
| asd    | as     |
| as     |        |
| da     |        |
| ad     | a      |
+-----------------+

所以从我有限的测试来看,这似乎适用于所有 3 种可能的情况(InStr 返回 > 1,InStr 返回 1,InStr 返回 0)。

【讨论】:

  • 非常感谢。我认为这会奏效。我希望避免自定义代码,但如果这是唯一的方法,我肯定会走这条路。
【解决方案2】:

这是 C Black 建议使用自定义代码的最终结果。我最终希望使用字符串的段在相反的列中以不同的颜色格式化匹配。我不得不添加一些 html 标签。它完美地工作。谢谢大家的帮助。

代码块:

Public Function ParseMatch (ByVal FullString As String, ByVal Criteria As String) As String

    Dim Segment(2) As String
    Dim Result As String

    If FullString.ToUpper.Contains(Criteria.ToUpper)

        Segment(0) = Left(FullString, InStr(Ucase(FullString), Ucase(Criteria) )-1 )
        Segment(1) = Criteria
        Segment(2) = Right(FullString, Len(FullString) - Len(Segment(0)) - Len(Criteria))

        Result = Segment(0) & "<b><FONT color=blue>" & Segment(1) & "</FONT></b>" & Segment(2)

    Else
        Result = FullString
    End If

    Return Result

End Function

报告单元格:

=Code.ParseMatch(Fields!Defendants.Value, Fields!Firm_Client_Name.Value)

如果在被告名单中找到该姓名,则会将该字段中的文本涂成蓝色并加粗。

【讨论】:

    【解决方案3】:

    使用SWITCH

    SWITCH 在找到第一个 True 后立即停止计算表达式。 Switch 适用于对(一个要评估的表达式和一个结果,如果它是真的)。最后的True 就像else

    =SWITCH
    (
    InStr(Fields!SearchField.Value, Fields!Criteria.Value) <= 1, "",
    True, Left(Fields!SearchField.Value, InStr(Fields!Criteria.Value, Fields!Criteria.Value)-1)                   
    )
    

    【讨论】:

    • 谢谢,艾伦!我会尝试一下,看看我是否可以重新解决这个问题。
    • 实际上,这会产生完全相同的结果。我在上面进行了编辑,因为我的示例字段错误。不过,它们在真实代码中是正确的。同样的情况。它不会创建 "" 值并停在那里。
    • 我什至将条件明确定义为 InStr(Fields!SearchField.Value, Fields!Criteria.Value) > 1 No joy.
    • 以后有机会我会去看看的。你能为每个字段提供 2 或 3 个样本值吗
    • 见下文。谢谢。
    【解决方案4】:

    为了可读性,我重写了它:

    =Switch
    (
        InStr(Fields!Defendants.Value, Fields!Firm_Client_Name.Value) = 0, "",  
        InStr(Fields!Defendants.Value, Fields!Firm_Client_Name.Value) = 1, "",  
        True, Left(Fields!Defendants.Value, InStr(Fields!Defendants.Value, Fields!Firm_Client_Name.Value)-1)
    )
    

    ' 0 = 错误

    ' 1 =

    ' >1 = 基于条件的子字符串

    1 和 >1 是正确的,但是当 InStr 计算结果为 0 时我仍然得到错误。

    问题是,我必须告诉 Left 函数 -1 否则它将返回分隔符的第一个字母,这是我不想要的。即使 InStr(Fields!Defendants.Value, Fields!Firm_Client_Name.Value) = 0 的条件为真,但它不会为列返回“”,而是返回错误。这告诉我它仍在被评估,尽管它超出了指定的条件。

    如果我在 Left 函数中省略 -1,则不会产生错误。然而我得到子字符串+分隔符的第一个字母。

    我处理敏感信息,所以我无法给出字符串的具体结果。

    【讨论】:

    • 您能否提供每个字段的示例数据,即使您在每种情况下都进行了编造和预期结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-25
    • 1970-01-01
    • 1970-01-01
    • 2018-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多