lunes, 25 de febrero de 2013

Curso Excel avanzado y mucho más... Marzo 2013.

Presento la edición de Cursos de Excel online de Marzo 2013.

Los cursos de Excel abiertos para el proximo Marzo son:

Curso Excel Avanzado para versiones 2007/2010

(ver más)

Curso Excel Financiero

(ver más)

Curso Tablas dinámicas en Excel

(ver más)

Curso Macros Iniciación

(ver más)

Curso Macros Medio

(ver más)

Curso preparación MOS Excel 2010 (Examen 77-882)

(ver más)


Esta nueva edición de Cursos de Excel y macros en modalidad elearning (online) dará comienzo el próximo día 1 de marzo de 2013.
Con la confianza de siempre....Anímate!!


Próximamente Curso Excel nivel medio y Curso Microsoft Access.

Informarte sin compromiso en cursos@excelforo.com o directamente en www.excelforo.com.

Recuerda que ahora también imparto clases particulares de Excel en Madrid te interesa?

jueves, 21 de febrero de 2013

VBA: Cargar un gráfico en un Formulario de Excel.

Días atrás un lector preguntaba por la manera de 'cargar' un gráfico dentro de un UserForm (formulario de usuario) empleando para ello macros.
De partida el asunto es sencillo, salvo por los eventos a emplear necesarios para que la carga del gráfico se actualice correctamente. Partiremos de la siguiente tabla de datos y de un gráfico de columnas ya construido:

VBA: Cargar un gráfico en un Formulario de Excel.



La idea por tanto es crear un UserForm (formulario de usuario) e insertar en él nuestro gráfico de columnas (llamado en este caso '1 Gráfico'). Por tanto nuestro primer paso será Insertar un UserForm desde el Editor de VB (Alt+F11 para abrirlo), menú Insertar y la opción de UserForm.
Una vez creado el UserForm, pasaremos desde el Cuadro de herramientas a insertar un control Imagen (Image), que desplegaremos en nuestro formulario:

VBA: Cargar un gráfico en un Formulario de Excel.


Si no lo tuvieramos a la vista, lo buscaremos entre los controles adicionales, pulsando el botón derecho del ratón y mostrando dichos controles:

VBA: Cargar un gráfico en un Formulario de Excel.



Una vez insertado el control Imagen (llamado Image1), procedemos a incorporar el código que cargue nuestro gráfico en él.
El asunto es sencillo, asociaremos nuestra macro al evento que inicializa el formulario (UserForm), podemos hacer click sobre el UserForm (UserForm_Initialize)y escribir:

Private Sub UserForm_Initialize()
'indicamos qué gráfico vamos a insertar como imagen en el Formulario
Set graficoactivo = Sheets(1).ChartObjects(1).Chart
'damos nombre al archivo GIF donde exportaremos el gráfico
NombreGIF = ThisWorkbook.Path & "\temporal.gif"

'redimensionamos el Alto y Ancho del objeto Imagen
'(del recuadro donde insertamos el gráfico)
alto = Sheets(1).Shapes("1 Gráfico").Height
ancho = Sheets(1).Shapes("1 Gráfico").Width
UserForm1.Image1.Height = alto
UserForm1.Image1.Width = ancho
base = UserForm1.Width
altura = UserForm1.Height

UserForm1.Image1.Top = (altura - alto) / 2
UserForm1.Image1.Left = (base - ancho) / 2

'Exportamos el gráfico al archivo GIF generado
graficoactivo.Export Filename:=NombreGIF, FilterName:="GIF"
    
'Colocamos la imagen Gif en el espacio destinado del Formulario
UserForm1.Image1.Picture = LoadPicture(NombreGIF)
End Sub



Por otra parte he creado un botón en la hoja de cálculo, al que he asociado la siguiente macro que carga el formulario, macro que hemos incluido en un módulo del explorador de proyectos dentro del Editor de VB:

Sub graficoformulario()
'Cargamos en memoria el Formulario
Load UserForm1
'refrescamos el formulario
UserForm1.Repaint
'y lo mostramos
UserForm1.Show
End Sub



