【问题标题】:How can I extract the 'logical_test' from an if statement in excel?如何从 excel 中的 if 语句中提取“logical_test”?
【发布时间】:2020-04-18 19:32:32
【问题描述】:

我正在整理一个用于计算的 Excel 电子表格,并且我需要能够显示与决策相关的公式,在大多数情况下它非常简单,但是当我遇到“如果”公式时一个 excel 单元格,我不想显示 value_if_true 和 value_if_false...只是logical_test 值。

示例:

公式为:=if(and(5<=A1, A1<=10),"Pass", "Fail");

结果将是:"and(5<=A1, A1<=10)"

我需要能够处理可能包括嵌套 if 语句的复杂逻辑测试,因此仅在逗号处拆分将无法可靠地工作。同样,value_if_true 和 value_if_false 语句也可以包含 if 语句。

有什么想法吗?

【问题讨论】:

  • 您打算如何表示逻辑测试?如果可以有多个嵌套级别,似乎会很棘手。
  • 如果有=A2+5*C5+B6/IF(X3=IF(Y2=9,4,0),5,7)这样的公式也会变得很棘手
  • 这是下一个挑战。对于简单的 if 语句来说这很容易,我将使用不同的函数来生成用户可读的方程(对于不是 excel 专家的用户)。
  • 我不确定您是否可以从一组嵌套的逻辑测试中提取单个独立的逻辑测试,这些逻辑测试一起可能不会仅评估为真/假,而是多个结果之一。

标签: vba excel


【解决方案1】:

如果对你的要求有清楚的理解,那么你可以使用这样的东西(只能与IF()声明一起使用:

Function extrIf(ByVal ifstatement As Range) As String

Dim S$, sRev$, x%, k
S = Replace(Replace(ifstatement.Formula, "IF(", "\"), "),", ")|")

sRev = StrReverse(S)

If InStr(1, sRev, "|") > InStr(1, sRev, "\") Or InStr(1, sRev, "|") = 0 Then
    x = InStr(1, StrReverse(Left(sRev, InStr(1, sRev, "\"))), ",") - 1
    S = Mid(S, 1, Len(S) - InStr(1, sRev, "\") + x) & "|"
End If

sRev = ""

For Each k In Split(S, "|")
    If k <> "" Then
        If k Like "*\*" Then
            sRev = sRev & ", " & Mid(k, InStr(1, k, "\") + 1, 999)
        End If
    End If
Next

extrIf = Mid(sRev, 3, 999)

End Function

示例:

测试:

也许这对你来说不是完整的解决方案,但我认为它可能会给你正确的方向。

【讨论】:

    【解决方案2】:

    如果单元格公式以 If 语句开头,那么您可以通过确定第一个逗号的位置来返回逻辑测试(从第一个左括号之后开始),其中前一个左括号的总和 - 前一个关闭的总和= 0。

    公式

    Function ExtractIfTest(Target As Range) As String
        Dim ch As String, s As String
        Dim openP  As Long
        Dim x As Long
        s = Target.formula
    
        For x = 5 To Len(s)
            ch = Mid(s, x, 1)
            If Mid(s, x, 1) = "(" Then
                openP = openP + 1
            ElseIf Mid(s, x, 1) = ")" Then
                openP = openP - 1
            ElseIf Mid(s, x, 1) = "," And openP = 0 Then
                ExtractIfTest = Mid(s, 5, x - 12)
            End If
        Next
    End Function
    

    结果

    可能存在不带括号的逗号A1,B1 的情况。如果发生这种情况,只需用括号 (A1,B1)

    转义它们

    【讨论】:

    • 这不是我所追求的。我需要提取逻辑测试,然后我可以在不同的函数中使用它(例如 MakeReadable(logical_test as string))。但是通过更清楚地定义logical_test,您可能会有所收获。如果我可以将logical_test 包裹在花括号或类似的东西中怎么办? (我不能......我检查过)。另一个想法是,我可以遍历一个公式字符串并创建一个要查找的字符串(左括号和引号),并且只有在考虑了所有左括号和引号后才接受第一个逗号......
    • 逻辑测试是否总是包含在If() 语句中?
    • 由logical_test 我指的是if() 语句的第一个参数。 !Image
    • @GerHick 我更新了我的答案以提取 if 语句的第一部分。我没有意识到您不会收到更新答案的通知。
    【解决方案3】:

    我编写了一个 UDF,可以提取目标公式的任何参数。它与 Thomas 答案中的相近,但更具全局性,并且考虑到了可以包含逗号或括号的字符串。

    Function ExtractFormulaParameter(Target As Range, Optional Position As Long = 1) As Variant
        Dim inString As Boolean
        Dim formula As String
        Dim st As Long, sp As Long, i As Long, c As String
        Dim parenthesis As Long, comma As Long
        formula = Target.formula
        st = 0: sp = 0
        If Position <= 0 Then ExtractFormulaParameter = CVErr(xlErrValue): Exit Function
    
        For i = 1 To Len(formula)
            c = Mid$(formula, i, 1)
            If inString Then
                If c = """" Then
                    inString = False
                End If
            Else
                Select Case c
                Case """"
                    inString = True
                Case "("
                    parenthesis = parenthesis + 1
                    If parenthesis = 1 And Position = 1 Then
                        st = i + 1
                    End If
                Case ")"
                    parenthesis = parenthesis - 1
                    If parenthesis = 0 And sp = 0 Then sp = i: Exit For
                Case ","
                    If parenthesis = 1 Then
                        comma = comma + 1
                        If Position = 1 And comma = 1 Then sp = i: Exit For
                        If Position > 1 And comma = Position - 1 Then st = i + 1
                        If Position > 1 And comma = Position Then sp = i: Exit For
                    End If
                Case Else
                End Select
            End If
        Next i
    
        If st = 0 Or sp = 0 Then
            ExtractFormulaParameter = CVErr(xlErrNA)
        Else
            ExtractFormulaParameter = Mid$(formula, st, sp - st)
        End If
    End Function
    

    默认情况下它返回第一个参数,但您也可以返回第二个或第三个参数,它应该适用于任何公式。

    【讨论】:

      【解决方案4】:

      感谢大家的回复。我对此进行了更多思考,最终提出了与上面发布的解决方案类似的解决方案 - 本质上是字符串操作,以提取我们期望找到逻辑测试的文本。

      效果很好,我相信我也可以用它从子字符串中提取更多的逻辑测试。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-19
        • 1970-01-01
        • 1970-01-01
        • 2018-12-30
        相关资源
        最近更新 更多