2015-03-18 7 views
0

У меня есть следующие функции для проверки существования переменной: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 с модуля. В этой строке я получаю ошибку компилятора «Variable not defined», потому что, конечно, это то, что я проверяю. Это небольшой модуль с несколькими процедурами, поэтому я мог бы избежать неприятностей, не требуя объявления переменных, но это не хорошая практика кодирования. Итак, какова альтернатива?

+0

Храните 'Option Explicit' и исправьте код. Вы просите о неприятностях здесь, если разные кодовые блоки делают одно и то же в зависимости от объявления переменной. – ja72

+0

Это не мой код для «исправления». Это общий код, который используется повторно для проектов, которые могут иметь или не иметь определенную переменную. – phrebh

ответ

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.

+0

Проверьте каждую строку для всей базы кода для каждого вызова функции. Хлоп! – ja72

+0

Он вызывается один раз, поэтому накладные расходы минимальны. – phrebh

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

Насколько я знаю, это должно работать на любом другом языке, который поддерживает что-то, что работает как If End If. Если язык имеет нечто аналогичное If, End If, но не имеет аналога If, Else, End If, тогда выполните If, End If для true и If, End If для false. –

+0

Не этот конкретный код, но этот код переведен. –

Смежные вопросы