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

しかし、それでも同じエラーが発生します。コードは、存在してはならない1つのアイテムを探すまで、すべてに対して正常に機能します。Not IsNothing、Not IsNullも試しましたが、何もキャッチしません。

4

3 に答える 3

2

チェランの正解に加えて(そしてフレークの欠陥を示すために):

短絡評価(目前の問題に対するより良いリンク)

動作中の短絡評価:

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. ネストされたIfとSelectCaseは、結果と同等です
  2. 詳細に興味がない場合は、コンマで区切られた式のリストが短絡されているため、SHORT Select Caseはすべての「不良ケース」を1行でフィルタリングできます(ただし、順序は重要です!)。
  3. 詳細が必要な場合は、SelectCaseの方が読みやすく編集/拡張しやすいです

フレークの答えの欠陥:

出力行4および8は、IsNothingテストが非オブジェクトに適用された場合に失敗することを示しています。したがって、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(...)'はオブジェクトではないことに注意してください。つまり、テストを1レベル上に移動する必要があります。

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 に答える