miércoles, 30 de mayo de 2012

Tercer aniversario Excelforo!!!

Hoy es un día especial para mí, hoy hace tres años que empecé con mi proyecto: Excelforo.
Han sido tres años llenos de satisfacciones, con muchas consultas resueltas, bien a través del correo bien a través de los comentarios del blog, y espero haber podido responder a todos y cada uno de vosotros personalmente como os merecéis. Por supuesto sin olvidar a los que buscando por internet habéis llegado a www.excelforo.blogspot.com y encontrásteis lo que buscábais...
Este ha sido y será siempre mi principal objetivo.

Ha sido un año con muchas novedades, yo lo he vivido así... he incluido algo de publicidad en el blog, seguramente a alguno de vosotros no le haya gustado, pero para mí es importante al menos para sufragar en parte los costes directos de mantenimiento (aún no lo he conseguido, pero no desisto ja, ja...), entiendo que es un mal necesario.

Mucho más importante ha sido el nacimiento de la web www.excelforo.com. No es sólo una web, pretende ser un portal de referencia donde poder realizar todo tipo de cursos de Excel o cursos de Macros, donde yo personalmente dirijo y asisto a los alumnos matriculados. Es un nuevo proyecto ambicioso, donde en pocos meses espero poder ofrecer una mayor oferta de curos.

A fecha de hoy puedes ver un:

Curso Excel Avanzado para versiones 2007/2010

(ver más)

Curso Macros Iniciación

(ver más)

En breve podrás acceder a Cursos de preparación para obtener el MOS Excel 2007/2010 y los Cursos de preparación para obtener el MOS Excel 2007/2010 Experto, también antes de finalizar el año un Curso medio para Macros Excel...

Como datos estadísticos acumulados hasta la fecha respecto al blog diré que son ya más 815.000 visitas únicas, con más de 1.300.000 páginas vistas, más de la mitad provienen de España, México y Colombia, aunque hay un grán número de visitantes asíduos que vienen de Perú, Chile, Argentina, Ecuador, ..., incluso de Alemánia, Francia o Reino Unido. Son más de 370 entradas, de casos prácticos concretos solucionados y explicados; más de 1.700 comentarios, y un sinfín de horas dedicadas a ayudáos.

Mi deseo para los próximos años es seguir ayudando, que sigamos creciendo, que sigamos aprendiendo mucho de Excel, por que de eso trata Excelforo.

Un saludo y muchas gracias a todos por estar ahí.
Ismael Romero - Excelforo

jueves, 24 de mayo de 2012

VBA: Una macro en Excel para listar las propiedades de un archivo.

En un articulo anterior mostré la forma en que podíamos listar los archivos contenidos en una carpeta de nuestro PC. Hoy, en respuesta a un lector que necesitaba además del nombre otras serie de datos de esos ficheros, explicaré qué código es necesario para obtener ciertas propiedades o atributos de los ficheros / archivos contenidos en una carpeta.
En particulas obtendremos en nuestra Hoja de excel, las propiedades:
Nombre = .Name
Fecha creación = .DateCreated
Fecha último acceso = .DateLastAccessed
Fecha última modificación = .DateLastModified
Tipo archivo = .Type
Tamaño en bytes = .Size
Ruta corta utilizada por los programas que necesitan necesitan la convención de nomenclatura 8+3 = .shortpath
Nombre corto utilizado por los programas que necesitan la convención de nomenclatura 8+3 = .shortname
Devuelve los atributos de archivos o carpetas. Lectura o escritura, o sólo lectura, dependiendo del valor atributo = .Attributes
Ruta completa = .Path

Insertaremos en un módulo del Explorador de proyectos del Editor de VBA el siguiente código, formando nuestra macro de Excel:

