Una de las consultas que recibo con bastante frecuencia es cómo generar hojas en un cuaderno a partir de una lista.
Supongamos que tenemos una hoja en un cuaderno con la lista de los meses del año.
Queremos que una macro genere 12 hojas en el cuaderno, un para cada mes, y les ponga el nombre del mes
Esto podemos hacerlo con una macro bastante sencilla
Sub crear_hojas()
Dim Lista As Range
Dim iX As Long
Set Lista = Application.InputBox(prompt:="Señalar rango de la lista", _
Title:="Lista de nombres", Type:=8)
Application.ScreenUpdating = False
For iX = Lista.Count To 1 Step -1
Sheets.Add.Name = Lista(iX)
Next iX
Sheets(1).Select
Application.ScreenUpdating = True
End Sub
Al correr esta macro, se abre un diálogo donde ponemos el rango que contiene la lista (pueden ser meses, días de semana o cualquier otra cosa); al pulsar el botón Aceptar
se generarán las hojas en el orden de la lista.
Si queremos usar esta macro con cierta frecuencia o pasársela a un compañero del trabajo, descubriremos que tenemos que hacer algunas mejoras.
Por ejemplo, si en el diálogo de elegir rango pulsamos Cancelar, se abrirá el editor de Vba y veremos este mensaje de error
Para evitar esto usamos la sentencia On Error
Sub crear_hojas()
Dim Lista As Range
Dim iX As Long
On Error GoTo Cancelar
Set Lista = Application.InputBox(prompt:="Señalar rango de la lista", _
Title:="Lista de nombres", Type:=8)
Application.ScreenUpdating = False
For iX = Lista.Count To 1 Step -1
Sheets.Add.Name = Lista(iX)
Next iX
Sheets(1).Select
Application.ScreenUpdating = True
Cancelar:End Sub
Otro problema puede generarse cuando ya existe en el cuaderno una hoja con uno de los nombres que aparecen en la lista. Por ejemplo, si la hoja Enero existe antes de correr la macro, obtenemos este resultado
Para evitar este problema tendremos que hacer algunas modificaciones a nuestra macro. Primero creamos una función para verificar si una hoja a crear ya existe
Function chequear_hoja(sheetName As String) As Boolean
Dim wkb As Worksheet
On Error Resume Next
Set wkb = Sheets(sheetName)
On Error GoTo 0
chequear_hoja = IIf(Not wkb Is Nothing, True, False)
End Function
Esta función da como resultado FALSE si la hoja no existe, y TRUE si la hoja ya existe en el cuaderno.
Lo que hacemos es usar esta función (adaptada de la propuesta por Colo) en nuestra macro para crear una condición. Si la hoja no existe, entonces creamos una nueva con el nombre correspondiente; de existir, pasamos a verificar el próximo nombre en la lista.
Sub crear_hojas2()
Dim Lista As Range
Dim iX As Long
On Error GoTo Cancelar
Set Lista = Application.InputBox(prompt:="Señalar rango de la lista", _
Title:="Lista de nombres", Type:=8)
Application.ScreenUpdating = False
For iX = Lista.Count To 1 Step -1
If chequear_hoja(Lista(iX)) = False Then
Sheets.Add.Name = Lista(iX)
End If
Next iX
Sheets("Hoja1").Activate
Application.ScreenUpdating = True
Cancelar:
End Sub
El cuaderno con las macros se puede descargar aquí
Technorati Tags: MS Excel
Sugerencias y ayuda para Excel en español. Ejemplos de funciones y fórmulas, gráficos, automatización con Vba, Power Query y PowerPivot
martes, marzo 25, 2008
miércoles, marzo 19, 2008
Operaciones con rangos discontinuos en Excel.
No todas las funciones de Excel permiten realizar cálculos con rangos discontinuos. Por ejemplo, supongamos estos dos rangos, A1:A3 y A5:A8
Supongamos que por algún motivo no podemos operar con el rango A1:A8. Si queremos sumar todos los valores en los dos rango podemos usar la fórmula
=SUMA(A1:A3,A5:A8)
Lo mismo si queremos contar cuántos elementos hay en ambos rangos
=CONTAR(A1:A3,A5:A8)
Pero si queremos usar CONTAR.SI para averiguar cuantos números mayores a 200 hay en los dos rangos, la fórmula
=CONTAR.SI((A1:A3,A5:A8),">200")
da como resultado #¡VALOR! Lo mismo sucede si queremos usar SUMAR.SI
La solución, por lo general, será combinar dos funciones CONTAR.SI. En nuestro caso sería
=CONTAR.SI(A1:A3,">200")+CONTAR.SI(A5:A8,">200")
El problema con esta solución es que en muchos casos tenemos que combinar muchas funciones CONTAR.SI, lo que convierte en engorrosa la tarea de construir nuestra fórmula.
Veamos cuáles son nuestras posibilidades:
Una posibilidad más compacta es ésta (propuesta por Juan Pablo González en el foro de MrExcel):
=SUMA(CONTAR.SI(INDIRECTO({"A1:A3";"A5:A8"}),">200"))
o utilizar la función ARRAY.JOIN del complemento Morefunc que tantas veces he recomendado
={SUMA((ARRAY.JOIN(A1:A3,A5:A8)>200)*1)}
Esta última fórmula es matricial y debe introducirse en la celda apretando simultáneamente Ctrl+Mayúsculas+Enter.
Los "puristas" pueden utilizar también
=SUMA(--(ARRAY.JOIN(A1:A3,A5:A8)>200))
donde usamos el doble signo menos (--) para forzar la conversión de valores lógicos a 1 (VERDADERO) o 0 (FALSO).
Ambas fórmulas dan como resultado 6.
Para sumar condicional podemos usar estas posibilidades:
=SUMA(SUMAR.SI(INDIRECTO({"A1:A3";"A5:A8"}),">200"))
una variante de la fórmula con INDIRECTO, adaptada a suma condicional, o
=SUMAPRODUCTO((ARRAY.JOIN(A1:A3,A5:A8)>200)*ARRAY.JOIN(A1:A3,A5:A8))
donde usamos SUMAPRODUCTO junto con ARRAY.JOIN
Podemos, y es recomendable, usar rangos nominados. Definimos dos nombres, cada uno refiriéndose a cada uno de los rangos
rango1 =Hoja1!$A$1:$A$3
rango2 =Hoja1!$A$5:$A$8
y utilizarlos en nuestras fórmulas. Por ejemplo:
=SUMA(SUMAR.SI(INDIRECTO({"rango1";"rango2"}),">200"))
Habrán notado que en las fórmulas con INDIRECTO usamos la expresión {"A1:A3";"A5:A8"}. Esta expresión crea un matriz en base a los datos de los rangos expresados como texto (que aparecen entre comillas y por ese motivo usamos INDIRECTO). Pueden consultar esta nota sobre funciones y constantes matriciales.
Supongamos que por algún motivo no podemos operar con el rango A1:A8. Si queremos sumar todos los valores en los dos rango podemos usar la fórmula
=SUMA(A1:A3,A5:A8)
Lo mismo si queremos contar cuántos elementos hay en ambos rangos
=CONTAR(A1:A3,A5:A8)
Pero si queremos usar CONTAR.SI para averiguar cuantos números mayores a 200 hay en los dos rangos, la fórmula
=CONTAR.SI((A1:A3,A5:A8),">200")
da como resultado #¡VALOR! Lo mismo sucede si queremos usar SUMAR.SI
La solución, por lo general, será combinar dos funciones CONTAR.SI. En nuestro caso sería
=CONTAR.SI(A1:A3,">200")+CONTAR.SI(A5:A8,">200")
El problema con esta solución es que en muchos casos tenemos que combinar muchas funciones CONTAR.SI, lo que convierte en engorrosa la tarea de construir nuestra fórmula.
Veamos cuáles son nuestras posibilidades:
Una posibilidad más compacta es ésta (propuesta por Juan Pablo González en el foro de MrExcel):
=SUMA(CONTAR.SI(INDIRECTO({"A1:A3";"A5:A8"}),">200"))
o utilizar la función ARRAY.JOIN del complemento Morefunc que tantas veces he recomendado
={SUMA((ARRAY.JOIN(A1:A3,A5:A8)>200)*1)}
Esta última fórmula es matricial y debe introducirse en la celda apretando simultáneamente Ctrl+Mayúsculas+Enter.
Los "puristas" pueden utilizar también
=SUMA(--(ARRAY.JOIN(A1:A3,A5:A8)>200))
donde usamos el doble signo menos (--) para forzar la conversión de valores lógicos a 1 (VERDADERO) o 0 (FALSO).
Ambas fórmulas dan como resultado 6.
Para sumar condicional podemos usar estas posibilidades:
=SUMA(SUMAR.SI(INDIRECTO({"A1:A3";"A5:A8"}),">200"))
una variante de la fórmula con INDIRECTO, adaptada a suma condicional, o
=SUMAPRODUCTO((ARRAY.JOIN(A1:A3,A5:A8)>200)*ARRAY.JOIN(A1:A3,A5:A8))
donde usamos SUMAPRODUCTO junto con ARRAY.JOIN
Podemos, y es recomendable, usar rangos nominados. Definimos dos nombres, cada uno refiriéndose a cada uno de los rangos
rango1 =Hoja1!$A$1:$A$3
rango2 =Hoja1!$A$5:$A$8
y utilizarlos en nuestras fórmulas. Por ejemplo:
=SUMA(SUMAR.SI(INDIRECTO({"rango1";"rango2"}),">200"))
Habrán notado que en las fórmulas con INDIRECTO usamos la expresión {"A1:A3";"A5:A8"}. Esta expresión crea un matriz en base a los datos de los rangos expresados como texto (que aparecen entre comillas y por ese motivo usamos INDIRECTO). Pueden consultar esta nota sobre funciones y constantes matriciales.
Technorati Tags: MS Excel
sábado, marzo 15, 2008
Gráficos con imágenes - algunos trucos
Una buena forma de enfatizar la representación de un presupuesto en un gráfico es mostrar un billete partido en pedazos, donde cada porción representa en forma proporcional un concepto del presupuesto
La técnica para hacerlo esta explicado en mi blog sobre gráficos y presentación de datos, en la nota Gráfico de presupuesto con Autoformas.
Si quieren el mismo gráfico, pero orientado horizontalmente
pueden leer la nota Otro gráfico de presupuesto con imágenes.
La técnica para hacerlo esta explicado en mi blog sobre gráficos y presentación de datos, en la nota Gráfico de presupuesto con Autoformas.
Si quieren el mismo gráfico, pero orientado horizontalmente
pueden leer la nota Otro gráfico de presupuesto con imágenes.
Technorati Tags: MS Excel
Suscribirse a:
Entradas (Atom)