Hojas de cálculo en Excel - página principal

Crear un gráfico, con un macro

A veces crear un gráfico puede convertirse en una tarea tediosa, porque normalmente vamos seleccionando las opciones como el tipo de gráfico, el rango de datos, y demás, a través del asistente de gráficos.

Si normalmente utilizamos siempre el mismo tipo de gráficos, podemos automatizar la tarea de creación de un gráfico, de forma muy sencilla. Nos bastará con crear el siguiente código:


Sub crear_grafico()
'Ocultamos el procedimiento
Application.ScreenUpdating = False
'Pasamos a una variable la celda donde estamos,
'para volver a ella al finalizar el macro

celda_donde_estamos = ActiveCell.Address
'Vamos al principio del rango de datos
'(celda de arriba a la izquierda).
'Mejor usar esto, que CurrentRegion:

If ActiveCell.Row <> 1 Then
If ActiveCell.Offset(-1, 0) <> "" Then
Selection.End(xlUp).Select
End If
End If
If ActiveCell.Column <> 1 Then
If ActiveCell.Offset(0, -1) <> "" Then
Selection.End(xlToLeft).Select
End If
End If
'Pasamos la celda inicial (donde estamos ahora)
celda_inicial = ActiveCell.Address
'si la celda está vacía, no creamos el gráfico
If celda_inicial = "" Or IsEmpty(ActiveCell) Then
mensaje = MsgBox("No hay datos para crear el gráfico. ", vbInformation, "Imposible crear gráfico")
Exit Sub
End If
'Pasamos a una variable, el nombre de la hoja
nombre_de_la_hoja = ActiveSheet.Name
'Pasamos a una variable, el área de datos para el gráfico
area_de_datos = Range(celda_inicial).CurrentRegion.SpecialCells(xlVisible).Address
'Creamos el gráfico
Charts.Add
'Informamos del tipo de gráfico que deseamos
ActiveChart.ChartType = xlColumnClustered
'Seleccionamos el área de datos para montar el gráfico
ActiveChart.SetSourceData Source:=Sheets(nombre_de_la_hoja).Range(area_de_datos), PlotBy:=xlColumns
'Creamos el gráfico en la hoja donde estamos
ActiveChart.Location Where:=xlLocationAsObject, Name:=nombre_de_la_hoja
'Cambiamos el título del gráfico
With ActiveChart
.HasTitle = True
.Axes(xlCategory, xlPrimary).HasTitle = False
.Axes(xlValue, xlPrimary).HasTitle = False
End With
'Quitamos la leyenda
ActiveChart.HasLegend = False
'Ponemos tamaño 8 para el eje Y
ActiveChart.Axes(xlValue).Select
Selection.TickLabels.AutoScaleFont = True
With Selection.TickLabels.Font
.Size = 8
End With
'Ponemos tamaño 8 para el eje X
ActiveChart.Axes(xlCategory).Select
Selection.TickLabels.AutoScaleFont = True
With Selection.TickLabels.Font
.Size = 8
End With
'Ponemos el título en negrita
ActiveChart.ChartTitle.Select
Selection.Font.Bold = True
'Volvemos a la celda donde estábamos inicialmente
Range(celda_donde_estamos).Select
'Mostramos el procedimiento
Application.ScreenUpdating = True
End Sub


En ese ejemplo que os dejo, se nos creará un gráfico de barras, en el que ajustaremos el tamaño de la fuente a 8, como cosas más importantes. Para que funcione el macro, y nos cree el gráfico, tan solo deberemos situarnos en una celda del rango que contenga datos. Da igual la celda donde nos situemos, tan solo deberemos posicionarnos encima de una de las celdas. De esa forma, y ejecutando el macro, tendremos nuestro gráfico creado en un plis plas.

Desde aquí podéis descargar el fichero de excel, con el código que os presento en este artículo, para que podáis ver en funcionamiento como se crean gráficos "al vuelo".



17 comentarios:

Anónimo dijo...

Gracias por estos códigos de programación. Fueron la base de una serie de macros para realizarun total de 40 gráficas en casi tres horas. Soy novato en el manejo de macros, pero lo poco que las he usado me han ayudado a reducir el tiempo para hacerlas de manera homologada. Gracia Javier.

Alberto C. de México

Javier Marco dijo...

Hola Alberto.

Me alegro que lo que has encontrado en el blog, te haya servido.

Muchas gracias por tu comentario.

Anónimo dijo...