Sub ListarPropiedadesFicherosCarpeta()
'www.excelforo.com
Dim Ruta As String
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Creamos el objeto FileSystemObject que
'proporciona acceso al sistema de archivos de un equipo
Set fso = CreateObject("Scripting.FileSystemObject")
'Indicamos la ruta de donde vamos a obtener
'los ficheros, en este caso D:\BancoFotos
Ruta = "D:\BancoFotos\"
'definimos dos variables que necesitaremos,
'para recuperar el nombre de la carpeta, y los ficheros que haya dentro
Set Carpeta = fso.GetFolder(Ruta)
Set ficheros = Carpeta.Files
'damos un título en negrita para la celda A1
Range("A1").Value = "Ficheros de la carpeta " & Ruta
Range("B1").Value = "Fecha creación"
Range("C1").Value = "Fecha último acceso"
Range("D1").Value = "Fecha última modificación"
Range("E1").Value = "Tipo archivo"
Range("F1").Value = "Tamaño en bytes"
Range("G1").Value = "Ruta corta"
Range("H1").Value = "Nombre corto"
Range("I1").Value = "Atributo"
Range("J1").Value = "Ruta completa"
Range("A1:J1").Font.Bold = True

'escribimos los ficheros, a partir de A2
Range("A2").Select
For Each archivo In ficheros
    'escribimos el nombre del fichero
    ActiveCell = archivo.Name
    ActiveCell.Offset(0, 1) = archivo.DateCreated
    ActiveCell.Offset(0, 2) = archivo.DateLastAccessed
    ActiveCell.Offset(0, 3) = archivo.DateLastModified
    ActiveCell.Offset(0, 4) = archivo.Type
    ActiveCell.Offset(0, 5) = archivo.Size
    ActiveCell.Offset(0, 6) = archivo.shortpath
    ActiveCell.Offset(0, 7) = archivo.shortname
    ActiveCell.Offset(0, 8) = archivo.Attributes
    ActiveCell.Offset(0, 9) = archivo.Path
    
    'bajamos una fila
    ActiveCell.Offset(1, 0).Select
Next archivo
Range("A:J").EntireColumn.AutoFit
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Limpiamos los objetos y variables definidas
Set fso = Nothing
Set Carpeta = Nothing
Set ficheros = Nothing

Application.ScreenUpdating = True
End Sub


Al ejecutar la macro en la hoja de Excel podemos ver el resultado:

martes, 22 de mayo de 2012

VBA: Una macro en Excel para insertar imágenes.

Finalizando con este post la serie de artículos sobre el tratamiento de imágenes, hoy explicaré como, mediante una macro de Excel podemos listar los ficheros contenidos en una Carpeta y en qué forma, aprovechando los nombres de esos ficheros (imágenes), los insertaremos en las celdas contigüas respectivas, adecuando el tamaño de la celda.
Es por tanto un resumen de las entradas anteriores, añadiendo a éstas la instrucción .Picture.Insert que habilita la inserción de imágenes si trabajamos con Excel 2007 o Excel 2010.

En el ejemplo sobre el que trabajo la ruta es fija, definida sobre una variable incluida en la macro de Excel, en particular: D:\BancoFotos\
Insertaremos en un módulo del Explorador de proyectos del Editor de VBA el siguiente código, formando nuestra macro de Excel:

Sub FicherosCarpeta()
'www.excelforo.com
Dim Ruta As String
Dim Fotos As Object
Dim rng As Range, celda As Range

'Saltamos posibles errores
On Error Resume Next
Application.ScreenUpdating = False
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim img As Shape
'si existe alguna foto, la borro:
On Error Resume Next
For Each img In ActiveSheet.Shapes
     If img.Type = 11 Then img.Delete
Next
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Creamos el objeto FileSystemObject que
'proporciona acceso al sistema de archivos de un equipo
Set fso = CreateObject("Scripting.FileSystemObject")
'Indicamos la ruta de donde vamos a obtener
'los ficheros, en este caso D:\BancoFotos
Ruta = "D:\BancoFotos\"
'definimos dos variables que necesitaremos,
'para recuperar el nombre de la carpeta, y los ficheros que haya dentro
Set Carpeta = fso.GetFolder(Ruta)
Set ficheros = Carpeta.Files
'damos un título en negrita para la celda A1
With Range("A1")
    .Value = "Ficheros de la carpeta " & Ruta
    .Font.Bold = True
End With
'escribimos los ficheros, a partir de A2
Range("A2").Select
For Each archivo In ficheros
    'escribimos el nombre del fichero
    ActiveCell = archivo.Name
    'bajamos una fila
    ActiveCell.Offset(1, 0).Select
