Curso Básico de Programación
en Visual Basic

 

Entrega Treinta y cinco: 12~14/Feb/2001
por Guillermo "guille" Som

Si quieres linkar con las otras entregas, desde el índice lo puedes hacer

 

Se que hay muchos programadores de VB a los que no les gusta usar el Datacontol para acceder a las bases de datos; pero también se que usar este control es más fácil que usar código directo, aunque esto último también lo vamos a ver a lo largo de este curso básico, incluso lo vamos a mezclar con el Datacontrol, ya que se puede acceder a bases de datos de las dos formas de forma conjunta.
En esta entrega vamos a ampliar el ejemplo usado en la entrega anterior, para añadirle algunas opciones nuevas, para añadir nuevos registros y para eliminar registros existentes, por tanto, si quieres conservar intacta la base de datos Biblio.mdb, te recomiendo que hagas una copia de la misma. También vamos a usar la opción de buscar que puse como ejercicio, por tanto, si no te has leído las soluciones de la entrega 34, es conveniente de que le eches un vistazo.

Vamos a empezar por mejorar la búsqueda en la base de datos:

Buscar en una base de datos.

En esta ocasión vamos a añadir un botón buscar y buscar siguiente, para que podamos seguir buscando a partir del último registro encontrado.
En el ejemplo anterior, se buscaba al pulsar Intro en la caja de textos, pero ahora vamos a crear un procedimiento Buscar, el cual, según el parámetro recibido, buscará la primera coincidencia o seguirá buscando desde el último dato hallado.

Antes de añadir un nuevo botón, vamos a modificar el código actual para usar el nuevo procedimiento Buscar.

Crea un nuevo procedimiento, en el menú Herramientas (Tools), selecciona Añadir procedimiento..., llámalo Buscar y haz que sea privado, ya que no tiene ningún sentido que sea público, porque sólo se usará desde el formulario.
También puedes copiar y pegar el siguiente código:

'
Private Sub Buscar()
    ' Procedimiento para buscar el dato indicado                    (12/Feb/01)
    Dim nReg As Long
    '
    ' Buscar la primera coincidencia en el recordset del Data1
    '
    If Option1.Value Then    ' en el campo Au_ID
        ' Convertir el contenido de TextBox en un número
        nReg = Val(Text4)
        '
        Data1.Recordset.FindFirst "Au_ID = " & nReg
    End If
    If Option2.Value Then   ' en el campo Author
        '
        Data1.Recordset.FindFirst "Author Like '" & Text4.Text & "'"
    End If
End Sub

Ahora hay que modificar el evento KeyPress del control Text4, para que llame al nuevo procedimiento.
Borra el código que había anteriormente en ese evento y sustitúyelo por este otro:

'
Private Sub Text4_KeyPress(KeyAscii As Integer)
    ' Se buscará sólo cuando pulsemos INTRO
    '
    ' Comprobar si la tecla pulsada es Intro: vbKeyReturn o 13 que es lo mismo
    If KeyAscii = vbKeyReturn Then
        ' Esta asignación evita que suene un BEEP
        KeyAscii = 0
        ' Llamamos al procedimiento Buscar:
        Buscar
    End If
End Sub

Pruébalo, para que veas que todo funciona como antes.


Ahora, vamos a añadir un botón para que busque el primer registro que coincida con lo escrito, esto es para hacer lo mismo que cuando pulsas Intro en el Text4, pero para el usuario será más lógico que el hecho de tener que pulsar Intro.
Por tanto, añade un nuevo botón, (no te preocupes por ahora dónde colocarlo en el formulario, ya lo haremos dentro de poco), cámbiale el nombre a cmdBuscar y el Caption a Buscar, (por defecto será Command1) y escribe o añade este código (también puedes hacerlo copiando y pegando):

'
Private Sub cmdBuscar_Click()
    ' Simplemente llamamos al procedimiento Buscar:
    Buscar
End Sub

Poca cosa, ¿verdad? Pues es igual de efectivo que pulsando Intro en el Text4, pruebalo para que veas que funciona.

Creo que ya es hora de que nos vayamos complicando la vida...

Vamos a añadir un botón para seguir buscando a partir del último dato hallado:
Añade un nuevo botón, llámalo cmdBuscarSig y en el Caption pones: Buscar siguiente, (seguramente el texto lo escribirá en dos líneas, pero no te preocupes).
El código a usar en el evento Click de ese nuevo botón sería prácticamente el mismo que en el de Buscar, aunque antes debemos añadir un nuevo procedimiento para que busque el siguiente dato al último que buscó:

