2011-08-23 57 views
0

我在用SecureCRT结合使用对Cisco设备某些流程的自动化,我(非常大的相比下来)以下代码:问题与在VBS我有变量设置为变量在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,并且在下次系统提示您输入主机名时,会显示旧主机名 - 有用的你第一次拼写错误,或者你连接到一堆具有相似名称的设备。

你可以看到,我们在这个Sub,这是它采用了crt Function称为WaitForStrings这使脚本暂停,直到它找到一个特定的字符串顺序循环的末尾调用prCommandLoop。当它发生时,它会熄灭一些东西,然后绕回去,直到它再次等待。

其中一个自动化命令检测是否存在连接菜单(因此我们已经退出了路由器会话)并提示用户输入其他主机名。

重要的是在最后的变量清除 - Set strConnectHost = Nothing。如果我将其保留并立即退出prCommandLoop并设置为booReconnect,则应尽快应用Set strConnectHost = NothingstrHost会死亡 - 如果我尝试引用它,则会收到错误Object Variable not set。我尝试在Sub的末尾放置一个MsgBox strHost行,这证明了这一点。

奇怪的是,如果我先在prCommandLoop中选择不同的自动化命令,然后退出会话,似乎并不打扰任何人。

任何人都可以帮助我解释为什么这是一个问题,因为它令我困惑。我可以很容易解决它(通过在prConnectToHost子的末尾没有发出Set strConnectHost = Nothing),但我只是想了解问题所在。

回答

0

设置用于将对象分配给变量。认为没有什么是一个非常特殊的对象

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

它只是用来指示变量的空白。您的

Set strConnectHost = Nothing 

将此Nothing指定给strConnectHost。在那之后,这个变量毫无用处 - 它保存着无法打印或用于计算或被要求执行方法的空对象。

类型前缀欺诈(* str * ConnectHost)应该提醒您这是可疑的。你使用字符串(和数字?);到清除/复位他们使用与空(简单)分配:

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

或用合适的值:

intWaitString = -1 ' or 0 ... 

(假设intWaitString不是另一种类型的前缀欺诈)。

第二次尝试:

我假设你打电话给你的分是这样的:

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) 

在你的情况下,修改分配没有到被称为 strConnectHost在Sub和strHost呼叫者水平的变量。正如我之前所说, ,使变量无用(除了测试是没有)。

我希望解释strHost的破坏。

WRT'内存管理':除了非常特殊的情况,你不需要在VBScript中清除/重置/ SetToNothing变量 。在您的 子/函数中使用局部变量是所有必需的。如果您决定使用全局变量 并自行管理它们的状态,则必须注意变量类型: 将对象的类型更改为对象(包括无)< =>非对象并且说谎 关于通过误导类型前缀的类型是危险的/一个可靠的方式来desaster。 如果您认为您必须清除strHost,请将空或分配给strConnectHost。

未来除了

所有的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 

类型名()和VarType函数()显示子类型和progammer可以使用一组 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 

所有气味(不重视类型的,很难牵制在后面的代码中的错误)。

+0

我不知道我是否忽略了这一点,但直到下一次调用例程时才使变量变为好,正是我想要的 - 我试图进行内存管理,或者这是错误的方式来做到这一点。 真正的问题是...为什么变量(strHost)从其他变量(strConnect)获取其值时变得无用,当它从(strConnect)获取其值的变量设置为无效时?这似乎没有道理。 strHost没有被清除,所以它为什么会受到影响? –

+0

你能解释一下你的意思吗?“类型前缀欺诈?” VBS没有选择变量类型的方法,所有变量都是变体。考虑到这一点,我已经使用前缀来区分我在功能上使用变量。我很困惑这有什么潜在的问题。 –