我正撞在墙上撞到墙上。我正在查看一些用VB6编写的旧数据库报告代码,并且遇到了这一行(代码将数据从“源”数据库移动到报告数据库中):
rsTarget!VehYear = Trim(Str(rsSource!VehYear))
当rsSource!VehYear
为Null
时,上面的行会生成“无效使用空”运行时错误。如果我在上面一行中断并在立即窗格中键入以下内容:
?rsSource!VehYear
输出Null
。很好,这很有道理。接下来,我尝试重现错误:
?Str(rsSource!VehYear)
我收到“无效使用空”错误。
但是,如果我在立即窗口中键入以下内容:
?Str(Null)
我没有收到错误。它只输出Null
。
如果我使用Trim()
而不是Str()
重复相同的实验,一切正常。 ?Trim(rsSource!VehYear)
会像Null
一样返回?Trim(Null)
。没有运行时错误。
所以,我的问题是,当Str(rsSource!VehYear)
没有,当{strong>知道 {{1}时Str(Null)
怎么可能抛出“无效使用空”错误}等于rsSource!VehYear
?
更新:如果我在“立即”窗口中键入以下内容,它将按预期工作(不会发生错误):
Null
这会输出?Str(rsSource!VehYear.Value)
。现在,我知道Null
实际上是rsSource!VehYear
个实例,但ADODB.Field
是其默认属性,因此Value
应该在Str
属性上运行(是Value
)。即使错误消息(“无效使用空”)也表明Null
正在接收Str
参数,但在一种情况下如何区别Null
而不是另一种?
我唯一的猜测是Null
的内部实现在某种程度上无法获取默认属性,并且“无效使用Null”错误发生的原因不同(除参数之外的其他原因导致“ “无效使用Null”,可能是在尝试从Str()
对象中检索默认属性时。
有没有人对这里发生的事情有更详细的技术解释?
简而言之:
Field
当?Str(rsSource!VehYear)
为rsSource!VehYear
时,会抛出“无效使用空”错误,但
Null
返回?Str(rsSource!VehYear.Value)
。
但是,Null
和Trim(rsSource!VehYear)
都会返回Trim(rsSource!VehYear.Value)
。
答案 0 :(得分:7)
如果您需要字符串以外的值,请尝试使用IsNull:
rsTarget!VehYear = IIf(IsNull(rsSource!VehYear), 0, rsSource!VehYear)
'注意0是默认值
答案 1 :(得分:6)
Str函数将专门检查是否传入Null值并相应地处理它。传入对象时,它会尝试将默认方法的结果转换为String。默认方法的结果不会传递给Str方法,但是Field对象是,因此检查初始Null将失败。当Str函数意识到它有一个对象时,它将继续检查它支持的数据类型的参数类型,它将尝试检索默认值。它不会像传入的参数那样重新尝试处理默认值,因此将Null作为String返回的尝试将失败。似乎MS没想到默认值为Null或Str的任何其他无效值。例如,Str也不支持空字符串。
答案 2 :(得分:1)
这是我在vb6天中的解决方法:
rsTarget!VehYear = Trim(Str(rsSource!VehYear & ""))
& “”将确保至少有一个空字符串可供使用。
答案 3 :(得分:0)
从内存中,空数据库字段为Nothing
(或可能为vbNull
),它们与Null
的规则不同。你应该能够快速检查一下:
If (rsSource!VehYear Is Nothing) Then
' Null
Else
' Not null
End If