Seguimos con las instrucciones de control de flujo, ésta vez vamos a comentar la que podemos utilizar cuando conocemos a priori el número de iteraciones que debemos realizar; ya que nos ofrece un control muy sencillo del numero de pasadas por el bucle y nos facilita un contador, que normalmente podremos utilizar como índice, o para cualquier otro servicio
La estructura de la sentencia es:
For <inicializacion de contador> to valor_final_contador
…… sentencias a ejecutar
next contador
Veamos la instrucción con un ejemplo
Supongamos que queremos reflejar los 56 colores de que disponemos, en las primeras 56 celdas de la hoja (A1:A56). Haremos:
Dim a As Integer Range("A1:A56").Select For a = 1 To 56 ' con a=1 hasta 56 Selection.Cells(a).Interior.Color = ActiveWorkbook.Colors(a) Next a
El bucle For….Next va dando vueltas, cambiando el valor de a , incrementandolo en 1, en cada pasada; cuando A vale 57, sale del bucle. ¿El resultado de esta tonteria?:
La macro anterior, nos ha generado el muestrario de colores de que dispone excel en su tabla de colores (ActiveWorkbook.Colors(a)) que hemos obtenido porque la variable a, ha estado modificándose desde 1 a 56, según le decía la instrucción for.
Si no decimos nada, este bucle va modificando la variable en incrementos de 1, si deseáramos cambiar este factor para, por ejemplo, hacer que avance de 3 en 3, podríamos añadir la palabra step 3:
For a=1 to 56 step 3
Veamos otro ejemplo, aunque la instrucción es lo suficiente sencilla para que se haya entendido.
Vamos a recorrer las primeras 10 filas y 10 columnas, y les iremos poniendo el número de orden que les corresponde, para hacerlo, anidaremos un for dentro de otro, el primero me irá dejando en a los valores de fila (de o a 10) y el segundo, el interior, me ira dejando en b los valores de columna, también de 0 a 10; cada vez que el interior haga 10 pasadas, saldrá y el exterior hará una más, para que él vuelva a hacer 10 pasadas… aquí os dejo el código:
For a = 1 To 10 For b = 1 To 10 ActiveSheet.Cells(a, b).Value = "Cell( " & a & "," & b & " )" ActiveSheet.Cells(a, b).NumberFormat = "@" Next b Next a
y aquí el resultado
Aunque hemos dicho que el bucle For….next esta pensado para recorrer áreas en las que conocemos previamente su longitud, hay veces que deseamos utilizarlo, por la facilidad que representa que el nos controle el indice, y vaya realizando el incremento. Entonces, lo único que necesitamos es conocer la longitud del elemento a recorrer.
Supongamos que queremos recoger todas las celdas con contenido en la columna A, y ponerlas en la columna B, si queremos utilizar For next, necesitamos saber cuantas són, para ello, podemos hacer:
fila = Application.WorksheetFunction.CountA(Range("A:A"))
ésto, me dejará en fila el número de celdas con contenido
Ahora, podemos hace un bucle For..next para ir dejando la información, pero tendremos que tener cuidado con la recogida, ya que puede haber celdas vacias….
Empiezo guardandome el rango de destino en la variable destino y cuento el total de celdas que tendré que dejar en la salida, contando las celdas con algo que tengo en el rango Origen
Set destino = Range("b1") fila = Application.WorksheetFunction.CountA(Range("A:A")) If fila = 0 Then Exit Sub Debug.Print fila
Vereis aparecer en la consola el número de celdas con contenido encontradas.
Ahora monto un bucle que irá moviendo las celdas encontradas hacia la salida, mientras que utilizo un while (lo veremos a continuacion) para esquivar las celdas vacias. (while-wend ira haciendo avanzar la seleccion hasta encontrar una no vacia)
Cuandoel For..next haya movido la cantidad prevista, se para y la macro termina. Aquí está todo el código
im r As Range Dim fila As Long Set destino = Range("b1") fila = Application.WorksheetFunction.CountA(Range("A:A")) If fila = 0 Then Exit Sub Debug.Print fila Application.ScreenUpdating = False Range("A:A").Select For a = 1 To fila While IsEmpty(ActiveCell) ActiveCell.Offset(1, 0).Select Wend destino.Cells(a, 1).Value = ActiveCell.Value ActiveCell.Offset(1, 0).Select Next a Application.ScreenUpdating = True
Ah!, el Application.ScreenUpdating me permite detener (false) la actualización de pantalla mientras corre la macro para ahorrar algo de tiempo.
Relacionado
Descubre más desde Recursos para formacion
Suscríbete y recibe las últimas entradas en tu correo electrónico.
8 comentarios
Gracias!!!
Hola que tal, excelente aporte. Me podrías orientar con los siguiente tengo dos archivos una con una base de datos y otra donde importar datos específicos de la base de datos, esta base de datos corresponde cada hoja a los días del mes actual. te adjunto el modulo que hago para copiar los datos. Lo que quiero es utilizar un bucle que me recorra todas las hojas para hacerlo mas simple. Agradezco tu ayuda. Sub MetodoAbrirLibro()
Application.ScreenUpdating = False
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False
Workbooks.Open «E:\Prueba\cierre inventarios » & Format(Now, «mmmm») & «.xls»
Windows(«cierre inventarios » & Format(Now, «mmmm») & «.xls»).Activate
Sheets(«1»).Select
Range(«D18:E18»).Select
Selection.Copy
Windows(«Indicadores.xlsm»).Activate
Sheets(«Hoja1»).Select
Range(«B3»).Select
Selection.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = Fals
Windows(«cierre inventarios » & Format(Now, «mmmm») & «.xls»).Activate
Sheets(«2»).Select
Range(«D18:E18»).Select
Selection.Copy
Windows(«Indicadores.xlsm»).Activate
Sheets(«Hoja1»).Select
Range(«B4»).Select
Selection.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = Fals
Windows(«cierre inventarios » & Format(Now, «mmmm») & «.xls»).Activate
Sheets(«3»).Select
Range(«D18:E18»).Select
Selection.Copy
Windows(«Indicadores.xlsm»).Activate
Sheets(«Hoja1»).Select
Range(«B5»).Select
Selection.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = Fals
Windows(«cierre inventarios » & Format(Now, «mmmm») & «.xls»).Activate
Sheets(«4»).Select
Range(«D18:E18»).Select
Selection.Copy
Windows(«Indicadores.xlsm»).Activate
Sheets(«Hoja1»).Select
Range(«B6»).Select
Selection.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = Fals
Windows(«cierre inventarios » & Format(Now, «mmmm») & «.xls»).Activate
Sheets(«5»).Select
Range(«D18:E18»).Select
Selection.Copy
Windows(«Indicadores.xlsm»).Activate
Sheets(«Hoja1»).Select
Range(«B7»).Select
Selection.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = Fals
Windows(«cierre inventarios » & Format(Now, «mmmm») & «.xls»).Activate
Sheets(«6»).Select
Range(«D18:E18»).Select
Selection.Copy
Windows(«Indicadores.xlsm»).Activate
Sheets(«Hoja1»).Select
Range(«B8»).Select
Selection.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = Fals
Windows(«cierre inventarios » & Format(Now, «mmmm») & «.xls»).Activate
Sheets(«7»).Select
Range(«D18:E18»).Select
Selection.Copy
Windows(«Indicadores.xlsm»).Activate
Sheets(«Hoja1»).Select
Range(«B9»).Select
Selection.PasteSpecial Paste:=xlPasteValues
Windows(«Indicadores.xlsm»).Activate
Sheets(«Hoja1»).Select
Range(«B33»).Select
Selection.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = Fals
Asi sucesivamente hasta el ultimo día del mes actual
Windows(«cierre inventarios » & Format(Now, «mmmm») & «.xls»).Activate
ActiveWindow.Close
End Sub
Hola que tal, excelente aporte. Me podrías orientar con los siguiente tengo dos archivos una con una base de datos y otra donde importar datos específicos de la base de datos, esta base de datos corresponde cada hoja a los días del mes actual. te adjunto el modulo que hago para copiar los datos. Lo que quiero es utilizar un bucle que me recorra todas las hojas para hacerlo mas simple. Agradezco tu ayuda. Sub MetodoAbrirLibro()
Application.ScreenUpdating = False
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False
Workbooks.Open «E:\Prueba\cierre inventarios » & Format(Now, «mmmm») & «.xls»
Windows(«cierre inventarios » & Format(Now, «mmmm») & «.xls»).Activate
Sheets(«1»).Select
Range(«D18:E18»).Select
Selection.Copy
Windows(«Indicadores.xlsm»).Activate
Sheets(«Hoja1»).Select
Range(«B3»).Select
Selection.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = Fals
Windows(«cierre inventarios » & Format(Now, «mmmm») & «.xls»).Activate
Sheets(«2»).Select
Range(«D18:E18»).Select
Selection.Copy
Windows(«Indicadores.xlsm»).Activate
Sheets(«Hoja1»).Select
Range(«B4»).Select
Selection.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = Fals
Windows(«cierre inventarios » & Format(Now, «mmmm») & «.xls»).Activate
Sheets(«3»).Select
Range(«D18:E18»).Select
Selection.Copy
Windows(«Indicadores.xlsm»).Activate
Sheets(«Hoja1»).Select
Range(«B5»).Select
Selection.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = Fals
Windows(«cierre inventarios » & Format(Now, «mmmm») & «.xls»).Activate
Sheets(«4»).Select
Range(«D18:E18»).Select
Selection.Copy
Windows(«Indicadores.xlsm»).Activate
Sheets(«Hoja1»).Select
Range(«B6»).Select
Selection.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = Fals
Windows(«cierre inventarios » & Format(Now, «mmmm») & «.xls»).Activate
Sheets(«5»).Select
Range(«D18:E18»).Select
Selection.Copy
Windows(«Indicadores.xlsm»).Activate
Sheets(«Hoja1»).Select
Range(«B7»).Select
Selection.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = Fals
Windows(«cierre inventarios » & Format(Now, «mmmm») & «.xls»).Activate
Sheets(«6»).Select
Range(«D18:E18»).Select
Selection.Copy
Windows(«Indicadores.xlsm»).Activate
Sheets(«Hoja1»).Select
Range(«B8»).Select
Selection.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = Fals
Windows(«cierre inventarios » & Format(Now, «mmmm») & «.xls»).Activate
Sheets(«7»).Select
Range(«D18:E18»).Select
Selection.Copy
Windows(«Indicadores.xlsm»).Activate
Sheets(«Hoja1»).Select
Range(«B9»).Select
Selection.PasteSpecial Paste:=xlPasteValues
Windows(«Indicadores.xlsm»).Activate
Sheets(«Hoja1»).Select
Range(«B33»).Select
Selection.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = Fals
Asi sucesivamente hasta el ultimo día del mes actual
Windows(«cierre inventarios » & Format(Now, «mmmm») & «.xls»).Activate
ActiveWindow.Close
End Sub