Un Gran Proyecto, Paso a Paso

 

Sexta Entrega (10/Abr/97)

Entregas anteriores: Primera, Segunda, Tercera, Cuarta, Quinta
Lo dicho en otras ocasiones, es recomendable que les eches una visual para seguir el hilo del proyecto.

Bajate las páginas HTML y los gráficos de las 6 entregas. (gsnotas_htm.zip 76.0 KB)
Bajate los listados del proyecto. (gsnotas.zip 30.4 KB)
(Estos tamaños variarán según el número de entregas; para saber el tamaño actual, deberías ver la última entrega)


Vamos a empezar hoy por el arreglo de algunas cosillas y a definir un tipo de datos, que posteriormente usaremos en la consulta.
Lo que he cambiado, añadido, está en esta lista:

  1. Arreglar el "bug" de que se quede marcado como terminado cuando acabamos de añadir un registro.
  2. Asignar los valores por omisión al pulsar en Nuevo.
  3. Una variable definida (TYPE) para saber con que campos estamos trabajando.
  4. Cambios para "detectar" los caracteres separadores en los campos de fecha.
  5. El formulario para realizar las consultas
  6. Para rematar.

1.- Arreglar el "bug" de que se quede marcado como terminado cuando acabamos de añadir un registro.

Para esto sólo tienes que añadir lo siguiente en la parte de Actualización, esta es parte del código:

    '...
    .Enabled = True
    'A ver si así se actualiza correctamente
    If Val(.Recordset.Terminada) Then
	Check1.Value = 1
    Else
	Check1.Value = 0
    End If
    .Refresh

 


2.- Asignar los valores por omisión al pulsar en Nuevo.

En esta ocasión, añade este código al procedimiento cmdActualizar, en la parte de añadir un Nuevo registro:

    '...
    Data1.Enabled = False
    'Asignar la fecha actual
    Text1(cFecha) = Format$(Now, "Short Date")
    Text1(cFechaInicio) = Text1(cFecha)
    Text1(cTerminada) = "0"
    YaEstoyAqui = False
    '...

3.- Una variable definida (TYPE) para saber con que campos estamos trabajando.

Esta variable, nos permitirá manejar, o al menos saber, los tipos de datos con los que estamos trabajando en un momento dado. También pongo la declaración de una variable que vamos a usar, este código deberás insertarlo en las declaraciones del módulo glbNotas.bas

'Tipo para los fields (campos) de la base de datos.
Type Campo_t
    Nombre As String
    Tipo As Long
    Tamaño As Integer
End Type
Global Campos() As Campo_t           'Para el manejo de los campos
Global sSepFecha As String           'El separador de las fechas

En el procedimiento de carga de la tabla, añede lo siguiente:

    '...
    '-(10/Abr/97)- Asignamos el tamaño del array de campos
    ReDim Campos(j)
    
    i = -1
    For Each Fd In Rs.Fields
        i = i + 1
        '-(10/Abr/97)- Asignamos los datos de los campos
        With Campos(i)
            .Nombre = Fd.Name
            .Tamaño = Fd.Size
            .Tipo = Fd.Type
        End With

4.- Cambios para "detectar" los caracteres separadores en los campos de fecha.

Y ahora unas cosillas para que al escribir en un campo de fecha, nos cambie los caracteres ".", "-" y "/" por el separador que esté definido en el formato corto de la fecha, normalmente "/"
Primero lo "comprobaremos" para que el programa use el que está definido, este código lo añades en el Form_Load.
(
Seguramente habrá alguna forma directa de obtenerlo, pero yo no la sé)

    Dim sTmp As String
    
    sSepFecha = "/"
    
    sTmp = Format$(Now, "Short Date")
    If InStr(sTmp, "/") Then
        sSepFecha = "/"
    ElseIf InStr(sTmp, "-") Then
        sSepFecha = "-"
    'Si usas algún separador "predefinido" incluyelo aquí
    End If

Ahora añade este código, para que al escribir en el TetBox, se compruebe...

Private Sub Text1_KeyPress(Index As Integer, KeyAscii As Integer)
    'Comprobar si estamos en un campo de fecha
    'Para los campos de fecha
    If Campos(Index).Tipo = dbDate Then
        Select Case KeyAscii
        Case Asc("-"), Asc("."), Asc("/")
            KeyAscii = Asc(sSepFecha)
        End Select
    End If
End Sub

5.- El formulario para realizar las consultas.

¡Ahora si! Al fin el dichoso formulario de consulta.
Vamos a necesitar de nuevo el gsInput, así que deberás añadirlo al proyecto (gsInput.frm y gsInput.bas)

El form en el que se muestra la consulta, quedará de la siguiente forma:

Form para el Resultado de la Consulta