Next archivo
ActiveCell.EntireColumn.AutoFit
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Set rng = Worksheets("Hoja1").Range("A2:A5")
For Each celda In rng
If Len(Trim(celda)) > 0 Then
        'defino la celda equivalente de la columna A y la selecciono
        Set r1 = Cells(celda.Row, "B")
        r1.Select
        'se inserta la imagen de la ruta definida
        Set Fotos = ActiveSheet.Pictures.Insert(Ruta & celda.Value)
        'con la posición definida respecto a la celda de la columna B seleccionada
        With Fotos
            .Top = r1.Top
            .Width = .Width / 1.5
            .Height = .Height / 1.5
            .Left = r1.Left + (r1.Width - Fotos.Width) / 2
            .ShapeRange.LockAspectRatio = msoFalse
             r1.EntireRow.RowHeight = .Height
            .Placement = xlMoveAndSize
        End With
    r1.Select
End If
Next celda
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Limpiamos los objetos y variables definidas
Set fso = Nothing
Set Carpeta = Nothing
Set ficheros = Nothing
Set rng = Nothing
Set r1 = Nothing
Set Fotos = Nothing

Application.ScreenUpdating = True
End Sub


En esta entrada lo más importante, y novedoso respecto a las anteriores explicaciones, es la parte del código VBA donde se recorre el rango A2:A5 donde se insertaron los nombres de los ficheros de imagen, para ir incorporando en la celda contigüa (columna B) la imagen que le corresponda por nombre:
ActiveSheet.Pictures.Insert(Ruta & celda.Value)

Podemos ver en imágenes el antes y después de la ejecución de la macro 'FicherosCarpeta':

VBA: Una macro en Excel para insertar imágenes.


Si ejecutamos la macro asignada al botón Listar e Insertar imágenes obtendríamos:

VBA: Una macro en Excel para insertar imágenes.


Consiguiendo lo que pretendíamos, es decir listar el contenido de ficheros de una carpeta de nuestro equipo, e insertar a nuestra Hoja de cálculo de Excel las imágenes de esa carpeta.

domingo, 20 de mayo de 2012

VBA: Centrar una imagen en el interior de una celda de Excel.

Siguiendo con el tema de los últimos días, hoy veremos cómo podemos tratar una imagen(Picture), para mediante una macro de Excel, ajustarla lo máximo posible, en el interior de una celda.
En particular trabajaremos con las propiedades .Top, .Left, .Height y .Width

Supongamos tenemos ya una imagen en nuestra Hoja de Excel, y queremos moverla, adaptádola a otra celda, por ejemplo F5:

VBA: Centrar una imagen en el interior de una celda de Excel.



Insertaremos en un módulo del Explorador de proyectos del Editor de VBA el siguiente código, formando nuestra macro de Excel:

Sub CentrarImagen()
Dim Fotos As Object
Dim celda As Range

Set celda = Cells(5, "F")
Set Fotos = ActiveSheet.Shapes.Range(Array("1 Picture"))
'asignamos un Anco a la columna de la celda F5, proporcianada al ancho de la Imagen
celda.ColumnWidth = Fotos.Width / 10.67111364
With Fotos
    .Top = celda.Top
    'reducimos el alto y ancho de la foto
    .Width = .Width / 1.5
    .Height = .Height / 1.5
    'se centra horizontalmente en la celda indicada
    .Left = celda.Left + (celda.Width - Fotos.Width) / 2
    'damos altura a la fila igual al alto final de la imagen
    celda.EntireRow.RowHeight = .Height
End With

Set celda = Nothing
Set Fotos = Nothing

End Sub


Podemos ver el resultado, ampliado, de cómo queda situada la imagen dentro de la celda F5, tras ajustar Ancho, Alto (reducidos en un 33%) y centrarla horizontalmente respecto a la celda F5.

VBA: Centrar una imagen en el interior de una celda de Excel.


Como vemos, conseguimos adaptar el tamaño de celda al tamaño final de la imagen, de manera bastante ajustada.

jueves, 17 de mayo de 2012

VBA: Macro para listar ficheros de una carpeta.

