Tras unos días de
pelear con ello, investigar en el foro, las ñus de Microsoft y
tratarlo entre varios de nosotros he decidido publicar aquí mis
conclusiones por si a alguien le pueden ser útiles.
El método
BuildCriteria nos simplifica el proceso de construir las cláusulas
WHERE de nuestras sentencias SQL o de las funciones agregadas de
dominio, DLookup, DCount, DMax, etc
Copiado de la
ayuda de Access
---------------------------
El método BuildCriteria permite construir fácilmente criterios para
un filtro que se base en las entradas del usuario. Analiza el
argumento expresión de la misma forma que si la expresión hubiera
sido analizada si hubiera sido introducida en el modo Cuadrícula de
diseño de la consulta, Filtro por formulario o Filtro de servidor
por formulario.
---------------------------
Este método
resulta muy útil de cara a construir criterios de búsqueda
simplificándonos el trabajo al no tener que pararnos a pensar en el
tipo de datos que manejamos, por ejemplo todos sabemos que cuando
tratamos de construir un criterio con una variable real, debemos
convertir esta en una cadena y reemplazar la coma por el punto
decimal, ya que es el único que VBA reconoce como tal, mediante
BuildCritería es tan simple como
sngValor = 0.5
BuildCriteria("Campo", dbSingle, sngValor)
lo que nos devuelve Campo=0.5 (perfecto)
De igual
manera cuando buscamos por fechas resulta un poco pesado transformar
el formato de la fecha al mm/dd/yy de turno y añadir las dichosas
almohadillas, pues bien, si ponemos
BuildCriteria("Campo", dbDate, "Entre " & Date & " y " & Date-1)
que devolverá Campo Between
#11/13/2006# And #11/12/2006# (chachi)
Peeeero, no todo
podía ser perfecto, existe un problema inherente al propio diseño
del método y es que ciertas búsquedas en determinadas condiciones no
resultarían correctas, por ejemplo
supongamos que
tenemos una tabla con los siguientes registros
reg1: "Rei o Globo"
reg2: "Rei"
reg3: "Globo"
reg4: "Otra empresa"
Mediante
BuildCriteria("Campo", dbText, "=" & ElCampo) obtendríamos el
siguiente criterio Campo = "Rei" Or Campo = "Globo",
lo que nos devolvería los registros 2 y 3, cuando en condiciones
normales hubiéramos querido que nos devolviera el primero, para
resolver esto hay una solución propuesta por Marius que no es otra
que
BuildCriteria("Campo", dbText, """" & ElCampo & """" ) o tambien
BuildCriteria("Campo", dbText, Chr(34) & ElCampo & Chr(34) ) que nos devolverá el siguiente
criterio de búsqueda Campo = "Rei o Globo" y en
este caso si obtendríamos como resultado el registro 1.
Otro inconveniente
puede ser el que si la cadena a buscar contiene caracteres como,
apostrofe ('), ampersand (&) o paréntesis, ya sea de apertura o
cierre, el resultado sin BuildCriteria no será correcto y si lo será
con el.
Está fue mi primera
opción, simplificada a posteriori, pero que también pongo aquí para
dejar constancia.
Public
Function BuildCriteria(strCampo
As String, dbTipo
As DataTypeEnum, strExpresion
As String)
As String
Debug.Print
strExpresion & vbTab,
strExpresion =
Replace(strExpresion, " y ", " " & Chr(138) & " ")
strExpresion =
Replace(strExpresion, " o ", " " & Chr(254) & " ")
strExpresion =
Replace(strExpresion, ")", Chr(221))
strExpresion =
Replace(strExpresion, "(", Chr(240))
strExpresion =
Replace(strExpresion, ".", Chr(245))
strExpresion =
Replace(strExpresion, "&", Chr(126))
strExpresion =
Application.BuildCriteria(strCampo, dbTipo, "=" & strExpresion)
strExpresion =
Replace(strExpresion, " " & Chr(138) & " ", " y ")
strExpresion =
Replace(strExpresion, " " & Chr(254) & " ", " o ")
strExpresion =
Replace(strExpresion, Chr(221), ")")
strExpresion =
Replace(strExpresion, Chr(240), "(")
strExpresion =
Replace(strExpresion, Chr(245), ".")
strExpresion =
Replace(strExpresion, Chr(126), "&")
BuildCriteria = strExpresion
End
Function
Y esta es, por el
momento, la versión definitiva, que en principio debiera ser mas
rápida.
He tratado de resumir ambas situaciones en una función personalizada
que además fuera transparente al usuario y lo he conseguido, pero
solo a medias, solo funciona con igualdades, no podríamos utilizar
condiciones del tipo mayor que, Entre tal y cual, etc.
Public
Function BuildCriteria(strCampo As
String, dbTipo As
DataTypeEnum, strExpresion As String,
Optional blnClasica
As Boolean =
True) As String
If Not
blnClasica Then
strExpresion =
Application.BuildCriteria(strCampo, dbTipo, "=" & """" &
strExpresion & """")
Else
strExpresion =
Application.BuildCriteria(strCampo, dbTipo, "=" & strExpresion)
End If
BuildCriteria = strExpresion
End Function