Notarás que está cambiado con respecto a lo que te mostré hace un par de entregas.

Vamos a ver cómo queda el form en el que se realizan las consultas. Este es el form gsQBE.frm

Form para realizar las consultas

Una vez vista las "fotos" de estos dos nuevos forms, vamos a ver el código.
Primero el del formulario de consulta. Decir que este código está basado en uno que me creé hace un par de años. Lo he adaptado para usarlo en el proyecto que tenemos entre manos, pero se puede usar más o menos de forma genérica, siempre que existan estas variables:
---una variable llamada elForm que haga referencia al form en el que se quiere hacer la consulta
---un array llamado Campos() del tipo t_Campo, o al menos que contengan los elementos Tipo, Nombre y Tamaño.
---una variable sTabla con el nombre de la Tabla a consultar.
---una variable sBase con el nombre de la base de datos en la que está esa tabla.
---y por último que la tabla tenga un campo llamado ID
Y por supuesto los forms de mostrar los datos y los genéricos usados en este proyecto.

Sin más dilación, es decir: "menos rollo y más manteca al bollo", pasamos al "dishoso" código:

'---------------------------------------------------------------
'gsQBE  Form para realizar las consultas
'
'(c)Guillermo Som, 1994-97
'---------------------------------------------------------------

Option Explicit
Option Compare Text

Dim nOpciones As Integer        'Número de Opciones para
                                'la búsqueda y mostrar
Dim MaxCampos As Integer
Dim ComparaOr() As String
Dim SumasCampos() As Long
Dim LongCampos() As Integer


Private Sub Command1_Click()
    'Preparado el proceso de búsqueda: 1/Dic/94
    Dim sBuscar As String
    Dim flag As Boolean
    Dim i As Integer
    Dim j As Integer
    Dim k As Integer
    Dim sTmp As String
    Dim sTmp2 As String
    Dim q As Integer
    Dim p As Integer
    Dim sLogico As String
    
    'Ahora si en Text1(), se escribe | (AltGr+1),
    'o [O] se hará una comparación OR
    'y si se empieza con [O] se hace un OR con el
    'siguiente campo en vez de un AND   (25/Nov/95)
    
    On Local Error Resume Next

    '---Asignar a sBuscar los campos y valores de la búsqueda.
    sBuscar = ""
    For i = 0 To nOpciones
        k = CboCampos(i).ListIndex
        If k >= 1 Then
            If cboComparación(i).ListIndex < 0 Then
                cboComparación(i).ListIndex = 0
            End If
            j = cboComparación(i).ListIndex
            'Comprobar si tiene |
            sTmp = Trim$(Text1(i).Text)
            sLogico = "AND "
            'Se admite [O] y [O<cualquier_cosa>]
            If Left$(sTmp, 2) = "[O" Then
                q = InStr(sTmp, "]")
                If q = 0 Then q = 2
                sLogico = "OR  "
                sTmp = Mid$(sTmp, q + 1)
            End If
            'Separar en el mísmo texto con | o [O]
            q = InStr(sTmp, "|")
            If q = 0 Then
                q = InStr(sTmp, "[O")
            End If
            p = 0
            If q Then
                ExtraeOpciones sTmp, q
                p = q
            End If
            If p Then
                sTmp = ""
                For q = 1 To p - 1
                    'Arreglar esto...
                    Select Case Campos(k).Tipo
                    Case dbByte, dbText, dbMemo
                        sTmp = sTmp & ComparaOr(q) & "*' OR " & Campos(k).Nombre & " " & cboComparación(i).List(j) & " '*"
                    Case dbDate
                        sTmp = sTmp & ComparaOr(q) & "') OR " & Campos(k).Nombre & " " & cboComparación(i).List(j) & " Datevalue('"
                    Case Else
                        sTmp = sTmp & ComparaOr(q) & " OR " & Campos(k).Nombre & " " & cboComparación(i).List(j) & " "
                    End Select
                Next
                sTmp = sTmp & ComparaOr(p)
            End If
            Select Case Campos(k).Tipo
            Case dbByte, dbText, dbMemo
                'poner '* ... *' si es Like o Not Like
                If InStr(cboComparación(i).List(j), "Like") Then
                    sBuscar = sBuscar & Campos(k).Nombre & " " & cboComparación(i).List(j) & " '*" & CStr(sTmp) & "*' " & sLogico
                Else
                    'sólo poner '...' por si se quiere una coincidencia exacta
                    sBuscar = sBuscar & Campos(k).Nombre & " " & cboComparación(i).List(j) & " '" & CStr(sTmp) & "' " & sLogico
                End If
            Case dbDate                 'poner datevalue('...')
                sBuscar = sBuscar & " " & Campos(k).Nombre & " " & cboComparación(i).List(j) & " Datevalue('" & sTmp & "') " & sLogico
            Case Else                   'no poner '* ... *'
                sBuscar = sBuscar & Campos(k).Nombre & " " & cboComparación(i).List(j) & " " & sTmp & " " & sLogico
            End Select
            flag = True
        End If
    Next
    If Not flag Then
        Beep
        MsgBox "Se debería seleccionar por lo menos un campo." & Chr$(13) & "Si lo que pretendes es cancelar la búsqueda, pulsa en el botón de Cancelar.", 64
        Exit Sub
    End If
    'Quitarle el final
    sBuscar = Left$(sBuscar, Len(sBuscar) - 4)

    'Guardar la selección en el fichero INI
    GuardarQBE
    'Procesar los datos de la consulta
    ProcesarConsulta sBuscar
