我有以下函数来检查是否存在变量:
Private Function DoesVariableExist(Optional valuePassed As Variant) As Boolean
If Not IsMissing(valuePassed) And Not IsEmpty(valuePassed) Then
DoesVariableExist = True
End If
End Function
这个想法是,如果变量不存在,我可以运行与它存在时不同的代码。
只要从模块中删除Option Explicit
行,代码就可以正常工作。在那里,我得到一个编译错误,“变量未定义”,因为,当然,这是我正在检查。这是一个只有少量程序的小模块,所以我可能不需要变量声明就可以逃脱,但这不是很好的编码实践。那么,还有什么选择呢?
答案 0 :(得分:0)
另一种方法是深入研究VBE本身的编程。此函数循环遍历传递项目中标准模块的声明部分,以查找声明传递的变量名称的任何行。它只检查声明部分,因为范围很重要,无论如何,这个函数都不会看到任何程序变量。
Private Function DoesVariableExist(book As Workbook, varName As String) As Boolean
Const ProcKind As Integer = 0 'sub or function
Const vbext_ct_StdModule As Integer = 1 'standard modules only
Const DIMSTMNT As String = "Dim"
Const PUBLICSTMNT As String = "Public"
Const PRIVATESTMNT As String = "Private"
Const CONSTSTMNT As String = "Const"
Dim VBProj As Object
Dim VBComp As Object
Dim codeMod As Object
Dim procName As String
Dim lineNum As Long
Dim lineText As String
DoesVariableExist = False
'set object to components within the project
Set VBProj = book.VBProject.VBComponents
'loop through components
For Each VBComp In VBProj
'find standard modules
If VBComp.Type = vbext_ct_StdModule Then
'set object to code module
Set codeMod = VBComp.CodeModule
With codeMod
'loop through lines of code in the declaration section
For lineNum = 1 To .CountOfDeclarationLines
lineText = .Lines(lineNum, 1)
'check for declarartion statement and passed variable name (case-insensitive)
If (InStrB(lineText, DIMSTMNT) > 0 Or _
InStrB(lineText, PUBLICSTMNT) > 0 Or _
InStrB(lineText, PRIVATESTMNT) > 0 Or _
InStrB(lineText, CONSTSTMNT) > 0) And _
InStrB(LCase(lineText), LCase(varName)) > 0 Then
DoesVariableExist = True
Exit Function
End If
Next lineNum
End With
End If
Next VBComp
End Function
当然,这有其自身的负面影响。您需要信任对VBA项目对象模型(在“信任中心设置”中找到)的访问权限,该模型可以为您打开恶意代码。但是在你不打开来自未知来源的文件的环境中,权衡可能是值得的。
另外,我在这里使用后期绑定,因此您不必设置访问VBE对象的引用。
答案 1 :(得分:0)
由于您无法确定变量是否存在,因此非常痛苦,将其加倍。创建变量后,请随其创建一个书签,然后检查该书签是否存在。如果书签存在,则您知道该变量存在。这是一行额外的代码,而不是多行编程
答案 2 :(得分:0)
前进-这不是采用任何代码的运行时逻辑的好方法。如果您的代码依赖于特定变量,那么您应该始终在过程中声明该变量,但要使用默认值,这实际上就是我们拥有Optional
的原因参数。无需检查变量是否存在,只需检查默认值即可。
例如
Sub Foo(Optional ByVal Bar As Integer = -99)
'// My code here....
If Bar = -99 Then
'// variable wasn't supplied to the procedure
Else
'// Do something with the variable that WAS supplied
End If
End Sub
答案 3 :(得分:-1)
Public Class Form1
Dim varExists As Boolean = False ' This should not be placed within a sub. Choose any valid name, preferably one that makes sense, like "varOneExists," as long as you change all instances of it to the new name.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ' This can be any other sub, just take the code within the sub and place it elsewhere.
Dim otherVar As String = "" ' Doesn't need to be a string. Any valid name is fine, as long as you change all instances of it to the new name.
varExists = True ' Always put this after the code that declares otherVar.
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click ' This can be any other sub, just take the code within the sub and place it elsewhere.
If varExists = True Then
' The code here will run if otherVar has been declared. Feel free to add more valid lines, as it will still work.
Else
' The code here will run If otherVar has not been declared. Feel free to add more valid lines, as it will still work.
End If
End Sub
End Class