Control de errores

From Apache OpenOffice Wiki
< ES‎ | Manuales‎ | GuiaAOO‎ | TemasAvanzados‎ | Macros‎ | StarBasic‎ | ElLenguajeOOoBasic
Revision as of 16:15, 17 March 2013 by Salva (Talk | contribs)

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


Editing.png Esta página está en estado borrador.

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()


ES StarBasic ControlErrores.01.png


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.


ES StarBasic ControlErrores.02.png


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.


ES StarBasic ControlErrores.03.png


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
Descripció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.



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