End Sub

Private Sub Command2_Click()
    Unload Me
End Sub

Private Sub Command3_Click()
    '----------------------------------------------
    ' Consulta directa
    '----------------------------------------------
    sFFPoner = Trim$(LeerIni(ficIni, "General", "Buscar", ""))
    gsPedirUnValor "Consulta directa", "Escribe el CAMPO y la comparación a usar. Ejemplo: Población LIKE '*Nerja*'", "", sFFPoner, "Aceptar"
    If iFFAccion <> cFFAc_Cancelar Then
        If Len(sFFPoner) Then
            GuardarIni ficIni, "General", "Buscar", sFFPoner
            ProcesarConsulta sFFPoner
        End If
    Else
        MostrarConsulta!Command1.Caption = ""
    End If
End Sub

Private Sub ExtraeOpciones(sTmp As String, q As Integer)
    Dim p As Integer
    Dim sTmp2 As String
    Dim i As Integer
    
    sTmp2 = sTmp
    p = 0
    Do
        q = InStr(sTmp, "|")
        If q Then
            sTmp = Mid$(sTmp, q + 1)
            p = p + 1
        Else
            'Buscar también [O
            q = InStr(sTmp, "[O")
            If q Then
                i = InStr(sTmp, "]")
                If i = 0 Then q = q + 1
                sTmp = Mid$(sTmp, q + 1)
                p = p + 1
            End If
        End If
    Loop While q
    If Len(Trim$(sTmp)) Then
        p = p + 1
    End If

    sTmp = sTmp2
    ReDim ComparaOr(p) As String
    p = 0
    Do
        q = InStr(sTmp, "|")
        If q Then
            p = p + 1
            ComparaOr(p) = Left$(sTmp, q - 1)
            sTmp = Mid$(sTmp, q + 1)
        Else
            q = InStr(sTmp, "[O")
            If q Then
                ComparaOr(p) = Left$(sTmp, q - 1)
                i = InStr(sTmp, "]")
                If i = 0 Then q = q + 1
                sTmp = Mid$(sTmp, q + 1)
                p = p + 1
            End If
        End If
    Loop While q
    If Len(Trim$(sTmp)) Then
        p = p + 1
        ComparaOr(p) = sTmp
    End If
    q = p

End Sub

