Control de errores
En teoría, un programa no debería tener errores o no necesitaría de un control de errores, en la practica, sabemos que esto no es así. En general podríamos hablar de tres tipos de errores dependiendo de cuando se producen o en que contexto.
- Errores en tiempo de diseño: son aquellos que se cometen cuando se esta codificando, programando, escribiendo nuestro código, generalmente son detectados por el IDE en cuanto tratamos de ejecutar el código y normalmente nos muestra un mensaje indicándonos el tipo de error cometido, muy comúnmente son errores de sintaxis, recordando que sintaxis es: -Conjunto de reglas que definen las secuencias correctas de los elementos de un lenguaje de programación- por ejemplo, el siguiente código, te deberá mostrar el siguiente mensaje de error que es muy claro:
Option Explicit Sub Errores1()
En el apéndice Errores más comunes en tiempo de diseño, te muestro una lista de los errores en tiempo de diseño más frecuentes.
- Errores lógicos: estos errores, son los más difíciles de detectar y corregir pues frecuentemente no te dan un mensaje o no se detiene el código, sino simplemente el código “no hace” las tareas para las que se supone esta desarrollado o “no devuelve” los valores esperados, entre más grande y complejo sea tu código, la probabilidad de que tenga errores lógicos aumenta considerablemente. Hay una frase que se le atribuye (no he podido comprobarlo) a Linus Torvalds que dice -ante los ojos de muchos, los errores son evidentes-, por supuesto, esto solo puede suceder con el software libre, como el que tu y yo usamos y desarrollamos, ¿verdad?, pues solo en el tenemos a nuestra disposición el código fuente que es la única forma de verificar que un software haga lo que dice que hace. Únicamente la experiencia y la practica te ayudaran a minimizar este tipo de errores.
- Errores en tiempo de ejecución: estos errores se producen durante el tiempo que se esta ejecutando tu programa o código. OOo Basic cuenta con instrucciones y palabras claves para controlar este tipo de errores y son los que aprenderemos en este capitulo.
Copia y ejecuta la siguiente macro:
Option Explicit Sub Manejo_Errores1() Dim sRutaArchivo As String sRutaArchivo = Trim(InputBox("Escribe la ruta del archivo a borrar")) Kill sRutaArchivo MsgBox "El archivo " & sRutaArchivo & " se borro correctamente" End Sub
Si escribes la ruta de un archivo que no existe, te “debe” dar el mensaje de error y nota que el ultimo mensaje con MsgBox ya “no” se muestra.
Claro, estarás pensando que es más fácil y más eficiente el validar antes que exista el archivo y estarás en lo correcto.
Sub Manejo_Errores2() Dim sRutaArchivo As String sRutaArchivo = Trim(InputBox("Escribe la ruta del archivo a borrar")) If sRutaArchivo<>"" And Dir(sRutaArchivo)<>"" Then Kill sRutaArchivo MsgBox "El archivo " & sRutaArchivo & " se borro correctamente" Else MsgBox "Ruta invalida o archivo no existe", 0, "Borrar archivo" End If End Sub
En la validación anterior estamos usando una función de OOo Basic que tal vez no conozcas, me refiero a la función Dir(valor), donde valor puede ser una ruta de archivo, si “no” encuentra el archivo, devuelve una cadena vacía.
Considera que cuando accedes a recursos externos, no tienes la seguridad que esos recursos estarán “siempre” disponibles, en el caso de los archivos, otros procesos pueden acceder y manipularlos, por ello, en este y otros casos, considera la utilización de un controlar de errores como en el ejemplo siguiente.
Option Explicit Sub Manejo_Errores3() Dim sRutaArchivo As String On Error Goto CONTROLAERRORES sRutaArchivo = Trim(InputBox("Escribe la ruta del archivo a borrar")) Kill sRutaArchivo MsgBox "El archivo " & sRutaArchivo & " se borro correctamente" Exit Sub CONTROLAERRORES: Select Case Err Case 0 Case 53 MsgBox "No se encontró la ruta especificada" & Chr(13) & Chr(13) & sRutaArchivo, 48 Case Else MsgBox "Ocurrió el error numero: " & Err & Chr(13) & Error & _ Chr(13) & "En la linea " & Erl End Select On Error Goto 0 End Sub
Veamos todas las partes del código anterior. Después de declarar la macro y las variables a usar, tenemos una nueva instrucción.
On Error Goto CONTROLAERRORES
La sintaxis general de esta instrucción es:
On Error Goto ''NombreEtiqueta''
En donde NombreEtiqueta es cualquier palabra que cumpla las características vistas para nombrar a las variables y literalmente significa -En caso de error salta (o va) a NombreEtiqueta. Después de iniciar el controlador de errores, tenemos propiamente el código de nuestra macro. Enseguida, observa que usamos la instrucción Exit Sub, esto es para que si, nuestro código se ejecuta sin problemas, salga de la macro “sin” ejecutar el controlador de errores. Ahora si, observa como declaramos la etiqueta usada en la declaración del controlador de errores, nota que esta etiqueta, excepto por que es indistinto las mayúsculas y minúsculas, es exactamente igual a la usada en la declaración del controlador de errores, también nota, muy importante, que esta termina en dos puntos (:) , estos, son indispensables para que no te muestre el siguiente mensaje de error en tiempo de diseño.
Inmediatamente después de la declaración de la etiqueta, observa que iniciamos un Select Case con la variable Err, esta, es una variable tipo Long de OOo Basic que contiene el número de error que se haya provocado, esta variable tendrá valor 0 si no ocurrió ningún error.
En nuestro ejemplo, sabemos que si no se encuentra un archivo, ocurre el error 53, el cual manipulamos con la linea:
Case 53 MsgBox "No se encontró la ruta especificada" & Chr(13) & Chr(13) & sRutaArchivo, 48
En caso de que ocurra un error no especificado o desconocido, mostramos el número de error (variable Err), la descripción del error (variable Error) y la línea donde este ocurrió (variable Erl), cuya valiosa información nos ayudara a corregirlo.
Case Else MsgBox "Ocurrió el error numero: " & '''Err''' & Chr(13) & '''Error''' & _ Chr(13) & "En la linea " & '''Erl'''
Después de cerrar la estructura Select Case con End Select, tenemos la linea:
On Error Goto 0
Que no hace otra cosa que reinicializar las variables de error, es decir Err, Error y Erl. La estructura de control o administración de errores que acabamos de ver, afortunadamente, no es la única pero es la que generalmente se usa, hay algunas variantes que a criterio puedes usar, veamos algunas. En caso de que quieras establecer un control de errores genérico, podrías usar el siguiente.
Sub Manejo_Errores4() On Error Goto CONTROLAERRORES 'Aquí va todo tú código Exit Sub CONTROLAERRORES: If Err <> 0 Then MsgBox "Ocurrió el error numero: " & Err & Chr(13) & Error & Chr(13) & "En la linea " & Erl End If On Error Goto 0 End Sub
En vez de mostrar el error con MsgBox, puedes optar por guardar en un archivo de registro estos errores, aunque siempre es bueno mostrarle al usuario que algo salio mal para poder corregirlo.
Puedes simular el error que quieras simplemente asignando el número de error a la variable Error de la siguiente manera.
'Aqui va todo tú código Error(12)
Esta es la lista de valores de errores que puedes usar en la variable Error o que en algún momento te pueden aparecer, toma en cuenta que algunos de estos errores “solo” ocurren en tiempo de diseño y varios de ellos “no” puedes interceptarlos, tan solo corregirlos en tu código.
Códigos de error | |||
---|---|---|---|
Nº | Descripción | Nº | Descripción |
2 | Error de sintaxis no especificado | 70 | Permiso denegado |
3 | Return sin Gosub | 71 | Disco no preparado |
4 | Restaurar desde el principio | 73 | Prestación no implementada |
5 | Llamada a procedimiento no válida | 74 | Imposible cambiar nombre con unidad distinta |
6 | Desbordamiento | 75 | Error de acceso a ruta/archivo |
7 | Memoria agotada | 76 | Ruta no encontrada |
8 | Matriz ya dimensionada | 91 | Variable de objeto no definida |
9 | Sunbíndice fuera de rango | 93 | Cadena de secuencia no válida |
10 | Definición duplicada | 94 | Uso de Null no válido |
11 | División por cero | 323 | Imposible cargar módulo |
12 | Variable no definida | 341 | Índice de objeto no válido |
13 | Discordancia de tipo | 366 | No hay documento o vista activos |
14 | Parámetro no válido | 380 | Valor de propiedad incorrecto |
18 | Interrupción de usuario | 382 | Propiedad de sólo lectura |
20 | Continuar sin error | 394 | Propiedad de sólo escritura |
28 | Espacio de pila agotado | 420 | Referencia de objeto no válida |
35 | Sub o Function no definidos | 423 | Propiedad o método no encontrados |
48 | Error al cargar DLL | 424 | Objeto necesario |
49 | Convención de llamada a DLL incorrecta | 425 | Uso de objeto no válido |
51 | Error interno | 430 | La clase no admite OLE |
52 | Nombre de archivo o número incorrectos | 438 | El objeto no admite este método |
53 | Archivo no encontrado | 440 | Error de automatización OLE |
54 | Modo de archivo incorrecto | 445 | El objeto no admite esta acción |
55 | Archivo ya abierto | 446 | El objeto no admite argumentos con nombre |
57 | Error de E/S de dispositivo | 447 | El objeto no admite la configuración de entorno local actual |
58 | Archivo ya existente | 448 | Argumento mencionado no encontrado |
59 | Longitud de registro incorrecta | 449 | Argumento no opcional |
61 | Disco lleno | 450 | Número de argumentos incorrecto |
62 | Entrada más allá del final del archivo | 451 | Objeto no es una colección |
63 | Número de registro incorrecto | 452 | Ordinal no válido |
67 | Demasiados archivos | 453 | Función DLL especificada no encontrada |
68 | Dispositivo no disponible | 460 | Formato de portapapeles no válido |
OOo Basic cuenta con una instrucción que complementa el uso de un controlador de errores, esta instrucción es Resume, básicamente tiene tres posibles usos, de la primer forma, nos permite regresar, es decir, volver a intentar ejecutar la línea que provoco el error, por supuesto, esto es recomendable ya que se hayan corregido o atendido las causas del error, por ejemplo.
Option Explicit Sub Manejo_Errores5() Dim sRutaArchivo As String Dim iRes As Integer On Error Goto CONTROLAERRORES sRutaArchivo = Trim(InputBox("Escribe la ruta del archivo a borrar")) Kill sRutaArchivo MsgBox "El archivo " & sRutaArchivo & " se borro correctamente" Exit Sub CONTROLAERRORES: Select Case Err Case 0 Case 53 iRes = MsgBox ("No se encontró la ruta especificada" & Chr(13) & Chr(13) & sRutaArchivo & Chr(13) & Chr(13) & "¿Deseas intentarlo de nuevo?", 32 + 4 ) If iRes = 6 Then '''Resume''' End If Case Else MsgBox "Ocurrió el error numero: " & Err & Chr(13) & Error & _ Chr(13) & "En la linea " & Erl End Select On Error Goto 0 End Sub Observa como dentro del bloque donde controlamos el error, preguntamos al usuario si desea volver a intentarlo. Case 53 iRes = MsgBox ("No se encontró la ruta especificada" & Chr(13) & Chr(13) & sRutaArchivo & Chr(13) & Chr(13) & "¿Deseas intentarlo de nuevo?", 32 + 4 ) If iRes = 6 Then '''Resume''' End If
Si no haces lo anterior, puedes quedar en un bucle infinito entre la linea que provoco el error y el controlador de errores.
La segunda forma, usando Resume Next, te permite continuar la ejecución de tu código en la línea siguiente a la que provoco el error, por ejemplo.
Sub Manejo_Errores6() Dim sRutaArchivo As String Dim iRes As Integer On Error Goto CONTROLAERRORES sRutaArchivo = Trim(InputBox("Escribe la ruta del archivo a borrar")) Kill sRutaArchivo MsgBox "El archivo " & sRutaArchivo & " se borro correctamente" Exit Sub CONTROLAERRORES: Select Case Err Case 0 Case 53 iRes = MsgBox ("No se encontró la ruta especificada" & Chr(13) & Chr(13) & sRutaArchivo & Chr(13) & Chr(13) & "¿Deseas continuar?", 32 + 4 ) If iRes = 6 Then '''Resume Next''' End If Case Else MsgBox "Ocurrió el error numero: " & Err & Chr(13) & Error & _ Chr(13) & "En la linea " & Erl End Select On Error Goto 0 End Sub
Aquí lo importante es que notes como nos muestra el mensaje de confirmación de borrado, aun y cuando este no se hizo efectivamente, tu tarea es corregir eso.
La ultima forma es usar la instrucción Resumen NombreEtiqueta, en donde NombreEtiqueta tiene las mismas consideraciones vistas al inicio de este tema, ejemplo.
Sub Manejo_Errores7() Dim sRutaArchivo As String Dim iRes As Integer On Error Goto CONTROLAERRORES REINTENTARLO: sRutaArchivo = Trim(InputBox("Escribe la ruta del archivo a borrar")) Kill sRutaArchivo MsgBox "El archivo " & sRutaArchivo & " se borro correctamente" Exit Sub CONTROLAERRORES: Select Case Err Case 0 Case 53 iRes = MsgBox ("No se encontró la ruta especificada" & Chr(13) & Chr(13) & sRutaArchivo & Chr(13) & Chr(13) & "¿Deseas intentarlo de nuevo?", 32 + 4 ) If iRes = 6 Then '''Resume REINTENTARLO''' End If Case Else MsgBox "Ocurrió el error numero: " & Err & Chr(13) & Error & _ Chr(13) & "En la linea " & Erl End Select On Error Goto 0 End Sub
No dejes de observar la declaración de la etiqueta correspondiente a donde va a saltar la instrucción Resume, aunque el uso más común es redirigir a un segundo bloque donde se sale de la macro de forma controlada, por ejemplo.
Sub Manejo_Errores8() Dim sRutaArchivo As String On Error Goto CONTROLAERRORES sRutaArchivo = Trim(InputBox("Escribe la ruta del archivo a borrar")) Kill sRutaArchivo MsgBox "El archivo " & sRutaArchivo & " se borro correctamente" Goto SALIDACONTROLADA CONTROLAERRORES: Select Case Err Case 0 Case 53 MsgBox "No se encontró la ruta especificada" & Chr(13) & Chr(13) & sRutaArchivo & Chr(13) & Chr(13) & "El programa terminara", 48 Resume SALIDACONTROLADA Case Else MsgBox "Ocurrió el error numero: " & Err & Chr(13) & Error & _ Chr(13) & "En la linea " & Erl End Select On Error Goto 0 SALIDACONTROLADA: 'Aquí va todo el código que quieras, por ejemplo 'cierre de archivos y bases de datos, la idea 'es salir de forma controlada de tu macro MsgBox "Se saldrá correctamente" End Sub
Nota también que en vez de usar Exit Sub, “antes” de la etiqueta y código de controlador de errores, usamos la instrucción Goto NombreEtiqueta, para saltar directamente a la etiqueta de salida. Estas opciones son solo variantes, una vez más tú decidirás que es lo que mejor se acomoda a tu forma de trabajar y de razonar, la recomendación es que no abuses de los saltos con Resume o Goto, por claridad, limita su uso lo más posible.
Para terminar este tema, te muestro otra instrucción para “omitir” errores, me refiero a la instrucción On Error Resume Next, que significa -En caso de error, continua el la siguiente línea-, y se usa de la siguiente manera:
Sub Manejo_Errores9() Dim sRutaArchivo As String On Error Resume Next sRutaArchivo = Trim(InputBox("Escribe la ruta del archivo a borrar")) Kill sRutaArchivo MsgBox "El archivo " & sRutaArchivo & " se borro correctamente" End Sub
Intentemos controlar el error.
Sub Manejo_Errores10() Dim sRutaArchivo As String On Error Resume Next sRutaArchivo = Trim(InputBox("Escribe la ruta del archivo a borrar")) Kill sRutaArchivo If Err = 0 Then MsgBox "El archivo " & sRutaArchivo & " se borro correctamente" End If End Sub
Notaras que no es posible, no importa el número de errores que sucedan.
Sub Manejo_Errores11() Dim sRutaArchivo As String On Error Resume Next Error(2) Error(3) Error(4) Error(5) Error(6) If Err = 0 Then MsgBox "No ocurrió ningún error" End If End Sub
Puedes tener juntas una después de otra las dos instrucciones para controlar errores.
On Error Resume Next On Error Goto CONTROLAERRORES
Pero tendrá prioridad On Error Resume Next, por lo que no es aconsejable, de hecho, no te recomiendo el uso de On Error Resume Next a menos que estés seguro de lo que haces.
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 |