Listo, ya podemos hacer uso de nuestro botón en la hoja de cálculo para cargar el gráfico, con los últimos cambios, en nuestro formulario.
Requiere especial mención el uso del método Repaint en la macro 'graficoformulario', ya que este método actualiza la pantalla volviendo a dibujar el formulario, especialmente útil si el contenido o la apariencia de un objeto cambia de forma significativa y no queremos esperar hasta que el sistema vuelva a dibujar el área automáticamente.


Vemos el resultado:

lunes, 18 de febrero de 2013

Formato condicional para un rango movil de Excel.

Recientemente una lectora me propuso un reto interesante, era asignar un Formato condicional a un rango de una hoja de Excel, basándose en ciertos valores determinados en otro rango, que sirven para definir un subrango mediante la función DESREF. La cuestión más o menos decía:
...lo que quiero es que me coloree en formato condicional ,en función a las celdas G15:G19, que sea dinámico respecto a la tabla (A1:T13)...
Veamos el planteamiento de la hoja en la siguiente imagen:

Formato condicional para un rango movil de Excel.


De lo que se trata entonces es asignar al rango A1:T13 un formato condicional en función a los valores del rango G15:G19, que son los que sirven como argumento de una función DESREF (empleada en este caso para definir un rango, y no solo una posición). Por tanto a partir de la posición dada en la celda G15, localizaremos la primera celda del rango y la última, para posteriormente poder aplicar el formato condicional en base a la posición.
Pero vamos por parte.

Lo primero que vamos a hacer es crear dos nombres definidos en su variante de fórmula matricial. Lo que conseguiremos es facilitar la operativa, ya que las fórmulas que se van a crear son algo largas. Son estas:
rng_1: =DIRECCION(FILA(DESREF(INDIRECTO($G$15);$G$16;$G$17));COLUMNA(DESREF(INDIRECTO($G$15);$G$16;$G$17)))
rng_2: DIRECCION(FILA(DESREF(INDIRECTO($G$15);$G$16+$G$18-1;$G$17+$G$19-1));COLUMNA(DESREF(INDIRECTO($G$15);$G$16+$G$18-1;$G$17+$G$19-1)))

Vemos que cada fórmula es un compendio de funciones anidadas. Antes de explicar cómo funcionan, diremos qué obtenemos con cada una de ellas. Con
rng_1 obtenemos la dirección absoluta de la primera celda del rango que queremos formatear.
rng_2 obtenemos la dirección absoluta de la última celda del rango a formatear.
La idea es determinar cuales son la primera y última fila del rango, y la primera y última columna del rango a formatear.

La explicación de esas funciones sería, desde lo más profundo de ellas:
Con DESREF(INDIRECTO($G$15);$G$16;$G$17) conseguimos el valor de la celda en cuestión, como no nos interesa el valor de la celda, sino su referencia, aplicamos sobre ella la función FILA y COLUMNA para conocer en número la fila y columna de dicha celda, de la primera celda que define el rango a formatear. Sabiendo cual es esa FILA y COLUMNA, obtenemos su referencia absoluta, anidando esos resultados en la función DIRECCION. Para el ejemplo de partida, obtendremos la referencia: $I$10.

De igual forma para el nombre definido 'rng_2', con la variante que ahora sólo nos interesa la última celda que deine el rango a formatear, por lo que como argumentos de DESREF aplicamos la altura y el ancho definidos. Para el ejemplo de partida obtenemos la referencia: $K$12.


El siguiente paso es deshacer, en parte lo conseguido, puesto que ya conozco la primera y última celda del rango, por su referencia absoluta, ahora para poder aplicar el Formato condicional, conseguiré el intervalo de filas y de columnas (por número) que corresponde al área a formatear. Esto lo conseguiremos anidano nuestros Nombres_fórmulas a la función INDIRECTO y FILA o COLUMNA:

Formato condicional para un rango movil de Excel.