Private Sub Form_Load()
    Dim i As Integer
    Dim j As Integer
    Dim t As Integer
    Dim dBase2
    Dim sTmp As String
    
    MaxCampos = UBound(Campos)
    
    Screen.MousePointer = vbHourglass
    
    Top = 0
    Left = 0
    'MostrarProgress "Asignando la ventana para la consulta a mostrar... " & vbCrLf
    
    'Ahora siempre se usan Combos para seleccionar los campos
    'ya que permiten hacer múltiples comparaciones (24/Nov/95)
    nOpciones = 11
    Height = 1510 + (nOpciones * 430)

    'Cargar los nombres de los campos...
    With cboComparación(0)
        .Clear
        .AddItem "Like"
        .AddItem "Not Like"
        .AddItem "<"
        .AddItem ">"
        .AddItem "=<"
        .AddItem ">="
        .AddItem "="
        .AddItem "<>"
    End With
    
    CboCampos(0).AddItem "Ninguno"
    CboMostrar(0).AddItem "No Mostrar"
    For i = 0 To MaxCampos
        With Campos(i)
           CboCampos(0).AddItem .Nombre
           CboMostrar(0).AddItem .Nombre
        End With
    Next
    Text1(0).Text = ""
    
    CboCampos(0).Top = cboComparación(0).Top
    CboCampos(0).Visible = True
    CboMostrar(0).Top = cboComparación(0).Top
    CboMostrar(0).Visible = True
    For i = 1 To nOpciones
        Load cboComparación(i)
        Load Text1(i)
        Load CboCampos(i)
        Load CboMostrar(i)
        For j = 0 To cboComparación(0).ListCount - 1
            cboComparación(i).AddItem cboComparación(0).List(j)
        Next
        For j = 0 To CboCampos(0).ListCount - 1
            CboCampos(i).AddItem CboCampos(0).List(j)
            CboMostrar(i).AddItem CboMostrar(0).List(j)
        Next
        cboComparación(i).Top = cboComparación(i - 1).Top + cboComparación(i - 1).Height + 75
        cboComparación(i).Visible = True
        CboCampos(i).Top = cboComparación(i).Top
        CboCampos(i).Visible = True
        CboMostrar(i).Top = cboComparación(i).Top
        CboMostrar(i).Visible = True
        Text1(i).Top = cboComparación(i).Top
        Text1(i).Visible = True
        Text1(i).Text = ""
    Next
    'Poder recuperar la última consulta...
    For i = 0 To nOpciones
        sTmp = "OpCampo" & RTrim$(Str$(i))
        CboCampos(i).ListIndex = LeerIni(ficIni, "QBE_" & sUsuario, sTmp, 0)
        sTmp = "OpComparacion" & RTrim$(Str$(i))
        cboComparación(i).ListIndex = LeerIni(ficIni, "QBE_" & sUsuario, sTmp, 0)
        sTmp = "OpTexto" & RTrim$(Str$(i))
        Text1(i).Text = LeerIni(ficIni, "QBE_" & sUsuario, sTmp, "")
        sTmp = "OpMostrar" & RTrim$(Str$(i))
        CboMostrar(i).ListIndex = LeerIni(ficIni, "QBE_" & sUsuario, sTmp, 0)
    Next
    'Poner en orden las tabulaciones...
    For i = nOpciones To 0 Step -1
        CboCampos(i).TabIndex = 0
        Text1(i).TabIndex = 0
        cboComparación(i).TabIndex = 0
        CboMostrar(i).TabIndex = 0
    Next
    Command3.TabIndex = 0
    Command2.TabIndex = 0
    Command1.TabIndex = 0
    
    Command1.Top = ScaleHeight - 510
    Command2.Top = Command1.Top
    Command3.Top = Command1.Top
    Label1(4).Top = Command1.Top + 45

    Screen.MousePointer = vbDefault
End Sub

Private Sub GuardarQBE()
    Dim i As Integer
    Dim sValor As String
    Dim sTmp As String
    
    'Guardar la última consulta...
    
    For i = 0 To nOpciones
        sTmp = "OpCampo" & RTrim$(Str$(i))
        sValor = Str$(CboCampos(i).ListIndex)
        GuardarIni ficIni, "QBE_" & sUsuario, sTmp, sValor
        
        sTmp = "OpComparacion" & RTrim$(Str$(i))
        sValor = Str$(cboComparación(i).ListIndex)
        GuardarIni ficIni, "QBE_" & sUsuario, sTmp, sValor
        
        sTmp = "OpTexto" & RTrim$(Str$(i))
        sValor = Text1(i).Text
        GuardarIni ficIni, "QBE_" & sUsuario, sTmp, sValor
        
        sTmp = "OpMostrar" & RTrim$(Str$(i))
        sValor = Str$(CboMostrar(i).ListIndex)
        GuardarIni ficIni, "QBE_" & sUsuario, sTmp, sValor
    Next
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Set gsQBE = Nothing
End Sub

