Los Trucos del Guille publicados en MSDN España

 

Lista de trucos publicados en MSDN España



Truco publicado con fecha 14/May/99:

 

¿Cómo ejecutar otros programas desde Visual Basic?

A pesar de que nuestra aplicación sea "autosuficiente", puede que en alguna ocasión necesitemos usar utilidades externas, por ejemplo mostrar un fichero de texto en el bloc de notas. Cuando se nos de esa ocasión, podemos usar la función SHELL del Visual Basic.
Esta función, que también se puede usar como instrucción, recibe en el primer parámetro el programa y los parámetros que queremos ejecutar, en el segundo parámetro le indicaremos el estilo de la ventana.

Hay que resaltar que esta función se ejecuta de forma asíncrona, es decir que no espera a que el programa ejecutado finalice, y por tanto sigue ejecutando lo que haya en la siguiente línea. Si quieres esperar a que el programa ejecutado finalice, tendrás que echar mano del API de Windows, si quieres ver cómo hacerlo, pásate por la sección de trucos de mis páginas o busca este título: Tip 191: Shelling to Other Applications en la Knowledge Base de Microsoft.

Vamos a ver un ejemplo para llamar al bloc de notas y que nos muestre el contenido del fichero Autoexec.bat, una vez que se ha llamado al programa, nos mostrará un mensaje; fíjate que este mensaje se mostrará aunque el bloc de notas aún no se haya cargado... en este ejemplo, el fichero no es tan grande como para que tarde, pero si fuese otro programa que tardase algo más en cargarse, se mostraría el mensaje antes de que el programa esté funcionando... Si no ves el mensaje, minimiza el bloc de notas y podrás verlo.


Dim strFic As String
Dim strParam As String

strFic = "Notepad.exe"
strParam = "C:\Autoexec.bat"

Shell strFic & " " & strParam, vbNormalFocus

MsgBox "Se está ejecutando el Notepad"

Si el programa a ejecutar no existiera, se produciría un error interceptable, por tanto, para prevenir estos casos, podríamos añadir unas líneas más al ejemplo:


Dim strFic As String
Dim strParam As String

' Esto es para el caso de que el programa a ejecutar no exista
On Local Error Resume Next

' Espero que no tengas un programa que se llame así... 8-)
strFic = "NoExiste.exe"
strParam = "Dará_Error"

Shell strFic & " " & strParam, vbNormalFocus

' Si se produce un error, lo comprobamos aquí
If Err Then
    MsgBox "Se ha producido el siguiente error:" & vbCrLf & _
           Err.Number & ", " & Err.Description & vbCrLf & _
           "al intentar ejecutar:" & vbCrLf & _
           strFic & " " & strParam
Else
    MsgBox "Se está ejecutando: " & strFic & " " & strParam
End If

' Nos aseguramos que el valor del error sea cero
Err = 0

Para probar el código de ejemplo, crea un nuevo proyecto, añade un botón (Command1) y pega el código en el evento Click; aunque también puedes ponerlo en el evento Form_Load, no es recomendable que te acostumbres a hacer las cosas en ese evento, ya que puede ralentizar la carga del formulario.


Truco publicado con fecha 28/May/99

 

¿Cómo detectar errores en Visual Basic?

Cuando quieras que el Visual Basic "ignore" los errores que se produzcan en tu aplicación o en parte de ella, usa:

On Error Resume Next

Esto hará que si se produce un error, se continúe ejecutando el código como si nada hubiese ocurrido.
Por supuesto que la recomendación es que compruebes si se ha producido un error, ya que no es bueno dejar que los errores ocurran sin más.
Para ello tendrás que 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; veamos un ejemplo:


On Local Error Resume Next

    ' Error 13 producirá un error de tipos (Type Mismatch)
    Error 13

If Err.Number Then
    MsgBox "Se ha producido el siguiente error:" & vbCrLf & _
            Err.Number & ", " & Err.Description
End If

Pero si haces esto, procura hacer un poco de limpieza... ya que, si desde este procedimiento llamas a otros procedimientos que a su vez tienen la instrucción On Error Resume Next y no has "limpiado" el valor del número del error... cualquier comprobación que hagas de ese valor dará como resultado que se muestre el mensaje.

Veamos un par de ejemplos:
Para crear el programa de pueba, crea un nuevo proyecto, añade tresd botones (Command1, Command2 y Command3), y pega este código:


Private Sub Command1_Click()
    ' Ejemplo para detectar errores en Visual Basic
    Dim i As Integer
    
    On Local Error Resume Next
    
    i = MsgBox("Pulsa SI para producir un error en este evento," & vbCrLf & _
                "pulsa en NO para llamar al procedimiento Command2_Click" & vbCrLf & _
                "pulsa en Cancelar para llamar al procedimiento Command3_Click", vbYesNoCancel)
    
    If i = vbYes Then
        ' Error 13 producirá un error de tipos (Type Mismatch)
        Error 13
    ElseIf i = vbNo Then
        ' El error producido en el procedimiento Command2 está controlado,
        ' por tanto no se mostrará el mensaje del final
        Command2_Click
    Else
        ' Esto producirá un error en Command3, pero se detectará aquí
        Command3_Click
    End If
    
    If Err Then
        MsgBox "Se ha producido el siguiente error:" & vbCrLf & _
                Err.Number & ", " & Err.Description, , "En Command1_Click"
    End If
    
End Sub


Private Sub Command2_Click()
    On Local Error Resume Next
    
    ' Error 76, (Path not found)
    Error 76
    
    If Err Then
	' Este error está comprobado dentro de este procedimiento, por tanto no mostrará nada
    End If
    
    ' Limpiamos el valor del error
    Err = 0
End Sub


Private Sub Command3_Click()
    
    ' Este procedimiento produce un error número 5
    Error 5
    
    ' Este mensaje NUNCA se mostrará
    MsgBox "El valor de Err.Number es: " & Err.Number & vbCrLf & _
           "Aquí no se notará que se ha producido un error..." & vbCrLf, , "En Command3_Click"
    
End Sub

Veamos que es lo que hace este código y porqué.

Cuando pulses en el Command1 te mostrará un mensaje pidiendote que selecciones el tipo de prueba que quieres hacer, para probar cada una de ellas, tendrás que pulsar varias veces en ese botón, una para cada una de las tres posibilidades.

Si pulsas en "SI", el error se producirá en este mismo evento y el mensaje del final nos indicará que se ha producido el error número 13.

Cuando pulses en "NO", se llamará al procedimiento Command2_Click en el que se produce un error 76, pero que el propio procedimiento se encarga de gestionar y "limpiar", por tanto, no ocurrirá, al menos aparentemente, nada.

Por último, al pulsar en "Cancelar", se llama al procedimiento Command3_Click, el cual produce el error 5, pero no detecta los errores; pero como el Visual Basic "sabe" que aún hay una rutina "interceptadora" de errores en funcionamiento, la del Command1, deja de ejecutar el código erróneo y vuelve a la siguiente instrucción que haya en el procedimiento Command1...

Después de estas tres pruebas, pulsa en el Command2. Nada ocurre, ya que el código detecta los posibles errores.

Cuando pulses en el Command3, verás que el Visual Basic se detiene mostrandonos una ventana de error, esto ocurre porque no hay ninguna rutina de detección de errores en funcionamiento y cuando no la hay... el Visual Basic nos muestra la suya propia y detiene el programa.

Ahora cambia el código del Command3_Click por este otro:

'
Private Sub Command3_Click()
    
    On Local Error Resume Next
    
    ' Este procedimiento produce un error número 5
    Error 5
    
    ' Ahora si que se mostrará este mensaje
    MsgBox "El valor de Err.Number es: " & Err.Number & vbCrLf & _
           "Aquí no se notará que se ha producido un error..." & vbCrLf, , "En Command3_Click"
    
End Sub

Como verás, al no "limpiar" el valor de la propiedad Err.Number, el valor se mantiene; y a pesar de que se haya detectado el error en ese evento, al volver de nuevo al código del Command1, se mostrará el mensaje de que hay error... y además el mensaje que tenemos en el evento Command2_Click, el cual antes no se mostraba.

 

Resumiendo:

Si detectas los errores con Resume Next, acostumbrate a dejar el valor de Err.Number a cero antes de que acabe y/o antes de salir del procedimiento. Recuerda que para salir de un procedimiento puedes usar Exit Sub, Exit Function o Exit Property.

También debes saber que, cuando acaba un procedimiento, la rutina que gestiona los errores también acaba, pero, como has podido comprobar, el valor del error permanece asignado.


la Luna del Guille o... el Guille que está en la Luna... tanto monta...