Estas serán las fórmulas que emplearemos a la hora de configurar nuestro formato condicional... que es el siguiente paso. Accedemos al formato condicional tipo fórmula, una vez seleccionado el rango A1:T13 con la celda A1 activa, e incluimos:
=Y(FILA(A1)>=FILA(INDIRECTO(rng_1));FILA(A1)<=FILA(INDIRECTO(rng_2));COLUMNA(A1)>=COLUMNA(INDIRECTO(rng_1));COLUMNA(A1)<=COLUMNA(INDIRECTO(rng_2)))
En ella comprobamos que la celda activa del rango, que su número de fila y de columna, se encuentran en el intervalo del rango a formatear; si es así le asignamos un formato particular, en el ejemplo color verde de fondo de celda.

miércoles, 13 de febrero de 2013

El ancho de las columnas en un ListBox o ComboBox: ColumnWidths.

Hoy aprenderemos a definir el aspecto de un control ActiveX (ComboBox o ListBox) multicolumna; lo que haremos mediante la configuración de la propiedad ColumnWidths. Aunque hablaremos en todo momento de controles ActiveX, esta propiedad es igualmente válida si vamos a trabajar con estos controles en un UserForm (formulario de usuario).
Partiremos de una tabla en el rango A1:D7 con cuatro columnas; sobre este rango en particular configuraremos nuestros controles, para que aparezcan a la hora de seleccionar sobre ellos, las cuatro columnas cada una de ellas con un ancho diferente. Esta sería nuestra tabla:

El ancho de las columnas en un ListBox o ComboBox: ColumnWidths.


Recordar que es importante trabajar sobre rangos convertidos en Tablas o bien con Nombres definidos, ya que facilita entre otras cosas la detección de la cabecera.

El siguiente paso es insertar un control ActiveX tipo Cuadro de Lista (ListBox) y un Cuadro Combinado (ComboBox):

El ancho de las columnas en un ListBox o ComboBox: ColumnWidths.



Primero sobre el ComboBox y después sobre el ListBox accederemos a las Propiedades de ambos controles, para ello o bien con el botón derecho del ratón, o desde la ficha Programador > grupo Controles > botón Propiedades, abriremos la ventan diálogo con el listado de Propiedades. Modificaremos algunas de ellas para llenar de datos los controles:

lunes, 11 de febrero de 2013

VBA: Verificando un formato de fecha en Excel.

Aunque no es muy frecuente, podría ocurrir que necesitáramos una 'alarma' que nos indicara que una celda tiene o no un formato 'reglado' y definido previamente. Yo diría que controlar que el formato introducido en una celda corresponde o sigue una regla particular es imposible desde la hoja de cálculo (salvo mejor opinión). Así que para dar respuesta a la cuestión planteada por un lector expondré la explicación de esta entrada:
... busco es solamente una señal de alerta sobre la misma celda (sin utilizar otra celda o columna), que aparezca cuando el usuario introduce un formato distinto al deseado....


Supongamos que el formato requerido es uno de tipo fecha, pero muy específico, por ejemplo:
"dd/mm hh:mm"
y para cualquier formato diferente a este en nuestro rango de análisis queremos una 'alarma' que se configurará posteriormente con el Formato condicional.


Nuestro trabajo comienza por generar una función personalizada (muy sencilla) en VBA que detecte si el formato de una celda concreta responde o no a ese formato buscado.
Por lo que generamos nuestra function 'formatofecha', que incorporamos a un módulo del Explorador de proyectos del Editor de VBA:

Function formatofecha(celda As Range)
'actualizamos el resultado de la función
Application.Volatile

'comprobamos que el formato de la celda es el deseado
'si cumple obtendremos 'VERDADERO' y 'FALSO' en caso contrario
If celda.NumberFormat = "dd/mm hh:mm" Then
    formatofecha = True
    Else
    formatofecha = False
End If
End Function



Realmente con esta función ya podemos averiguar qué celda cumple o no con la regla de fecha personalizada:

VBA: Verificando un formato de fecha en Excel.



Completaremos algo más la propuesta, combinando esta función 'formatofecha' con un Formato condicional con fórmula:
=formatofecha(B2)
sobre el rango seleccionado B2:B8 y siendo la celda activa B2.