Private Sub Label1_Click(Index As Integer)
    Dim msg As String

    If Index = 4 Then
        msg = "CONSEJOS PARA USAR LA OPCIÓN DE BÚSQUEDA" & vbCrLf & vbCrLf
        msg = msg & "Selecciona los campos de búsqueda, la comparación, "
        msg = msg & "el texto a comparar y los campos que quieres mostrar." & vbCrLf
        msg = msg & "Por defecto se hace una búsqueda selectiva, es decir deben coincidir "
        msg = msg & "todos los campos especificados con la comparación que se hace." & vbCrLf
        msg = msg & "Aunque se puede hacer una búsqueda opcional, (no selectiva): "
        msg = msg & "no tienen porqué coincidir todos los campos, sino que se puede "
        msg = msg & "buscar por conceptos distintos, más abajo hay varios ejemplos." & vbCrLf
        msg = msg & "Las comparaciones que se pueden hacer son: " & vbCrLf
        msg = msg & "    LIKE   Igual" & vbCrLf
        msg = msg & "NOT LIKE   Distinto (no igual)" & vbCrLf
        msg = msg & "       >   Mayor" & vbCrLf
        msg = msg & "       <   Menor" & vbCrLf
        msg = msg & "      >=   Mayor o igual" & vbCrLf
        msg = msg & "      <=   Menor o igual" & vbCrLf
        msg = msg & "       =   Igual" & vbCrLf
        msg = msg & "      <>   Distinto" & vbCrLf
        msg = msg & "La diferencia entre 'LIKE'/'NOT LIKE' y '='/'<>' "
        msg = msg & "es que con los LIKE se pueden usar los comodines: * ? #" & vbCrLf
        msg = msg & "-- ? un caracter cualquiera" & vbCrLf
        msg = msg & "-- # un dígito (número)" & vbCrLf
        msg = msg & "-- * cualquier cantidad de caracteres" & vbCrLf
        msg = msg & "Ejemplos:" & vbCrLf
        msg = msg & "-- M* todos los registros que en el campo especificado, empiecen por M" & vbCrLf
        msg = msg & "-- *M* que tenga una M" & vbCrLf
        msg = msg & "-- A?C cualquier secuencia que empiece con A y termine con C: ABC, AAC, etc." & vbCrLf
        msg = msg & vbCrLf & "IMPORTANTE: Por defecto, para los campos de texto, lo que se escriba en la casilla "
        msg = msg & "del texto a buscar, se pone entre dos *, de esta forma se buscará "
        msg = msg & "cualquier registro que tenga ese texto escrito; por tanto el uso del "
        msg = msg & "comodín * no tiene actualmente ningún significado, en el futuro "
        msg = msg & "es posible que haya que expecificarlo, pero por ahora no es necesario." & vbCrLf & vbCrLf
        msg = msg & "En CONSULTA DIRECTA si se puede especificar este comodín, (más abajo se explica como usar la Consulta Directa)." & vbCrLf & vbCrLf
        msg = msg & "En una misma casilla de texto, se pueden especificar varias palabras, "
        msg = msg & "separando cada palabra con: " & vbCrLf
        msg = msg & "| (AltGr+1) o con [O]" & vbCrLf
        msg = msg & "Ejemplo: para buscar la palabra CASA o CHALET, escribiríamos: "
        msg = msg & "CASA|CHALET o bien CASA[O]CHALET" & vbCrLf
        msg = msg & "Veamos varios ejemplos:" & vbCrLf
        msg = msg & "Buscar las fechas iguales a 4/11/95 o 7/11/95" & vbCrLf
        msg = msg & " COMPARACIÓN       TEXTO" & vbCrLf
        msg = msg & "    =              04/11/95|07/11/95" & vbCrLf
        msg = msg & "Buscar las fechas mayores al 10/11/95" & vbCrLf
        msg = msg & "    >              10/11/95" & vbCrLf
        msg = msg & "Cuidado cuando se especifican varias comparaciones ya "
        msg = msg & "que puede que se pidan cosas imposibles:" & vbCrLf
        msg = msg & "Si estos dos ejemplos se especifican en la mísma "
        msg = msg & "búsqueda, no mostraría nada, ya que se le dice:" & vbCrLf
        msg = msg & "   Todas las fechas que sean iguales al 4 de nov" & vbCrLf
        msg = msg & "   'O' iguales al 7 de nov" & vbCrLf
        msg = msg & "   'Y' que sean mayores al 10 de nov" & vbCrLf
        msg = msg & "la verdad es que no se cumpliría esa comparación, "
        msg = msg & "ya que no puede ser igual al 4 nov y también mayor que el 10 nov." & vbCrLf
        msg = msg & "El error está en pensar que se haría de esta forma:" & vbCrLf
        msg = msg & "   Todas las fechas que sean iguales al 4 de nov" & vbCrLf
        msg = msg & "   'O' iguales al 7 de nov" & vbCrLf
        msg = msg & "   'Y' LAS que sean mayores al 10 de nov" & vbCrLf & vbCrLf
        msg = msg & "Es importante tener en cuenta, como apunté al principio, que siempre que se "
        msg = msg & "comparan varios campos (o uno en distintas "
        msg = msg & "líneas) se hace un 'Y', es decir que se tienen que "
        msg = msg & "cumplir todas las comparaciones, (comparación selectiva)." & vbCrLf
        msg = msg & "Para cambiar el 'Y'  por un 'O' (comparación opcional), "
        msg = msg & "escribir [O] en el campo anterior al que se quiere aplicar." & vbCrLf
        msg = msg & "En el ejemplo anterior, escribiríamos en el primer campo:" & vbCrLf
        msg = msg & " COMPARACIÓN       TEXTO" & vbCrLf
        msg = msg & " =                 [O]04/11/95|07/11/95" & vbCrLf
        msg = msg & "en el segundo:" & vbCrLf
        msg = msg & " >                 10/11/95" & vbCrLf
        msg = msg & "Se mostrarían todas las fechas:" & vbCrLf
        msg = msg & "   iguales al  4 nov" & vbCrLf
        msg = msg & "   'O' igual al  7 nov" & vbCrLf
        msg = msg & "   'O' mayor al 10 nov" & vbCrLf
        msg = msg & "NOTA: Cuando se usan fechas, hay que tener en cuenta el formato usado, es decir si se deben especificar o no los ceros delante de los números. Por regla general, deben especificarse." & vbCrLf
        msg = msg & "En caso de textos:" & vbCrLf
        msg = msg & "Buscar todos los JUAN 'O' los que viven en NERJA" & vbCrLf
        msg = msg & "  CAMPO          COMPARACIÓN     TEXTO" & vbCrLf
        msg = msg & "  Nombre         Like            [O]Juan" & vbCrLf
        msg = msg & "  Población      Like            Nerja" & vbCrLf & vbCrLf
        msg = msg & "COMO USAR LA CONSULTA DIRECTA:" & vbCrLf
        msg = msg & "En la consulta directa se debe especificar el o los campos a comparar y la comparación a realizar: " & vbCrLf
        msg = msg & "Para eso es necesario saber como se llama el campo que se quiere comparar, "
        msg = msg & "la lista de los nombres de los campos sale en la ventana de la opción de configuración, "
        msg = msg & "por defecto las etiquetas informativas de la pantalla principal o las listas de los nombres "
        msg = msg & "de los campos que aparecen en esta opción de búsqueda, son los nombres de "
        msg = msg & "los campos, salvo que se hayan cambiado con la opción de Configuración." & vbCrLf
        msg = msg & "En la consulta directa no se permite usar | ni [O]" & vbCrLf
        msg = msg & "Ejemplo: Buscar todos los JUAN 'O' los que viven en NERJA" & vbCrLf
        msg = msg & "Se hará de esta forma:" & vbCrLf
        msg = msg & "Nombre LIKE '*Juan*' OR [Población] LIKE '*Nerja*'" & vbCrLf
        msg = msg & "Para buscar todos los registros que en el campo Nombre tengan Juan "
        msg = msg & "y la Fecha sea superior al 10/11/95:" & vbCrLf
        msg = msg & "Nombre LIKE '*Juan*' OR Fecha > DATEVALUE('10/11/95')" & vbCrLf
        msg = msg & "Como se puede ver, la Consulta Directa es más complicada de usar y está "
        msg = msg & "sólo para usarla si se sabe lo que se quiere hacer o para especificar otras "
        msg = msg & "opciones que no están contempladas en la búsqueda normal." & vbCrLf
        msg = msg & "El lenguaje que se usa es SQL (Structured Query Lenguage) "
        msg = msg & "y la instrucción que se hace es:" & vbCrLf
        msg = msg & "SELECT * FROM " & sTabla & " WHERE <búsqueda> ORDER BY ID" & vbCrLf
        msg = msg & "<búsqueda> es el texto que se escribe." & vbCrLf
        msg = msg & "Los datos mostrados, serán los que se especifiquen en los campos a mostrar, al igual que en la consulta normal." & vbCrLf & vbCrLf
        msg = msg & "IMPORTANTE: En estas rutinas de búsqueda no se hace distinción entre mayúsculas y minúsculas."
        msg = msg & vbCrLf & vbCrLf & "[FIN DEL MENSAJE DE AYUDA]"
        
        If MsgConfirm(msg) Then
        End If
        msg = ""
    End If
