Criando uma função chamada IFTRUE que se comporta como IFERROR, mas para uma função retornando TRUE. Worsheetfunction.if não funciona. O que estou fazendo de errado?

1

Eu queria criar uma função personalizada que fosse uma abreviação de if(somefunction(arg)=something,"sometext",somefunction(arg)) . Então, não preciso duplicar somefunction(arg) sempre que faço isso, assim como iferror nos permite acabar com if(iserror(somefunction(arg)),"sometext",somefunction(arg)

Por exemplo, quero poder digitar iftrue(somefunction(arg),"=A1","message") e que seja equivalente a if(sumfunction(arg)=A1,"message",sumfunction(arg))

Eu tentei:

Function iftrue(Fx, condition, show)
    iftrue = Application.WorksheetFunction.if(Fx & condition, show, Fx)
End Function

Mas dá #value.

Para diagnosticar o meu problema, eu tentei algumas funções mais simples, para ver onde eu estava indo errado. Então, eu dupliquei as funções SUM e If.

Esta função "sum" funciona.

Function testsum(a, b)
    test = Application.WorksheetFunction.Sum(a, b)
End Function

Mas esta função "if" não funciona.

Function testif(a, b, c)
    testif = Application.WorksheetFunction.if(a, b, c)
End Function

Então, acho que meu problema é como invoco o worksheet.function.if .

Eu sei que eu poderia contornar isso usando o VBA ifs em vez disso, mas não é exatamente isso que eu quero fazer.

    
por Some_Guy 21.10.2016 / 14:59

1 resposta

2

Não há Application.WorksheetFunction.If()

Mesmo se houvesse você ainda precisaria enviar cotações extras para a parte de teste do if. por exemplo, se o fx fosse resolvido para "test" e a condição fosse "=test" , a cadeia resultante seria "test = test"

Coloque isso

Então, use Avaliar em vez disso.

Precisamos analisar a string em um determinado formato para Avaliar.

precisamos inserir aspas extras na string resultante. por exemplo, se o fx for resolvido para "test" e a condição for "=test" , a string resultante será "test = test" .

Colocando isso em Evaluate, a função procuraria por uma função chamada test . Portanto, precisamos de uma string igual a ""test"="test"" , que será resolvida como True.

Se a condição fosse sempre uma igualdade e nunca uma desigualdade, poderíamos simplesmente usar IF fx = condition then no lugar de tudo até e inclusive If tst Then .

Esta função é mais dinâmica do que isso, pois permite desigualdades:

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

Você então ligaria assim

=IFtrue(SUM(A1,A2),"=A3","Must Be True")

Editar

Você pode usar o IIF () e reduzir o número de linhas

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
    
por 21.10.2016 / 15:19