'
Private Sub BuscarSiguiente()
    ' Procedimiento para buscar el dato indicado                    (12/Feb/01)
    Dim nReg As Long
    '
    ' Buscar la siguiente coincidencia, a partir del último hallado
    '
    If Option1.Value Then    ' en el campo Au_ID
        ' Convertir el contenido de TextBox en un número
        nReg = Val(Text4)
        '
        Data1.Recordset.FindNext "Au_ID = " & nReg
    End If
    If Option2.Value Then   ' en el campo Author
        '
        Data1.Recordset.FindNext "Author Like '" & Text4.Text & "'"
    End If
End Sub

Si te fijas, el código es prácticamente el mismo que el del procedimiento Buscar, lo único que cambia es que aquí se usa FindNext en lugar de FindFirst
Es decir FindFirst busca el primer dato que coincida con lo buscado y FindNext el siguiente al último que se buscó.
Para probar este nuevo procedimiento, en el evento cmdBuscarSig_Click, escribe: BuscarSiguiente.
Así es como quedaría ese evento:

Private Sub cmdBuscarSig_Click()
    ' Buscar el siguiente registro
    BuscarSiguiente
End Sub


Como hemos visto, el código usado en los dos procedimientos de búsqueda son prácticamente iguales, así que vamos a unificarlos para crear un sólo procedimiento de búsqueda, de esta forma, refrescarás tu memoria y sabrás algo más de parámetros en procedimientos, así como parámetros opcionales.

Parámetros opcionales.

Como sabrás, (y si no lo sabes, te lo cuento yo ahora), a partir de la versión 4 de Visual Basic se pueden usar parámetros opcionales en los procedimientos y funciones.
Esto quiere decir que podemos usar el procedimiento de varias formas, indicando todos los parámetros o sólo los que realmente son necesarios.
Por ejemplo, en el caso en que estamos ahora, el procedimiento Buscar podría tener un parámetro opcional para indicarle si es la primera búsqueda o la siguiente.
No voy a entrar en demasiadas explicaciones, ya que este tema lo veremos de forma más amplia en otra entrega, sobre todo porque tiene sus pormenores, o lo que es lo mismo, existen diferencias entre las versiones 4 y posteriores (al menos hasta la 6) de Visual Basic e incluso en las dos últimas se puede usar de dos formas diferentes...

En esta ocasión voy a usar el formato de las versiones 5 y 6, en estas versiones los parámetros opcionales pueden ser de un tipo de datos diferente a Variant y también pueden indicársele un valor por defecto, para que, si no se especifica, tenga el valor indicado; por supuesto, si no le indicamos el valor, tendrán el valor que ese tipo de datos tengan por defecto, por ejemplo el tipo Boolean tendrá un valor False si no se indica el valor.
Cuando se indican parámetros con tipo, a diferencia de los parámetros del tipo Variant, no se puede usar IsMissing para comprobar si el parámetro se ha especificado o no, pero, eso es otro tema...

Este es el código del procedimiento Buscar y a continuación te indico cómo llamarlo desde el evento Click del botón cmdBuscarSig:

'
Private Sub Buscar(Optional ByVal Siguiente As Boolean = False)
    ' Procedimiento para buscar el dato indicado                    (12/Feb/01)
    ' Si Siguiente = True, se busca a partir del registro activo
    ' Si no se indica, (valdrá False), buscará el primer registro
    Dim nReg As Long
    '
    ' Buscar la primera coincidencia en el recordset del Data1
    '
    If Option1.Value Then    ' en el campo Au_ID
        ' Convertir el contenido de TextBox en un número
        nReg = Val(Text4)
        '
        ' Si se busca el siguiente dato
        If Siguiente Then
            Data1.Recordset.FindNext "Au_ID = " & nReg
        Else
            Data1.Recordset.FindFirst "Au_ID = " & nReg
        End If
    End If
    If Option2.Value Then   ' en el campo Author
        '
        ' Si se busca el siguiente dato
        If Siguiente Then
            Data1.Recordset.FindNext "Author Like '" & Text4.Text & "'"
        Else
            Data1.Recordset.FindFirst "Author Like '" & Text4.Text & "'"
        End If
    End If
End Sub



Private Sub cmdBuscarSig_Click()
    ' Buscar el siguiente registro
    Buscar True
