Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vbscript 变量在VBS中设置为变量时出现问题_Vbscript_Scope_Secure Crt - Fatal编程技术网

Vbscript 变量在VBS中设置为变量时出现问题

Vbscript 变量在VBS中设置为变量时出现问题,vbscript,scope,secure-crt,Vbscript,Scope,Secure Crt,在我使用的VBS中,我与SecureCRT一起使用它来自动化Cisco设备上的某些过程,我(非常精简)了以下代码: 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 hostn

在我使用的VBS中,我与SecureCRT一起使用它来自动化Cisco设备上的某些过程,我(非常精简)了以下代码:

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
Sub-Main有如下部分:

Do While booReconnect = True
  Call prConnectToHost("")
Loop
strHost = "SomeHost"
prConnectToHost strHost
crt.Dialog.Prompt
MsgBox
相同,只是它集中在窗口而不是屏幕上,所以比较整洁。变量
strHost
是脚本中全局的实际主机名字符串,包含我们要连接的主机名。它在
提示符
行中用作默认文本,其思想是,如果您断开连接并设置了
booReconnect
标志,则会再次调用此
子项
,下次提示您输入主机名时,旧的主机名就在那里-如果您第一次拼写错误,它会很有用,或者您正在连接一组具有类似名称的设备

您可以看到我们在
Sub
末尾调用
prCommandLoop
,这是一个循环,它使用一个名为
WaitForStrings
crt函数
,将脚本搁置,直到找到一个特定的字符串序列。当它这样做时,它会发射一些东西,然后循环,直到它再次坐在那里等待

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

重要的位在变量clearup末尾-
设置strConnectHost=Nothing
。如果我保留此选项,并立即使用
booReconnect
set退出
prCommandLoop
,只要应用
set strConnectHost=Nothing
strHost
就会消失-如果我尝试引用它,我会得到一个错误
未设置对象变量
。我尝试将
MsgBox strHost
行放在
Sub
的末尾,这证明了这一点

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


谁能帮我解释一下为什么这是一个问题,因为它让我困惑。我可以很容易地解决这个问题(通过在
prConnectToHost
子部分末尾不发出
Set strConnectHost=Nothing
),但我只想了解问题所在。

Set用于将对象分配给变量。不要把任何东西看作是非常特殊的对象

>> WScript.Echo IsObject(Nothing)
>>
-1
它仅用于指示变量的空值。你的

Set strConnectHost = Nothing
未将此内容分配给strConnectHost。在那之后,这个变量就一无是处了——它保存着一个空对象,这个空对象不能被打印,不能用于计算,也不能被要求执行方法

类型前缀fraud(*str*ConnectHost)应提醒您这是可疑的。您使用字符串(和数字?);要清除/重置它们,请使用空的(简单)赋值:

>> strConnectHost = Empty
>>
>> WScript.Echo IsEmpty(strConnection)
>>
-1
或具有合适的值:

intWaitString = -1 ' or 0 ...
(假设intWaitString不是另一种类型的前缀欺诈)

第二次尝试:

我想你是这样称呼你的潜艇的:

Do While booReconnect = True
  Call prConnectToHost("")
Loop
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中的strConnectionHost和调用方级别的strHost。正如我之前所说, 这使得变量没有用处(除了测试Is Nothing)

我希望这能解释斯特霍斯特的惨败

WRT“内存管理”:除了非常特殊的情况外,您不需要 清除/重置/设置VBScript中的任何变量。在应用程序中使用局部变量 潜艇/功能是所有必要的。如果您决定使用全局变量 并自行管理其状态,您必须注意变量类型: 将类型从object(不包括任何内容)更改为non object和Living 通过误导类型前缀来了解类型是危险的/肯定的方法。 如果您认为必须清除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]()
执行它们的函数-在一定程度上,作为赋值 可能会改变“引擎盖下”的类型

>> 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

所有的气味(不注意类型和以后代码中难以确定的错误)。

我不知道我是否遗漏了要点,但让变量在下次调用例程之前一事无成正是我想要的——我正在尝试进行内存管理,还是这样做是错误的。真正的问题是。。。当从另一个变量(strConnect)获取值的变量(strHost)设置为空时,为什么从另一个变量(strConnect)获取值的变量(strHost)变得无用?这似乎没有道理。strHost未清除,为什么会受到影响?您能解释一下“类型前缀欺诈”的含义吗?VBS没有选择变量类型的方法,所有变量都是变量。考虑到这一点,我使用前缀来区分我在功能上使用变量的目的。我不清楚这可能会导致什么问题。