Bucles

From Apache OpenOffice Wiki
< ES‎ | Manuales‎ | GuiaAOO‎ | TemasAvanzados‎ | Macros‎ | StarBasic‎ | ElLenguajeOOoBasic
Revision as of 12:01, 14 July 2018 by Sancho (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

En ocasiones necesitamos repetir un determinado proceso un determinado número de veces, o hasta que se cumpla una condición, o mientras se cumpla una condición.

OOo Basic incorpora dos estructuras para crear bucles o repeticiones:

  • For...Next
  • Do...Loop

Veamos ejemplos de cada una de ellas:

Estructura For...Next

La sintaxis de esta estructura es:


     For Variable = Inicio To Fin [Step Salto]
         'codigo
         [Exit For]
     Next [Variable]


Lo indicado entre corchetes es opcional.

Empecemos con un ejemplo sencillo:


 Option Explicit
 
 Sub PortarseBien
 Dim Contador As Integer
 
     'Inicia el contador con los limites especificados
     For Contador = 1 To 2
         'Este es el código que se ejecuta el numero de veces
         'especificado con los limites en nuestro caso 2 veces
         MsgBox "Tengo que portarme bien"
     Next
 
 End Sub


Para hacer uso de la estructura For...Next, es necesaria una variable de apoyo; en nuestro caso escogimos la variable Contador; con frecuencia encontraras que algunos programadores usan la letra I, J, K, L, N y siguientes como contadores, pero tu eres libres de elegir y usar la variable que más te plazca.

El código anterior solo mostrará el mensaje dos veces, que son las indicadas por el límite inferior y superior del contador especificadas con 1 To 2.

Veamos otro ejemplo para establecer valores más grandes y de paso, aprovecharemos para ver como “sumar” cadenas de texto. En programación, la “suma” de cadenas de texto se conoce como “concatenar” y no es otra cosa que pegar cadenas de texto una tras la otra:


 Sub TuNombre
 Dim Nombre As String
 Dim Apellido1 As String
 Dim Apellido2 As String
 Dim NombreCompleto As String
 
     Nombre = InputBox( "¿Cual es tu Nombre?")
     Apellido1 = InputBox( "¿Cual es tu primer Apellido?")
     Apellido2 = InputBox( "¿Y el segundo?")
     NombreCompleto = Nombre + Apellido1 + Apellido2
 
     MsgBox "Tu nombre completo es: " + NombreCompleto
 
 End Sub


En el código solicitamos el nombre y apellido, y al final, lo mostramos en sólo una línea de texto. En el ejemplo hemos utilizado el operador +, pero es más común usar el operador ampersan (&) como concatenador de cadenas de texto.


 Sub TuNombre2
 Dim Nombre As String
 Dim Apellido1 As String
 Dim Apellido2 As String
 Dim NombreCompleto As String
 
     Nombre = InputBox( "¿Cual es tu Nombre?")
     Apellido1 = InputBox( "¿Cual es tu primer Apellido?")
     Apellido2 = InputBox( "¿Y el segundo?")
     NombreCompleto = Nombre & Apellido1 & Apellido2
 
     MsgBox "Tu nombre completo es: " & NombreCompleto
 
 End Sub


En el anterior ejemplo el nombre completo se muestra sin espacios. Puedes modificar el código para que muestre espacios entre el nombre y los apellidos.

Hagamos nuestro bucle más grande; probaremos primero con 10.


 Sub PortarseBien2
 Dim Contador As Integer
 Dim Texto As String
 
     For Contador = 1 To 10
         Texto = Texto & "Tengo que portarme bien"
     Next
     MsgBox Texto
 
 End Sub


Para mejorarlo un poco le agregaremos un saldo de línea al final de cada frase:


 Sub PortarseBien3
 Dim Contador As Integer
 Dim Texto As String
 
     For Contador = 1 To 10
         Texto = Texto & "Tengo que portarme bien" & Chr(13)
     Next
     MsgBox Texto
 
 End Sub


Mejoramos agregándole el número a cada línea:


 Sub PortarseBien4
 Dim Contador As Integer
 Dim Texto As String
 
     For Contador = 1 To 10
         Texto = Texto & Contador & ".- Tengo que portarme bien" & Chr(13)
     Next
     MsgBox Texto
 
 End Sub


ES.StarBasic.ElLenguajeOOoBasic.Bucles.001.png


Límites inferior y superior

Los límites inferior y superior no necesariamente tienen que ser positivos:


     For Contador = -5 To 5


La instrucción Step

Tampoco tienen por que ir de uno en uno, cuando podemos ir de dos en dos, de tres en tres o en el intervalo que necesitemos, utilizando la palabra Step.


 Sub PortarseBien5
 Dim Contador As Integer
 Dim Texto As String
 
     For Contador = 1 To 20 Step 2
         Texto = Texto & Contador & ".- Tengo que portarme bien" & Chr(13)
     Next
     MsgBox Texto
 
 End Sub


ES.StarBasic.ElLenguajeOOoBasic.Bucles.002.png


Step no necesariamente tiene que ser entero, ni positivo:


     For Contador = 100 To 10 Step -10


Una práctica habitual es escribir después de la palabra clave Next el mismo nombre de la variable que se ha usado como contador, por ejemplo.


     For Contador = 10 To 100 Step 5
         ' Aquí iría el código
     Next Contador


Es muy útil cuando existen varios bucles de repetición anidados.


 Sub BuclesAnidados
 Dim co1 As Integer, co2 As Integer
 
     For co1 = 1 To 5
         For co2 = 1 To 10
 
         Next co2
     Next co1
 
 End Sub


La instrucción Exit For

La instrucción Exit For nos sirve para salir anticipadamente de un ciclo For...Next.


 Option Explicit
 
 Sub Usando_Exit_For()
 Dim co1 As Integer
 Dim sLetra As String
 Dim sVocales As String
 Dim sConsonantes As String
 
     For co1 = 1 To 100
         sLetra = Chr( Rnd() * 25 + 65 )
         Select Case sLetra
             Case "A", "E", "I", "O", "U"
                 sVocales = sVocales & " " & sLetra
             Case "S"
                 Exit For
             Case Else
                 sConsonantes = sConsonantes & " " & sLetra
         End Select
     Next
     MsgBox "El ciclo termino en: " & co1 & Chr(13) & Chr(13) & _
             "Vocales: " & sVocales & Chr(13) & _
             "Consonantes: " & sConsonantes, 0, "Ejemplo Exit For"
 
 End Sub


La función Chr(valor) nos devuelve el carácter ASCII correspondiente ha dicho valor. Por ejemplo, la letra A tiene un valor de 65 y la letra Z tiene un valor de 90. Por ello en la línea:


 sLetra = Chr( Rnd() * 25 + 65 )


Obtenemos un valor aleatorio entre 65 y 90 y Chr nos devuelve el carácter correspondiente al valor aleatorio obtenido. Después evaluamos si es una vocal, si es la letra S o si es una consonante. Sólo en el caso de que el carácter devuelto sea una S, interrumpimos el ciclo For...Next y salimos utilizando el Exit For.

Al final mostramos el valor del contador para saber si terminó el ciclo o salió antes.


Estructura Do...Loop

Al tipo de ciclo usado en For..Next, algunos autores le llaman determinado pues sabemos donde empieza y donde termina, hay otro tipo de ciclos llamados indeterminados, pues dependen de otras condiciones para empezar o terminar el ciclo; veamos cuales son:

La instrucción Do...Loop, también nos sirve para crear repeticiones, pero en lugar de usar un contador, se evalúa una condición para decidir cuando terminar un bucle e incluso cuando empieza o si empieza.

Veamos ejemplos:


 Sub DameTuNombre
 Dim Nombre As String
 
     Do
         Nombre = InputBox( "¿Cual es tu Nombre?")
     Loop While Nombre = "”
 
 End Sub


Analicemos línea por línea el código anterior.


 Sub DameTuNombre            'Iniciamos la macro
 
 Dim Nombre As String        'Declaramos una variable de texto
 
 Do                        'Iniciamos el bucle
 
 Nombre = InputBox( "¿Cual es tu Nombre?")    'Solicitamos un valor, en este caso un nombre
 
 Loop While Nombre = ""    'Continuamos el bucle “'''mientras'''” la condición sea VERDADERA
 
 End Sub                    'Finalizamos la macro


Mediante el código forzamos al usuario a escribir un valor en el cuadro de dialogo, si bien suele ser deseable proporcionar al usuario una forma de cancelar o interrumpir el bucle. Veamos una primera alternativa:


 Sub DameTuNombre2
 Dim Nombre As String
 Dim Respuesta As Integer
 
     Do
         Nombre = InputBox( "¿Cual es tu Nombre?" )
         If Nombre = "" Then
             Respuesta = MsgBox( "Al parecer no escribiste nada, ¿realmente quieres salir?", 32 + 4, "Salir" )
             'Recuerda que un 6 significa que el usuario presiono el botón SI
             If Respuesta = 6 Then
                 'Establecemos la variable con cualquier cosa para que termine el bucle
                 Nombre = "cualquier cosa"
             End If
         End If
     Loop While Nombre = ""
 
 End Sub


El código anterior parece que funciona bien, pero hay una simple forma de “engañarla”. Prueba a introducir varios espacios y verás que sale inmediatamente. Para subsanar este inconveniente haremos uso de una función integrada en OOo Basic que sirve para eliminar los espacios vacíos al inicio y al final de una cadena: la instrucción Trim, que se utiliza de la siguiente forma.


 Sub DameTuNombre3
 Dim Nombre As String
 Dim Respuesta As Integer
 
     Do
         Nombre = InputBox( "¿Cual es tu Nombre?" )
         '''Nombre = Trim( Nombre )'''
         If Nombre = "" Then
             Respuesta = MsgBox( "Al parecer no escribiste nada, ¿realmente quieres salir?", 32 + 4, "Salir" )
             'Recuerda que un 6 significa que el usuario presiono el botón SI
             If Respuesta = 6 Then
                 'Establecemos la variable con cualquier cosa para que termine el bucle
                 Nombre = "cualquier cosa"
             End If
         End If
     Loop While Nombre = ""
 
 End Sub


Hemos mejorado su comportamiento, si bien siempre se nos puedes ocurrir más alternativas por prever o mejorar el código.


La instrucción Until

Veamos otra variante de esta estructura que nos permite invertir la lógica de la condición:


 Sub DameTuNombre4
 Dim Nombre As String
 
     Do
         Nombre = InputBox( "¿Cual es tu Nombre?")
     Loop '''Until''' Nombre <> "" 
 
 End Sub


Ahora con la instrucción Until evaluamos la variable Nombre. Mientras sea diferente de vacía, es decir, contenga algo, el bucle se repetirá, con lo que estamos definiendo hasta cuando se repite. La condición tiene que seguir siendo verdadera para que el bucle termine.

Veamos ahora la macro completa, con validación incluída.


 Sub DameTuNombre5
 Dim Nombre As String
 Dim Respuesta As Integer
 
     Do
         Nombre = InputBox( "¿Cual es tu Nombre?")
         Nombre = Trim( Nombre )
         If Nombre = "" Then
             Respuesta = MsgBox( "Al parecer no escribiste nada, ¿realmente quieres salir?", 32 + 4, "Salir" )
             'Recuerda que un 6 significa que el usuario presiono el botón SI
             If Respuesta = 6 Then
                 'Establecemos la variable con cualquier cosa para que termine el bucle
                 Nombre = "cualquier cosa"
             End If
         End If
     Loop Until Nombre <> "" 
 
 End Sub


Tal vez te preguntaras ¿porque dos formas de hacer lo mismo? No todos tenemos el mismo modo de razonar. En casi todo y más en programación, hay más de una forma de hacer las mismas cosas, lo cual enriquece y es bueno para ampliar horizontes.


La instrucción Do While

Las dos variantes de la estructura que hemos visto ejecutan el código escrito entre Do..Loop al menos una vez. Si necesitamos o queremos controlar que en caso de cumplirse una condición no se ejecute ni una sola vez, pasaremos la instrucción al inicio de la estructura de la siguiente forma:


 Sub DameTuNombre6
 Dim Nombre As String
 Dim Lista As String
 
     'Solicitamos un dato
     Nombre = InputBox( "¿Dame un Nombre?")
     'Le quitamos los espacios sobrantes al inicio y al final
     Nombre = Trim( Nombre )
     'Iniciamos el bucle, si la variable es diferente de vacía
     Do While Nombre <> ""
         'Formamos una lista de los nombres introducidos
         Lista = Lista & " - " & Nombre
         'Solicitamos otro nombre
         Nombre = Trim( InputBox( "¿Dame otro Nombre?") )
     Loop
     'Si la lista contiene algo lo mostramos
     If Lista <> "" Then
         MsgBox Lista
     End If
 
 End Sub


Destacamos las dos formas en que hacemos uso de la instrucción InputBox: la primera de forma directa y la segunda, de forma anidada.

Anidar funciones resulta muy familiar si eres un usuario medio/avanzado de cualquier hoja de calculo. La anidación de funciones resulta muy útil en programación.

Existe otra variante para lograr el mismo propósito, utilizando la palabra clave Until, en lugar de While.


La instrucción Exit Do

Si deseamos finalizar anticipadamente un bucle Do...Loop, podemos utilizar la palabra clave Exit Do de la siguiente forma:


 Option Explicit
 
 Sub Usando_Exit_Do()
 Dim sClave As String
 Dim sTmp As String
 
     sClave = "mellon"
     Do
         sTmp = Trim(InputBox("Habla amigo y entra"))
         If sTmp = "mellon" Then
             MsgBox "Y se abren las puertas de Moria"
             Exit Do
         End If
     Loop Until sTmp = "salir"
 
 End Sub


Por lo tanto, disponemos de dos formas de terminar el bucle: la condición final, y utilizando Exit Do.

Documentation caution.png Ten cuidado con los ciclos indeterminados, una condición mal planteada te puede dejar dentro de un ciclo infinito

Con los elementos vistos hasta ahora ya se pueden hacer muchas cosas. Podemos empezar a a pensar en como automatizar esos pasos tan repetitivos y tediosos que a veces se nos presentan; para ello, tendremos presente siempre en mente el diagrama que vimos en el apartado Declarar Variables.


ES.Plantillas.Logo foro es.png
Si tienes dudas acerca de lo aquí explicado, tienes algún problema con AOO,
o quieres ampliar la información, no dudes en dirigirte al

Foro Oficial en español de Apache OpenOffice para Macros y API UNO

Personal tools