我正在尝试阻止#error显示在我正在创建的报告中
当我将2个数字分开并且其中一个为零时会发生这种情况
所以我尝试使用if / switch语句在进行除法之前检查2号中的任何一个是否为0:
=IIf(Fields!Field1.Value = 0
or Fields!Field2.Value = 0
or Not(IsNumeric(Fields!Field1.Value))
or Not(IsNumeric(Fields!Field2.Value)),
0,
(Fields!Field1.Value/Fields!Field2.Value)*100
)
=Switch(
Fields!Field1.Value = 0 or Fields!Fields.Value = 0, 0,
IsNumeric(Fields!Field1.Value) or IsNumeric(Fields!Fields.Value), (Fields!Field1.Value/Fields!Fields.Value)*100
)
这两个仍然抛出错误。即使if语句为真,似乎仍然会评估else条件
如果我将代码更改为仅为if和else打印X或Y,那么它可以工作 - 所以if语句中没有错误
这对我来说太可笑了
请告诉我我做错了什么?当if为真时,我无法相信语言会评估其他
修改
所以似乎评估了else条件。那么你如何绕过零误差的潜在鸿沟呢?
以下是答案: http://www.sqlservercentral.com/Forums/Topic442497-150-1.aspx#bm1115960
另一种选择(特别是如果你有一个包含许多表达式的报告可能会导致零除的情况,那就是使用自定义代码功能。
在“报告属性”的“代码”选项卡/窗口中,输入以下内容:
Public Function DivideBy(ByVal Exp1, ByVal Exp2)
If Exp2 = 0 Then
DivideBy = 0
Else : DivideBy = Exp1 / Exp2
End If
End Function
然后插入表达式 = code.DivideBy(场!ToBeDivided.Value,场!DividingBy.Value) 进入任何有可能被零问题分割的细胞。
答案 0 :(得分:7)
是的,IIf函数的真假部分都得到了评估:
http://en.wikipedia.org/wiki/IIf#Side_Effects
副作用
IIf的另一个问题是因为它是一个图书馆 function:与C派生的条件运算符不同,都是truepart和 无论实际是哪一个,都将评估falsepart 回。请考虑以下示例:value = 10 result = IIf(value = 10, TrueFunction, FalseFunction)
虽然TrueFunction是要调用的函数,但是IIf会 导致TrueFunction和FalseFunction都被执行。
还要考虑这个:
a = 10 b = 0 result = IIf(b <> 0, a / b, 0)
而程序员 打算通过执行除零来避免引发错误, 只要b为零,就会发生错误。这是因为 代码段中的代码将被理解为
a = 10 b = 0 _temp1 = a / b ' Error if b = 0 _temp2 = 0 _temp3 = b <> 0 result = IIf(_temp3, _temp1 , _temp2)
这个问题 IIf()调用没有条件运算符那么有用。要解决 这个问题,微软开发人员曾考虑过将IIf转换为 内在的功能;如果发生这种情况,编译器就会发生 能够通过替换来执行类型推断和短路 使用内联代码进行函数调用。
答案 1 :(得分:6)
Iif()
和Switch()
都是函数调用,因此将评估传递给它们的所有参数。他们没有短路的能力。
答案 2 :(得分:3)
IIF
是一个函数,在评估函数本身之前,会对函数的所有参数进行求值。
要防止出现此问题,您需要使用完整的If/Else
语句。
另外相关的是,如果您习惯于对布尔表达式进行短路评估(例如C语言中的&&
),则需要在VB中使用AndAlso
和OrElse
.NET。
答案 3 :(得分:0)
对于VB中的IIF语句,我认为无论初始条件如何,都会对所有内容进行评估。这是必须在IIF声明中解决的问题。
在第二个声明中,第一个IIF声明中的Fields!Field**2**.Value
变为Fields!Field**s**.Value
。由于.Value
Fields!Fields
如果{{1}}什么都不是
答案 4 :(得分:0)
我试图在RS 2005中重现此错误,但我不能!我采用了以下数据集:
select 5 as field1, 0 as field2
union
select 10 as field1, 5 as field2
union
select null as field1, 5 as field2
union
select 3 as field1, null as field2
union
select null as field1, null as field2
union
select 0 as field1, null as field2
union
select null as field1, 0 as field2
union
select 11 as field1, 10 as field2
union
select PI() as field1, 0 as field2
union
select PI() as field1, PI() as field2
并使用你的表达式,Jon Egerton在交换机中进行了修正。然后我做了一个纯粹的未经检查的师。
你的表达都有效,即使我除以0,我得到“无限”或“南”,但不是#Error。
如果用1/0替换除法,会发生什么。你得到#Error还是得到Infinity?