![]() |
||||||
|
|
||||||
Fallos en Access
Bucles recursivosLos bucles recursivos, o bucles sin fin, se producen cuando el código que estamos usando, entran en un ciclo que se repite indefinidamente. Si tenemos suerte, al cabo de cierto tiempo se producirá el error 6 (desbordamiento), o el error 28 (no hay suficiente espacio de pila). Pero si el código no hace que se dispare algún error, se seguirá ejecutando indefinidamente. Veamos el siguiente código:
Function UnProcedimiento() As Long
Dim i As Integer Dim l As Long Do While i < 2 l = l + 1 Loop UnProcedimiento = l End Function En esta función, se dimensionan dos variables, y después se usa un bucle del tipo Veamos otro ejemplo, en el que usamos un objeto
Public Sub MalaActualizacion()
Dim rst As DAO.Recordset Dim strSql As String Dim strCampo As String strSql = "SELECT Campo2 FROM Tabla1" Set rst = CurrentDb.OpenRecordset(strSql) Do While Not rst.EOF strCampo = "Modificado" rst.Edit rst("Campo2") = strCampo rst.Update Loop rst.Close Set rst = Nothing End Sub En este código, cargamos un conjunto de registros para modificar uno de sus campos. En un principio, parece que está bien, pero no es así. Si ejecutamos el procedimiento, se ejecutará indefinidamente, y no se parará ni por error, hasta que nos cansemos y decidamos parar la ejecución mediante la combinación de teclas Además de los bucles sin fin, también existen las funciones recursivas, o funciones que se llaman a sí mismas para realizar lo que deseamos. El ejemplo más manido de este tipo de funciones es la función para calcular el factorial de un número. El factorial es el número que se genera al multiplicar un número por los números menores que él, hasta llegar a uno. Es decir, el factorial de 4 es 4 x 3 x 2 x 1 = 24. Así, podemos crear una función que devuelva el resultado de multiplicar el número que reibe por el resultado de sí misma por el número menor:
Public Function Factorial(UnNumero As Long) As Long
If UnNumero > 12 Then Factorial = -1 ElseIf UnNumero < 0 Then Factorial = 0 ElseIf UnNumero <= 1 Then Factorial = 1 Else Factorial = UnNumero * Factorial(UnNumero - 1) End If End Function Si nos fijamos en esta función, lo primero que hacemos es controlar el número que se recibe: si el número es mayor que doce, se devuelve -1 directamente, porque el factorial que se genera es demasiado grande para almacenarlo en un número de tipo entero largo. Si el número es negativo (menor que cero), se devuelve cero directamente, ya que no se pueden calcular los factoriales de números negativos (restando de 1 en 1 a un número negativo, nunca se llega a 1 positivo). Cuando el número que se recibe es uno, se devuelve uno, porque hemos llegado al último número que sirve para generar el factorial. Y, para el resto de números, se multiplica el número recibido por el resultado de la propia función, enviándole el número menos uno. Es decir, cuando creamos una función que se llama a sí misma, al igual que con los bucles, debemos tener en cuenta más datos de los normales, para conseguir que en ninguna circunstancia, se que la función llamándose a sí misma indefinidamente. Si no tenemos en cuenta todos los datos, obtendremos el error 28: espacio de pila insuficiente. Y la pila no es una batería de 12 voltios. Es una zona de la memoria del ordenador, donde se almacenan las funciones que se están ejecutando, y en qué orden se ejecutan. Si nos aparece este error, es porque estamos usando tantas funciones, o una función se ha llamado a sí misma tantas veces, que llega un momento en que la pila no tiene espacio para almacenar todas las funciones que se están ejecutando, y por eso salta este error.
Pero hay que tener en cuenta otra cosa: los bucles sin fin no se producen sólo cuando trabajamos con VBA: también se pueden producir cuando diseñamos una consulta, un formulario o un informe. Supongamos que tenemos un formulario (FormBucle en la base de datos de ejemplo), con 3 cuadros de texto. Y cada cuadro de texto recoge el dato que tiene el cuadro de texto anterior y, tras operar con él, devuelve el resultado. Si no cerramos el bucle (el primer cuadro de texto no toma el dato del último), no ocurrirá nada grave. Pero si el primer cuadro de texto toma el dato del tercero, obtendremos un #Error en todos los cuadros de texto, tal y como se ve en la imagen. Esto es debido a que cada cuadro de texto actualiza su valor dependiendo de otro y, como siempre se actualizan, siempre se generan nuevos valores y vuelven a actualizarse, con lo que Access detecta el error y muestra ese mensaje. Si a cualquiera de los 3 cuadros de texto le quitamos el valor que tiene en su propiedad Origen del registro, dejaremos de tener un bucle sin fin, y aparecerán los valores correctamente. |
||||||
|
2008 Patxi Sanz Libro de visitas |