Continuando con una serie de artículos hoy contaré cómo poder listar en una Hoja de cálculo de Excel los diferentes ficheros o archivos contenidos en una carpeta concreta de nuestro equipo.
La siguiente macro, bastante sencilla, emplea el objeto FileSystemObject, que habilita el acceso al sistema de todos los archivos de nuestros PC.

Insertaremos en un módulo del Explorador de proyectos del Editor de VBA el siguiente código, formando nuestra macro de Excel:

Sub ListarFicherosCarpeta()
'www.excelforo.com
Dim Ruta As String
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Creamos el objeto FileSystemObject que
'proporciona acceso al sistema de archivos de un equipo
Set fso = CreateObject("Scripting.FileSystemObject")
'Indicamos la ruta de donde vamos a obtener
'los ficheros, en este caso D:\BancoFotos
Ruta = "D:\BancoFotos\"
'definimos dos variables que necesitaremos,
'para recuperar el nombre de la carpeta, y los ficheros que haya dentro
Set Carpeta = fso.GetFolder(Ruta)
Set ficheros = Carpeta.Files
'damos un título en negrita para la celda A1
With Range("A1")
    .Value = "Ficheros de la carpeta " & Ruta
    .Font.Bold = True
End With
'escribimos los ficheros, a partir de A2
Range("A2").Select
For Each archivo In ficheros
    'escribimos el nombre del fichero
    ActiveCell = archivo.Name
    'bajamos una fila
    ActiveCell.Offset(1, 0).Select
Next archivo
ActiveCell.EntireColumn.AutoFit
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Limpiamos los objetos y variables definidas
Set fso = Nothing
Set Carpeta = Nothing
Set ficheros = Nothing

Application.ScreenUpdating = True
End Sub


En este caso, por simplificar, he decidido añadir la Ruta de la carpeta de manera manual, en mi caso, una carpeta donde guardo imágenes que utilizaré en una entrada posterior.
El funcionamiento de la macro comienza permitiendo el acceso al sistema de directorios y carpetas de nuestro equipo de trabajo, luego, tras definir la Ruta exacta que terminaremos abriendo, empleando el método GetFolder, que devuelve un objeto Folder que corresponde a la carpeta de la ruta especificada.El resto es simple, ya que forzamos un texto en la celda A1, y con un proceso FOR EACH...IN...NEXT pasamos por todos los ficheros contenidos en la carpeta definida en 'Ruta' y nos lo traemos a la Hoja de cálculo a partir de la celda A2.
Finalmente auyoajustamos el ancho de la columna y limpiamos las variables definidas con la instrucción SET.

Podemos ver el resultado en la imagen, para mi caso, un listado de cuatro ficheros:

VBA: Macro para listar ficheros de una carpeta.

domingo, 13 de mayo de 2012

VBA: Una macro de Excel para borrar sólo imágenes entre objetos.

Como principio a una serie de artículos, comenzaré hoy explicando cómo podemos borrar las imagenes (Picture) de una hoja de cálculo, pero sólo las imágenes(Picture)!!, respetando el resto de objetos existentes, como botones, autoformas, gráficos, etc...
Esto es importante en muchos casos cuando queremos 'hacer limpieza' en nuestra hoja de Excel, pero limitada a cierto tipo de objetos.

En primer lugar, para generalizar nuestra macro de hoy, necesitaremos tener conciencia de cómo identifica Excel estos objetos, cómo los diferencia. Para ejemplarizarlo veremos la imagen siguiente donde observamos varias imágenes, junto a otros objetos (dos Botones, un Gráfico, un Rectángulo de texto, una autoforma ovalada):

VBA: Una macro de Excel para borrar sólo imágenes entre objetos.


Usando una instrucción Type sobre cada objeto, veremos de manera muy sencilla, qué identificador único usa Excel para cada objeto.
Insertaremos en un módulo del Explorador de proyectos del Editor de VBA el siguiente código, dándo forma a nuestra macro de Excel:

Sub TipoObjetos()
Dim img As Shape
On Error Resume Next
For Each img In ActiveSheet.Shapes
    MsgBox img.Name & " " & img.Type
Next
End Sub


