jueves, agosto 11, 2011

Lista desplegable con actualización automática

Sigo saldando las deudas con mis lectores y en esta oportunidad cómo crear dinámicamente una lista desplegable con valores únicos.

La situación es la siguiente: creamos una tabla de facturas en una hoja de Excel con los campos “fecha”, “Cliente” y “Total”.



El campo “Cliente” contiene una lista desplegable creada con Validación de Datos. El objetivo es que el usuario introduzca el nombre del cliente eligiéndolo de la lista desplegable.

Para eso necesitamos crear una lista desplegable que se actualice automáticamente cada vez que agregamos un registro con un nuevo cliente en la base de datos.

Supongamos que la los registros únicos de la lista desplegable los ponemos en la columna H (en un modelo real el rango de la lista desplegable estaría en una hoja oculta). Nuestro objetivo es actualizar la lista cada vez que ingresemos un cliente nuevo.



Para actualizar la lista desplegable vamos a programar un evento. Como verán a continuación el código es muy sencillo ya que vamos a usar la herramienta Filtro Avanzado para crear una lista de valores únicos.
Empecemos por señalar que el rango de la base de datos lo definimos como Tabla (Lista en Excel 2003), de manera que la validación de datos del campo Cliente (la columna B) se agregue en forma automática cada vez que agregamos un registro en la base de datos.

Veamos como funciona el modelo:



1 - Creamos un nombre que se refiere a un rango dinámico con la fórmula

=DESREF('base de datos'!$H$1,1,,CONTARA('base de datos'!$H:$H))



Esta fórmula genera un rango dinámico donde el último valor del rango es una celda vacía. Esto es necesario para evitar que la validación de datos nos impida ingresar un cliente que aún no encuentra en la lista de clientes. Obviamente, esto cancela la validación de datos, ya que al haber una celda vacía todo valor que ingresemos será valido, pero nos permite crear el efecto de actualización automática.

2 - Programamos un evento de hoja Worksheet_SelectionChange con este código

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

    If Union(Target, Range("C:C")).Address = Range("C:C").Address Then
        Range("H:H").ClearContents
        Range("B:B").AdvancedFilter Action:=xlFilterCopy, _
                            CopyToRange:=Range("H1"), Unique:=True
    End If

End Sub


En este código el evento se produce cuando seleccionamos una celda en la columna C, es decir, después de haber ingresado el cliente en la columna B.

Si queremos que la lista desplegable aparezca ordenada alfabéticamente podemos en el evento una llamada a este código (que va en un módulo común del Vbe)

Sub ordenar_clientes()

    Range("H1").CurrentRegion.Sort Key1:=Range("H2"), _
                Order1:=xlAscending, Header:=xlYes _
                , OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
                 DataOption1:=xlSortNormal

End Sub


El código del evento en el módulo de la hoja Base de datos quedaría

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

    If Union(Target, Range("C:C")).Address = Range("C:C").Address Then
        Range("H:H").ClearContents
        Range("B:B").AdvancedFilter Action:=xlFilterCopy, _
                            CopyToRange:=Range("H1"), Unique:=True
    End If

    Call ordenar_clientes
  
End Sub



Todo sobre listas desplegables en Excel, técnicas avanzadas y descarga gratuita de ejemplos  en la Caja de Herramientas Excel - Listas Desplegables de JLD. Ver la nota o ir a la página de descarga de la guía.

miércoles, agosto 10, 2011

Crear tablas dinámicas independientes.

Tal vez habrán notado un problema que existe en tablas dinámicas que comparten la misma base de datos: aplicar agrupar o desagrupar en una tabla produce el mismo efecto en la otra.

Supongamos que tenemos una tabla de facturas por fecha (como siempre, la bendita base de datos Northwind)



Creamos dos tablas dinámicas: una que muestra las ventas por año y mes y la segunda por año y trimestre, para lo que usaremos Agrupar

Para la primer tabla



con este resultado



Ahora creamos la segunda tabla basándonos en la misma base de datos, para lo cual usamos Insertar-Tabla Dinámica (o Datos-Tabla Dinámica en Excel Clásico). Pero al momento de crear la tabla, antes de que hayamos arrastrado alguno de los campos a alguna de las áreas podemos notar que el campo Años, creado al agrupar la tabla anterior, está presente en la lista de campos