Gracias por esto!
muy didactico los de los comentarios en cada entrada!
se agradece mucho,
tambien soy novato y esto me servira cantidades.

Gracias de nuevo javier.

Anónimo dijo...

Hola, yo tambien soy novato en esto de los macros y las graficas en excel asi es que me gustaria pedirte un poco de ayuda Javier Marcos. Como es que se ejecuta este codigo o en donde lo creo? me podrias ayudar con eso. Muchas Gracias
Atte: Alejandro

boofunky dijo...

Javier una consulta, Tengo 2 columnas (Codigos y Duracion)
por ej: Codigo: 1 2 4 2 1 3 2 1
Duracion: 5 6 8 1 2 9 8 2

Y en otra hoja debo obtener la duracion total por código.. ej:
Código: 1 2 3 4
Duracion: 9 9 9 8

si hay por ahí una funcion que lo realice.

Pedro Silvestre dijo...

Hola Javier.

Solo con una consulta, en el caso de que tenga 20 columnas, donde la primera representa la variable "Y" y las siguientes constituyen variables "X", còmo hago para que la macro genere las 19 gràficas de una sola vez?

Agradecerìa tu ayuda.

Gracias

Anónimo dijo...

muchas gracias por la macro, me parece estupenda, me va a servir en un grafico de una hoja personal que tengo que cada vez que añado mas registros tengo que modificar el rango de datos del grafico.
y tu macro me lo hace automaticamente.

un detalle que te pediria y es un boton para borrar el grafico ya creado para hacer uno nuevo, por que si clico dos veces el boton me crea dos graficos, uno sobre otro, al anterior se queda debajo.

y otra cosita, que como soy novato en programacion no me sale y es como puedo hacer que se ejecute la misma macro en dos hojas al mismo tiempo, como llamo a las dos hojas en la misma macro?

te explico, tengo una macro que me colorea las celdas segun el nombre que contengan
el codigo de los formatos lo tengo que tener duplicado al ser dos hojas donde se debe ejecutar, son lo mismo en las dos hojas y por avitar duplicaciones y quitar trabajo cuando se añade algunos otros nombres me gustaria que fuera una unica macro que se ejecute en las dos hojas, pero no veo la forma, seguro que es bien sencillo
me podrias ayudar? gracias mil

Karina dijo...

Hola javier, te planteo el problema a ver que solucion se te ocurre para simplificarme la tarea.
Tengo un archivo excel con las series vendidas (Ej 354007038434798) y otro archivo con las series liquidadas con su respectivo importe. Tengo que enfrentar ambos archivos a ver si todas las series vendidas figuran liquidadas. Hasta ahora busco manualmente una por una!!! Desde ya muchas gracias!!!

Javier Marco dijo...

Con la función BUSCARV podrás solucionarlo, siempre y cuando tengas los datos de la tabla de las unidades liquidadas ordenada de forma creciente, pues quieres ver si las unidades vendidas aparecen en esa otra tabla.

En la ayuda de Excel (F1) obtendrás más información al respecto.

Raul Fdez dijo...

Estimado Javier,
Favor ayuda con lo siguiente:

Necesito que el grafico que se crea sea un ChartSpace insertado en un UserForm.

O al revez que los datos de origen del ChartSpace provengan de una hoja del libro (como en tu ejemplo), y no de un SpreadSheet o de la "hoja de datos" del propio ChartSpace, como en la mayoria de los ejemplos muestran.

Muchas Gracias, y saludos!

Anónimo dijo...

Hola,
Sabeis como se puede colorear cada barra de un grafico segun el texto. Alguien podria decirme como hacerlo o tiene una macro que lo haga.
Gracias

velis dijo...

Hola me podrías ayudar para hacer unas gráficas, en las filas tengo nombres de colonias en las columnas las clasificaciones como hacer gráficas por cada colonia si son 200 colonias que tengo que graficar

Anónimo dijo...

Hola¡¡, estoy haciendo un proyecto con macros y la verdad lo llevo fatal...ahora mismo me he atascado con una cosa seguro bastante tonta.Tengo un gráfico con un rango de valores del eje X de -30 a 60...y quiero hacer una macro para que el usuario pueda introducir un intervalo, y el gráfico cambie para que los límites sean los introducidos.Primero hice un procedimiento que pregunta con dos inputbox los límites inferior y superior al usuario, Linf y Lsup.Estos valores los paso a otro procedimiento que hice con la herramienta "grabar macro"donde fui haciendo paso a paso con el ratón lo de cambiar los límites en "dar formato a eje"....pero no funciona¡¡ y ya no se que hacer...por favor, si me pudieses ayudar te lo agradecería muchísimo, porque ya no se que más probar¡¡¡ gracias¡¡¡


