
Я хотел создать пользовательскую функцию, которая была бы сокращением для if(somefunction(arg)=something,"sometext",somefunction(arg))
Чтобы мне не приходилось дублировать somefunction(arg)
каждый раз, когда я это делаю, так же, как iferror
позволяет нам избавиться отif(iserror(somefunction(arg)),"sometext",somefunction(arg)
Например, я хочу иметь возможность печатать, iftrue(somefunction(arg),"=A1","message")
и это будет эквивалентноif(sumfunction(arg)=A1,"message",sumfunction(arg))
Я пытался:
Function iftrue(Fx, condition, show)
iftrue = Application.WorksheetFunction.if(Fx & condition, show, Fx)
End Function
Но это дает #ценность.
Чтобы диагностировать свою проблему, я попробовал несколько более простых функций, чтобы увидеть, где я ошибаюсь. Поэтому я продублировал функции SUM и If.
Эта функция «суммы» работает.
Function testsum(a, b)
test = Application.WorksheetFunction.Sum(a, b)
End Function
Но эта функция «если» не работает.
Function testif(a, b, c)
testif = Application.WorksheetFunction.if(a, b, c)
End Function
Поэтому я думаю, что проблема в том, как я вызываю worksheet.function.if
.
Я знаю, что можно было бы обойти это, используя вместо этого операторы VBA if, но это не совсем то, что мне нужно.
решение1
Здесь нетApplication.WorksheetFunction.If()
Даже если бы это было так, вам все равно пришлось бы вставлять дополнительные кавычки в тестовую часть if. Например, если бы fx разрешался в "test"
и условие было бы "=test"
результирующей строкой"test = test"
Положи это
Поэтому вместо этого используйте Evaluate.
Нам необходимо проанализировать строку в определенном формате для Evaluate.
нам нужно вставить дополнительные кавычки в результирующую строку. например, если fx разрешен как "test"
и условие было , "=test"
результирующая строка будет "test = test"
.
Если поместить это в Evaluate, функция будет искать функцию с именем test
. Поэтому нам нужна строка, которая похожа на ""test"="test""
, которая будет разрешена как True.
Если условие быловсегдаравенство и никогда неравенство, которое мы могли бы просто использовать IF fx = condition then
вместо всего, вплоть до If tst Then
.
Эта функция более динамична, чем предыдущая, поскольку допускает неравенства:
Function IFTrue(fx, condition As String, show)
Dim tst As Boolean
Dim z As Integer
Dim t As String
'test whether the condition is assuming "="
If InStr("<>=", Left(condition, 1)) = 0 Then condition = "=" & condition
'Find whether there is one or two qulifiers
If InStr("<>=", Mid(condition, 2, 1)) > 0 Then z = 2 Else z = 1
'Parse string to remove qulifiers from the quotes and make everything a string
t = """" & fx & """" & Left(condition, z) & """" & Mid(condition, z + 1) & """"
'evaluate the formula string to resolve to True or False
tst = Application.Caller.Parent.Evaluate(t)
If tst Then
IFTrue = show
Else
IFTrue = fx
End If
End Function
Тогда вы бы назвали это так
=IFtrue(SUM(A1,A2),"=A3","Must Be True")
Редактировать
Вы можете использовать IIF() и сократить количество строк
Function IFTrue2(fx, condition As String, show)
Dim z As Integer
'test whether the condition is assuming "="
If InStr("<>=", Left(condition, 1)) = 0 Then condition = "=" & condition
'Find whether there is one or two qulifiers
If InStr("<>=", Mid(condition, 2, 1)) > 0 Then z = 2 Else z = 1
IFTrue2 = IIf(Application.Caller.Parent.Evaluate("""" & fx & """" & Left(condition, z) & """" & Mid(condition, z + 1) & """"), show, fx)
End Function