|
Curso básico
de programación en Visual Basic
Lección
32
Detección
de errores en los cuadros de diálogos comunes
|
Realizamos
programas para la gestión de empresas. Empresas medianas y
pequeñas. Programas de contabilidad, cartera de pedidos
clientes proveedores, facturación control de albaranes,
tesorería cartera de cobros y pagos y estadísticas.
Nuestro
agradecimiento a todos los que por unas causas o por otras
visitan nuestra web. Gestión de empresas PYMES. Curso de
programación de Visual Basic.
|
¿Que tal?
Creías que ya no volvería por aquí ¿verdad? pues te has vuelto a
equivocar... espero que te cueste trabajo librarte de mí... así
que... a aguantar al Guille que aún me queda cuerda "pa"
rato... ¡espero!
En esta entrega terminaremos de ver
el código del Editor ese con el que llevamos varias entregas
"enfangao", si no recuerdo mal, (mirando de reojo al final
de la entrega anterior), lo que tenemos pendiente es:
Usar detección de errores, al
menos al acceder a los cuadros de diálogos,
Seleccionar la impresora a usar e imprimir el contenido del texto
que hemos escrito...
además de las "respuestas" a los ejercicios
"camuflados"... ya veremos en que queda todo esto... (es
que los ejercicios yo aún no los he resuelto... je, je, en fin...)
Empecemos por:
La detección
de errores al usar los cuadros de diálogos
Cuando pulsas en el botón cancelar
del cuadro de diálogo no hay forma de saber que se ha pulsado ese
botón... pero lo lógico es hacer algo en particular si así ha
sido... ¿verdad? (si bwana), pues eso... vamos a ver cómo
"detectar" que se ha pulsado en Cancelar...
Para lograr esto, usaremos la
instrucciones:
On Error Resume Next
Cuando Visual Basic se encuentra
con esta instrucción continuará a pesar de que ocurran errores...
¿de que sirve el que continúe cuando se produce un error?
La verdad es que de nada si no tenemos en cuenta ese
"detalle", por tanto, si usamos esa instrucción,
tendremos que ser consecuentes con nuestros actos... (Guille, eso te
ha quedado en plan sermón... no se si lo aguantaré...)
La forma de saber que se ha
producido un error es comprobarlo... ¿cómo? usando la propiedad
Number del objeto Err, o lo que es lo mismo la propiedad por defecto
del objeto Err, por tanto podemos hacerlo de dos formas:
If
Err.Number Then...
o
If Err
Then...
El resultado es el mismo: si se ha
producido un error se ejecutará el código que esté después del
Then...
Veamos esto que te estoy contando
en el código de abrir y de camino vemos la respuesta:
'
Private Sub mnuFicAbrir_Click()
' Comprobar si el texto se ha modificado
' si es así, guardarlo o no, según la respuesta del usuario
Dim ret As Long
If Modificado Then
ret = MsgBox("El fichero se ha modificado, ¿quieres guardarlo?",_
vbYesNoCancel)
' Si hemos contestado "Si"
If ret = vbYes Then
' Guardarlo
mnuFicGuardar_Click
' Si pulsamos el botón Cancelar, salimos del procedimiento
ElseIf ret = vbCancel Then
Exit Sub
End If
End If
' Usar detección de errores para saber si se ha pulsado en cancelar
On Error Resume Next
With CommonDialog1
' Esto hará que VB devuelva un error al pulsar Cancelar
.CancelError = True
'
.DialogTitle = "Seleccionar un fichero para abrilo"
.FileName = NombreFichero
.ShowOpen
' Si no se ha producido ningún error,
' es que NO se ha pulsado en Cancelar
If Err.Number = 0 Then
If Len(.FileName) Then
NombreFichero = .FileName
' Abrir el fichero y asignarlo al textbox
Dim nFic As Long
Dim sTmp As String
nFic = FreeFile
Open .FileName For Input As nFic
sTmp = Input$(LOF(nFic), nFic)
Close nFic
' Asignarlo al textbox
txtEditor.Text = sTmp
Modificado = False
End If
End If
End With
' Es buena costumbre volver a ponerlo a cero...
Err = 0
End Sub
Como ves no tiene mayor problema
comprobar si el contenido del fichero ha cambiado y preguntar si
queremos guardarlo, etc. (me estoy refiriendo al ejercicio que
había al principio del procedimiento de abrir), en el procedimiento
de Guardar se comprueba si hay algún nombre asignado y si no es
así, se preguntará por ese nombre... de eso se encargan los
procedimientos de Guardar y Guardar como...
Para hacer la pregunta he usado un MsgBox, pero con tres opciones:
Si, No y Cancelar... por si nos arrepentimos y no queremos guardar
el contenido del textbox con el nombre por defecto, por ejemplo...
En cuanto a la detección de
errores... primero ponemos las instrucciones esas que vimos hace un
rato... en el Cuadro de diálogos se asigna a True la propiedad .CancelError,
con esto se le dice al Visual Basic que si se pulsa en Cancelar,
produzca un error detectable, (el número 32755), por tanto,
después del .ShowOpen comprobamos si NO se ha producido un
error, en ese caso quiere decir que se puede continuar, ya que si se
produce un error, no hacemos nada y se continúa con el resto del
código... que por cierto es ninguno, ya que el código restante
está dentro del If Then... salvo el volver a poner el número del
objeto Err a cero, para que no se quede ningún número de error
"colgado" y pueda interferir en otros procedimientos.
Sigue
este link y aprenderás un poco más sobre esto de la detección de
errores.
En cuanto a la respuesta de cómo
abrir el fichero y asignarlo al textbox, ya tenias la respuesta en
la parte de mezclar... o casi, pero como ves es bastante simple y no
hay que hacer nada del otro mundo.
Simplemente abrimos el fichero, leemos el TOTAL del contenido del
mismo y lo asignamos a una variable y después lo asignamos al
TextBox, aunque podríamos haberlo asignado directamente... pero es
que tengo costumbre de usar variables intermedias... cosas... en
fin...
Fíjate que después de abrir el
fichero se asigna el valor False a la variable Modificado, esto es
para que se sepa que el contenido no se ha modificado después de
asignar el contenido al textbox... aunque creo que esto ya lo
expliqué en otra ocasión... ¿no? la verdad es que no me acuerdo,
así que mejor son dos que ninguna...
Veamos ahora:
Cómo
seleccionar la impresora a usar por nuestra aplicación.
Para hacer esto, usaremos también
el Common Dialog que tenemos insertado en nuestro formulario:
'
Private Sub mnuFicImpSelec_Click()
' Seleccionar la impresora a usar
' La detección de errores es por si no hay impresora instalada
On Error Resume Next
With CommonDialog1
.DialogTitle = "Seleccionar impresora"
.Flags = cdlPDPrintSetup
.ShowPrinter
End With
Err = 0
End Sub
El truco está en usar el valor cdlPDPrintSetup
como valor para la propiedad Flags del cuadro de diálogo y
después, por supuesto, usar el método ShowPrinter; cuando
el control de diálogos comunes se encuentra con ese
"flag" sabe que debe mostrar el cuadro de diálogo de
configurar impresora, desde el cual podemos seleccionar otra de las
impresoras instaladas en el sistema.
Nota:
Los valores a usar con Flags puedes averiguarlos pulsando F1
sobre la propiedad Flags, la ayuda te dará una lista de los
valores posibles.
Ahora veamos:
Cómo
imprimir el contenido de la caja de textos.
En esta ocasión también usaremos
el Cuadro de Diálogo pero, para saber cuantas copias quiere el
usuario imprimir, si la quiere en horizontal o vertical, etc.,
etc. (aunque esto último se suele hacer al configurar la impresora,
no al imprimir).
'
Private Sub mnuFicImpImp_Click()
' Imprimir el contenido del TextBox en la impresora
On Error Resume Next
' Averiguamos cuantas copias quiere el usuario y dejamos que elija
' otras cosas el propio cuadro de diálogo nos lo permitirá hacer...
With CommonDialog1
.CancelError = True
.DialogTitle = "Imprimir"
' cdlPDHidePrintToFile No mostrar el botón de imprimir en un archivo
' cdlPDNoPageNums No mostrar desde que página imprimir, etc.
' CdlPDUseDevModeCopies Dejar al SO que se encargue de imprimir las copias
' En caso de que la impresora no lo soporte, estará
' deshabilitada la opción del número de copias.
.Flags = cdlPDHidePrintToFile Or cdlPDNoPageNums Or cdlPDUseDevModeCopies
.ShowPrinter
' Si no se ha cancelado
If Err = 0 Then
' En la propiedad .Copies estará el número de copias a imprimir.
' Hay casos en los que las impresoras "automáticamente" usan ese valor,
' por tanto si no queremos hacer un bucle para imprimir el número de
' copias solicitadas, podemos dejar que sea el propio sistema el que
' se encargue de esa cuestión...
' El problema, cuando la impresora no permite imprimir varias copias
' Para simplificar, dejaremos que sea el propio O.S. el que se encargue
'
' Imprimimos el contenido del textbox... simple, ¿verdad?
Printer.Print ""
Printer.Print txtEditor.Text
Printer.EndDoc
End If
End With
End Sub
También podríamos hacerlo más
complicado, de forma que podamos controlar cada una de las líneas a
imprimir... no es que tenga ninguna utilidad práctica, pero así
sabes como controlar el contenido de cada una de las líneas de un
TextBox Multiline, por ejemplo puedes usarlo para hacer que el texto
esté justificado, etc... aunque no se si esa parte la veremos en el
curso básico... ya veremos.
Cómo
controlar cada línea de un TextBox Multiline
Esta tarea está contenida en un
procedimiento, el cual recibe como parámetro un TextBox Multiline
el cual contendrá el texto a imprimir; el hacerlo de esta forma, en
lugar de usar directamente el control txtEditor, es para los casos
en que necesitemos una rutina genérica o bien porque tengamos más
textboxes en nuestro proyecto...
Para usarlo simplemente se haría:
ImprimirPorLinea txtEditor
Este es el contenido del mencionado
procedimiento.
'
Private Sub ImprimirPorLinea(qControl As TextBox)
' Este procedimiento tomará cada línea de un textbox multiline
' y lo imprimirá en la impresora predeterminada
'
' El parámetro qControl, será el TextBox a usar, en este caso no es
' necesario ya que sólo tenemos un TextBox, pero si se usaran varios...
' sería un procedimiento de uso genérico...
'
Dim i As Long, k As Long
Dim L1 As Long, L2 As Long
' Constantes para usar con SendMessage
Const EM_GETLINECOUNT = &HBA
Const EM_LINEFROMCHAR = &HC9
Const EM_LINELENGTH = &HC1
' Número de líneas del TextBox
k = SendMessage(qControl.hWnd, EM_GETLINECOUNT, 0, 0&)
Printer.Print ""
For i = 0 To k - 1
' Primer carácter de la línea actual
L1 = SendMessage(qControl.hWnd, EM_LINEINDEX, i, 0&) + 1
' Longitud de la línea actual
L2 = SendMessage(qControl.hWnd, EM_LINELENGTH, L1, 0&)
' Imprimimos el trozo de texto que representa a una línea
Printer.Print Mid$(qControl.Text, L1, L2)
Next
' Le indicamos que ya no hay más que imprimir
Printer.EndDoc
End Sub
Esto es todo, al menos por ahora,
aunque aún queda por hacer la parte de Buscar y Reemplazar, pero
eso lo dejaremos para otra ocasión, ya que si no se iba a alargar
más de la cuenta el tema y no es plan, como adelanto te diré que
seguramente, lo programaremos usando clases, que ya va siendo hora
de que entremos de lleno en ese mundo tan desconocido para unos y
casi tan mágico para otros... o casi... aún así, espero que no
tengas queja... ya que esta entrega ha valido por dos... o más...
ahora, a esperar a la siguiente... paciencia,
paciencia...
Nos vemos
|
|