2012-11-08 23 views
0

Object_required:_ 'state.Item(...)项目(...)'物体则IsObject测试

我有这行代码发生该错误;

If state.Item(level).Item(conflictItem).Item("menu_state") = "CHECKED" Then 
... do some stuff 
End If 

我知道可能有些时候没有定义,所以我这样做,而不是;

If IsObject(state.Item(level).Item(childRequires).Item("menu_state")) And state.Item(level).Item(childRequires).Item("menu_state")state.Item(level).Item(childRequires).Item("menu_state") = "CHECKED" Then 
    ... do some stuff       
End If 

但我仍然得到相同的错误。代码对所有内容都可以正常工作,直到它找到不应该在那里的一个项目。我也尝试过不是没有,不是IsNull,没有什么捕捉它。

+0

你有没有检查对象进一步上链? – Nilpo

回答

-1
If (NOT (state.Item(level).Item(childRequires).Item("menu_state") is NOTHING)) 
1

VBScript逻辑运算符是not short-circuited。这意味着无论怎样(除了运行时错误,我猜想)都会评估这两种情况。相反,你应该构造你的条件为:

If IsObject(state.Item(level).Item(childRequires).Item("menu_state")) Then 
    If state.Item(level).Item(childRequires).Item("menu_state") = "CHECKED" Then 
     ... do some stuff 
    End If 
End If 

注意,然而,根据你的错误,'state.Item(...).Item(...)'不是一个对象。这意味着,你需要将你的测试上一级:

If IsObject(state.Item(level).Item(childRequires)) Then 
    If state.Item(level).Item(childRequires).Item("menu_state") = "CHECKED" Then 
     ... do some stuff 
    End If 
End If 
+0

宾果!我从来没有想过要这样做。很高兴知道更多关于如何阅读这些错误的信息。谢谢! – user1601513

2

除了基兰的正确答案(并显示在薄片缺陷):

Short-circuit evaluation(更好的链接,手头的问题在动作)

短路评价:

VBScript是渴望(到不必要的计算表达式):

Explicit选项

Function F() 
    WScript.StdOut.Write "F() called ==> " 
    F = True 
End Function 

Dim A, R 
For Each A In Array(False, True) 
    WScript.StdOut.Write CStr(A) & " and F() ==> " 
    If A And F() Then R = "YES" Else R = "NO" 
    WScript.StdOut.WriteLine R 

    WScript.StdOut.Write CStr(A) & " or F() ==> " 
    If A Or F() Then R = "YES" Else R = "NO" 
    WScript.StdOut.WriteLine R 
Next 

输出:

False and F() ==> F() called ==> NO 
False or F() ==> F() called ==> YES 
True and F() ==> F() called ==> YES 
True or F() ==> F() called ==> YES 

JScript是懒(不必要的检查被跳过):

function F() { 
    WScript.StdOut.Write("F() called ==> "); 
    return true; 
} 

var B = [false, true]; 
var R; 
for (var I in B) { 
    var A = B[I]; 
    WScript.StdOut.Write(A + " and F() ==> "); 
    if (A && F()) {R = "YES";} else {R = "NO";} 
    WScript.StdOut.WriteLine(R); 

    WScript.StdOut.Write(A + " or F() ==> "); 
    if (A || F()) {R = "YES";} else {R = "NO";} 
    WScript.StdOut.WriteLine(R); 
} 

输出:

false and F() ==> NO 
false or F() ==> F() called ==> YES 
true and F() ==> F() called ==> YES 
true or F() ==> YES 

Option Explicit 

Class C 
    Function F() 
    WScript.StdOut.Write "C.F() called ==> " 
    F = True 
    End Function 
End Class 

Class D 
    Public m_C 
    Private Sub Class_Initialize() 
    Set m_C = Nothing 
    End Sub 
    Function init() 
    Set init = Me 
    Set m_C = New C 
    End Function 
End Class 

Class I 
    Private m_I 
    Private Sub Class_Initialize() 
    m_I = 0 
    End Sub 
    Public Default Function Inc() 
    m_I = m_I + 1 
    Inc = Right(" " & m_I, 3) & " " 
    End Function 
End Class 

Dim N : Set N = New I 
Dim O, R 
For Each O In Array(Empty, "Nix", Nothing, New D, (New D).init()) 
    WScript.StdOut.Write N() & TypeName(O) & " via nested Ifs ==> " 
    If IsObject(O) Then 
     If O Is Nothing Then 
      R = "O Is Nothing" 
     Else 
      If IsObject(O.m_C) Then 
      If O.m_C Is Nothing Then 
       R = "O.m_C Is Nothing" 
      Else 
       If O.m_C.F() Then 
        R = "YES" 
       Else 
        R = "NO" 
       End If 
      End If 
      Else 
      R = "O.m_C is not an object" 
      End If 
     End If 
    Else 
     R = "O is not an object" 
    End If 
    WScript.StdOut.WriteLine R 

    WScript.StdOut.Write N() & TypeName(O) & " via Select Case False ==> " 
    Select Case False 
     Case IsObject(O) 
     R = "O is not an object" 
     Case Not O Is Nothing 
     R = "O Is Nothing" 
     Case IsObject(O.m_C) 
     R = "O.m_C is not an object" 
     Case Not O.m_C Is Nothing 
     R = "O.m_C Is Nothing" 
     Case Else 
     If O.m_C.F() Then 
      R = "YES" 
     Else 
      R = "SURPRISE" 
     End If 
    End Select 
    WScript.StdOut.WriteLine R 

    WScript.StdOut.Write N() & TypeName(O) & " via SHORT Select Case False ==> " 
    Select Case True 
     Case Not IsObject(O), O Is Nothing, Not IsObject(O.m_C), O.m_C Is Nothing 
     R = "Something rotten" 
     Case Else 
     If O.m_C.F() Then 
      R = "YES" 
     Else 
      R = "SURPRISE" 
     End If 
    End Select 
    WScript.StdOut.WriteLine R 

    On Error Resume Next 
    If O Is Nothing Then R = "Surprise" 
    If Err.Number Then WScript.Echo N(), Err.Number, Err.Description 
    On Error GoTo 0 

Next 

输出:

1 Empty via nested Ifs ==> O is not an object 
    2 Empty via Select Case False ==> O is not an object 
    3 Empty via SHORT Select Case False ==> Something rotten 
    4 424 Object required 
    5 String via nested Ifs ==> O is not an object 
    6 String via Select Case False ==> O is not an object 
    7 String via SHORT Select Case False ==> Something rotten 
    8 424 Object required 
    9 Nothing via nested Ifs ==> O Is Nothing 
10 Nothing via Select Case False ==> O Is Nothing 
11 Nothing via SHORT Select Case False ==> Something rotten 
12 D via nested Ifs ==> O.m_C Is Nothing 
13 D via Select Case False ==> O.m_C Is Nothing 
14 D via SHORT Select Case False ==> Something rotten 
15 D via nested Ifs ==> C.F() called ==> YES 
16 D via Select Case False ==> C.F() called ==> YES 
17 D via SHORT Select Case False ==> C.F() called ==> YES 

如果忽略输出4,8和比较只是特里普尔1-3,...个嵌套IFS认证通过选择案例假/真要避免-17,并期待在correspondig代码行,你看

  1. 嵌套如果和选择情况下相当于WRT结果
  2. 如果您AR对细节不感兴趣,简短选择案例可以在一行中过滤全部'坏案例'(尽管命令很重要!),因为逗号分隔的表达式列表短路
  3. 如果你需要的细节,选择案例更易于阅读/编辑/增加

该漏洞在薄片的回答:

输出行4和8显示如果应用于非对象,Is Nothing测试将失败。所以它必须用IsObject()检查来保护。那么合并检查的问题就会出现(在该贡献中完全忽略)。

+0

谢谢你指出这一点。我没有完全意识到“短路”。关于用'isObject()'检查守护,在这个特定的情况下,是不是'Not(is nothing)'检查不够? – SearchAndResQ

+0

@Flakes - 没有,因为*不是O没有什么*如果O没有被定义/空(输出行4,OT希望避免的'坏情况'),会抛出一个“Object Expected”错误。 –

+0

谢谢,只是想确认一下。 – SearchAndResQ