End Sub

Private Sub ProcesarConsulta(sBuscar As String)
    Dim Db As Database
    
    Dim strCampos As String
    Dim SQLtmp As String
    Dim MySnap As Recordset
    Dim i As Integer
    Dim flag As Integer
    Dim j As Integer
    Dim k As Integer
    Dim sTmp As String
    Dim sTmp2 As String
    Dim q As Integer
    Dim p As Integer
    Dim sLogico As String
    Dim iLongCampo As Integer
    
    ReDim LongCampos(MaxCampos)

    On Local Error Resume Next

    Screen.MousePointer = vbHourglass

    'Abrir la base...
    Set Db = OpenDatabase(sBase)

    'Ejecutar orden SQL con los datos solicitados
    SQLtmp = "select * from " & sTabla & " where " & sBuscar & " order by ID"
    Set MySnap = Db.OpenRecordset(SQLtmp, dbOpenSnapshot)
    MySnap.MoveFirst
    If Err Then
        Err = 0
        'no hay datos, avisar
        MsgBox "No hay datos que coincidan con la búsqueda especificada.", 64
        cboComparación(0).SetFocus
        Screen.MousePointer = vbDefault
        Exit Sub
    End If
    Load MostrarConsulta
    MostrarConsulta!List1.Clear

    strCampos = ""
    'Añadir los nombres de los "campos" a mostrar
    For i = 0 To nOpciones
        k = CboMostrar(i).ListIndex
        If k >= 1 Then
            If Campos(k - 1).Tipo = dbLong Then
                LongCampos(k - 1) = 12
            ElseIf Campos(k - 1).Tipo = dbText Then
                LongCampos(k - 1) = Campos(k - 1).Tamaño
                If LongCampos(k - 1) > 30 Then
                    LongCampos(k - 1) = 30
                End If
            Else
                LongCampos(k - 1) = 8
            End If
            strCampos = strCampos & Left$(Trim$(Campos(k - 1).Nombre) & Space$(LongCampos(k - 1)), LongCampos(k - 1)) & ", "
        End If
    Next
    With MostrarConsulta
        .List1.AddItem strCampos
        .List1.ItemData(.List1.NewIndex) = -1
        .List1.AddItem String$(Len(strCampos), "-")
        .List1.ItemData(.List1.NewIndex) = -1
    End With
    flag = False
    MySnap.MoveFirst
    Do Until MySnap.EOF
        DoEvents
        strCampos = ""
        For i = 0 To nOpciones
            k = CboMostrar(i).ListIndex - 1
            If k >= 0 Then
                flag = True
                iLongCampo = LongCampos(k - 1)
                strCampos = strCampos & Left$(Trim$(MySnap(Campos(k - 1).Nombre) & " ") & Space$(iLongCampo), iLongCampo) & ", "
                If Err Then
                    strCampos = strCampos & Left$("¡¡¡ERROR!!!" & Space$(iLongCampo), iLongCampo) & ", "
                    Err = 0
                End If
            End If
        Next
        MostrarConsulta!List1.AddItem strCampos
        MostrarConsulta!List1.ItemData(MostrarConsulta!List1.NewIndex) = MySnap("ID")
        MySnap.MoveNext
    Loop
    If Not flag Then
        'no hay datos, avisar
        MsgBox "No hay datos que coincidan con la búsqueda especificada.", 64
        cboComparación(0).SetFocus
        Screen.MousePointer = vbDefault
        Exit Sub
    End If
    Screen.MousePointer = vbDefault
    Unload Me
