viernes, 20 de noviembre de 2009

Solución a un problema con VBA: SELECT CASE.

Solicitaba ayuda un usuario a este respecto:

Quiero crear funcion con SI anidada pero por lo visto supera el limite permitido y da error.
Se trata de valores de pH. Para determinados intervalos de pH se le adjudica un numero que es una nota de calidad:
(7-8]=1
(6,5-7] y [8-8,5) = 2
(6-6,5] y [8,5-9) = 3
(5,5-6] y [9-9,5) = 4
(4,5-5,5] y [9,5-10,5) = 5
<=4,5 y >=10,5 = 6
Como veis, menos en el primero, hay dos intervalos para cada nota.


Efectivamente vemos cómo nos sería tedioso, no imposible, solucionar este problema empleando un SI anidado, aunque Excel 2003 sólo nos permita anidar hasta un máximo de siete funciones, sin embargo, para Excel 2007 es factible, pues hace posible anidar hasta 64 funciones SI...
Por tanto, en este caso propuesto, podríamos intentar resolverlo con una función Si anidada (en ambas versiones funcionaría igual), sobre la tabla de valores propuesta:


Si asignamos un nombre a la celda F1, la llamaremos pH, para facilitar el entendimiento de la siguiente fórmula:
=SI(O(ph<=4,5;ph>=10,5);6;SI(O(Y(ph>4,5;ph<=5,5);Y(ph>=9,5;ph<10,5));5;SI(O(Y(ph>5,5;ph<=6);Y(ph>=9;ph<9,5));4;SI(O(Y(ph>6;ph<=6,5);Y(ph>=8,5;ph<9));3;SI(O(Y(ph>6,5;ph<=7);Y(ph>=8;ph<8,5));2;SI(Y(ph>7;ph<8);1))))))
en la que hemos ido pasando por todo los intervalos, aprovechando la coincidencia de esas 'notas de calidad' para cada dos intervalos, para lo que he empleado la funciones lógicas O e Y (ya vistas en entradas anteriores).
Sin duda, la labor de construir esta fórmula es árdua y llevaría asociada la posibilidad de cometer un error en su desarrollo, por este motivo, cuando tenemos que trabajar con esta cantidad de intervalos, se recomienda hacer uso de las funciones definidas por el usuario (UDF).
Desarrollamos, hace algún tiempo, la manera de definir estas funciones personalizadas (ver función definida por el usuario); y es precisamente este desarrollo el que debemos implantar también en este caso.
Abrimos el editor de Visual Basic, Insertamos un Procedimiento de Función, y empleando la instrucción SELECTCASE definimos todos los casos posibles de pH para determinar nuestra nota de calidad.
La programación sería:


Con lo que tendríamos resuelto igualmente el problema:


También se podría haber desarrollado en VBA empleando la instrucción IF...THEN

4 comentarios:

  1. tengo 150 proveedores con su respectivo RUC, necesito, en otra hoja2 en A escribir el ruc de cualquiera y que me bote el B el nombre del proveedor . quien ayuda

    ResponderEliminar
  2. Hola,
    la solución que necesitas pasa por emplear la función BUSCARV(valor buscado; matriz donde buscar; indicador columna; tipo coincidencia);
    puedes ver su funcionamiento en
    http://excelforo.blogspot.com/2009/06/funciones-de-busqueda-buscarv-y-buscarh.html
    En tu caso sería, en la hoja2, en la celda B1:
    =BUSCARV(celda A1; rango datos; 2; 0)
    donde tu rango de datos es el listado de dos columnas que tienes en la hoja1 (primera columna es el RUC, y la segunda el Nomnbre del proveedor).
    Espero que sea lo que buscabas.
    Saludos

    ResponderEliminar
  3. Alguien me puede ayudar como hago para hacer la siguiente funcion , 1 si es hombre y 2 si es mujer,
    SI(Y(F7=1;G14>=5;G14<=13);"deportista";SI(Y(F7=1;G14>=14;G14<=18);"fitness";SI(Y(F7=1;G14>=19;G14<=24);"Riesgo Potencial";"obesidad"));(SI(Y(F7=2;G14>=12;G14<=22);"deportista";SI(Y(F7=2;G14>=16;G14<=25);"fitness";SI(Y(F7=2;G14>=16;G14<=25);"Riesgo Potencial";"obesidad")

    ResponderEliminar
    Respuestas
    1. Hola,
      tendrías que contruir tu función con un SELECT CASE anidado dentro de otro.
      Puedes ver un ejemplo casi idéntico al que planteas en:
      http://excelforo.blogspot.com.es/2010/04/select-case-anidado.html
      Un saludo

      Eliminar