Estoy tratando de usar InputBox para obtener un operador matemático

Por ejemplo: +. Cuando reemplazo el operador con la variable, da un error

Esperada entonces o GoTo

Esto no funciona:

Sub NumTest()
Dim Val As Integer

Val = Application.InputBox("Value", "Value", Type:=1)
oper = Application.InputBox("Op")
rcell = Range("D2")

If rcell oper Val = True Then
    MsgBox "True"
End If
End Sub

Esto funciona:

Sub NumTest()
Dim Val As Integer

Val = Application.InputBox("Value", "Value", Type:=1)
oper = Application.InputBox("Op")
rcell = Range("D2")

If rcell > Val = True Then
    MsgBox "True"
End If
End Sub
2
FreeSoftwareServers 4 dic. 2019 a las 20:19

2 respuestas

La mejor respuesta

Cree una cadena y use Application.Evaluate:

Sub NumTest()
    Dim Val As Integer
    Val = Application.InputBox("Value", "Value", Type:=1)
    Dim oper As String
    oper = Application.InputBox("Op")
    Dim rcell As String
    rcell = ActiveSheet.Range("D2")

    If Application.Evaluate(rcell & oper & Val) Then
        MsgBox "True"
    Else
        MsgBox "False"
    End If
End Sub
5
Scott Craner 4 dic. 2019 a las 17:24

Los operadores son elementos de lenguaje sintáctico, y no están disponibles: no puede simplemente decidir usar alguna variable de identificador / cadena, y en el nombre de su contenido de cadena como un operador, trátelo como un operador: sintácticamente, es una variable, no un operador.

Entonces el compilador no tiene idea de lo que quieres decir aquí:

If rcell oper Val = True Then

Debido a que la expresión rcell oper Val = True no tiene sentido, sintácticamente:

If variable1 variable2 variable3 = True Then

Tenga en cuenta que la parte = True es redundante: una expresión booleana solo puede ser True o False; si la expresión es True, no será más cierto si la compara con el valor literal True.

Usar Application.Evaluate funcionará, siempre y cuando esté dispuesto a dejar que Excel haga el trabajo. Si su código necesita ser transferido a cualquier otra aplicación de host VBA, entonces no puede hacerlo. Bueno, podría , pero podría ser excesivo hacer referencia al modelo de objetos de Excel solo para aprovechar su motor de cálculo para evaluar expresiones simples.

Lo que puede hacer es asignar los valores legales oper a las funciones. Haga un módulo de clase ExpressionEvaluator para esto.

Public Function AddOperator(ByVal LHS As Variant, ByVal RHS As Variant) As Variant
    AddOperator = LHS + RHS ' let VBA deal with type mismatches & other issues
End Function

Public Function SubtractOperator(ByVal LHS As Variant, ByVal RHS As Variant) As Variant
    SubtractOperator = LHS - RHS ' let VBA deal with type mismatches & other issues
End Function

Public Function LessThanOperator(ByVal LHS As Variant, ByVal RHS As Variant) As Boolean
    LessThanOperator = LHS < RHS ' let VBA deal with type mismatches & other issues
End Function

'...

Public Property Get BinaryOperatorMap() As Scripting.Dictionary
    Static map As Scripting.Dictionary
    If map Is Nothing Then
        Set map = New Scripting.Dictionary
        map.Add "+", "AddOperator"
        map.Add "-", "SubtractOperator"
        map.Add "<", "LessThanOperator"
        '...
    End If
    Set BinaryOperatorMap = map
End Property

Y luego puede analizar las entradas proporcionadas por el usuario y utilizar CallByName para invocar la función asignada y alimentarla con los argumentos LHS y RHS:

Public Function Evaluate(ByVal LHS As Variant, ByVal oper As String, ByVal RHS As Variant) As Variant
    Dim operation As String
    operation = BinaryOperatorMap(oper)

    Dim instance As Object
    Set instance = Me
    Evaluate = CallByName(instance, operation, vbMethod, LHS, RHS)
End Function

Tenga en cuenta que CallByName necesita una instancia de objeto; Es por eso que necesita que las operaciones se implementen en un módulo de clase.

3
Mathieu Guindon 4 dic. 2019 a las 19:17