Al ejecutar esta macro, idetificamos mediante un Cuadro MsgBox el nombre del objeto, y al lado el tipo o identificador. Como vemos en la imagen siguiente para dos de los objetos, lo importante es que para todas las imágenes (Picture) el tipo tiene el valor 11, y por ejemplo el gráfico el valor 3, o la autoforma Ovalada el valor 1.
Para nosotros, el valor 11 de las imágenes es lo importante.

VBA: Una macro de Excel para borrar sólo imágenes entre objetos.


Con la clave descubierta, lo que sigue es lo más sencillo, ya que construiremos una nueva macro, similar a la anterior:
Insertaremos en un módulo del Explorador de proyectos del Editor de VBA el siguiente código, dándo forma a nuestra macro de Excel:

Sub borrarImagenes()
Dim img As Shape
On Error Resume Next
For Each img In ActiveSheet.Shapes
     If img.Type = 11 Then img.Delete
Next
End Sub


Y al ejecutarla podremos observar cómo elimina o borra sólo los objetos tipo imágen, dejando el resto visibles y con todas sus funcionalidades...

miércoles, 9 de mayo de 2012

Cómo construir rangos con fórmulas matriciales en Excel.

Últimamente me llegan, recurrentemente, consultas sobre cómo construir fórmulas matriciales y cómo emplearlas; asi que me he animado a subir una nueva entrada tratando este asunto de Matriciales en Excel. En concreto, trataré de explicar la utilidad de trabajar con matriciales para conseguir rangos de trabajo, y emplear éstos en otras funciones que requieren como argumento una matriz.
Anticipar, que no todo es posible con estas potentes fórmulas, y que en ocasiones es mucho más ágil trabajar con otras herramientas igual de poderosas, como las Tablas dinámicas.

En la entrada de hoy daré respuesta a la consulta de un lector, que solicitaba obtener sobre un origen de datos, cierta información condicionada; en particular daré una doble solución, una con fórmulas matriciales y otra mediante Tablas dinámicas, empleando además la Segmentación de datos.
Veamos el origen de datos y qué información es la que se requiere:

Cómo construir rangos con fórmulas matriciales en Excel.


Como vemos la idea es completar los tres informes, uno para cada categoría (niño, joven o adulto) según los tres menores tiempos obtenidos.
En primer lugar asignaremos una función K.ESIMO.MENOR 'matricial', esto es, incorporaremos como primer argumento de la función una fórmula matricial que devolvería únicamente los tiempos marcados por aquellos con categoría 'niño':
{=K.ESIMO.MENOR(SI($A$2:$A$10=$C$12;$C$2:$C$10;"");B13)}
con la fórmula SI($A$2:$A$10=$C$12;$C$2:$C$10;"") conseguimos trabajar sólo con los tiempos de los niños; y al anidar ese rango en la función K.ESIMO.MENOR e ir indicándole la posición de tiempo, conseguimos los tres mejores tiempos de aquellos con categoría 'niño'.

Cómo construir rangos con fórmulas matriciales en Excel.

Repetiriamos la fórmula para cada tabla y categoría ('joven' o 'adulto')

Con estos 'tiempos' completos, podemos proceder a conseguir los Nombres de quienes hayan hecho esos tiempos. Asi que nuevamente conseguimos rangos de celdas mediante fórmulas matriciales.
Mediante el uso de la funciín INDICE y COINCIDIR, como tantas veces, conseguiremos el nombre correspondiente:
{=INDICE(SI($A$2:$A$10=$C$12;$B$2:$B$10;"");COINCIDIR(C13;SI($A$2:$A$10=$C$12;$C$2:$C$10;"");0))}
Con la matricial SI($A$2:$A$10=$C$12;$B$2:$B$10;"") tendríamos el rango de nombres sólo de la categoría a estudio ('niño' para este caso); y con COINCIDIR(C13;SI($A$2:$A$10=$C$12;$C$2:$C$10;"");0) encontramos la posición del tiempo buscado en el rango de tiempos exclusivos de los 'niño'.

martes, 8 de mayo de 2012

Curso Excel Avanzado y Curso de Iniciación a Macros por Excelforo