VBA: Verificando un formato de fecha en Excel.



Sin duda una manera rápida y sencilla de verificar el formato de una celda.

viernes, 8 de febrero de 2013

Una matricial en Excel para sumar referencias cruzadas.

Nuevamente atacando con las matriciales. En esta ocasión en respuesta a la cuestión planteada:
...Se trata de una tabla en la que la cabecera de la primera fila figuran unos años, pongamos del 2010 al 2017.
En la cabecera de las columnas figuran los nombres de unos centros de trabajo (que pueden estar repetidos).

Y la matriz está compuesta por unos numeros que son las horas que cada centro de trabajo ha estado produciendo en cada uno de esos años.

Por otro lado tengo dos celdas que contienen un AÑO DE INICIO y un AÑO DE FIN. Y en otra celda tengo el nombre de uno de los centros de trabajo.

Necesito una fórmula -no valen tablas dinámicas-, tiene que ser en fórmula que me obtenga las horas de producción para ESE CENTRO DE TRABAJO ENTRE las fechas de INICIO y FIN que figuran en las celdas correspondientes...


Lo interesante de esta fórmula matricial en nuestro Excel es que trabajamos en un rango conjunto de datos, sobre parámetros en fila y en columnas... es decir, sobre una tabla de referencias cruzadas, en definitiva sobre un rango bidimensional!! (normalmente nuestros rangos son únicamente una columna o una fila).
Veamos en la imagen el planteamiento:

Una matricial en Excel para sumar referencias cruzadas.



El objetivo está claro, debo obtener en la celda O3 una sóla fórmula que acumule los valores para las filas con igual 'Centro de trabajo' que estén en el intervalo de Años dado.
Sin duda el asunto sería algo más sencillo si pudieramos trabajar con columnas auxiliares, pero el reto de hoy es conseguirlo en una sóla celda; y para ello deberemos recordar todo lo aprendido respecto al trabajo de las matriciales, y el comportamiento de los rangos 'virtuales' en ellas.


Empezaremos por el final, para los impacientes, mostrando la fórmula matricial deseada (recordemos que para ejecutarla debemos presionar a un tiempo Ctrl+Mayusc+Enter):
=SUMA(SI($B$3:$B$9=$L$3;SI(C$2:J$2>=$M$3;SI(C$2:J$2<=$N$3;C$3:J$9;0);0)))



Y ahora la explicación o desglose. La parte más profunda de la fórmula nos devolvería rangos en columna para aquellos Años que cumplan la condición de estar entre 'Inicio'(celda M3) y 'Fin'(celda N3).
Si ejecutamos la siguiente matricial para cada una de las columnas de 'Año', es decir, una matricial en C11:C17, otra en D11:D17, otra en E11:E17, etc conseguiríamos parte de la información necesaria, segregando, momentaneamente los Años de estudio. Esta es la fórmula matricial parcial que nos devuelve datos únicamente para los Años entre el intervalo de análisis:
=SI(Y(E$2>=$M$3;E$2<=$N$3);E$3:E$9;0)

miércoles, 6 de febrero de 2013

Las posibilidades de SUMAPRODUCTO en Excel.

Hoy voy a hablar sobre algunas de las funciones más empleadas en nuestras hojas de Excel, las funciones SUMAR.SI y SUMAR.SI.CONJUNTO (de las que se han hablado largo y tendido en este blog); pero sobre todo de una función alternativa a estas, con multitud de ventajas, la función SUMAPRODUCTO.
En muchas ocasiones al elaborar nuestros cálculos nos hemos dado cuenta de las limitaciones de esas funciones SUMAR.SI o SUMAR.SI.CONJUNTO, que aunque muy potentes, nos restringen las operaciones al criterio Y, es decir, funcionan únicamente con sumas acumulativas de registros que cumplen condiciones simultáneas. Por ejemplo:
=SUMAR.SI.CONJUNTO(A1:A10;B1:B10;>100;C1:C10;"a")
que sumaría los importes del rango A1:A10 sólo en los casos en que la cantidad de B1:B10 correspondiente sea mayor a 100 y al mismo tiempo en C1:C10 contenga el texto "a".