End Sub


Puedes borrar el procedimiento BuscarSiguiente, ya que no es necesario. Tampoco es necesario modificar el código de los eventos Text4_KeyPress ni el de cmdBuscar_Click, ya que esos dos eventos llaman al procedimiento Buscar con el valor predeterminado y al ser opcional, no es necesario indicarlo...

Si pruebas el nuevo código, te darás cuenta de que, la primera vez, pulsando tanto en Buscar como en Buscar siguiente, encuentra lo mismo, esto es debido a que FindNext, busca a partir de la última posición hallada y en el caso de buscar por primera vez, busca desde el principio.
En el caso de que cambies el texto buscado y pulses en Buscar siguiente, se mostrará el próximo registro, desde el último hallado, que contenga dicho texto, (estas pruebas hay que hacerlas en el campo Author, ya que no tienen ningún sentido hacerlo en el ID del autor). Para buscar el resto de autores con el nuevo texto, tendrás que pulsar en Buscar para que empiece a buscar desde el principio.

Fíjate en el código, se da por hecho de que Siguiente tiene un valor, el cual, (al ser del tipo Boolean), puede ser False o True. En caso de que sea True, es decir se ha especificado con ese valor, se buscará con FindNext y en caso de no especificarse o de hacerlo con el valor False, se usará FindFirst.
Lo mismo da: Buscar False que Buscar (sin parámetros)
Esto último: lo de no especificarse o si se especifica con el valor False, es algo que hay que tener en cuenta si el parámetro fuese de tipo Variant (cosa obligatoria si usas VB4), ya que IsMissing sólo nos informa si el parámetro no se ha especificado, pero si se especifica, puede hacerse con un valor False o True, por tanto, también habría que tenerlo en cuenta... 
Ya sé que dije que lo iba a dejar para otra entrega... pero, que haces si estás usando VB4 ¿dejar aquí el curso?
Así que vamos a ver el código de Buscar para usar con VB4 o con las versiones 5 y 6 pero usando el tipo Variant.

'
Private Sub Buscar(Optional ByVal vSiguiente As Variant)
    ' Procedimiento para buscar el dato indicado                    (12/Feb/01)
    '
    ' Si Siguiente = True, se busca a partir del registro activo
    ' Si no se indica, (valdrá False), buscará el primer registro
    '
    ' Cuando el parámetro es de tipo Variant,
    ' no se puede indicar un valor por defecto,
    ' así que vamos a usar una variable interna para indicar el valor del parámetro
    Dim Siguiente As Boolean
    '
    Dim nReg As Long
    '
    ' Asignar correctamente el valor del parámetro indicado
    ' Si no se especifica, le asignamos el valor por defecto, en este caso: False
    If IsMissing(vSiguiente) Then
        Siguiente = False
    Else
    ' Si se indica, asignarlo a la variable interna
        Siguiente = CBool(vSiguiente)
    End If

    ' El resto del código es igual que antes

    ' Buscar la primera coincidencia en el recordset del Data1
    '
    If Option1.Value Then    ' en el campo Au_ID
        ' Convertir el contenido de TextBox en un número
        nReg = Val(Text4)
        '
        ' Si se busca el siguiente dato
        If Siguiente Then
            Data1.Recordset.FindNext "Au_ID = " & nReg
        Else
            Data1.Recordset.FindFirst "Au_ID = " & nReg
        End If
    End If
    If Option2.Value Then   ' en el campo Author
        '
        ' Si se busca el siguiente dato
        If Siguiente Then
            Data1.Recordset.FindNext "Author Like '" & Text4.Text & "'"
        Else
            Data1.Recordset.FindFirst "Author Like '" & Text4.Text & "'"
        End If
    End If
End Sub

Fíjate que he cambiado el nombre del parámetro y he creado una variable interna que es la que posteriormente se usa para saber si se busca desde el primero o desde el anterior.
En el caso de que no se haya especificado el parámetro, la comprobación de IsMissing se cumple, por tanto aquí le indicaremos el valor que queramos que tenga por defecto, en nuestro ejemplo no es necesario asignar ningún valor, ya que False es el valor que tendrá la variable Siguiente si no le asignamos ningún valor.
Por tanto en este ejemplo, podríamos haber hecho sólo lo siguiente, sin necesidad de usar el IsMissing:
Siguiente = CBool(vSiguiente)
Pero lo he mostrado de la forma recomendable, para que sepas qué hacer en el caso de que el valor por defecto fuese otro del que Visual Basic asigna a las variables por defecto.