Al arrastrar el campo Fechas al área de filas, los datos estarán agrupados por meses



Veamos que pasa al agrupar los datos en la segunda tabla por trimestres



Ambas tablas sufren el mismo cambio. Para que esto no suceda tenemos que construir la segunda tabla usando el asistente de tablas dinámicas.

En Excel Clásico (97-2003), al crear la segunda tabla usando la misma base de datos, veremos este mensaje



Todo lo que nos queda por hacer es apretar No para crear informes independientes



En Excel 2007/10 no se abre la opción de crear tablas independientes al construir la segunda tabla. Para que esta opción se presente tenemos que usar el asistente de tablas dinámicas. El viejo asistente existe en Excel 2007/10, pero está oculto lejos de los ojos del usuario. Para hacerlo visible usamos el atajo de teclado Alt+T+B



Seguimos los pasos hasta recibir el mensaje



Procedemos como en el caso anterior y creamos tablas dinámicas independientes también en Excel 2007/10

sábado, julio 23, 2011

Gantt con actividades repetidas en Excel

En el pasado he tocado el tema de construir diagramas Gantt con Excel. Podemos usar, básicamente, dos técnicas: gráficas de barras apiladas o formato condicional (también pueden consultar mi nota sobre diagrama Gantt dinámico).

Las técnicas que muestro en la nota no contemplan el caso en que una tarea se repite a lo largo del proyecto. En esta nota mostraré una técnica sencilla para crear ese tipo de diagrama de Gantt.

Supongamos este ejemplo sencillo



Nuestro proyecto comprende cinco tareas, algunas de las cuales se repiten en la segunda etapa.
Esto es lo que queremos obtener:



Empezamos por construir nuestro diagrama que mostrará la primera etapa del proyecto, seleccionando el rango A2:C7 en nuestro ejemplo e insertando un gráfico de tipo barra apilada



En Excel 2010 obtenemos este resultado, así que tendremos que hacer algunas modificaciones:



Abrimos el asistente Seleccionar origen de datos y:

Editamos el eje de las categorías para que incluya sólo los valores del rango A3:A7



Agregamos la serie Comienzo (el rango B3:B7) y la movemos al primer lugar (usando la flecha indicada en la imagen)



Ocultamos la serie “Comienzo” marcando “Sin relleno” en el asistente de formato de la serie y “Sin línea” en la opción Borde



También el eje de los valores (horizontal) requiere nuestra atención. Cambiamos el valor mínimo del eje de manera que coincida con la primer fecha del proyecto



Finalmente, eliminamos la leyenda y si es necesario cambiamos la orientación de los ejes de manera que la primer tarea quede en la parte superior del diagrama. Para esto seleccionamos el eje de las categorías (el vertical) y cambiamos las definiciones



El resultado es el siguiente



Para poder representar la segunda etapa de la tarea tendremos que crear una columna auxiliar. Podemos incluirla en la tabla, pero mi inclinación personal es ocultarla ya que no aporta ninguna información útil al usuario.

Insertamos una columna a la izquierda de la tabla (o mejor aún dos, Ay B) y creamos la columna auxiliar “Intervalo”



Intervalo cuenta los días transcurridos entre el final de la primer etapa de la tarea y el comienzo de la segunda etapa.

Ahora agregamos dos nueva series a la gráfica: Intervalo y Duración (de la etapa 2)



Dado que vamos a ocultar la columna A, tenemos que cambiar la forma en que Excel representa los datos de columna ocultas apretando el botón “Celdas ocultas y vacías” y marcando “Mostrar datos en filas…”



Ahora tenemos que volver la serie Intervalos invisible, tal como hicimos con la serie Comienzo, cambiando las definiciones de relleno y borde

El último detalle que nos queda son los valores 00/01/1900 (rango I5:I7), Esto se debe a que los valores son ceros, pero el formato es de fecha. Lo que hacemos es cambiar levemente el formato usando formato personalizado “dd/mm/aa;;” (agregamos dos veces punto y coma)



El resultado final



El archivo con el ejemplo se puede descargar aquí (versiones Excel 2003 y Excel 2010).