0

Object_required:_'state.Item(...).Item(...)'

我在这行代码上发生了这个错误;

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

但我仍然得到同样的错误。代码适用于所有内容,直到它查找不应该存在的一项。我也尝试过 Not IsNothing,Not IsNull,没有任何反应。

4

3 回答 3

2

除了 Cheran 的正确答案(并显示 Flakes 中的缺陷):

短路评估(手头问题的更好链接)

实际短路评估:

VBScript 是急切的(不必要地计算表达式):

选项显式

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

Select Case False/True 可以避免嵌套 If:

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,... 15-17 并查看对应的代码行,您会看到

  1. 嵌套的 Ifs 和 Select Case 在结果上是等价的
  2. 如果您对细节不感兴趣,SHORT Select Case 可以在一行中过滤所有“坏情况”(尽管顺序很重要!),因为逗号分隔的表达式列表是短路的
  3. 如果您需要详细信息,选择案例更易于阅读/编辑/扩充

Flakes 回答中的缺陷:

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

于 2012-11-09T11:15:30.930 回答
1

VBScript 逻辑运算符没有短路。这意味着无论如何都会评估这两个条件(我想除非出现运行时错误)。相反,您应该将条件构造为:

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
于 2012-11-09T08:13:16.380 回答
-1
If (NOT (state.Item(level).Item(childRequires).Item("menu_state") is NOTHING) )
于 2012-11-09T07:02:52.193 回答