martes, 17 de julio de 2018

Bucles For anidados

Puede descargar el archivo BuclesForAnidados.xlsm

Vamos a trabajar con dos bucles For...Next anidados. Realizaremos unos ejercicios con macros Excel programando en VBA.

Llegaremos a realizar la siguiente figura con números que van entre 1 y 9, tanto en horizontal como en vertical.


Pero antes de llegar a obtener esa imagen que hemos denominado 'Bandera Color' vamos a ir paso a paso.



Borra

Como vamos a trabajar en varios casos, antes de comenzar  nos interesa borrar el contenido del rango A1.I9. También vamos a borrar el color de fondo de las celdas.


Sub Borra()
Dim R As Range
Set R = Range("A1:I9")
R.ClearContents
R.Interior.Pattern = xlNone
End Sub


Completo

Anidamos dos bucles For para conseguir imprimir en cada una de las celdas del cuadrado de 9 filas y 9 columnas, los números i j.



Sub Completo()
Dim i As Byte, j As Byte
Call Borra
For i = 1 To 9
  For j = 1 To 9
    Cells(i, j) = Str(i) & " " & Str(j)
  Next j
Next i
End Sub


Caja

Ahora queremos que no se imprima el cuadrado completo, únicamente deseamos imprimir los bordes. Para ello precisamos incluir dentro de los bucles anidados un condicional if que imprima únicamente los índices i j cuando se cumpla que el primero es igual a 1 o 9, o bien el segundo sea igual a 1 o 9. De esta forma conseguimos imprimir solo el perímetro del cuadrado.



Sub Caja()
Dim i As Byte, j As Byte
Call Borra
For i = 1 To 9
  For j = 1 To 9
    If i = 1 Or i = 9 Or j = 1 Or j = 9 Then
      Cells(i, j) = Str(i) & " " & Str(j)
    End If
  Next j
Next i
End Sub


Diagonal 1

Queremos imprimir únicamente la diagonal primera que se consigue haciendo que el condicional if filtre únicamente aquellos valores donde los índices i j coincidan.




Sub Diagonal_1()
Dim i As Byte, j As Byte
Call Borra
For i = 1 To 9
  For j = 1 To 9
    If i = j Then
      Cells(i, j) = Str(i) & " " & Str(j)
    End If
  Next j
Next i
End Sub


Diagonal 2

La segunda diagonal se consigue buscando qué tienen en común los índices i j. Observamos que esta diagonal cumple que al sumar ambos índices la suma siempre es igual a 10. Esta será la condición que impondremos en el condicional if.



Sub Diagonal_2()
Dim i As Byte, j As Byte
Call Borra
For i = 1 To 9
  For j = 1 To 9
    If i + j = 10 Then
      Cells(i, j) = Str(i) & " " & Str(j)
    End If
  Next j
Next i
End Sub


Bandera


Deseamos imprimir únicamente los bordes y las dos diagonales. A esta figura la hemos llamado bandera. Observe que se consigue incluyendo en el if seis condiciones concatenadas con el operador lógico Or.



Sub Bandera()
Dim i As Byte, j As Byte
Call Borra
For i = 1 To 9
  For j = 1 To 9
    If i = 1 Or i = 9 Or j = 1 Or j = 9 Or i = j Or i + j = 10 Then
      Cells(i, j) = Str(i) & " " & Str(j)
    End If
  Next j
Next i
End Sub


Bandera Color

Nos gustaría que la bandera tuviera colores. Los colores de fondo de cada celda se consiguen con Interior.ColorIndex=número. Donde el número nos da el color.





Sub BanderaColor()
Dim i As Byte, j As Byte
Call Borra
For i = 1 To 9
  For j = 1 To 9
    If i = j Or i + j = 10 Then
      Cells(i, j) = Str(i) & " " & Str(j)
      Cells(i, j).Interior.ColorIndex = 3 'rojo
    ElseIf i = 1 Or i = 9 Or j = 1 Or j = 9 Then
      Cells(i, j) = Str(i) & " " & Str(j)
      Cells(i, j).Interior.ColorIndex = 6 'amarillo
    Else
      Cells(i, j).Interior.ColorIndex = 8 'azul
    End If
  Next j
Next i
End Sub

Ya tenemos bandera.

2 comentarios:

  1. Saludos! Excelente el ejemplo. Gracias.
    No soy muy bueno con los bucles, pero quisiera hacer uno que me permitiera hacer una resta sucesiva de los montos de una columna, de manera que al introducir un monto en la columna adyacente se reste automáticamente. Crees que se pueda con un For?

    ResponderEliminar
  2. Hola Dennis.
    Imagino el caso que quieres plantear. Supongamos la columna A con una serie de valores numéricos de importe creciente, podría ser el acumulado de alguna otra columna. Lo que queremos es que en la columna B aparezca la resta de dos valores consecutivos de la columna A. O dicho de otra forma, si en la columna A tenemos acumulados lo que queremos en la columna B es 'desacumular'. Si este es el ejemplo, lo mejor es optar por la solución más sencilla que consiste en operar con fórmulas de Excel sin necesidad de recurrir a macros o código de programación VBA. En este caso se podría simplemente restar dos valores consecutivos de la columna A y ya estarías construyendo la columna B.
    No se si he interpretado bien el caso que planteas, pero lo que si hemos de hacer siempre es optar por el método más sencillo que suele ser usar Excel antes de meternos a programar.
    Espero que esta reflexión pueda ayudarte.
    Un saludo.

    ResponderEliminar