Vba 解析函数的参数

Vba 解析函数的参数,vba,excel,udf,Vba,Excel,Udf,我有一个用VBA编写的自定义项,我从工作表中调用它。该函数采用3个参数:函数CONCATIF(arg1作为范围,arg2作为布尔值,可选arg3作为范围)作为变量 UDF需要知道arg2的公式,即在将arg2计算为TRUE或FALSE之前拦截arg2。为此,我使用了Application.Caller.Formula,它(以最简单的形式)给出了“=CONCATIF(arg1,arg2,arg3)(或者代替,arg3)或者,)) 然后,我可以通过简单地使用Split(Application.Cal

我有一个用VBA编写的自定义项,我从工作表中调用它。该函数采用3个参数:
函数CONCATIF(arg1作为范围,arg2作为布尔值,可选arg3作为范围)作为变量

UDF需要知道arg2的公式,即在将arg2计算为
TRUE
FALSE
之前拦截arg2。为此,我使用了
Application.Caller.Formula
,它(以最简单的形式)给出了
“=CONCATIF(arg1,arg2,arg3)
(或者代替
,arg3)
或者
,)
) 然后,我可以通过简单地使用
Split(Application.Caller.Formula,“,”)

不过,我想处理几个问题

  • 在逗号处拆分意味着我的任何参数都不能包含逗号,它们可能必须包含逗号
  • 公式可能是嵌套的,例如
    =SUM(1,IF(CONCATIF(arg1,arg2,arg3)=“a”,1,0))
    ,因此我不知道拆分数组中的哪一项是arg2。(我认为这应该很容易解决:在字符串中找到
    CONCATIF
    ,切掉开头,数一数其后的开/闭括号,直到open=close,然后切掉结尾
  • 参数可以是公式本身;
    arg1
    可以是对范围的引用,而不是实际范围
  • 棘手:
    CONCATIF
    可能会在一个公式中出现多次,但使用标准字符串搜索,我总是会选择第一个(如果在一个公式中有多个,我可能只需要返回一个错误,因为我根本不知道如何解决这个问题)
我想要的是:一种从调用方单元格中获取正确的
CONTCATIF()
公式的通用方法,然后将三个参数解析为数组中的三个字符串。作为参考,以下是我的代码(抱歉,命名与问题有点不同)


如果您有一个合适的公式解析器,您可以解决所有这些问题,除了在一个公式中处理对CONCATIF的多个调用:我不知道有什么方法可以100%找出当前正在调用的CONCATIF实例

有各种各样的公式解析器,你可以适应:从这里开始

包含代码始终是一种良好的做法。即使不需要它,也表明您尽了最大的努力来解决问题。发布您的代码。@tompreston已发布,但我不知道它会有多大帮助,因为我已经在问题中概述了我所知道的一切!
Public Function CONCATIF(checkRange As Range, testFunction As Boolean, Optional concatRange As Range) As Variant

Dim concatArray() As Variant
Dim formulaText As String, formulaParts() As String, formulaTest As String
Dim topLeft As Range, subCell As Range
Dim newTest As String
Dim results() As Boolean, result As Boolean
Dim loopval As Long
'''
'input checking
'''
If concatRange Is Nothing Then
    concatArray = checkRange
ElseIf Not (checkRange.Cells.Count = concatRange.Cells.Count And checkRange.Rows.Count = concatRange.Rows.Count And checkRange.Rows.Count = 1) Then
    CONCATIF = CVErr(xlErrValue)
    Exit Function
Else
    concatArray = concatRange.Value2
End If
'''
'Extract test function
'''
formulaText = Application.Caller.Formula
formulaParts = Split(formulaText, ",") 'Assumes 1)no commas 2) formula isn't nested 3) formula doesn't contain nested functions
formulaTest = formulaParts(1) 'get the test function as a string to be evaluated
Set topLeft = checkRange.Cells(1, 1) 'This is the 'reference' cell - substitute each of the values in the check range for this to test each one
ReDim results(0)
On Error GoTo Err
'''
'Run test on each of the cells in checkRange
'''
For Each subCell In checkRange
    newTest = Replace(formulaTest, topLeft.Address(0, 0), subCell.Address)
    If Count(newTest, "(") < Count(newTest, ")") Then 'when optional parameter is missed out, sometimes you get a ,) and sometimes a ) after formulaTest, so we must check
        newTest = Left(newTest, Len(newTest) - 1)
    End If
    result = (Evaluate(newTest))
skip:
    results(UBound(results)) = result
    ReDim Preserve results(UBound(results) + 1)
Next subCell
'''
'Then use array of Booleans for UDF function
'''
CONCATIF = "test"
Exit Function

Err:
result = False 'if the evaluate results in an error, it means the input was invalid, so probably won't meet the criteria, therefore can be ignored
loopval = loopval + 1
If loopval > checkRange.Cells.Count Then CONCATIF = CVErr(xlErrNA): Exit Function 'exit error loop gracefully if I've missed some edge case
Resume skip

End Function
Function Count(str As String, chr As String) As Long 'counts the number of instances of a character in a string
     Count = Len(str) - Len(Replace(str, chr, ""))
End Function