VBA:检查变量是否存在

时间:2015-03-18 18:35:32

标签: vba

我有以下函数来检查是否存在变量:

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行,代码就可以正常工作。在那里,我得到一个编译错误,“变量未定义”,因为,当然,这是我正在检查。这是一个只有少量程序的小模块,所以我可能不需要变量声明就可以逃脱,但这不是很好的编码实践。那么,还有什么选择呢?

4 个答案:

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