La página Web de Emilio Sancha - MVP 2006/11
La página Web de Emilio Sancha

Inicio    |   Access    |   Excel    |    Visual Script    |   Enlaces    |   Búsquedas    |   Apuntes    |   Libro de Visitas

Suscripcion RSS

Publicado el 14/10/2006 en el foro de Access y VBA http://www.mvp-access.com/foro/forum_posts.asp?TID=30586
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.

'*******************************************************************************
'* BuildCriteria
'* reemplaza a la función BuildCriteria original, "salvando" los inconvenientes
'* que esta presenta con ciertos caracteres, y, o, (, ), . &
'* he respetado el nombre y formato originales con objeto de que sea totalmente
'* transparente al usuario
'* Argumentos: strCampo => Nombre del campo
'*                   dbTipo => tipo de campo
'*                   strExpresion => Criterio que debe cumplirse
'* uso: strCadena = BuildCriteria("NombreCompañía", dbText, "=" & rst!NombreCompañía)
'* ESH 11/11/06 18:09
'*******************************************************************************
Public Function BuildCriteria(strCampo As String, dbTipo As DataTypeEnum, strExpresion As String) As String
Debug.Print strExpresion & vbTab,
' reemplazo los distintos caracteres "sensibles" por otros poco usuales
' en el caso de las conjunciones copulativas "o" e "y" lo hago con caracteres en blanco para así no hacerlo dentro de palabras
strExpresion = Replace(strExpresion, " y ", " " & Chr(138) & " ") ' y
strExpresion = Replace(strExpresion, " o ", " " & Chr(254) & " ") ' o
strExpresion = Replace(strExpresion, ")", Chr(221)) ' )
strExpresion = Replace(strExpresion, "(", Chr(240)) ' (
strExpresion = Replace(strExpresion, ".", Chr(245)) ' .
strExpresion = Replace(strExpresion, "&", Chr(126)) ' &
' construyo la cadena criterio sin caracteres "sensibles"
strExpresion = Application.BuildCriteria(strCampo, dbTipo, "=" & strExpresion)
' restituyo los caracteres originales
strExpresion = Replace(strExpresion, " " & Chr(138) & " ", " y ") ' y
strExpresion = Replace(strExpresion, " " & Chr(254) & " ", " o ") ' o
strExpresion = Replace(strExpresion, Chr(221), ")") ' )
strExpresion = Replace(strExpresion, Chr(240), "(") ' (
strExpresion = Replace(strExpresion, Chr(245), ".") ' .
strExpresion = Replace(strExpresion, Chr(126), "&") ' &
' devuelvo el resultado
BuildCriteria = strExpresion
End Function ' BuildCriteria

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.

'*******************************************************************************
'* BuildCriteria
'* permite reemplazar la función BuildCriteria original, "salvando" los
'* inconvenientes que esta presenta con ciertos caracteres, y, o, (, ), . &
'* he respetado el nombre y formato originales con objeto de que sea totalmente
'* transparente al usuario
'* Argumentos: strCampo => Nombre del campo
'*                   dbTipo => tipo de campo
'*                   strExpresion => Criterio que debe cumplirse
'*                   blnClasica => (opcional True) utiliza directamente la función
'*                                      original o no (por defecto si)
'* uso: strCadena = BuildCriteria("Campo", dbText, "=" & "Juan y Pedro")
'* devuelve Campo="Juan" And Campo="Pedro"
'* strCadena = BuildCriteria("Campo", dbText, "=" & "Juan y Pedro", False)
'* devuelve Campo="=Juan y Pedro"
'* http://www.mvp-access.es/emilio/
'* Si utilizas este código, respeta la autoría y los créditos
'* ESH 12/11/06 18:51
'*******************************************************************************
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
' devuelvo el resultado
BuildCriteria = strExpresion
End Function ' BuildCriteria

Aquí tenéis un magnifico articulo de Chea a este respecto http://jbengoechea.com/ConstruyeCriterio.htm

 


  • NOTA: La información contenida en esta página, así como el código fuente incluido en la misma, se proporciona TAL CUAL, sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo explicado, recomendado o sugerido en la presenta página.

    This page is provided AS IS with no warranties, and confers no rights. You assume all risk for your use.

    Ultima actualización:  Sábado, 15 de Octubre de 2016
    © Emilio Sancha 2.004-2.016