Las mejoras e innovaciones introducidas
han convertido a Formato Condicional en el nuevo Excel (2007/2010) en una aun más excelente herramienta para analizar datos. En esta nota mostraré como usar Formato Condicional para resumir en forma eficiente y sencilla los resultados de una encuesta.
Hace unas semanas recibí una consulta sobre como resumir concisamente una encuesta sobre el nivel de servicio de ciertos departamentos de una empresa. La encuesta fue montada usando la herramienta Formularios de la aplicación Documentos de Google.
Google va acumulando los resultados en una hoja de cálculo que puede descargarse a Excel. Los encuestados debían calificar en una escala de 0 (pésimo) a 5 (excelente) el funcionamiento de ciertos departamentos de servicios de la empresa.
Veremos como podemos crear una “termo-mapa” para mostrar en forma concisa y práctica los resultados de la encuesta.
Empezamos por convertir la matriz de los resultados en una tabla (Insertar-Tabla)
El próximo paso es crear una tabla dinámica, que ubicamos en una nueva hoja. Personalmente no me agrada el diseño por defecto de las tablas dinámicas en el nuevo Excel, por lo que uso Opciones de tablas-Mostrar para definir el diseño clásico de tabla dinámica que también permite arrastrar los campos a la cuadrícula
Arrastramos le campo de departamentos al área de las filas y cada uno de los campos de las preguntas al área de los valores. Resumimos los valores con la función Promedio y ajustamos el formato de los números.
Quitamos “Promedio de” en los encabezados de la columna para hacerlos más legibles.
Seleccionamos el área de valores y aplicamos Formato Condicional –Escala de Color
El resultado habla por si mismo.
Cuanto más verde es el fondo, mejor la calificación y, por lo contrario, cuando más rojo peor la calificación. Claramente podemos ver que el mejor departamento en la calificación general es Recursos Humanos. El nivel de servicio del Taller es claramente deplorable!
Sugerencias y ayuda para Excel en español. Ejemplos de funciones y fórmulas, gráficos, automatización con Vba, Power Query y PowerPivot
lunes, febrero 27, 2012
martes, febrero 21, 2012
Validación de datos en varias hojas – código mejorado
Gracias al comentario del amigo Juan Munevar en mi nota anterior, vimos que el código para evitar duplicados a través de varias hojas tiene un inconveniente: si la propiedad "mover después de presionar Entrar" está activada el código puede borrar el contenido de la celda equivocada.
Para que el código de la anterior funcione, la propiedad "mover después de presionar Entrar" debe estar desactivada
Como no podemos saber de antemano cuál es la definición del cuaderno debemos escribir un código para cubra todas las posibilidades. Lo que debemos tomar en cuenta es el orden de los eventos cuando apretamos Entrar.
El código evalúa el valor de la celda que era la celda activa al disparar el evento (Target). Es decir, si la opción de mover la selección después de apretar Entrar no está activada, borramos el contenido de la celda activa que es la misma que Target; si se mueve a la izquierda Target se encuentra a la derecha de la celda activa; si se mueve hacia abajo, Target se encuentra arriba; si se mueve hacia arriba, Target es la celda inmediata inferior.
Un caso particular es si la selección se mueve a la izquierda. En este caso, si la celda evaluada está en la columna A, Target coincide con la celda activa ya que Excel no puede seleccionar una celda que no existe.
En definitiva, el código es el siguiente:
Sub valid_accross_sheets(valValue)
Dim iValCalc As Integer
iValCalc = WorksheetFunction.CountIf(Range("Lista1"), valValue) + _
WorksheetFunction.CountIf(Range("Lista2"), valValue) + _
WorksheetFunction.CountIf(Range("Lista3"), valValue)
If iValCalc > 1 Then
MsgBox "El valor " & ActiveCell.Value & " ya existe"
Select Case Application.MoveAfterReturn
Case Is = False
ActiveCell.ClearContents
Case Else
Select Case Application.MoveAfterReturnDirection
Case Is = xlDown
ActiveCell.Offset(-1, 0).ClearContents
Case Is = xlUp
ActiveCell.Offset(1, 0).ClearContents
Case Is = xlToRight
ActiveCell.Offset(0, -1).ClearContents
Case Is = xlToLeft
If ActiveCell.Column = 1 Then
ActiveCell.ClearContents
Else
ActiveCell.Offset(0, 1).ClearContents
End If
End Select
End Select
End If
End Sub
El cuaderno puede descargarse aquí.
Para que el código de la anterior funcione, la propiedad "mover después de presionar Entrar" debe estar desactivada
Como no podemos saber de antemano cuál es la definición del cuaderno debemos escribir un código para cubra todas las posibilidades. Lo que debemos tomar en cuenta es el orden de los eventos cuando apretamos Entrar.
El código evalúa el valor de la celda que era la celda activa al disparar el evento (Target). Es decir, si la opción de mover la selección después de apretar Entrar no está activada, borramos el contenido de la celda activa que es la misma que Target; si se mueve a la izquierda Target se encuentra a la derecha de la celda activa; si se mueve hacia abajo, Target se encuentra arriba; si se mueve hacia arriba, Target es la celda inmediata inferior.
Un caso particular es si la selección se mueve a la izquierda. En este caso, si la celda evaluada está en la columna A, Target coincide con la celda activa ya que Excel no puede seleccionar una celda que no existe.
En definitiva, el código es el siguiente:
Sub valid_accross_sheets(valValue)
Dim iValCalc As Integer
iValCalc = WorksheetFunction.CountIf(Range("Lista1"), valValue) + _
WorksheetFunction.CountIf(Range("Lista2"), valValue) + _
WorksheetFunction.CountIf(Range("Lista3"), valValue)
If iValCalc > 1 Then
MsgBox "El valor " & ActiveCell.Value & " ya existe"
Select Case Application.MoveAfterReturn
Case Is = False
ActiveCell.ClearContents
Case Else
Select Case Application.MoveAfterReturnDirection
Case Is = xlDown
ActiveCell.Offset(-1, 0).ClearContents
Case Is = xlUp
ActiveCell.Offset(1, 0).ClearContents
Case Is = xlToRight
ActiveCell.Offset(0, -1).ClearContents
Case Is = xlToLeft
If ActiveCell.Column = 1 Then
ActiveCell.ClearContents
Else
ActiveCell.Offset(0, 1).ClearContents
End If
End Select
End Select
End If
End Sub
El cuaderno puede descargarse aquí.
sábado, febrero 18, 2012
Validación de datos en múltiples hojas de un cuaderno Excel
Allá por el 2007 publiqué dos notas sobre cómo aplicar validación de datos entre valores que se encuentran en varias hojas de un mismo cuaderno. La idea era impedir la entrada de valores duplicados en el cuaderno, sin importar en que hoja.
Después de una búsqueda en la Internet, encontré un pequeño comentario de Bob Umlas (Excel MVP):
En las notas mostré dos métodos con fórmulas en contradicción con el comentario de Umlas. El problema con los métodos que expuse en mis notas es que no funcionan. Así que como gesto de contrición y arrepentimiento (que viene a ser lo mismo), aquí va mi nota sobre como validar datos a través de las hojas de un cuaderno utilizando Vba (macros).
Siguiendo con el ejemplo que expuse en esas notas, tenemos un cuaderno con tres hojas; en cada hoja hay una lista de nombres. La idea es que no podamos ingresar en cualquiera de las listas un nombre que ya existe en cualquiera de las otras listas.
Para cada lista hemos creado un nombre que se refiere al rango en forma dinámica (con la función DESREF)
=DESREF(Hoja1!$A$2;0;0;CONTARA(Hoja1!$A:$A)-1;1)
=DESREF(Hoja2!$A$2;0;0;CONTARA(Hoja2!$A:$A)-1;1)
=DESREF(Hoja3!$A$2;0;0;CONTARA(Hoja3!$A:$A)-1;1)
Lo que hacemos ahora es crear un evento de manera que cuando se produzca un cambio en alguna de las hojas, el evento dispare una macro que controle si el nuevo valor introducido en alguna de las tres listas ya existe.
El código de la macro que hace esta tarea es:
Sub valid_accross_sheets(valValue)
Dim iValCalc As Integer
iValCalc = WorksheetFunction.CountIf(Range("Lista1"), valValue) + _
WorksheetFunction.CountIf(Range("Lista2"), valValue) + _
WorksheetFunction.CountIf(Range("Lista3"), valValue)
If iValCalc > 1 Then
ActiveCell.ClearContents
MsgBox "El valor " & ActiveCell.Value & " ya existe"
End If
End Sub
Esta macro usa la función CONTAR.SI de Excel para comprobar cuantas veces aparece el valor de la celda activa (en la que hemos introducido el valor). Si el valor aparece más de una vez, el contenido de la celda activa es borrado y aparece un mensaje diciendo que el valor ya existe.
El valor de la celda activa es pasado a la macro por evento Workbook_SheetChange del objeto ThisWorkbook. Usamos este evento para evitar tener que programar un evento para cada hoja
El código es muy sencillo: hace una llamada a la macro valid_accross_sheets(valValue) pasando el valor de Target (la celda en la que hemos ingresado el nuevo valor).
Un detalle a tener en cuenta es que los rangos de los nombres deben ser continuos. Si dejamos una fila en blanco, el rango dinámico no incluirá el nuevo valor y la validación fallará.
El cuaderno con el ejemplo puede descargarse aquí.
Después de una búsqueda en la Internet, encontré un pequeño comentario de Bob Umlas (Excel MVP):
Data validation across sheets isn't supported. You may need an event macro with code to do the checking for you as the worksheet changes (no se puede aplicar validación de datos a través de varias hojas. Habría que usar una macro de tipo evento para hacer la comprobación a medida que se van introduciendo cambios en la hoja).
En las notas mostré dos métodos con fórmulas en contradicción con el comentario de Umlas. El problema con los métodos que expuse en mis notas es que no funcionan. Así que como gesto de contrición y arrepentimiento (que viene a ser lo mismo), aquí va mi nota sobre como validar datos a través de las hojas de un cuaderno utilizando Vba (macros).
Siguiendo con el ejemplo que expuse en esas notas, tenemos un cuaderno con tres hojas; en cada hoja hay una lista de nombres. La idea es que no podamos ingresar en cualquiera de las listas un nombre que ya existe en cualquiera de las otras listas.
Para cada lista hemos creado un nombre que se refiere al rango en forma dinámica (con la función DESREF)
=DESREF(Hoja1!$A$2;0;0;CONTARA(Hoja1!$A:$A)-1;1)
=DESREF(Hoja2!$A$2;0;0;CONTARA(Hoja2!$A:$A)-1;1)
=DESREF(Hoja3!$A$2;0;0;CONTARA(Hoja3!$A:$A)-1;1)
Lo que hacemos ahora es crear un evento de manera que cuando se produzca un cambio en alguna de las hojas, el evento dispare una macro que controle si el nuevo valor introducido en alguna de las tres listas ya existe.
El código de la macro que hace esta tarea es:
Sub valid_accross_sheets(valValue)
Dim iValCalc As Integer
iValCalc = WorksheetFunction.CountIf(Range("Lista1"), valValue) + _
WorksheetFunction.CountIf(Range("Lista2"), valValue) + _
WorksheetFunction.CountIf(Range("Lista3"), valValue)
If iValCalc > 1 Then
ActiveCell.ClearContents
MsgBox "El valor " & ActiveCell.Value & " ya existe"
End If
End Sub
Esta macro usa la función CONTAR.SI de Excel para comprobar cuantas veces aparece el valor de la celda activa (en la que hemos introducido el valor). Si el valor aparece más de una vez, el contenido de la celda activa es borrado y aparece un mensaje diciendo que el valor ya existe.
El valor de la celda activa es pasado a la macro por evento Workbook_SheetChange del objeto ThisWorkbook. Usamos este evento para evitar tener que programar un evento para cada hoja
El código es muy sencillo: hace una llamada a la macro valid_accross_sheets(valValue) pasando el valor de Target (la celda en la que hemos ingresado el nuevo valor).
Un detalle a tener en cuenta es que los rangos de los nombres deben ser continuos. Si dejamos una fila en blanco, el rango dinámico no incluirá el nuevo valor y la validación fallará.
El cuaderno con el ejemplo puede descargarse aquí.
miércoles, febrero 15, 2012
Coordinar horarios con Excel
Esta nota viene a colación de mi reencuentro con un entrañable amigo de la juventud. Nos unen maravillosos recuerdos de la juventud pero nos separan 15 husos horarios.
Después de intercambiar nuestras direcciones de Skype empezamos a coordinar el día y la hora para comunicarnos. Fijamos el próximo fin de semana, pero ¿a qué hora? Aquí es donde Excel puede darnos una buena ayuda.
Yo resido en la Ciudad 1 y mi amigo en la Ciudad 2. La diferencia horaria es de 15 horas y el día elegido para conversar es el sábado 18 de febrero. Las horas activas, es decir, cuando nuestro estado mental permite una conversación más o menos coherente, son entre las 9 de la mañana y las 10 de la noche (cada uno en su ciudad). Este es el modelo que construí en Excel para ver las horas en que ambos coincidimos
En el cuadro de definiciones (el rango E2:F6) ponemos la fecha, la diferencia horaria, y las horas de comienzo y final del horario de actividad y en el rango H2:I25 vemos las horas en que coincidimos con fondo verde y texto en negrita.
¿Cómo funciona el modelo?
Las celdas de la tabla de horarios (el rangoE2:F6 H2:I25) contienen esta fórmula:
=$F$2+((FILA()-2)/24) para Ciudad 1
=$F$2+((FILA()-2+$F$3)/24) para Ciudad 2
donde $F$3 es la diferencia horaria entre las ciudades
La expresión (FILA()-2)/24 calcula la hora del día en saltos de 1 hora, usando el valor de la función FILA y dividiendo por 24 (ese es el método que usa Excel para los cálculos de horas). Esta fórmula nos permite pasar al día siguiente cuando se cumplen las primeras 24 horas.
Para mostrar el resultado con el día de la semana usamos formato personalizado:
Para poner el fondo verde y el texto en negrita usamos formato condicional. La técnica que propongo usa columnas auxiliares ocultas, como seguramente mis perspicaces lectores habran ya notado (en la primer imagen la primer columna visible es la columna D).
Como puede verse, la fórmula usada es muy sencilla: =$C2=1. Veamos qué hay en C2
En A2 ponemos la fórmula:
=Y(HORA(H2)>=HORA($F$5);HORA(H2)<=HORA($F$6))
El resultado es verdadero si la hora de la fecha evaluada en la columna de la ciudad 1 cae dentro del rango establecido entre F5 y F6; lo mismo con la fórmula en la celda B2 para la ciudad 2
=Y(HORA(I2)>=HORA($F$5);HORA(I2)<=HORA($F$6))
En la columna C multiplicamos ambos resultados. Como se trata de expresiones lógicas, dan 1 si ambos resultados son VERDADERO y 0 si alguno de los resultados es FALSO.
Si bien podemos crear una fórmula compleja que combine las tres fórmulas y usarla directamente en el formato condicional, esta técnica tiene en mi opinión la ventaja de exponer en forma más clara la forma del cálculo.
Después de intercambiar nuestras direcciones de Skype empezamos a coordinar el día y la hora para comunicarnos. Fijamos el próximo fin de semana, pero ¿a qué hora? Aquí es donde Excel puede darnos una buena ayuda.
Yo resido en la Ciudad 1 y mi amigo en la Ciudad 2. La diferencia horaria es de 15 horas y el día elegido para conversar es el sábado 18 de febrero. Las horas activas, es decir, cuando nuestro estado mental permite una conversación más o menos coherente, son entre las 9 de la mañana y las 10 de la noche (cada uno en su ciudad). Este es el modelo que construí en Excel para ver las horas en que ambos coincidimos
En el cuadro de definiciones (el rango E2:F6) ponemos la fecha, la diferencia horaria, y las horas de comienzo y final del horario de actividad y en el rango H2:I25 vemos las horas en que coincidimos con fondo verde y texto en negrita.
¿Cómo funciona el modelo?
Las celdas de la tabla de horarios (el rango
=$F$2+((FILA()-2)/24) para Ciudad 1
=$F$2+((FILA()-2+$F$3)/24) para Ciudad 2
donde $F$3 es la diferencia horaria entre las ciudades
La expresión (FILA()-2)/24 calcula la hora del día en saltos de 1 hora, usando el valor de la función FILA y dividiendo por 24 (ese es el método que usa Excel para los cálculos de horas). Esta fórmula nos permite pasar al día siguiente cuando se cumplen las primeras 24 horas.
Para mostrar el resultado con el día de la semana usamos formato personalizado:
Para poner el fondo verde y el texto en negrita usamos formato condicional. La técnica que propongo usa columnas auxiliares ocultas, como seguramente mis perspicaces lectores habran ya notado (en la primer imagen la primer columna visible es la columna D).
Como puede verse, la fórmula usada es muy sencilla: =$C2=1. Veamos qué hay en C2
En A2 ponemos la fórmula:
=Y(HORA(H2)>=HORA($F$5);HORA(H2)<=HORA($F$6))
El resultado es verdadero si la hora de la fecha evaluada en la columna de la ciudad 1 cae dentro del rango establecido entre F5 y F6; lo mismo con la fórmula en la celda B2 para la ciudad 2
=Y(HORA(I2)>=HORA($F$5);HORA(I2)<=HORA($F$6))
En la columna C multiplicamos ambos resultados. Como se trata de expresiones lógicas, dan 1 si ambos resultados son VERDADERO y 0 si alguno de los resultados es FALSO.
Si bien podemos crear una fórmula compleja que combine las tres fórmulas y usarla directamente en el formato condicional, esta técnica tiene en mi opinión la ventaja de exponer en forma más clara la forma del cálculo.
viernes, febrero 10, 2012
Formato personalizado numérico condicional en Excel
En los albores de este blog ya había tocado el del formato personalizado de números. Vuelvo sobre el tema debido a la consulta que puso uno de mis lectores en un comentario de la entrada:
En formato personalizado de celda de Excel existe la posibilidad de usar formatos condicionales. El método es muy elemental y admite sólo tres condiciones, de las cuales dos son explícitas y la tercera implícita. Las condiciones, o criterios, son comparaciones numéricas sencillas.
Si la consulta de mi estimado lector se limitara a tres condiciones, digamos mañana, tarde y noche, se podría hacer. Para el caso que queramos que aparezca "mañana" si la hora es anterior o igual a las 12:00, "tarde" si cae entre las 12:00 y las 18:00 y noche para el resto, la sintaxis es la siguiente
[<=0,5]"Mañana";[>0,75]"Noche";"Tarde"
Las dos condiciones explícitas las ponemos entre [] y la implícita es "todo el resto".
El valor 0,5 resulta de dividir 12 por 24; el valor 0,75 de dividir 18 por 24. Como ya explicamos en el pasado, en Excel las horas son números que resultan de dividir la hora por el total de horas del día (24).
En esta imagen podemos ver las horas 08:00 y 16:00 con tres formatos distintos: hora, general y personalizado condicional
Dado que el formato numérico condicional está limitado a tres criterios, no podemos resolver la consulta de mi lector con esta herramienta. La alternativa es usar formato condicional, que a partir de Excel 2007 no está limitado a tres condiciones. En el caso de la consulta los criterios son:
Usaremos formato condicional con la opción Fórmula, definiendo una fórmula para cada uno de los criterios. Para evitar problemas de precisión, usaremos la función HORANUMERO para calcular los números de series de las horas
El cuaderno con el ejemplo se puede descargar aquí.
tengo unos registros en donde guardo la hora del día, pero quiero que me ponga madrugada si la hora es de 0 a las 5, mañana si es de 6 a 12, tarde de 13 a 19, y noche de 20 a 24, ¿se podrá con el formato personalizado?
En formato personalizado de celda de Excel existe la posibilidad de usar formatos condicionales. El método es muy elemental y admite sólo tres condiciones, de las cuales dos son explícitas y la tercera implícita. Las condiciones, o criterios, son comparaciones numéricas sencillas.
Si la consulta de mi estimado lector se limitara a tres condiciones, digamos mañana, tarde y noche, se podría hacer. Para el caso que queramos que aparezca "mañana" si la hora es anterior o igual a las 12:00, "tarde" si cae entre las 12:00 y las 18:00 y noche para el resto, la sintaxis es la siguiente
[<=0,5]"Mañana";[>0,75]"Noche";"Tarde"
Las dos condiciones explícitas las ponemos entre [] y la implícita es "todo el resto".
El valor 0,5 resulta de dividir 12 por 24; el valor 0,75 de dividir 18 por 24. Como ya explicamos en el pasado, en Excel las horas son números que resultan de dividir la hora por el total de horas del día (24).
En esta imagen podemos ver las horas 08:00 y 16:00 con tres formatos distintos: hora, general y personalizado condicional
Dado que el formato numérico condicional está limitado a tres criterios, no podemos resolver la consulta de mi lector con esta herramienta. La alternativa es usar formato condicional, que a partir de Excel 2007 no está limitado a tres condiciones. En el caso de la consulta los criterios son:
Usaremos formato condicional con la opción Fórmula, definiendo una fórmula para cada uno de los criterios. Para evitar problemas de precisión, usaremos la función HORANUMERO para calcular los números de series de las horas
El cuaderno con el ejemplo se puede descargar aquí.
lunes, febrero 06, 2012
Formato condicional numérico
Josep me consulta cómo cambiar el formato numérico de una celda en función del valor de otra celda (celda de control). La idea es que si en la celda de control aparece el símbolo del Euro (€) el número de la celda formada condicionalmente reciba el forma “moneda-Euro”; si en la celda de control aparece el símbolo del dólar ($), el formato del número cambiará de acuerdo.
Microsoft introdujo en Excel 2007 (y en Excel 2010) la posibilidad de dar formato condicional numérico. Con las nuevas versiones de Excel podemos podemos hacer esto:
y si cambiamos el símbolo, veremos esto
En la celda B2 usamos Validación de Datos con la opción Lista
En E2 definimos dos reglas para el formato condicional
En las versiones de Excel Clásico (97-2003) no tenemos la posibilidad de definir el formato numérico con Formato Condicional. Así que tendremos que echar mano al Vba (macros). Lo que haremos es programar un evento en la hoja relevante
Private Sub Worksheet_Change(ByVal Target As Range)
If Union(Target, Range("B2")).Address = Range("B2").Address Then
If Range("B2") = "€" Then Range("E2").NumberFormat = "[$€-2] #,##0.00"
If Range("B2") = "$" Then Range("E2").NumberFormat = "[$$-409]#,##0.00"
End If
End Sub
¿Cómo saber qúe código de formato usar (por ejemplo "[$€-2] #,##0.00" para el Euro)? Formamos una celda con el formato deseado; abrimos el menú de formato de celdas y en Número elegimos la opción Personalizado. En la ventanilla Tipo veremos la sintaxis del formato
Microsoft introdujo en Excel 2007 (y en Excel 2010) la posibilidad de dar formato condicional numérico. Con las nuevas versiones de Excel podemos podemos hacer esto:
y si cambiamos el símbolo, veremos esto
En la celda B2 usamos Validación de Datos con la opción Lista
En E2 definimos dos reglas para el formato condicional
En las versiones de Excel Clásico (97-2003) no tenemos la posibilidad de definir el formato numérico con Formato Condicional. Así que tendremos que echar mano al Vba (macros). Lo que haremos es programar un evento en la hoja relevante
Private Sub Worksheet_Change(ByVal Target As Range)
If Union(Target, Range("B2")).Address = Range("B2").Address Then
If Range("B2") = "€" Then Range("E2").NumberFormat = "[$€-2] #,##0.00"
If Range("B2") = "$" Then Range("E2").NumberFormat = "[$$-409]#,##0.00"
End If
End Sub
¿Cómo saber qúe código de formato usar (por ejemplo "[$€-2] #,##0.00" para el Euro)? Formamos una celda con el formato deseado; abrimos el menú de formato de celdas y en Número elegimos la opción Personalizado. En la ventanilla Tipo veremos la sintaxis del formato
Suscribirse a:
Entradas (Atom)