Las posibilidades de SUMAPRODCUTO en Excel.


¿Pero, y qué podemos hacer si en lugar del criterio Y deseamos aplicar el criterio O?. Aquí es donde comienza la potencia de SUMAPRODUCTO.

Si buscamos en la ayuda de Excel esta función leeremos: SUMAPRODCUTO Multiplica los componentes correspondientes de las matrices suministradas y devuelve la suma de esos productos.; y efectivamente este sería el uso más habitual, sin embargo es mucho más interesante observar los argumentos de la función, en la Sintáxis:
SUMAPRODUCTO(matriz1; [matriz2]; [matriz3]; ...)

Lo especial de esta función es que permite trabajar u operar con Rangos o matrices!!!, lo que es poco frecuente, excepto con las funciones matriciales. Es, sobre este punto, sobre el que incidiré.
Esta forma parecida a la matricial de trabajar de nuestra función es la que ocupará nuestra entrada del día; ya que con ella podremos operar empleando ambos criterios lógicos Y y O (AND y OR); esto lo conseguiremos empleando los operadores * y +:
para el operador lógico Y usaremos *
para el operador lógico O usaremos +

En esencia conseguiremos que Excel evalúe las condiciones que le vamos a dar, empleando estos operadores, para que nos devuelva VERDADERO o FALSO (1 ó 0 en valor numérico respectivamente), todo ello sin emplear la forma matricial de ejecutar las funciones.


Veremos, como siempre, algunos ejemplos de este uso especial de SUMAPRODUCTO. Partiremos de la siguiente base de datos, al que hemos asignado ciertos Nombres definidos para trabajar de una forma más visual:
Comercial =Hoja2!$A$2:$A$14
Importe =Hoja2!$D$2:$D$14
Unidades =Hoja2!$C$2:$C$14
Zona =Hoja2!$B$2:$B$14

Las posibilidades de SUMAPRODCUTO en Excel.


Un primer ejemplo serviría para sustituir a las funciones SUMAR.SI o SUMAR.SI.CONJUNTO.
=SUMAR.SI.CONJUNTO(Importe;Comercial;"Pepe";Unidades;">60")
puede ser sustituido por
=SUMAPRODUCTO(Importe*(Comercial="Pepe")*(Unidades>60))

En ambos casos nos indica cuánto suman los importes para el comercial 'Pepe' cuando las Unidades vendidas superan las 60.
Notemos como las dos condiciones de SUMAR.SI.CONJUNTO son equivalentes al operador * (que implica el criterio lógico Y).

lunes, 4 de febrero de 2013

Algo más sobre Filtros avanzados en Excel.

Una vez vez más se demuestra que nunca lo sabes todo, y que cada día aprendes algo nuevo. Recientemente respondiendo la consulta de una lectora me percaté de una funcionalidad del Filtro avanzado a la hora de mostrar o copiar los registros filtrados a otro lugar.
Veremos en esta entrada cómo podemos conseguir mostrar no solo los registros que cumplan ciertas condiciones, si no también solo los campos que nosotros indiquemos.

Partiremos de un origen de datos sencillo, convertido en Tabla: 'Tabla1', lo que siempre facilitará posteriormente el trabajo:

Algo más sobre Filtros avanzados en Excel.


Sobre este rango aplicaremos una condición sencilla, por ejemplo, 'Unidades' mayores a 12. Así que en el rango G1:G2 indicamos tal condición.
Y lo más importante, puesto que nuestra idea es mostrar algunos campos de la 'Tabla1' que cumplan la condición anterior, en el rango G4:I4, indicamos los campos a mostrar: Código, Precio, Total:

Algo más sobre Filtros avanzados en Excel.


Perfecto, estamos listos para ejecutar la herramienta de Excel Filtro avanzado; navegamos a la ficha Datos > grupo Ordenar y filtrar > botón Avanzadas, y configuramos la ventana abierta: