如何在 Excel 中传递带参数的字符串以进行评估?

How to pass a string with parameters for evaluation in Excel?

在 VBA 中,有没有一种方法可以创建一个函数,该函数将其中一个参数作为字符串接收,并具有要由 IF 块评估的条件?

这应该让我知道我在寻找什么,但我现在不是那么简单:

Function StringAsCondition(a As String) As Boolean

    Dim result As Boolean
    Dim b As Long
    Dim c As Long
    b = 4
    c = 2
    If a Then
        result = True
    End If
    StringAsCondition = result

End Function

Sub Test()

    Dim a As String
    a = "b >= c"
    Dim functionresult As Boolean
    functionresult = StringAsCondition(a)
    MsgBox functionresult

End Sub

在 "fancy" 编程语言(除了 VBA 之外)中,字符串的计算实际上是一项相当容易的任务。在那里,您只需使用某种类型的字符串格式、替换和求值。

在 VBA 中,您可以构建自己的字符串格式(致谢 Is there an equivalent of printf or String.Format in Excel)并使用它:

Sub Test()

    Dim condition As String
    Dim b As Long, c As Long
    b = 4
    c = 2

    condition = "{0} >= {1}"
    Debug.Print Application.Evaluate(StringFormat(condition, b, c))

End Sub

Public Function StringFormat(mask As String, ParamArray tokens()) As String

    Dim i As Long
    For i = LBound(tokens) To UBound(tokens)
        mask = Replace$(mask, "{" & i & "}", tokens(i))
    Next
    StringFormat = mask

End Function

我的回答只是试图以一种直接回答请求的方式呈现(@Vitiata 的)真正的解决方案:

Function StringAsCondition(cond As String) As Boolean
    Dim result As Boolean
    Dim b As Long
    Dim c As Long

    b = 4
    c = 2
    result = CBool(Application.Evaluate(StringFormat(cond, b, c)))

    StringAsCondition = result
End Function
Sub TestEV()
    Dim a As String
    Dim functionresult As Boolean
    a = "{0} >= {1}" 'instead of a = "b >= c"

    functionresult = StringAsCondition(a)

    MsgBox functionresult
End Sub
Private Function StringFormat(mask As String, ParamArray tokens()) As String
    Dim i As Long
    For i = 0 To UBound(tokens)
        mask = Replace$(mask, "{" & i & "}", tokens(i))
    Next
    StringFormat = mask
End Function

允许以任何顺序占位变量

除了 @Vityata 的巧妙解决方案之外,还有一个类似的解决方案,其掩码定义更接近于具有任何顺序的变量的常见数学公式。

所以表达式(条件)例如

  • y >= x*c 可以很容易地转换为像
  • 这样的掩码字符串
  • expression = "{y} >= {x}*{c}"
Sub TestStringFormat()
' Purp: evaluate mask with place holding variables in any order
    Dim expression As String
    expression = "{y} >= {x}*{c}"               ' "17 >= 4*2"  ~~> True

    Dim myVars As String: myVars = "c,x,y"      '     "c,x,y", c  x  y
    Debug.Print Application.Evaluate(StrFrm(expression, myVars, 2, 4, 17))

End Sub
Public Function StrFrm(mask As String, myVars As String, ParamArray tokens()) As String
' Purpose: mask with place holding variables in any order  ' e.g.      y >= x*c
' Note: modified by T.M.; credit to https://whosebug.com/users/246342/alex-k
' Site: 
    Dim vars: vars = Split(myVars, ",") ' variables c,x,y
    Dim i As Long
    For i = LBound(vars) To UBound(vars)
        mask = Replace$(mask, "{" & vars(i) & "}", tokens(i))
    Next
    StrFrm = mask
    Debug.Print StrFrm
End Function