我试图通过连接操作数和运算符来评估逻辑表达式。在Excel 2016中是否有从文本转换为逻辑的公式,类似于VALUE()
从文本转换为数字的方式?我正在寻找一个解决方案,所以我可以动态改变条件而不改变实际的Excel公式。我已经搜索并阅读了Excel函数描述,但没有任何内容可以作为解决方案。
'The operands and operator
A1: 1
A2: >
A3: 0
'Concatenation
B4: =CONCAT(A1:A3) 'This evaluates to 1>0
B5: =A1&A2&A3 'This also evaluates to 1>0
'Some checks
C4: =ISTEXT(B4) 'This evaluates to TRUE.
C5: =ISTEXT(B5) 'This also evaluates to TRUE
D4: =ISLOGICAL(B4) 'This evaluates to FALSE
D5: =ISLOGICAL(B5) 'This also evaluates to FALSE
'Vain attempts
E4: =AND(B4,TRUE) 'This ALWAYS is TRUE, even when my desired output is FALSE
E5: =OR(B5) 'This spits out a #VALUE! error
由于我正在寻找动态的东西,我想避免使用诸如
的解决方案
=IF(A2=">",A1>A3,FALSE)
。我也更愿意避免使用UDF,但是如果没有内置函数来转换文本中的逻辑表达式并将其评估为逻辑表达式,我愿意继续使用该路径。
答案 0 :(得分:0)
基于没有内置函数处理这个问题的注释,我为逻辑创建了一个名为L()的用户定义函数(“UDF”),在内置函数之后函数N()和T(),用于数字和文本。
Function L(exp As Variant) As Variant
Dim limit As Integer
Dim counter As Integer
'Set an upper limit to how many cycles the loop may run
limit = 1000
'Assuming the possibility of nested functions, loop until the expression resolves to logical or to an error or until the loop limit has been reached
Do
exp = [exp] 'This avoids Error 2015 if exp is a Range reference. Comment if there's a better way!
exp = Application.Evaluate(exp) 'Evaluate the expression
counter = counter + 1 'Increment the loop counter
Loop Until Application.IsLogical(exp) Or Application.IsError(exp) Or counter >= limit
'Return the evaluated expression
L = exp
End Function
即使我像=L(TRUE)
或=L(CONCAT(A1:A2)&A3)
甚至=l(CONCAT(A1:A2)&"""foo""")
那样抛出一些愚蠢的东西,这个功能仍然有效。但它不会在可能应该出现的情况下抛出错误,例如=l(123)
或=l("123")
。在这些情况下,感谢计数器限制,因为123
和"123"
永远不会评估为逻辑或错误。
答案 1 :(得分:0)
要编写一个可以处理Range或Variant / String输入的UDF调用Evaluate,请尝试以下操作:
Function L(exp As Variant) As Variant
Dim vExp As Variant
vExp = exp
L = Application.Evaluate(vExp)
End Function
为什么会这样?
第vExp = exp
行是神奇的。如果exp
是一个Range,则该分配使用默认的.Value
属性并复制为Variant / String(因为我们没有使用Set
)。如果它是Variant / String,那么它就是一个直接副本。
它确实有使用Application.Evaluate
的缺点(如下所述
here)
还可以处理从VBA调用的可能性的版本,尝试
Function L(exp As Variant) As Variant
If TypeName(exp) = "Range" Then
L = exp.Worksheet.Evaluate(exp.Value)
Else
If IsError(Application.Caller) Then
'Calls from VBA are hanbled here.
' Note: Best to fully qualify any range references in exp
' to avoid unexpected references to the active sheet
L = ActiveSheet.Evaluate(exp)
Else
L = Application.Caller.Worksheet.Evaluate(exp)
End If
End If
End Function