Una vez visto el procedimiento de búsqueda, vamos a añadir dos nuevos botones para Añadir y Eliminar registros.
Recuerda lo que te dije al principio: haz una copia de la base de datos para que las pruebas no afecten al contenido de la misma.

Añade dos nuevos botones y asignales los nombres cmdAdd y cmdBorrar, así como los captions Añadir y Eliminar, el código será el siguiente:

'
Private Sub cmdAdd_Click()
    ' Añadir un nuevo registro
    Data1.Recordset.AddNew
End Sub

Private Sub cmdBorrar_Click()
    ' Eliminar el registro actual
    Data1.Recordset.Delete
End Sub


Tanto cuando se añade como cuando se borra, se debería mover el registro actual para que los cambios tengan efecto en la base de datos, ya que si se añade un nuevo registro y el mismo no se actualiza, se pierde.
Para probarlo, ejecuta el proyecto, pulsa en Añadir y directamente sin hacer nada más cierra el ejecutable, (pulsando en la x del formulario o ventana).
Ejecuta de nuevo el proyecto y si pulsas en el botón de ir al último registro del Datacontrol, verás que no hay ningún registro nuevo.
Ahora vuelve a pulsar en Añadir y escribe lo que quieras en las cajas de texto del Nombre y Año de nacimiento y pulsa en el botón de ir al primer registro y después al último (ya sabes que me refiero a los botones del Datacontrol), verás que ahora si se muestra dicho registro y si pulsas en el botón de ir al anterior, verás que se salta un número... ese es el que había reservado para nosotros, pero al no actualizar los datos, se perdió en el limbo...

¿Será por estos detalles que algunos programadores prefieran usar código puro y duro en lugar del Datacontrol?
Puede... pero no creo que sea por este motivo... ya que esto mismo se puede mejorar y no es necesario abandonar el Datacontrol para que todo funcione más o menos como debiera...
Primero vamos a hacer que los nuevos datos tengan algo, para ello, le asignaremos la cadena Nuevo al nombre del autor y haremos que se desplace al último registro, para que los datos sean permanentes, (si no modificamos algunos de los campos, el nuevo registro se perdería)
En el caso de Eliminar, vamos a movernos al primer registro, para que el registro activo sea uno con información.
Este sería el código de los eventos Click de los dos botones:

'
Private Sub cmdAdd_Click()
    ' Añadir un nuevo registro
    Data1.Recordset.AddNew
    ' Añadimos algún texto, para que no se pierda este registro
    Text2 = "Nuevo"
    ' Movemos al último registro para que los cambios se hagan permanentes
    ' y se muestre el nuevo registro
    Data1.Recordset.MoveLast
End Sub

Private Sub cmdBorrar_Click()
    ' Eliminar el registro actual
    Data1.Recordset.Delete
    ' Movemos al primer registro para que los cambios se hagan permanentes
    ' (también podriamos haberlo movido al último registro)
    Data1.Recordset.MoveFirst
End Sub

Toma nota de la forma en que se haría para mover al primer o al último registro del Recordset.
También habría que tener en cuenta si hemos sobrepasado el principio o el final de los registros, cosa que ocurre cuando no hay más registros, para ello podemos comprobar tanto EOF (End Of File, final del fichero) como BOF (Beginnig Of File, principio del fichero) y en caso de que sea cierto (True), avisar o simplemente no hacer nada...
Esto sólo habría que hacerlo al eliminar registros, ya que al añadir se supone que habrá al menos el que añadimos...

'
Private Sub cmdBorrar_Click()
    '
    ' Comprobar que hay registros, porque si no hay, dará error
    If (Data1.Recordset.EOF Or Data1.Recordset.BOF) Then
        ' Avisar de que no hay registros
    Else
        ' Eliminar el registro actual
        Data1.Recordset.Delete
        '
        ' Movemos al primer registro para que los cambios se hagan permanentes
        ' (también podriamos haberlo movido al último registro)
        Data1.Recordset.MoveFirst
    End If
End Sub


Y esto es todo por hoy.
En la próxima entrega veremos cómo acceder a bases de datos usando el ADO datacontrol.

Nos vemos
Guillermo
P.S.
Si quieres bajarte los ejemplos usados, pulsa este link. (basico35_cod.zip 3.11 KB)


 
entrega anterior ir al índice siguiente entrega

Ir al índice principal del Guille