在查看了一些 BigBen 提供的相关帖子后,我决定只写解决方案。
我确信它可以从一些效率优化中受益,并且它不考虑 XOR 等扩展布尔逻辑。它只处理 AND、OR 和 NOT。但这比我在其他任何地方都能找到的要多。
此代码中的方法是将完整字符串分解为一层字符串(由括号确定),然后使用 AND 然后 OR 的操作顺序处理每一层逻辑。接下来,它将每个单层术语替换为单个结果真或假,然后继续到下一层,直到到达逻辑的顶层。该函数返回一个字符串,以便它可以调用自身并将结果无缝地馈送到原始字符串评估中。
Public Function EvaluateBooleanString(BooleanString As String) As String
Dim StrPos As Integer
Dim TermStartPos As Integer
Dim TermEndPos As Integer
Dim DepthCounter As Integer
Dim SubBool As String
Dim OrArray() As String
Dim AndArray() As String
Dim OrCounter As Integer
Dim AndCounter As Integer
Dim AndArgs As String
Dim OrArgs As String
TermStartPos = 0
TermEndPos = 0
For StrPos = 1 To Len(BooleanString)
If Mid(BooleanString, StrPos, 1) = "(" Then
DepthCounter = DepthCounter + 1
If DepthCounter = 1 Then TermStartPos = StrPos
End If
If Mid(BooleanString, StrPos, 1) = ")" Then
If DepthCounter = 1 Then
TermEndPos = StrPos
DepthCounter = DepthCounter - 1
SubBool = EvaluateBooleanString(Mid(BooleanString, TermStartPos + 1, (TermEndPos - TermStartPos) - 1))
BooleanString = Left(BooleanString, TermStartPos - 1) & SubBool & Right(BooleanString, Len(BooleanString) - TermEndPos)
TermStartPos = 0
TermEndPos = 0
StrPos = 1
End If
End If
Next StrPos
BooleanString = Replace(BooleanString, "OR", "|", , , vbTextCompare)
BooleanString = Replace(BooleanString, "AND", "&", , , vbTextCompare)
OrArray = Split(BooleanString, "|")
For OrCounter = LBound(OrArray) To UBound(OrArray)
AndArray = Split(OrArray(OrCounter), "&")
If LBound(AndArray) < UBound(AndArray) Then
For AndCounter = LBound(AndArray) To UBound(AndArray)
AndArgs = AndArgs & AndArray(AndCounter) & ","
Next AndCounter
AndArgs = Left(AndArgs, Len(AndArgs) - 1)
Else
AndArgs = AndArray(0)
End If
AndArgs = Replace(AndArgs, "not true", "false", , , vbTextCompare)
AndArgs = Replace(AndArgs, "not false", "true", , , vbTextCompare)
OrArray(OrCounter) = Application.Evaluate("=AND(" & AndArgs & ")")
AndArgs = ""
OrArgs = OrArgs & OrArray(OrCounter) & ","
Next OrCounter
OrArgs = Left(OrArgs, Len(OrArgs) - 1)
OrArgs = Replace(OrArgs, "not true", "false", , , vbTextCompare)
OrArgs = Replace(OrArgs, "not false", "true", , , vbTextCompare)
If LBound(OrArray) < UBound(OrArray) Then
EvaluateBooleanString = Application.Evaluate("=OR(" & OrArgs & ")")
Else
EvaluateBooleanString = OrArgs
End If
End Function