当使用Str()和Null Recordset字段时,“Null的使用无效”,但Str(空)可以正常工作
我正在用头撞墙。我看着写在VB6一些旧的数据库报告代码和跨越这条线进来(代码从“源”数据库将数据移动到报告数据库):当使用Str()和Null Recordset字段时,“Null的使用无效”,但Str(空)可以正常工作
rsTarget!VehYear = Trim(Str(rsSource!VehYear))
当rsSource!VehYear
是Null
,上面的行生成“无效使用Null”运行时错误。如果我在上述行中断开并在“即时”窗格中键入以下内容:
?rsSource!VehYear
它输出Null
。好吧,这很有道理。接下来,我尝试重现该错误:
?Str(rsSource!VehYear)
我收到“无效使用空值”错误。
但是,如果我键入以下到即时窗口:
?Str(Null)
我没有得到一个错误。它只是输出Null
。
如果我用Trim()
而不是Str()
重复同样的实验,一切正常。 ?Trim(rsSource!VehYear)
返回Null
,与?Trim(Null)
一样。没有运行时错误。
所以,我的问题是,如何才能Str(rsSource!VehYear)
可能抛出一个“无效使用的Null”错误时Str(Null)
不,当我知道是rsSource!VehYear
等于Null
?
更新:如果我键入立即窗口下面,它按预期工作(没有发生错误):
?Str(rsSource!VehYear.Value)
此输出Null
。现在,我知道rsSource!VehYear
实际上是一个ADODB.Field
实例,但Value
是它的默认属性,所以Str
应该在Value
属性(即Null
)上运行。即使是错误消息(“无效使用空值”),也表明Str
正在接收Null
参数,但是如何在一种情况下对待Null
而不是另一种呢?
我唯一的猜测是Str()
的内部实现在某种程度上无法获得默认属性,并且“无效的Null使用”错误是由于其他原因而发生的(参数之外的其他原因导致“Invalid use of空“,也许当它试图从Field
对象中检索默认属性时)。
有没有人对这里实际发生的事情有更详细的技术解释?
简而言之:
?Str(rsSource!VehYear)
抛出 “无效使用Null” 错误时rsSource!VehYear
是Null
,但
?Str(rsSource!VehYear.Value)
返回Null
。
然而,Trim(rsSource!VehYear)
和Trim(rsSource!VehYear.Value)
都返回Null
。
Str函数将专门检查是否传递一个Null值并相应地处理它。当你传入一个对象时,它会尝试将默认方法的结果转换为一个String。默认方法的结果不会传递到Str方法,但是Field对象是,所以检查初始Null将失败。 Str函数将继续检查它支持的数据类型的参数类型,当它意识到它具有一个对象时,它将尝试检索默认值。它不会重新尝试处理默认值,因为它与传入的参数一样,所以尝试返回Null作为字符串将失败。似乎MS并没有预期默认值为Str或任何其他无效值。例如Str不支持空字符串。
从内存中,空数据库字段为Nothing
(或可能为vbNull
),它们没有应用于它们的相同规则作为Null
。你应该能够做到快速检查:
If (rsSource!VehYear Is Nothing) Then
' Null
Else
' Not null
End If
很好的建议,但该领域绝对是等于'Null'。我通过将它悬停在IDE中进行检查,并将其打印到立即窗口中。 – 2010-05-06 22:52:43
这是我的解决方法在VB6天:
rsTarget!VehYear = Trim(Str(rsSource!VehYear & ""))
的&“”将确保有百达至少空串来处理。
我知道我可以解决这个问题,在这种情况下,我实际上可以完全删除对“Trim”和“Str”的调用,因为数据库字段实际上是一个数字字段。我更关心为什么问题中的代码无法按预期工作的技术原因。 – 2010-05-07 14:29:23
如果你需要比一个字符串的值,请尝试使用ISNULL代替:
rsTarget!VehYear = IIf(IsNull(rsSource!VehYear), 0, rsSource!VehYear)
'注意0是默认值
这清除了一切。顺便说一下,感谢SimplyVBUnit;) – 2010-05-11 15:10:20