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.
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:

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

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.)