I N D I C E D E C O N T E N I D O S CAPI TULO VII VII. MANEJO DE ERRORES .................................................................225 VII.1. LA COMPILACIÓN...............................................................225 VII.1.i. Errores de compilación ......................................................226 VII.2. ERRORES EN TIEMPO DE EJECUCIÓN .............................226 VII.2.i. Capturando errores: On Error...........................................228 VII.2.i.1. La rutina de error ...............................................................229 VII.2.ii. Obteniendo información del error: objeto Err ................230 VII.2.iii. Disimular los posibles errores de un programa ..............233 VII.3. DEPURACIÓN ......................................................................234 VII.3.i. Técnicas de depuración .....................................................234 VII.3.i.1. Los puntos de interrupción ...............................................235 VII.3.i.2. Conocer el valor de las variables ......................................235 VII.4. Creación de un ejecutable .................................................237 VII.4.i. Asistente de instalación.....................................................238 LABORATORIO II - AÑO 2008 CAPITULO VII: MANEJO DE ERRORES Página 224 Mg. Ing. Fátima Martínez PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008 CAPITULO VII Página 225 VII. MANEJO DE ERRORES Existen tres tipos de errores: errores de sintaxis o de compilación, errores de ejecución y errores lógicos. Cualquier programador con un mínimo de experiencia sabe que una parte muy importante del tiempo destinado a la elaboración de un programa se destina a la detección y corrección de errores. Por lo tanto éstos son un aspecto importante a tener en cuenta para poder minimizarlos y dominarlos (Birnios, B. y Birnios, M.; 2003: 443). Casi todos los entornos de desarrollo disponen hoy en día de potentes herramientas que facilitan enormemente el descubrimiento de las fuentes de errores y la depuración de los programas. VII.1. LA COMPILACIÓN Para darle instrucciones a una computadora en algún lenguaje de alto nivel, es necesario disponer de un editor que permita ingresar el código original del programa llamado código fuente el cual puede almacenarse en memoria y en disco. Un programa así escrito debe traducirse a un código que pueda “entender” la máquina. Los programas traductores que realizan esta operación se llaman compiladores. Compilación es el proceso por el cual se traducen programas en código fuente a programas en código objeto. El programa que realiza esta traducción se llama compilador. El archivo de código objeto que se obtiene con la compilación está representado normalmente en código de máquina. Los dos elementos: editor y compilador están presentes en todos los Entornos Integrados de Desarrollo (IDE). El programador debe conocer previamente como compilar sus programas en ese entorno. En el IDE de un lenguaje compilado como el Visual Basic, el programa desarrollado nunca se ejecuta mientras haya errores, sino hasta que luego de haber compilado el programa, ya no aparecen errores en el código. Visual Basic compila en dos ocasiones: cuando se va a crear el archivo ejecutable (EXE ) y cuando se ejecuta el proyecto utilizando la opción “Iniciar con compilación completa”. Mg. Ing. Fátima Martínez CAPITULO VII: MANEJO DE ERRORES Mg. Ing. Fátima Martínez Básicamente hay dos formas de ejecutar un programa desde el entorno Visual Basic: 1. Pulsando [F 5 ], Inicio: compila sólo la parte del código necesario para arrancar. Luego a medida que sea necesario, va compilando el resto del programa. Esto se llama Compilación por petición. Se activa sólo si se habilita la opción de la solapa G e n e r a l en el menú H e r r a m i e n t a s – Opciones . 2. Pulsando [ C T R L ] + [F 5] , Iniciar con compilación completa: compila absolutamente todo el proyecto antes de la ejecución y por lo tanto, se detiene si encuentra algún error de este tipo. VII.1.i. Errores de compilación Por ejemplo si en el programa se escribió: Private Sub Command1_Click() Dim a As Integer, b As Integer Ejemplo de A + = b ‘esta línea produce error de compilación Error de Compilación End Sub Si se pulsa [ F 5 ] no aparece el error de primera instancia hasta que se haga clic en el botón. En cambio si se ejecuta con [ C T R L ]+[ F5 ], Visual Basic informa del error y la compilación se detiene allí. Los errores de compilación no suelen ser complicados y se pueden resolver leyendo bien el código y prestando atención a los mensajes de Visual Basic. VII.2. ERRORES EN TIEMPO DE EJECUCIÓN Estos errores se producen durante la ejecución de un programa y no pueden ser advertidos en el proceso de compilación. Generalmente se deben a situaciones particulares que pueden darse o no. Algunos de ellos pueden ser: 1. Se intentó acceder a un subíndice de un vector, pero se sobrepasa el límite. 2. Se intentó abrir un archivo que no existe. 3. En una variable se cargó un valor numérico superior al que dicha variable puede soportar. Es conocido como Overflow. Cuando un error se produce siempre, es muy fácil solucionar el problema. Cuando es inesperado y se produce de forma aislada, seguramente la causa es una falla en la lógica del programa, que debe ser solucionada con un poco más de investigación y trabajo utilizando técnicas de depuración. Cuando se produce un error en tiempo de ejecución y no hay ninguna rutina de manejo de errores activada, el programa muestra un mensaje informativo bastante chocante. Página 226 PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008 • Si el programa se ejecutaba desde el entorno de desarrollo de VB aparece por ejemplo un mensaje como el siguiente: • Si el programa se ejecutaba desde un ejecutable compilado (EXE) el mensaje se ve como la siguiente figura: CAPITULO VII Página 227 Debido a que los errores de compilación ocurren de forma inesperada es necesario poder obtener toda la información posible para corregirlos. Lo más importante es saber cuál fue la acción que lo produjo y bajo qué circunstancias. Cada error tiene su propio código numérico que informa en los mensajes. Para obtener una lista de los errores en tiempo de ejecución se puede buscar en la Ayuda el tema Errores Interceptables. Algunos de los más importantes: Nº Descripción 5 El argumento o la llamada al procedimiento no son válidos 6 Desbordamiento 7 Sin memoria 9 El subíndice está fuera del intervalo 11 División por cero 13 No coinciden los tipos 53 No se pudo encontrar el archivo especificado 58 El archivo ya existe 61 Disco lleno 70 Se ha denegado el permiso 71 El disco no está listo 75 Error de acceso a la ruta o acceso 76 No se ha encontrado la ruta de acceso Mg. Ing. Fátima Martínez CAPITULO VII: MANEJO DE ERRORES Nº Mg. Ing. Fátima Martínez Descripción 380 Valor o propiedad no válido 424 Se requiere un objeto 449 El objeto no es opcional VII.2.i. Capturando errores: On Error Capturar un error significa evitar que aparezca el mensaje informativo y tener la posibilidad de hacer que la aplicación siga funcionando correctamente. La instrucción que permite capturar un error es On Error. Para capturar un error es necesario programar una rutina de manejo de errores, que entre en acción al producirse una falla. Por ejemplo en el caso de Overflow, Visual Basic no mostraría el mensaje sino que devolvería el control al programa y éste se encargaría de tomar una decisión al respecto. On Error activa una rutina de control de errores y especifica la ubicación de la misma en un procedimiento; también puede utilizarse para desactivar una rutina de control de errores. Se puede utilizar de tres maneras diferentes: On Error Goto Etiqueta Al encontrar un error, Visual Basic salta a la línea de código indicada por la Etiqueta. La línea especificada en Etiqueta debe encontrarse en el mismo procedimiento que la instrucción On Error de lo contrario, se producirá un error en tiempo de compilación. Para que el Visual Basic "ignore" los errores que se produzcan en una aplicación o en parte de ella, se usa: On Error Resume Next Ignora por completo el error y sigue con la próxima instrucción. La siguiente desactiva cualquier controlador de errores del procedimiento actual: On Error Goto 0 Las rutinas de manejo de errores son locales a un procedimiento o función. Es decir, el uso de On Error tiene validez sólo en el procedimiento en donde es usada. Un ejemplo: Private Sub MiProcedimiento() Ejemplo de una Página 228 PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008 rutina para manejo de error CAPITULO VII Página 229 Dim A As Byte On Error Goto ManejoError: A = 15000 Exit Sub ManejoError: ‘Rutina manejo de error End Sub Al producirse un error en MiProcedimiento, el control salta automáticamente al la etiqueta ManejoError. De esta manera no aparecerá ningún mensaje de error, solamente el programa sabrá que hubo una falla y tiene la posibilidad de solucionarla. Se utiliza Exit Sub para salir del procedimiento sin pasar por la rutina de error. VII.2.i.1. La rutina de error Se pueden tomar varias decisiones: • Mostrar un mensaje informativo, pero más amable tratando de minimizar el problema, y luego retomar la ejecución del programa. • Controlar que no sea un error demasiado grave, en este caso no informar nada y seguir adelante. • Guardar un archivo log con el error y la situación que lo provocó. Luego de la rutina de error se debe volver a la línea de código que provocó el error. Para esto se puede utilizar la sentencia Resume que acepta tres usos diferentes: 1. Resumen Vuelve a la línea que produjo el error y continúa la ejecución desde allí. 2. Resume Next Vuelve a la línea siguiente a la que produjo el error y continúa la ejecución desde allí. 3. Resume Etiqueta Continúa la ejecución desde la Etiqueta indicada. En el ejemplo anterior para continuar con la línea siguiente a la que provocó el error: Un ejemplo: Ejemplo de rutina para manejo de error Mg. Ing. Fátima Martínez Private Sub MiProcedimiento() Dim A As Byte On Error Goto ManejoError: CAPITULO VII: MANEJO DE ERRORES Mg. Ing. Fátima Martínez A = 15000 Exit Sub ManejoError: Resume Next ‘Continúa con la línea siguiente End Sub Es decir seguiría con la instrucción Exit Sub (sale del procedimiento). Nota: El manejo de errores es local al procedimiento, no tiene vigencia fuera de ella. Se debe programar una rutina para cada procedimiento. VII.2.ii. Obteniendo información del error: objeto Err Capturar errores suele ser bueno pero solamente en la máquina del usuario. Mientras se programa lo mejor e s q u e “salten” los errores para poderlos corregir. Es decir, la recomendación es que se compruebe si se ha producido un error, ya que no es bueno dejar que los errores ocurran sin más. Se deberá averiguar qué tipo de error se produjo y partir de allí tomar una decisión. Para ello se suele chequear el valor de la propiedad Number del objeto Err, (que al ser la propiedad por defecto no es necesario especificarla), si ese valor es cero quiere decir que no se ha producido un error. El objeto Err contiene información acerca de errores en tiempo de ejecución. Acepta los métodos Raise y Clear para generar y limpiar errores en tiempo de ejecución. Cuando se produce un error en tiempo de ejecución, las propiedades del objeto Err se rellenan con información que identifica de forma única al error y con información que se puede usar para manipularlo. Las propiedades del objeto Err se restablecen a cero o a cadenas de longitud cero ("") después de una instrucción On Error Resume Next. El método Clear se puede usar para restablecer explícitamente Err . Un ejemplo: On Error Resume Next Err.Raise 6 Ejemplo para obtener información del error If Err.Number Then MsgBox "Se ha producido el siguiente error:" & vbCrLf & Err.Number & ", " & Err.Description End If Err.Clear Página 230 'Genera un error de desbordamiento ' Limpia el error PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008 CAPITULO VII Página 231 Este ejemplo presenta el mensaje: Para salir de un procedimiento se puede usar Exit Sub, Exit Function o Exit Property . Además cuando termina un procedimiento, la rutina que gestiona los errores también termina y el valor del error permanece asignado (Som, G.; 2000).Al detectar los errores con Resume Next, una buena costumbre es dejar el valor de Err.Number a cero antes de terminar con la rutina y/o antes de salir del procedimiento. 1. Ejercicio: rutina para manejo de error La aplicación permite seleccionar un archivo dentro de una carpeta dentro de una unidad. Si la unidad no esta disponible “salta” el error en tiempo de ejecución. Para esto se ha creado una rutina de manejo de error. El código de los eventos de cada control Private Sub Dir1_Change() 'Archivos de un directorio File1.Path = Dir1.Path End Sub Private Sub Drive1_Change() 'Directorios de una unidad 'Puede ocasionar Error 68 El dispositivo no esta disponible On Error GoTo Mensaje Dir1.Path = Drive1.Drive Mg. Ing. Fátima Martínez 'Manejo de error CAPITULO VII: MANEJO DE ERRORES Mensaje: Mg. Ing. Fátima Martínez 'Muestra un mensaje y sale del procedimiento MsgBox "Se ha producido el error " & Err _ & "." & vbCrLf & Err.Description & "." & _ vbCrLf & "Seleccione otra unidad.", vbInformation, "Error!!" Exit Sub 'Sale del procedimiento End Sub Private Sub File1_Click() 'Selecciona un archivo lblArchivo = File1.FileName End Sub Private Sub txtExt_Change() 'Para ingresar la extensión de los archivos a mostrar File1.Pattern = txtExt End Sub Estructura Select Case Suele utilizarse una estructura del tipo Select Case para preguntar por el número de error. 2. Ejercicio: manejo de errores con la estructura Select Case El siguiente procedimiento intenta abrir un archivo1 para lectura que es pasado mediante el parámetro Archivo desde el control CommonDialog2 (Ver en la Ayuda). El código de los eventos Private Sub cmdLee_Click() On Error GoTo Mensaje 'manda a la rutina de manejo de error Dim Archivo As String, Linea1 As String Dim Linea2 As String, Linea3 As String CommonDialog1.ShowOpen ' un control CommonDialog para abrir Archivo = CommonDialog1.FileName Open Archivo For Input As #1 'Abre el archivo para lectura Input #1, Linea1, Linea2, Linea3 Label1.Caption = Linea1 & Chr(13) & Linea2 & Chr(13) & Linea3 Close Exit Sub Mensaje: 'Sale del procedimiento para no pasar por la rutina siguiente 'rutina de manejo de error Select Case Err 'rutina de manejo de error según el valor de Err 1 El tema de archivos se verá más adelante, el ejercicio tiene el propósito de ejemplificar el manejo de errores. Este control se agrega como un componente más en la barra de herramientas, Microsoft Common Dialog Control 6.0. (SP6). 2 Página 232 PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008 CAPITULO VII Página 233 'Utiliza la estructrua Select Case para las opciones de los errores Case 62: MsgBox "El archivo no tiene tres líneas" & Chr(13) & "Elija un Archivo con tres o más líneas", vbExclamation, "Error" Case 75: Exit Sub especificación de la ruta del archivo 'error de Case Else: MsgBox "Error " & Err.Number & " " & Err.Description 'otro error End Select End Sub El Error 62 ocurre porque la entrada de dato a ha sobrepasado el final del archivo (no puede leer más allá de la posición de final de archivo) o está intentando leer un archivo que no es de acceso secuencial. En el caso de que no sea ninguno de los errores 62 o 75, se presenta un mensaje con el número de error y su descripción. También se puede presentar al usuario un mensaje en el cual se indique el error y se le pregunte si desea seguir adelante: If MsgBox("Error " & Err.Number & " " & Err.Description & vbCrLf & "Desea continuar?", vbYesNo) = vbYes Then Resume Next 'continua con la siguiente línea Else End 'Si ejecución presionó en el botón No termina la End If Si su respuesta es No termina la ejecución del programa, en cambio si es Sí continúa la ejecución en la próxima línea desde donde ocurrió el error, de esta manera ignora el error. VII.2.iii. Disimular los posibles errores de un programa Disimular el error con la instrucción Resume Next, a veces puede ser favorable pero en otras no conviene ignorar el error. Por lo tanto se aconseja no usarla siempre, solamente cuando el error es de menor importancia, porque es como decir “Continua pase lo que pase, no te detengas”. La experiencia indica que es conveniente usar esta técnica en pocas ocasiones, cuando se tiene cierto control de la situación. Mg. Ing. Fátima Martínez CAPITULO VII: MANEJO DE ERRORES VII.3. Mg. Ing. Fátima Martínez DEPURACIÓN Los errores causados por el programa, errores de lógica, son conocidos como bugs y la herramienta más utilizada para ellos es el Depurador o Debugger. Un error de compilación o de ejecución puede llegar a ser fácil de solucionar, pero un error en la lógica de un programa puede absorber varias horas de trabajo de un programador si ignora cómo utilizar las herramientas de depuración (Birnios, B. y Birnios, M.; 2003: 447). Depurar significa probar un programa y eliminar todos los errores o bugs que contenga. Existen varias técnicas para ello siguiendo paso a paso la ejecución de un programa y verificando los valores de las variables y otras estructuras. La herramienta más utilizada para ello es el Depurador o Debugger. La característica principal del Debugger es que permite ejecutar parcialmente el programa, deteniendo la ejecución en el punto deseado y estudiando cada momento el valor de cada una de las variables. De esta manera se facilita enormemente el descubrimiento de las fuentes de errores (Rodríguez Bucarelly, C. M.; 2004:26). VII.3.i. Técnicas de depuración En general todas las técnicas de depuración se encuentran en el menú Depuración. Cuando se advierte que el programa no funciona como es de esperar, se debe analizar cuales son los datos necesarios examinar que ocasionan el problema. Estos pueden ser: • El lugar exacto donde se produce el error. • El estado de las variables en ese momento. En el siguiente ejemplo se pretende encontrar la longitud de la primera palabra de una cadena utilizando la función de cadena Instr(). Dim Longitud As Integer Dim Cadena As String Ejemplo de un Cadena = “Manual de Referencia” error de Longitud = Instr(Cadena, “ ”) programación MsgBox “Longitud de la primera palabra: ” & Longitud La primera palabra Manual tiene longitud 6, pero el programa informa que tiene 7, ¿por qué? Seguramente el valor asignado a la variable Longitud no es el correcto. Sería conveniente chequear su valor justo después de su asignación. Para esto se puede insertar puntos de interrupción y hacer una inspección de su valor. Página 234 PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008 CAPITULO VII Página 235 El error lógico ocurre porque la función Instr() devuelve la posición de la subcadena “ ” (primer espacio de Cadena ) pero la palabra termina justo antes. Lo correcto sería: Longitud = Instr(Cadena, “”) -1 VII.3.i.1. Los puntos de interrupción Los puntos de interrupción pueden insertarse en cualquier línea de código, luego cuando la ejecución llegue a ese punto, se detendrá y entraremos en modo de depuración. En este modo se puede: • Consultar el valor de las variables. • Modificar el código fuente. • Probar pequeñas líneas de código. • Avanzar paso a paso; etc. Para insertar puntos de interrupción: • Se insertan con [F 9 ] o • Ir al menú D e p u r a r → A l t e r n a r puntos de interrupción. Cuando se ubican puntos de interrupción, la línea se marca con otro color y aparece un círculo a la izquierda. Otra forma de interrumpir la ejecución es pulsando [ C T R L ] + [ P a u s a ]. O producir una interrupción desde: menú E j e c u t a r → Interrumpir . Para salir del modo de interrupción: tecla [ F5 ] o E j e c u t a r → Terminar. VII.3.i.2. Conocer el valor de las variables Es importante conocer el valor de las variables. En el modo de depuración existen varias opciones: Ä Ventana de Inspección. Mg. Ing. Fátima Martínez CAPITULO VII: MANEJO DE ERRORES Mg. Ing. Fátima Martínez Ä Ventana Inmediato (C T R L + G ). Brinda la posibilidad de ejecutar instrucciones en el acto, con variables y expresiones que se encuentren dentro del contexto actual del programa. Ä Ventana Pila de llamadas (C T R L + L ). Permite seguir el hilo de ejecución del programa. La ventana muestra cuál es el procedimiento que se ejecutó. Las tres pertenecen al menú V e r . Un modo de conocer el valor de la variable Primero se deben insertar los puntos de interrupción; luego al ejecutar (tecla [F 5 ]) el programa, Visual Basic entra en modo de depuración. Después de esto puede conocer el valor de la variable de la siguiente manera: • Mientras se está ejecutando, ubicar el puntero del mouse sobre el nombre de la variable, aparece un recuadro con su contenido. • Ubicar el cursor sobre la variable y pulsar [S h i f t ] + [F 9 ] para abrir la ventana de Inspección o desde Menú D e p u r a c i ó n → Inspección rápida. • Luego, hacer clic en el botón A g r e g a r y aparece la ventana Inspecciones. • Ir a la ventana Inmediato, pulsar [C t r l ] + [G ] y allí escribir Print nombre de la variable o expresión. En el ejemplo se puede escribir: Print Página 236 En el momento en que se pulsa [E n t e r ], la instrucción se ejecuta y muestra el resultado. PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008 sexo o Print optSexo(0). CAPITULO VII Página 237 En el primer caso, el resultado puede ser: Masculino o Femenino , los dos valores posibles de la variable sexo. En el segundo caso daría: True o False . También es posible realizar asignaciones. Otra manera es: • Seleccionar la variable y Agregar Inspección desde el menú: Depuración → Agregar inspección… En el cuadro de diálogo activar la opción: Modo de interrupción cuando el valor cambie. • Se presione [F5] para ejecutar el programa. VII.4. Cuando la ejecución del programa pas a por la línea donde el valor de la variable agregada ha cambiado, aparece la venta de Inspección y muestra su nuevo valor. Creación de un ejecutable El archivo ejecutable puede correr en la PC sin tener instalado necesariamente Visual Basic (pero sí algunas librerías). Para crear el archivo ejecutable: • Ir al menú A r c h i v o . • Elegir G e n e r a r ( a r c h i v o ) . e x e … Donde archivo es el nombre del ejecutable que Visual Basic creará. • En el cuadro siguiente, cambiar el nombre del archivo si es necesario y modificar otras opciones del mismo mediante el botón O p c i o n e s . Mg. Ing. Fátima Martínez CAPITULO VII: MANEJO DE ERRORES Mg. Ing. Fátima Martínez • Pulsar el botón A c e p t a r para comenzar con la compilación. Las aplicaciones no son sólo un archivo ejecutable sino que también usan librerías de uso común las Dll y otros archivos que tienen funciones generales. La librería que contiene todas las funciones provistas por VB se llama Msvbvm60.dll. Para que un programa funcione todas las librerías necesarias deben estar instaladas en el directorio Windows\System. Por ello el programa debe tener un instalador que además de copiar los archivos propios del programa se asegure de copiar las librerías necesarias. VII.4.i. Asistente de instalación Para hacer este proceso automáticamente, VB provee de un Asistente de instalación. → M i c r o s o f t V i s u a l S t u d i o 6 . 0, seleccionar: H e r r a m i e n t a s d e M i c r o s o f t V i s u a l S t u d i o 6 . 0 → Asistente para empaquetado y distribución. Desde el botón I n i c i o Página 238 PROGRAMADOR UNIVERSITARIO LABORATORIO II - VISUAL BASIC AÑO 2008 CAPITULO VII Página 239 En el Asistente se comienza eligiendo el tipo de Empaquetado. Si es Estándar: VB sólo genera un archivo con la lista de todas las librerías requeridas por nuestro programa. Luego se elige la ubicación de los archivos y otras características requeridas. Mg. Ing. Fátima Martínez CAPITULO VII: MANEJO DE ERRORES Mg. Ing. Fátima Martínez BIBLIOGRAFÍA CONSULTADA Y RECURSOS EN LA WEB Nombre Curso Básico de Programación en Visual Basic; Cap.32 Visual Basic 6. Programación Orientada a Objetos Microsoft Visual Basic 6.0. Manual de Referencia Página 240 Autor/Año Som, G.; 2000 Rodríguez Bucarelly, C. M.; 2004 Birnios, B. y Birnios, M.; 2003 Edición, Editorial / Dirección del Sitio http://www.elguille.info/vb/cursos_vb/BASICO/ basico32_2.htm; (accedido 03/11/2007). http://www.lawebdelprogramador.com/cursos/en lace.php?idp=2175&id=93&texto=visual+basic (accedido 10/03/2007) Manuales USERS; MP Ediciones; Buenos Aires; Argentina.