End Sub

Ahora le toca el turno al form de mostrar los datos.

'---------------------------------------------------------------
' Para mostrar los datos de la consulta
'
'(c)Guillermo Som, 1994-97
'---------------------------------------------------------------
Option Explicit

Dim EstaImprimiendo As Integer
Dim CancelarImpresion As Integer

Private Sub CmdBuscar_Click()
    Hide
    gsQBE.Show vbModal
    If MostrarConsulta!Command1.Caption = "" Then
        Unload MostrarConsulta
    Else
        MostrarConsulta.Show
    End If
End Sub

Private Sub CmdEditar_Click()
    Dim registro As Long
    
    If List1.ListIndex < 0 Then 'No ha registro seleccionado
        MsgBox "Debes seleccionar de la lista el registro a mostrar.", 48
    Else
        registro = List1.ItemData(List1.ListIndex)
        If registro > 0 Then
            With elForm
                .Data1.Recordset.FindFirst "ID = " & registro
                If .Data1.Recordset.EOF Then
                    Beep
                    MsgBox "Ese registro no ha sido hallado " & registro
                    .Data1.Recordset.MoveFirst
                Else
                    .Show
                End If
            End With
            Unload Me
        End If
    End If
End Sub

Private Sub CmdImprimir_Click()
    Dim nFicSal As Integer
    Dim sLPT As String
    Dim i As Integer
    Dim j As Integer
    Dim sTmp As String
    Dim sImpresora As String
    Dim k As Integer
    Dim sngFS As Single
    Dim sFN As String
    
    On Local Error GoTo ErrorImprimiendo

    If EstaImprimiendo Then
        CancelarImpresion = True
        Command1.Enabled = True
        CmdBuscar.Enabled = True
        CmdImprimir.Caption = "Imprimir"
    Else
        '--- Para leer del Win.ini
        'sTmp = GetSetting("win.ini", "windows", "device", "")
        'sLPT = "LPT1"
        'sImpresora = "Impresora desconocida"
        'If Len(sTmp) Then
        '    i = InStr(sTmp, ",")
        '    If i Then
        '        sImpresora = Left$(sTmp, i - 1)
        '        sTmp = Mid$(sTmp, i + 1)
        '        'Quitar el nombre del controlador...
        '        i = InStr(sTmp, ",")
        '        If i Then
        '            sTmp = Mid$(sTmp, i + 1)
        '        End If
        '        i = InStr(sTmp, ":")
        '        If i Then
        '            sLPT = Left$(sTmp, i - 1)
        '        End If
        '    End If
        'End If
        '---
        sImpresora = Printer.DeviceName
        sLPT = Printer.Port
        If Right$(sLPT, 1) = ":" Then
            sLPT = Left$(sLPT, Len(sLPT) - 1)
        End If

        sTmp = "Para imprimir los datos en:" & Chr$(13) & sImpresora & " en " & sLPT & Chr$(13) & "Pulsa:" & Chr$(13)
        sTmp = sTmp & "Si: para usar el controlador de Windows." & Chr$(13)
        sTmp = sTmp & "No: para imprimir directamente, en letra pequeña." & Chr$(13)
        sTmp = sTmp & "Cancelar: para no imprimir."
        'Imprimir los datos...
        i = MsgBox(sTmp, 32 + 3, "Imprimir datos")
        EstaImprimiendo = True
        Command1.Enabled = False
        CmdBuscar.Enabled = False
        CmdImprimir.Caption = "Cancelar Impresión"
        sTmp = Caption
        k = List1.ListCount
        If i = 6 Then
            'Usar controlador de Windows
            sngFS = Printer.FontSize
            sFN = Printer.FontName
            If MsgBox("¿Quieres Imprimir con Courier New 9 puntos?", 4 + 32, "Imprimir") = 6 Then
                Printer.FontSize = 9
                Printer.FontName = "Courier New"
            End If
            Printer.Print ""
            Printer.Print ""
            For i = 0 To k - 1
                DoEvents
                If CancelarImpresion Then Exit For
                Caption = "Imprimiendo " & i + 1 & " de " & k
                Printer.Print Left$(List1.List(i), 132)
            Next
            Printer.EndDoc
            Printer.FontSize = sngFS
            Printer.FontName = sFN
        ElseIf i = 7 Then
            'Imprimir directamente...
            j = 0
            nFicSal = FreeFile
            Open sLPT For Output As nFicSal
            Print #nFicSal, Chr$(15);   'Letra pequeña
            For i = 0 To k - 1
                DoEvents
                If CancelarImpresion Then Exit For
                Caption = "Imprimiendo " & i + 1 & " de " & k
                Print #nFicSal, Left$(List1.List(i), 136)
                j = j + 1
                If j = 50 Then
                    Print #nFicSal, Chr$(12);
                    j = 0
                End If
            Next
            If j Then
                Print #nFicSal, Chr$(12);
            End If
            Print #nFicSal, Chr$(18);
            Close nFicSal
        End If
        Caption = sTmp
        EstaImprimiendo = False
        CancelarImpresion = False
        Command1.Enabled = True
        CmdBuscar.Enabled = True
        CmdImprimir.Caption = "Imprimir"
    End If
    Exit Sub
ErrorImprimiendo:
    MsgBox "Se ha producido el error" & Chr$(13) & Error$(Err) & Chr$(13) & "al intentar imprimir."
    Caption = sTmp
    EstaImprimiendo = False
    CancelarImpresion = False
    Command1.Enabled = True
    CmdBuscar.Enabled = True
    CmdImprimir.Caption = "Imprimir"
    Exit Sub

End Sub

Private Sub Command1_Click()
    Unload Me
End Sub

Private Sub Form_Activate()
    Const LB_SETHORIZONTALEXTENT = &H400 + 21
    Const NULO = &O0
    Dim ListhWnd
    Dim ListLen
    Dim iTmp
    Dim ScaleTmp As Integer

    'Mostrar el número de datos hallados
    Caption = "Resultado de la búsqueda: " & List1.ListCount - 4 & " datos"
    'Poner un scroll horizontal al ListBox
    ScaleTmp = ScaleMode
    ListhWnd = List1.hWnd
    ScaleMode = 3
    ListLen = 4000
    iTmp = SendMessage(ListhWnd, LB_SETHORIZONTALEXTENT, ListLen, NULO)
    ScaleMode = ScaleTmp
End Sub

Private Sub Form_Load()
    'Posicionarla en la parte superior izquierda
    Top = 0
    Left = 0

End Sub

Private Sub Form_Resize()
    If WindowState <> 1 Then
        Command1.Top = ScaleHeight - Command1.Height - 120
        CmdImprimir.Top = Command1.Top
        CmdBuscar.Top = Command1.Top
        cmdEditar.Top = Command1.Top
        List1.Move 90, 90, ScaleWidth - 180, Command1.Top - 180
    End If
End Sub

6.- Para Rematar.

Bueno, creo que ya está la cosa más lograda. Por supuesto hay que añadir al menú archivo la opción de consulta, si no se hace, ¿cómo vas a ejecutarla? La forma de llamar a esta ventana es la siguiente:

Private Sub mnuConsulta_Click()
    gsQBE.Show vbModal
    If MostrarConsulta!Command1.Caption = "" Then
        Unload MostrarConsulta
    Else
        MostrarConsulta.Show
    End If
End Sub

Ya está bien por hoy. Sigue atento a esta pantalla, para ver cuando es la próxima entrega...

Nos vemos. (...pronto espero.)


ir al índice