Sub valoresvariables()
'pide los límites para el eje X

Dim Linf As Integer, Lsup As Integer

Linf = InputBox("Introduce el límite inferior")
Lsup = InputBox("introduce el límite superior")
Call macro1(Linf, Lsup)
End Sub


Sub macro1(Linf, Lsup)
'código realizado con "grabar macro"


Sheets("Diagrama variable").Select
ActiveSheet.ChartObjects("1 Gráfico").Activate
ActiveChart.Axes(xlCategory).Select
ActiveSheet.ChartObjects("1 Gráfico").Activate
ActiveChart.Axes(xlCategory).MinimumScale = Linf
ActiveChart.Axes(xlCategory).MaximumScale = Lsup
End Sub

Me sale un Error del sistema el parámetro no es correcto

Javier Marco dijo...

Ponle esta primera línea al macro llamado macro1(Linf, Lsup):

MsgBox(Linf)

Y verás como te sale un MsgBox vacío (sin la cifra que has escrito en el InputBox). ¿Por qué?. Pues porque en un macro estás llamando a una variable de otro macro. En principio las variables solo sirven en el ámbito de un procedimiento, por lo que no puedes "llamarlas" desde otro, a no ser que expresamente les indiques que quieres tenerlas disponibles en otros procedimientos. ¿Cómo se indica esto?.

Pues de esta forma (pon esto al principio, encima de los procedimientos):

Public Linf
Public Lsup

De esa forma siempre tendrás accesible el valor de esas variables.

Si ahora pruebas el MsgBox que te indicaba al principio, verás como te devuelve lo que escribiste en el InputBox.

Saludos.

Anónimo dijo...

Muchísimas gracias¡¡¡, ya lo cambié...pero ahora me surje otro problema....Resulta que tengo un bucle con el que copio unos valores en otro sitio...y luego se llama al procedimiento de antes para lo de los ejes....por separado funcionan bien, pero cuandollamo a uno desde el otro no funcionaa¡¡¡....te mando el trozo de código¡¡
If Range("O3").Value = "5" Then 'Intervalo variable

Range("B6").Select
Do While Not IsEmpty(ActiveCell)
If ((ActiveCell.Value <> " ") Or (ActiveCell.Value <> "")) Or ((ActiveCell.Offset(0, 1).Value <> " ") Or (ActiveCell.Offset(0, 1).Value <> "")) Then
ActiveCell.Offset(0, 19).Value = ActiveCell.Offset(0, 5).Value
'aqui salta al otro antes de tiempo ActiveCell.Offset(0, 20).Value = ActiveCell.Offset(0, 6).Value


Else
ActiveCell.Offset(0, 19).Value = ""
ActiveCell.Offset(0, 20).Value = ""
End If
ActiveCell.Offset(1, 0).Select
Loop
Call valoresvariables()

'Este procedimiento sigue y se cierra el if más abajo

---------------------------
Sub valoresvariables()
Dim Linf As Integer, Lsup As Integer
'código realizado con "grabar macro"
Linf = InputBox("Introduce el límite inferior")
Lsup = InputBox("introduce el límite superior")

Sheets("Diagrama variable").Select
'ActiveSheet.ChartObjects("1 Gráfico").Activate
ActiveChart.Axes(xlCategory).Select
ActiveChart.Axes(xlCategory).MinimumScale = Linf
ActiveChart.Axes(xlCategory).MaximumScale = Lsup
End Sub


LO que pasa ahora es que funcionan separados...pero cuando los junto el de rellenar las celdas se interrumpe y salta el otro.....es como si el While no se terminase....es horrible, porque necesito que vayan juntos¡¡....además salta un error que pone 400

Mil gracias por la ayuda¡¡¡

Javier Marco dijo...

No puede saltar el macro valoresvariables() antes de tiempo, porque no lo llamas desde dentro del condicional, sino desde fuera, una vez finalizado el bucle. Es decir te salta el macro, cuando encuentra la primera fila vacía.

Siento no poder ayudarte más, pero te recomiendo que te pases por el subforo de ofimática de forosdelweb, porque sino esto se convertiría en un chat: www.forosdelweb.com/f90

Espero que lo entiendas :-)

Un saludo.

Anónimo dijo...

ok¡¡¡ me sirvió de mucho tu ayuda y la página que me recomendaste....muchas gracias¡¡