Ya cercano a cumplir tres años con mi blog excelforo.blogspot.com, satisfecho por el trabajo realizado, y sobre todo por todos los agradecimientos recibidos por las ayudas y colaboraciones prestadas, y en respuesta a bastantes peticiones recibidas a lo largo de este tiempo, donde se me preguntaba por cursos de Excel de calidad, que realmente merezcan la pena, me he decidido a ser yo mismo quien preste ese servicio.
Ese es el motivo de este post, anunciar el lanzamiento de dos cursos en modalidad elearning (online) a un precio más que competitivo:

Curso Excel Avanzado para versiones 2007/2010

(ver más)

Curso Macros Iniciación

(ver más)


El objetivo principal de este nacimiento es poder ofertar Cursos de Excel donde se puedan adquirir los conocimientos necesarios, no sólo teóricos, sino prácticos, para poder desarrollarlos de acuerdo a nuestras necesidades profesionales.
Estos cursos los he desarrollado e implementado en la plataforma educativa Moodle; en ellos podrás encontrar:
  • Contenido teórico, acompañado de imagenes explicativas, que hacen fácil identificar el paso a paso de cada apartado. Todo explicado sobre la base de ejemplos prácticos.
  • Libros de trabajo descargables con los ejemplos desarrollados en el temario.
  • Una serie de Ejercicios prácticos para asentar ideas y conceptos (junto con la solución, para hacerlo más didactico)
  • Unos pdf descargables para facilitar la lectura de los temas de cada curso

Por supuesto estos cursos no son simplemente cursos descargables online, durante la duración de los cursos existirá un contacto constante conmigo, bien a través de las herramientas que ofrece la plataforma Moodle: Mensajería interna o a través de los Foros de debate abiertos en cada tema; bien a través del correo electrónico.
la idea principal es que nunca estés solo durante la realización del curso, que cualquier duda relacionada con éstos, se resuelva lo más rápido posible; y que consigas tu objetivo: Aprender.

Si no encuentras ningún Curso de Excel Avanzado que responda a tu necesidad, o quieres empezar desde cero con las Macros entra en www.excelforo.com o contacta conmigo en cursos@excelforo.com.
No lo dudes, cuentas con la gran ventaja de conocer mi trabajo, mi forma de explicar, mis conocimientos, mi historía...¿alguien te ofrece una garantía mayor?.

sábado, 5 de mayo de 2012

VBA: macro para obtener rango de celdas asociado a una selección.

Tiempo atrás expliqué como mediante el uso de un objeto Collection en una macro de Excel conseguíamos un listado de valores únicos de una forma muy sencilla (ver entrada).
Esta entrada nos servirá para responder la cuestión planteada, en la que se pide extraer los valores asociados a un dato previamente seleccionado; y veremos como podemos combinar diferentes Eventos sobre un mismo control(ActiveX) para conseguir diferentes efectos, en este ejemplo, usaremos el evento GotFocus y el evento Change.
Esta es la cuestión:

...La siguiente lista me muestra que en la columna A tengo un dato y en la columna B me muestra todos los valores asociados a la celda de la columna A. La pregunta es cómo puedo buscar, utilizando el dato de la columna A, los datos de asociados de la columna B...

Veamos la imagen de la tabla origen:

VBA: macro para obtener rango de celdas asociado a una selección.


Se puede observar en la imagen que en la columna A (campo 'Código') existen varios valores repetidos (ax, bx, cx, dx, etc.), y que asociados a estos, en la columna B (campo 'Descripción') les corresponden diferentes valores; para ax le toca ax-01, ax-02, ax-03 y ax-04; y así sucesivamente.
La idea es ser capaz de seleccionar un elemento único del campo 'Código' para de manera inmediata se despliegue en la Hoja de cálculo los valores asociados del campo 'Descripción'.

Para trabajar de manera más cómoda hemos convertido en Tabla el origen de datos, asignando además Nombres definidos a ambos campos:
Código =Hoja1!$A$2:$A$12
Descripción =Hoja1!$B$2:$B$12

El siguiente paso es sencillo, insertaremos desde la Ficha Programador > Controles > Insertar > Control ActiveX > Cuadro Combinado, es decir, insertaremos un control ComboBox en la hoja de cálculo, al que asignaremos para empezar un evento GotFocus, que habilitará el listado de valores únicos como elementos (items) del ComboBox al presionarlo.
Al hacer click sobre el Cuadro Combinado recien insertado se abre una ventana de código (en la Hoja1) en la que insertaremos lo siguiente:

Private Sub comboBox1_gotfocus()

Dim celda As Object
Dim i As Integer

ComboBox1.Clear
Set unicos = New Collection

For Each celda In Range("Código")
    On Error Resume Next
    unicos.Add celda.Value, CStr(celda.Value)
    On Error GoTo 0
Next celda

For i = 1 To unicos.Count
    ComboBox1.AddItem unicos(i)
Next i

End Sub


Con esto hemos conseguido rellenar el ComboBox con los elementos únicos que componen en campo 'Código', como vemos en la imagen:

VBA: macro para obtener rango de celdas asociado a una selección.


De momento el ComboBox no hace nada más, pero si añadimos a continuación un nuevo evento Change sobre él mismo, conseguiremos nuestro objetivo, que es listar los valores del campo 'Descripción' asociados a nuestra selección.
Asi que a continuación del código anterior escribimos:

Private Sub comboBox1_change()
Dim seleccionado As Variant
seleccionado = ComboBox1.Value
x = 0
Range(Range("E4"), Range("E4").End(xlDown)).Clear
Range("E4").Select
Dim celda2 As Object
For Each celda2 In Range("Código")
    If celda2.Value = seleccionado Then
    ActiveCell.Offset(x, 0).Value = celda2.Offset(0, 1)
    x = x + 1
    End If
Next celda2
End Sub


Con este segundo código, con el evento Change, indicamos que al seleccionar algún elemento del Cuadro combinado (ComboBox) liste, a partir de la celda E4 de la hoja las diferentes 'Descripciones' asociadas.
Podemos ver el resultado en la imagen:

jueves, 3 de mayo de 2012

Un gráfico de Excel con Etiquetas de categorías de múltiples niveles.

En esta entrada veremos cómo construir un gráfico con distintos niveles para el eje de categorías, en respuesta a la cuestión planteada por un lector:
...digamos que tienes 2 vendedores por lo tanto tienes 4 series de datos, 2 de una zona Sur uno de cada vendedor, y otros 2 de otra zonz norte nuevamente uno de cada vendedor; mi duda es como graficar para que en cada mes salgan 2 barras con 2 series cada uno y no una sola barra con 4 series, osea quiero 2 barras (cada barra representa a cada vendedor) con 2 series cada una (zona norte y zona sur) en cada mes...

Como siempre lo más importante en los gráficos es el resultado visual final, sin embargo, sabemos que para conseguir este resultado, tenemos que tratar de manera muy especial el origen de datos; en esta ocasión más, ya que necesitaremos un eje de categorías de múltiples niveles de manera muy concreta.
Empezaremos en primer lugar viéndo la disposición de datos necesaria para poder construir nuestro gráfico, según las especificaciones del lector. Necesitaremos una columna con datos del Mes, el cual, como veremos en la imagen, debe ir alternando un elemento con otra celda vacía (esta es la clave para configurar nuestro gráfico con múltiples niveles), otro campo con los Comerciales (reiterando, para nuestro ejemplo, para cada mes los dos comerciales), y acabaremos con las series propiamente de datos, una para los valores de la 'Zona sur' y otro para los de la 'Zona norte'. En la siguiente imagen se ve mucho mejor:

Un gráfico de Excel con Etiquetas de categorías de múltiples niveles.


Realmente no necesitamos nada más, simplemente seleccionamos el rango B1:B25, con todo el origen de datos, e insertamos un gráfico, en nuestro caso, un gráfico de Columnas > Columnas 2D > Columnas apiladas, consiguiendo el gráfico:

Un gráfico de Excel con Etiquetas de categorías de múltiples niveles.


Podemos observar como el resultado era el requerido, tenemos por cada mes, dos columnas apiladas por Zona (Norte y Sur), una columna por cada Comercial.
Es importante remarcar que sólo en gráficos con un origen de dato similar, Excel reconocerá la existencia de múltiples niveles, activándose en el Formato de ejes la opción Etiquetas de categorías de múltiples niveles: