Siete funciones SI()
Publicado por JuanC (792 intervenciones) el 10/04/2007 14:38:08
A aquellos que quieran darme una mano testeando, corrigiendo
y mejorando este humilde pero ambicioso proyecto...
'//-------------------------------------------------------------
'// Función: SIEx(ParamArray a() As Variant) As Variant
'//-------------------------------------------------------------
'// Versión: 1.0 (Beta) // Desarrollado en Office 2000
'// Creado: Lunes 9 de Abril de 2007
'// Autor: JuanC
'// Contacto: [email protected]
'//-------------------------------------------------------------
'// Comentarios
'//-------------------------------------------------------------
'//Surge como respuesta al problema general
'//de utilizar la función SI() con un nivel de
'//anidamiento superior a siete. (límite para cualquier función)
'//Si bien el nº de anidamientos sigue siendo "el problema",
'//las posibilidades aumentan considerablemente.
'//También es sabido que además del problema del anidamiento,
'//existe el problema de las funciones "demasiado largas"???
'//Conclusión, no es un asunto sencillo para resolver...
'//Pretendo crear una función similar a la función
'//lógica SI() pero optimizada, es decir, evitar el
'//uso excesivo de anidamientos e intentar trabajar con fórmulas
'//relativamente "más pequeñas" y más legibles, además de
'//poder evaluar más condiciones a la vez.
'//La versión creada hasta el momento soporta 29 argumentos,
'//lo cual permite 14 comparaciones (se alcanzan más si la
'//combina con la función SI())
'//Según algunas pruebas y comparaciones, se supera la
'//"capacidad" de la función SI() entre un 20% y un 30%;
'//obviamente los resultados mejoran cuando se combinan
'//las dos funciones SI() y SIEx(), llegando a más del 40%.
'//-------------------------------------------------------------
'// Uso (demás está decir que el código va en un módulo...)
'//-------------------------------------------------------------
'//Como la función SI() estándar
'//=SIEx(prueba_lógica; valor_si_verdadero; valor_si_falso)
'//De una manera más "compleja" (evaluando más condiciones)
'//=SIEx(p_lógica0; val_si_verd0; p_lógica2; val_si_verd2; ...)
'//-------------------------------------------------------------
'// Ejemplos
'//-------------------------------------------------------------
'//=SIEx(A1>B1; C1; A1<B1; D1; A1="a"; E1; -1)
'// fórmula equivalente con la función SI()
'//=SI(A1>B1; C1; SI(A1<B1; D1; SI(A1="a"; E1; -1)))
'//=SIEx(ELEGIR(DIASEM("9/4/07");0;"Lun";0;0;0;0;0); "Ufa!"; "")
'// devuelve Ufa!
'// fórmula equivalente con la función SI()
'//=SI(ELEGIR(DIASEM("9/4/07");0;"Lun";0;0;0;0;0); "Ufa!" ;"")
'// devuelve #¡VALOR! (la prueba_lógica no puede ser texto)
'//-------------------------------------------------------------
'// Información "extra"
'//-------------------------------------------------------------
'//El siguiente esquema intenta explicar brevemente
'//el mecanismo utilizado por la función.
'//Forma general:
'//=SIEx(A; B; 2[C;D; 4[E;F; 6...]])
'---------------------------------------------------------------
'Nº Prueba Condicional
'---------------------------------------------------------------
'0 SI(A;B; [2]) //La prueba 0 no se cumple (A=Falso),
'2 SI(C;D; [4]) //evaluar la condición 2 y así
'4 SI(D;E; [6]) //sucesivamente hasta finalizar...
'6 SI(F;G; [8])
'...
'28 SI(Xi;Xi+1; 29)
'//-------------------------------------------------------------
'// A continuación el código... para los más curiosos...
'// y para aquellos que quieran colaborar, probando,
'// revisando y depurando el código...
'// El código no está comentado; considero que no es "difícil".
'// Agradezco su atención y cualquier colaboración positiva.
'//
'// "Mas naides se crea ofendido, pues a ninguno incomodo;
'// ...,
'// no es para mal de ninguno sino para el bien de todos".
'// "Martín Fierro", José Hernández
'//
'// Saludos desde Baires, JuanC
'//-------------------------------------------------------------
Option Explicit
Public Function SIEx(ParamArray a() As Variant) As Variant
Dim iMax As Byte, i As Byte, j As Byte, Exp As Variant
On Error Resume Next
Application.Volatile
iMax = UBound(a)
For i = 0 To 28 Step 2
If IsMissing(a(i)) Then
Exp = False
ElseIf TypeName(a(i)) = "Range" Then
If IsEmpty(a(i)) Then
SIEx = Null
Exit For
Else
If IsDate(a(i)) Then
Exp = True
ElseIf IsNumeric(a(i)) Or _
VarType(a(i)) = vbString Then
Exp = a(i)
ElseIf VarType(a(i)) = vbError Then
SIEx = a(i)
Exit For
Else
Exp = Evaluate(CStr(a(i)))
End If
End If
ElseIf IsDate(a(i)) Then
Exp = True
ElseIf IsNumeric(a(i)) _
Or TypeName(a(i)) = "String" Then
Exp = a(i)
ElseIf VarType(a(i)) = vbError Then
SIEx = a(i)
Exit For
Else
Exp = Evaluate(a(i))
End If
j = i + 1
If Exp Then
If j >= iMax Then j = j - 1
If IsMissing(a(j)) Then
SIEx = Null
ElseIf IsDate(a(j)) Then
SIEx = CDate(a(j))
ElseIf TypeName(a(j)) = "Range" Then
If IsNumeric(a(j)) Or _
VarType(a(j)) = vbString Or _
VarType(a(j)) = vbError Then
SIEx = a(j)
Else
SIEx = Evaluate(CStr(a(j)))
End If
ElseIf IsNumeric(a(j)) Or _
TypeName(a(j)) = "String" Then
SIEx = a(j)
Else
SIEx = Evaluate(a(j))
End If
Exit For
End If
Next
End Function
y mejorando este humilde pero ambicioso proyecto...
'//-------------------------------------------------------------
'// Función: SIEx(ParamArray a() As Variant) As Variant
'//-------------------------------------------------------------
'// Versión: 1.0 (Beta) // Desarrollado en Office 2000
'// Creado: Lunes 9 de Abril de 2007
'// Autor: JuanC
'// Contacto: [email protected]
'//-------------------------------------------------------------
'// Comentarios
'//-------------------------------------------------------------
'//Surge como respuesta al problema general
'//de utilizar la función SI() con un nivel de
'//anidamiento superior a siete. (límite para cualquier función)
'//Si bien el nº de anidamientos sigue siendo "el problema",
'//las posibilidades aumentan considerablemente.
'//También es sabido que además del problema del anidamiento,
'//existe el problema de las funciones "demasiado largas"???
'//Conclusión, no es un asunto sencillo para resolver...
'//Pretendo crear una función similar a la función
'//lógica SI() pero optimizada, es decir, evitar el
'//uso excesivo de anidamientos e intentar trabajar con fórmulas
'//relativamente "más pequeñas" y más legibles, además de
'//poder evaluar más condiciones a la vez.
'//La versión creada hasta el momento soporta 29 argumentos,
'//lo cual permite 14 comparaciones (se alcanzan más si la
'//combina con la función SI())
'//Según algunas pruebas y comparaciones, se supera la
'//"capacidad" de la función SI() entre un 20% y un 30%;
'//obviamente los resultados mejoran cuando se combinan
'//las dos funciones SI() y SIEx(), llegando a más del 40%.
'//-------------------------------------------------------------
'// Uso (demás está decir que el código va en un módulo...)
'//-------------------------------------------------------------
'//Como la función SI() estándar
'//=SIEx(prueba_lógica; valor_si_verdadero; valor_si_falso)
'//De una manera más "compleja" (evaluando más condiciones)
'//=SIEx(p_lógica0; val_si_verd0; p_lógica2; val_si_verd2; ...)
'//-------------------------------------------------------------
'// Ejemplos
'//-------------------------------------------------------------
'//=SIEx(A1>B1; C1; A1<B1; D1; A1="a"; E1; -1)
'// fórmula equivalente con la función SI()
'//=SI(A1>B1; C1; SI(A1<B1; D1; SI(A1="a"; E1; -1)))
'//=SIEx(ELEGIR(DIASEM("9/4/07");0;"Lun";0;0;0;0;0); "Ufa!"; "")
'// devuelve Ufa!
'// fórmula equivalente con la función SI()
'//=SI(ELEGIR(DIASEM("9/4/07");0;"Lun";0;0;0;0;0); "Ufa!" ;"")
'// devuelve #¡VALOR! (la prueba_lógica no puede ser texto)
'//-------------------------------------------------------------
'// Información "extra"
'//-------------------------------------------------------------
'//El siguiente esquema intenta explicar brevemente
'//el mecanismo utilizado por la función.
'//Forma general:
'//=SIEx(A; B; 2[C;D; 4[E;F; 6...]])
'---------------------------------------------------------------
'Nº Prueba Condicional
'---------------------------------------------------------------
'0 SI(A;B; [2]) //La prueba 0 no se cumple (A=Falso),
'2 SI(C;D; [4]) //evaluar la condición 2 y así
'4 SI(D;E; [6]) //sucesivamente hasta finalizar...
'6 SI(F;G; [8])
'...
'28 SI(Xi;Xi+1; 29)
'//-------------------------------------------------------------
'// A continuación el código... para los más curiosos...
'// y para aquellos que quieran colaborar, probando,
'// revisando y depurando el código...
'// El código no está comentado; considero que no es "difícil".
'// Agradezco su atención y cualquier colaboración positiva.
'//
'// "Mas naides se crea ofendido, pues a ninguno incomodo;
'// ...,
'// no es para mal de ninguno sino para el bien de todos".
'// "Martín Fierro", José Hernández
'//
'// Saludos desde Baires, JuanC
'//-------------------------------------------------------------
Option Explicit
Public Function SIEx(ParamArray a() As Variant) As Variant
Dim iMax As Byte, i As Byte, j As Byte, Exp As Variant
On Error Resume Next
Application.Volatile
iMax = UBound(a)
For i = 0 To 28 Step 2
If IsMissing(a(i)) Then
Exp = False
ElseIf TypeName(a(i)) = "Range" Then
If IsEmpty(a(i)) Then
SIEx = Null
Exit For
Else
If IsDate(a(i)) Then
Exp = True
ElseIf IsNumeric(a(i)) Or _
VarType(a(i)) = vbString Then
Exp = a(i)
ElseIf VarType(a(i)) = vbError Then
SIEx = a(i)
Exit For
Else
Exp = Evaluate(CStr(a(i)))
End If
End If
ElseIf IsDate(a(i)) Then
Exp = True
ElseIf IsNumeric(a(i)) _
Or TypeName(a(i)) = "String" Then
Exp = a(i)
ElseIf VarType(a(i)) = vbError Then
SIEx = a(i)
Exit For
Else
Exp = Evaluate(a(i))
End If
j = i + 1
If Exp Then
If j >= iMax Then j = j - 1
If IsMissing(a(j)) Then
SIEx = Null
ElseIf IsDate(a(j)) Then
SIEx = CDate(a(j))
ElseIf TypeName(a(j)) = "Range" Then
If IsNumeric(a(j)) Or _
VarType(a(j)) = vbString Or _
VarType(a(j)) = vbError Then
SIEx = a(j)
Else
SIEx = Evaluate(CStr(a(j)))
End If
ElseIf IsNumeric(a(j)) Or _
TypeName(a(j)) = "String" Then
SIEx = a(j)
Else
SIEx = Evaluate(a(j))
End If
Exit For
End If
Next
End Function
Valora esta pregunta
0