
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)
cada vez que faço isso, assim como iferror
nos permite acabar comif(iserror(somefunction(arg)),"sometext",somefunction(arg)
Por exemplo, quero poder digitar iftrue(somefunction(arg),"=A1","message")
e que isso seja equivalente aif(sumfunction(arg)=A1,"message",sumfunction(arg))
Tentei:
Function iftrue(Fx, condition, show)
iftrue = Application.WorksheetFunction.if(Fx & condition, show, Fx)
End Function
Mas dá #valor.
Para diagnosticar meu problema, tentei algumas funções mais simples, para ver onde estava errando. Então dupliquei as funções SUM e If.
Esta função "soma" 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 é a maneira como estou invocando o arquivo worksheet.function.if
.
Eu sei que poderia contornar isso usando ifs do VBA, mas não é isso que eu quero fazer.
Responder1
Não háApplication.WorksheetFunction.If()
Mesmo se houvesse, você ainda precisaria inserir aspas extras na parte de teste do if. por exemplo, se o fx fosse resolvido "test"
e a condição fosse, "=test"
a string resultante seria"test = test"
Coloque isso
Então use Avaliar.
Precisamos analisar a string em um determinado formato para Avaliar.
precisamos colocar aspas extras na string resultante. por exemplo, se o fx fosse resolvido "test"
e a condição fosse "=test"
, a string resultante seria "test = test"
.
Colocando isso em Avaliar, a função procuraria uma função chamada test
. Portanto, precisamos de uma string semelhante a ""test"="test""
, que será resolvida como True.
Se a condição fossesempreuma igualdade e nunca uma desigualdade que 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 chamaria 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