0

シスコデバイスの一部のプロセスを自動化するためにSecureCRTと組み合わせて使用​​するVBSには、次のコードがあります(非常に簡素化されています)。

Sub prConnectToHost(strConnectHost)

  'If no host is passed into subroutine then we need to prompt for one.
  If strConnectHost = "" Then strConnectHost = LCase(crt.Dialog.Prompt("Enter hostname or IP address:", "Connect to a host", strHost, False))

  strHost = strConnectHost

  'If user hits Cancel or hits Ok with no hostname entered then exit.
  If strHost = "" Then
    booReconnect = False
    Exit Sub
  End If

  'Write to connection log
  Call prWriteToConnectionLog

  'Run command capture subroutine.
  Call prCommandLoop

  Set intWaitString = Nothing:  Set strScreenGet = Nothing
  Set strLatestScriptVersion = Nothing:  Set strConnectHost = Nothing
End Sub

サブメインには次のようなセクションがあります。

Do While booReconnect = True
  Call prConnectToHost("")
Loop

crt.Dialog.Promptと同じですがMsgBox、画面ではなくウィンドウの中央に配置されるだけなので、少しすっきりしています。変数strHostは、スクリプト内でグローバルであり、接続するホスト名を含む実際のホスト名文字列です。これはPromptデフォルトのテキストとして行で使用されます。切断してbooReconnectフラグが設定されると、これSubが再度呼び出され、次にホスト名の入力を求められたときに、古いホスト名が表示されます。スペルを入力すると便利です。初めて間違った、または同じような名前のデバイスの束に接続しています。

prCommandLoopこれの最後にどこを呼び出すかがわかります。これは、特定の文字列シーケンスが見つかるまでスクリプトを保留にするcalledSubを使用するループです。その場合、いくつかのものを起動し、再び待機するまでループバックします。crt FunctionWaitForStrings

自動化コマンドの1つは、接続メニューの存在を検出し(したがって、ルーターセッションを終了しました)、接続する別のホスト名の入力をユーザーに求めます。

重要なビットは、最後の変数のクリアアップにあります- Set strConnectHost = Nothing。これをそのままにして、すぐにsetで終了prCommandLoopすると、適用されるとすぐに死にます。これを参照しようとすると、エラーが発生します。の最後に線を引くことを試みましたが、これが証明されました。booReconnectSet strConnectHost = NothingstrHostObject Variable not setMsgBox strHostSub

奇妙なことに、prCommandLoop最初に別の自動化コマンドを選択してからセッションを終了しても、Set strConnectHost = Nothing誰も気にしないようです。

それが私を困惑させているので、誰かがこれが問題である理由を説明するのを手伝ってもらえますか?Set strConnectHost = Nothing(サブの最後に発行しないことで)簡単に回避できますprConnectToHostが、問題が何であるかを理解したいだけです。

4

1 に答える 1

0

Setは、オブジェクトを変数に割り当てるために使用されます。何も非常に特別なオブジェクトとは考えない

>> WScript.Echo IsObject(Nothing)
>>
-1

これは、変数が空であることを示す場合にのみ役立ちます。あなたの

Set strConnectHost = Nothing

このNothingをstrConnectHostに割り当てます。その後、変数は何の役にも立ちません。印刷したり、計算に使用したり、メソッドを実行したりすることができない空のオブジェクトを保持します。

タイププレフィックス詐欺(* str * ConnectHost)は、これが怪しいことを警告するはずです。文字列(および数字?)を操作します。それらをクリア/リセットするには、Emptyで(単純な)割り当てを使用します。

>> strConnectHost = Empty
>>
>> WScript.Echo IsEmpty(strConnection)
>>
-1

または適切な値で:

intWaitString = -1 ' or 0 ...

(intWaitStringが別のタイプのプレフィックス詐欺ではないと仮定します)。

2番目の試み:

私はあなたがこのようにあなたの潜水艦を呼ぶと仮定します:

strHost = "SomeHost"
prConnectToHost strHost

サブの関連ダイジェストは次のとおりです。

Sub prConnectToHost( [ByRef] strConnectHost)
  ...
  Set strConnectHost = Nothing
End Sub

VBScriptは参照によりパラメーターの受け渡しをデフォルトとして使用するため、変更すると呼び出し元の変数strHostが変更されます。これは、非オブジェクト変数にも発生します。

  Dim sVar : sVar = "String 0"
  WScript.Echo 0, sVar
  changeString sVar
  WScript.Echo 1, sVar

  Sub changeString( sByRefVar )
    sByRefVar = "String 1: changed by changeString( ByRef sByRefVar )"
  End Sub

出力:

0 String 0
1 String 1: changed by changeString( ByRef sVar )

あなたの場合、変更により、SubではstrConnectHostと呼ばれ、呼び出し元レベルではstrHostと呼ばれる変数にNothingが割り当てられます。前に言ったように、それは変数を役に立たなくします(Is Nothingのテストを除いて)。

それがstrHostの破壊を説明することを願っています。

WRT'メモリ管理':非常に特殊な場合を除いて、VBScriptで変数をクリア/リセット/SetToNothingする必要はありません。必要なのは、サブ/関数でローカル変数を使用することだけです。グローバル変数を使用してその状態を自分で管理する場合は、変数の型に注意する必要があります。オブジェクトから型を変更する(Nothingを含む)<=>非オブジェクトであり、誤解を招く型プレフィックスによって型について嘘をつくことは危険です/確かです災害への道。strHostをクリアする必要があると思われる場合は、strConnectHostにEmptyまたは""を割り当てます。

次の追加

すべてのVBScript変数はバリアントですが、すべてのバリアントが同じように作成されるわけではありません。

>> s0 = "string"
>> s1 = CStr( 12.35 )
>> WScript.Echo TypeName( s0 ), TypeName( s1 )
>>
String String
>> n0 = 1
>> n1 = CByte( n0 )
>> WScript.Echo TypeName( n0 ), TypeName( n1 )
>>
Integer Byte

TypeName()とVarType()はサブタイプを示し、プログラム担当者は一連の C[hange/onvertTo]<Type>()関数を使用してそれらを強制できます。割り当てによって「内部」でタイプが変更される可能性があるためです。

>> WScript.Echo TypeName( n0 ), TypeName( n1 )
>>
Integer Byte
>> n0 = 1.1
>> n1 = 2 ^ 20
>> WScript.Echo TypeName( n0 ), TypeName( n1 )
>>
Double Double

タイプの不一致エラーもあります:

>> WScript.Echo Nothing
>>
Error Number:       13
Error Description:  Type mismatch
>>

>> WScript.Echo s0 Is Nothing
>>
Error Number:       424
Error Description:  Object required

したがって、サブタイプが重要です。型の接頭辞はかっこいいとは思わない人もいますが、弱い型の言語ではそれらを貴重な助けと見なす人もいます。それらを使用することにした場合は、正しく使用する必要があります-

   Set strWhatEver = objWhatever
   objWhatever = intWhatever
   intWhatever = objWhatever
   If strWhatEver = intWhatever Then

すべてのにおい(タイプに注意を払わず、後のコードでエラーを特定するのが難しい)。

于 2011-08-23T12:21:41.037 に答える