SSRS表达式除以零错误

20

我有一个表格框,其中包含一个除法表达式。当除以零或null时,在我的报告中显示#Error。我尝试创建了一个IIF语句,并使用静态值进行测试。这验证了我的语法是正确的,但我仍然在我的报告中看到错误。

Report Preview

=IIF(Sum(Fields!CY_Dollars.Value)=0, 0, (Sum(Fields!CY_Dollars.Value) - Sum(Fields!PY_Dollars.Value))/(Sum(Fields!PY_Dollars.Value)))

因此,我正在取得当前年份的美元数,减去去年同期的美元数,然后将该总数除以去年同期的美元数,以获得百分比变化。我是否存在不明白的技巧?!


你提到你的数据中有空值?尝试将每个字段调用嵌套在一个NULL替换函数中。例如,我会使用以下格式IIF(Fields!PY_Dollars.Value = Nothing, 0, Fields!PY_Dollars.Value = Nothing)来处理当前公式中的每个Fields!PY_Dollars.Value。 更好的方法是在源查询中处理空值。 - Eric Hauenstein
你的IIF语句中的条件没有检查分母是否为零(你在CY中检查了零,而不是PY值)。请尝试使用以下代码:=IIF(Sum(Fields!PY_Dollars.Value)=0, 0, (Sum(Fields!CY_Dollars.Value) - Sum(Fields!PY_Dollars.Value))/(Sum(Fields!PY_Dollars.Value))) - rpyzh
4个回答

57
您可以向报告代码中添加一个函数来处理除零条件,这将使在多个单元格中进行实施更加容易,例如:

您可以向报告代码中添加一个函数来处理除以零的情况,这样在多个单元格中实施会更加容易,例如:

Public Function Divider (ByVal Dividend As Double, ByVal Divisor As Double)
If IsNothing(Divisor) Or Divisor = 0
  Return 0
Else
  Return Dividend/Divisor
End If
End Function 
你可以像这样在单元格中调用它:
=Code.Divider(Fields!FieldA.Value, Fields!FieldB.Value)

1
此函数仅可在报表设计界面中使用,不能在SQL或MDX查询中使用。有许多处理MDX中除零计算的方法,例如http://www.bidn.com/blogs/dustinryan/ssis/465/mdx-handle-dividing-by-null-or-0-gracefully,但如果您使用的是SQL Server 2012或更高版本,则可以使用新的Divide()函数,它可以完成与上述代码类似的工作。 - Nathan Griffiths
1
你不需要定义返回类型吗?这不是必要的吗? - Emil
5
我希望我可以像点赞1000次一样给这个帖子点赞。谢谢,伙计,完美的解决方案。 - LittleTreeX
很好。但是你也想用支票来获得股息。即:如果被除数或除数为null或零,则返回零。 - Gary Thomann
1
所以......如果有人需要重构他们的共享除法代码,这是一个实际有效的内联方法 https://sqldusty.com/2011/08/01/ssrs-expression-iif-statement-divide-by-zero-error/ 。基本上是IIF(denominator=0,0,Numerator) / IIF(Denominator=0,1,Denominator) - Nick.McDermaid
显示剩余9条评论

15

我猜你遇到了一个问题,SSRS实际上没有对IIF语句进行短路处理;即使你检查的是0,你仍然会遇到除以零的错误。

尝试像这样做:

=IIf(Sum(Fields!PY_Dollars.Value) = 0, 0, Sum(Fields!CY_Dollars.Value) - Sum(Fields!PY_Dollars.Value))
  / IIf(Sum(Fields!PY_Dollars.Value) = 0, 1, Sum(Fields!PY_Dollars.Value))

使用两个 IIf 语句,意味着您可以通过在等式 0/1 中使用它来避免错误,当 Sum(Fields!PY_Dollars.Value) = 0 时,因此只返回 0

还要注意上面的表达式检查的是 Sum(Fields!PY_Dollars.Value) = 0,但是您的表达式检查的是 Sum(Fields!CY_Dollars.Value) = 0 - 在这里分母需要进行零检查。


我明白逻辑,它应该是可以运行的,但SSRS却没有正确地计算它。我仍然在这方面遇到错误。 - d90
2
这是一篇关于使用双重iif语句的文章:http://ntsblog.homedev.com.au/index.php/2010/03/12/sql-server-reporting-services-ssrs-iif-statement-divide-by-zero-error/ - Bobby

9
为了避免维护代码的开销,我认为以下解决方案最整洁。它通过将可能最小的Double值(Double.Epsilon,即4.94e-324)加到分母中来避免零除。这个值对于人们使用SSRS处理的任何内容都太小而不会影响分数的值。它也避免了IIF函数的嵌套。
=IIF(Sum(Fields!Denominator.Value)>0, 
     Sum(Fields!Numerator.Value)/(Sum(Fields!Denominator.Value)+Double.Epsilon),
     nothing)

这是最简单的解决方案。事实上,通过将Double.Epsilon添加到分母中,您甚至不再需要iif语句了。 - Nicko

0
为什么不直接将值表示为DOUBLE呢?这样可以避免使用多个IIF函数,而且性能应该更好。
=IIF(Sum(CDbl(Fields!CY_Dollars.Value))=0, 0, (Sum(CDbl(Fields!CY_Dollars.Value)) - 
    Sum(CDbl(Fields!PY_Dollars.Value)))/(Sum(CDbl(Fields!PY_Dollars.Value))))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接