
Quería crear una función personalizada que fuera una abreviatura de if(somefunction(arg)=something,"sometext",somefunction(arg))
Para no tener que duplicar somefunction(arg)
cada vez que hago esto, al igual que iferror
nos permite eliminarif(iserror(somefunction(arg)),"sometext",somefunction(arg)
Por ejemplo, quiero poder escribir iftrue(somefunction(arg),"=A1","message")
y que eso sea equivalente aif(sumfunction(arg)=A1,"message",sumfunction(arg))
Lo intenté:
Function iftrue(Fx, condition, show)
iftrue = Application.WorksheetFunction.if(Fx & condition, show, Fx)
End Function
Pero da #valor.
Para diagnosticar mi problema, probé algunas funciones más simples para ver dónde me estaba equivocando. Entonces dupliqué las funciones SUMA y Si.
Esta función de "suma" funciona.
Function testsum(a, b)
test = Application.WorksheetFunction.Sum(a, b)
End Function
Pero esta función "si" no funciona.
Function testif(a, b, c)
testif = Application.WorksheetFunction.if(a, b, c)
End Function
Entonces creo que mi problema es la forma en que invoco worksheet.function.if
.
Sé que podría solucionar este problema usando VBA ifs, pero eso no es realmente lo que quiero hacer.
Respuesta1
No hayApplication.WorksheetFunction.If()
Incluso si lo hubiera, aún necesitarías incluir comillas adicionales en la parte de prueba del if. por ejemplo, si el fx se resolvió "test"
y la condición fuese "=test"
la cadena resultante sería"test = test"
Pon eso
Entonces use Evaluar en su lugar.
Necesitamos analizar la cadena en un formato determinado para Evaluar.
Necesitamos insertar comillas adicionales en la cadena resultante. por ejemplo, si el fx se resolvió "test"
y la condición fuese, "=test"
la cadena resultante sería "test = test"
.
Al poner esto en Evaluar, la función buscaría una función llamada test
. Entonces necesitamos una cadena similar a ""test"="test""
, que se resolverá en Verdadero.
Si la condición fuerasiempreuna igualdad y nunca una desigualdad que podríamos usar simplemente IF fx = condition then
en lugar de todo, incluido If tst Then
.
Esta función es más dinámica que eso ya que 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
Entonces lo llamarías así
=IFtrue(SUM(A1,A2),"=A3","Must Be True")
Editar
Puedes usar IIF() y reducir el número de líneas.
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