Id. de artículo: 550662 - Última revisión: martes, 03 de junio de 1997 - Versión: 1.0 Optimización de consultas: consultas dinámicas y DLOOKUP()
Este artículo se publicó anteriormente con el número E10612 ResumenEn este artículo se explica cómo optimizar las consultas en Microsoft Access, tanto a nivel de uso como a nivel de programación. Se darán pautas y consejos generales aplicables a todo tipo de consultas. Además, se comentará cómo crear consultas dinámicas a partir de datos introducidos en un formulario y el uso de la función DLookup(). La información de este artículo se aplica a Microsoft Access 2.0 y Microsoft Access 7.0. Más informaciónEste artículo asume que tiene tablas locales en vez de tablas vinculadas o adjuntas. Si sus tablas son adjuntas o vinculadas, esta información sí se puede aplicar. OPTIMIZADOR DE CONSULTAS ------------------------ El motor de bases de datos Jet de Microsoft contiene varios componentes, pero el más importante para consultas (y el más complejo) es el Optimizador. El Optimizador está "basado en coste", es decir, asigna un coste de tiempo para cada tarea de la consulta, y entonces elige la lista de tareas para llevar a cabo de menor coste que genere el resultado que se quiere conseguir. Cuanto más tarda una tarea en ejecutarse, mayor es el coste que tiene. Para decidir qué estrategia de consultas utilizar, el Optimizador utiliza estadísticas. Estas estadísticas están basadas en el número de registros en una tabla, si hay o no índices, si los índices son únicos, etc. Basándose en estas estadísticas, el Optimizador selecciona la mejor estrategia interna para ocuparse de esa determinada consulta. Las estadísticas se actualizan cada vez que se compila la consulta. Una consulta puede tener dos estados, compilada o no compilada. Una consulta está compilada cuando se ha ejecutado por primera vez, mientras que si modificamos una consulta o las tablas subyacentes y no la ejecutamos, quedará como no compilada lo cual penalizará el rendimiento. Si una consulta debe ser compilada, la compilación y actualización de las estadísticas se realiza la siguiente vez que se ejecuta la consulta. La compilación generalmente tarda de 1 a 4 segundos. Si añade un número significativo de registros a su base de datos, debe abrir y guardar sus consultas para recompilarlas. Por ejemplo, si diseña y revisa una consulta usando un conjunto pequeño de datos de ejemplo, debe recompilar la consulta después de que se hayan añadido más registros a la base de datos. Con esto se asegura que el rendimiento de la consulta será óptimo una vez que su aplicación esté en uso. NOTA: No se pueden ver los esquemas de optimización de la base de datos Jet ni tampoco especificar cómo optimizar una consulta. Sin embargo, puede utilizar el Documentador de bases de datos para ver si hay índices presentes y si los índices son únicos. El Documentador de bases de datos está en el comando Archivo Complementos. Para más información, busque en la ayuda "Documentador de bases de datos". CRONOMETRAJE DE CONSULTAS ------------------------- Hay dos medidas de tiempo significativas para una consulta de selección: el tiempo para presentar la primera pantalla de datos y el tiempo para obtener el primer registro. Si una consulta devuelve solamente una pantalla de datos, las dos medidas son iguales. Si una consulta devuelve muchos registros, entonces estos tiempos pueden ser muy diferentes. Si las dos medidas son iguales, cuando se muestra la hoja de datos de una consulta de selección verá una pantalla de datos y un número total de registros devuelto por la consulta por ejemplo "Registro 1 de N". Si es más rápido para el motor de bases de datos Jet presentar la primera pantalla de datos, entonces para completar la consulta y recuperar el último registro, verá una pantalla de datos pero no "N" en "Registro 1 de N". El valor "N" se dejará en blanco hasta que la consulta se haya completado o usted se mueva hasta el último registro. Este comportamiento es el resultado de la estrategia utilizada por el motor Jet: completar la consulta, y después presentar los datos; o presentar los datos, y a continuación completar la consulta. No se puede controlar qué estrategia se usa; sin embargo el motor Jet seleccionará aquella que sea más eficiente. ANALIZADOR DE RENDIMIENTO ------------------------- Si está usando Microsoft Access para Windows 95, puede utilizar el analizador de rendimiento para analizar las consultas de su base de datos. Como el análisis del rendimiento de las consultas está unido al motor de bases de datos Jet, el Analizador de rendimiento sugerirá añadir índices solamente cuando el motor Jet utilice realmente los índices para optimizar la consulta. Esto significa que el Analizador de Rendimiento puede proporcionar ideas más específicas para la base de datos sobre la que esté actuando que las sugerencias que se dan a continuación. Para ejecutar el Analizador de Rendimiento, seleccione el comando Herramientas Analizar y a continuación Rendimiento. CONSEJOS PARA MEJORAR EL RENDIMIENTO DE LAS CONSULTAS 1. Compacte la base de datos. Compactar la base de datos, puede aumentar la velocidad de las consultas ya que este proceso reorganiza los registros de una tabla para que éstos se sitúen en páginas contiguas de la base de datos, ordenados por la clave primaria de la tabla. Con esto se consigue mejorar el rendimiento al examinar secuencialmente los registros de una tabla, porque habrán de leerse el mínimo número de páginas de la base de datos para devolver todos los registros. También, compactando la base de datos, se añaden flags a todas las consultas que necesiten ser compiladas y regenera las estadísticas de la tabla utilizadas en el proceso de optimización de la consulta. Como las estadísticas se "cachean" en memoria, las estadísticas pueden llegar a no estar actualizadas. Por ejemplo, porque se haya hecho transacciones con RollBack o bien porque haya apagado la estación de trabajo sin haber cerrado previamente Access. 2. Cuando relacione tablas, intente indexar los campos de ambos lados de la relación. Esto aumenta la velocidad de ejecución de la consulta permitiendo al optimizador de consultas utilizar una estrategia de unión interna más sofisticada. 3. Si está utilizando criterios para restringir los valores de un campo que participa en la relación, verifique si la consulta se ejecuta más rápido con el criterio situado en el lado "uno" de la relación o en el lado "varios". En algunas consultas, se consigue mayor rapidez situando el criterio en el lado "uno" de la relación. 4. Indexe tantos campos como sea posible. Si una base de datos no se actualiza frecuentemente, entonces se debe situar un índice en todos los campos que se utilizan en una relación o en una restricción. Con la incorporación de la optimización de consultas con la tecnología Rushmore en el motor de bases de datos Jet versión 2.0 (y posterior), las consultas pueden aprovecharse de múltiples índices en una sola tabla. 5. Utilice consultas de creación de tablas para crear tablas a partir de resultados de consultas si sus datos no van a cambiar a menudo. Podrá crear formularios, informes u otras consultas basándose en estas nuevas tablas. 6. Intente construir sus consultas de forma que la tecnología Rushmore se pueda utilizar para ayudar a optimizarlas. Rushmore es una tecnología de acceso de datos que permite que puedan ser consultados conjuntos de registros eficientemente. Con Rushmore, cuando utilice ciertos tipos de expresiones en los criterios de la consulta, su consulta se ejecutará mucho más rápido. Rushmore no aumenta la velocidad de todas las consultas automáticamente. Debe construir las consultas de una cierta forma para la tecnología Rushmore pueda mejorarlas. Para más información sobre cómo aprovechar la tecnología Rushmore en Microsoft Access, busque en la ayuda "Rushmore, tecnología". 7. Utilice los operadores BETWEEN (ENTRE).... AND (Y), el IN (EN), y la igualdad (=) en columnas indexadas. 8. Vuelva a diseñar las consultas que utilicen NOT IN (NEGADO EN) porque es difícil optimizarlas. Por ejemplo, la siguiente consulta: SELECT Clientes.* FROM Clientes WHERE Clientes.[ID Cliente] NOT IN (SELECT [ID Empleado] FROM Pedidos); irá mucho más lenta que. SELECT Clientes.* FROM Clientes LEFT JOIN Pedidos ON Clientes.[ID Cliente]=Pedidos.[ID Cliente] WHERE ((Pedidos.[ID Cliente] Is Null)); NOTA: El asistente de consultas Buscar no-coincidentes utiliza la segunda sintaxis del ejemplo anterior. 9. Si usa el operador LIKE (COMO) con parámetros, intente concatenar el criterio de la consulta en código. Como el valor es desconocido en el momento en que la consulta se compila, los índices no se utilizarán. Para más información, consulte el apartado "Crear consultas mediante código" más adelante en este artículo. 10.Si está utilizando el operador LIKE (COMO) con un asterisco, utilice solamente un asterisco al final de la cadena de caracteres para asegurarse que se utiliza un índice. Por ejemplo, los siguientes criterios usan utilizan un índice: Like "Martín" Like "Mar*" Los siguientes criterios no utilizan un índice: Like "*sen* Like "*sen" 11.Cuando cree una consulta, añada solamente los campos que necesite. En campos utilizados para establecer criterios, no active la casilla Mostrar si no quiere presentar esos campos. 12.Evite, siempre que sea posible, restringir los criterios a campos calculados o campos no indexados. 13.Evite campos calculados en consultas anidadas. Si añade una consulta que contenga un campo calculado a otra consulta, la expresión del campo calculado puede disminuir el rendimiento de la consulta de "mayor nivel". En el siguiente ejemplo, la consulta Q1 se utiliza como entrada en la consulta Q2: Q1: SELECT SiInm([Campo]="H";"Hola";"Adios") AS X FROM MiTabla Q2:SELECT * FROM Q1 WHERE X="Hola"; Como la expresión SiInm en Q1 no se puede optimizar, Q2 tampoco se puede optimizar. Si una expresión se entierra demasiado en un árbol de consultas, se puede olvidar que está allí y como resultado conseguimos que la cadena entera de consulta no se pueda optimizar. Una forma mejor para escribir la consulta anterior es la siguiente: Q1: SELECT * FROM MiTabla WHERE Campo='H' Si una expresión es necesaria en la salida, intente situarla en un control de un formulario o informe. 14.Cuando agrupe registros por los valores de un campo que sea campo de unión de dos tablas, especifique Agrupar por el campo que está en la misma tabla que el campo sobre el que se está calculando el total. Por ejemplo, si su consulta hace un total de ventas por empleado, agrupe por el Id de Empleado de la tabla Ventas no por el Id de Empleado de la tabla Empleados. 15.Cuando sea posible, agrupe los menos campos posibles; como alternativa, utilice la función Primero() (First()) cuando sea apropiado. Por ejemplo, si su consulta está basada en las tablas Clientes y Pedidos, y está agrupando por ID de Cliente, Nombre Cliente, y Ciudad del Cliente, podría utilizar la función Primero() para Nombre Cliente y Ciudad del Cliente en vez de Agrupar por porque el valor será el mismo para todas las filas con el mismo ID de Cliente. 16.Si una consulta de totales, incluye una relación, intente agrupar los registros en una consulta y añadir esta consulta a una consulta separada que llevará a cabo la relación. Con esto se aumenta el rendimiento de algunas consultas. Por ejemplo, en vez de la consulta siguiente (puede utilizar la base de datos Neptuno.mdb para seguir este ejemplo): SELECT Clientes.[Nombre de compañía], Clientes.[Nombre del contacto], Max(Pedidos.[Fecha de pedido]) AS [Fecha Máxima Pedido] FROM Clientes INNER JOIN Pedidos ON Clientes.[ID de cliente] = Pedidos.[ID de cliente] GROUP BY Clientes.[Nombre de compañía], Clientes.[Nombre del contacto]; Divida la consulta en dos consultas separadas como sigue: Q1: SELECT PEDIDOS.[ID de Cliente],Max(Pedidos.[Fecha de pedido]) AS [Fecha máxima Pedido] FROM Pedidos GROUP BY Pedidos.[ID de Cliente] Q2: SELECT Clientes.[Nombre de compañía], Clientes.[Nombre del contacto], Q1.[Fecha máxima Pedido] FROM Q1 INNER JOIN Clientes ON Q1.[ID de cliente] = Clientes.[ID de cliente]; 17.Utilice COUNT(*) mejor que COUNT([Nombre de columna]) para determinar el número de registros en una tabla ya que existe una optimización especial en el motor de bases de datos Jet que permite que COUNT(*) se ejecute mucho más rápido en algunas situaciones que COUNT([Nombre de columna]). 18.Evite usar funciones de total, como Dlookup (Dbúsq) en una consulta para acceder a datos de una tabla. En vez de esto, añada la tabla a la consulta o bien cree una subconsulta. 19.Cuando defina un campo en una tabla, elija el tipo de datos apropiado más pequeño. Además, establezca para campos relacionados el mismo tipo de datos o bien tipos compatibles. 20.Procure ordenar por campos indexados. 21.En consultas de referencia cruzada, procure usar encabezados de columnas fijos siempre que sea posible. CREAR CONSULTAS MEDIANTE CaDIGO: CONSULTAS POR FORMULARIO (QBF) USANDO QueryDef dinámicos En este apartado se verá cómo usar un formulario para especificar los criterios para una consulta construida mediante una función de Access Basic (versión 2.0 de Access) o de Visual Basic para Aplicaciones (versión 7.0 de Access). Esta técnica es conocida con el nombre Consulta por formulario (QBF). Puede utilizar el método QBF para especificar los criterios de filtro para una consulta existente, pero este método puede llegar a ser complejo cuando añada más campos al formulario y por ejemplo, deje algún campo que participe en el filtro vacío. Un método QBE mucho más flexible es utilizar una función de Visual Basic para crear dinámicamente la instrucción SQL para la consulta; esta instrucción (la consulta), se borrará y se recreará cada vez que se ejecute la función. Este método no utiliza un campo de criterio vacío como parte de la condición WHERE de la consulta. Veamos un ejemplo para clarificar lo dicho anteriormente. Concatenar instrucciones SQL en Visual Basic o Access Basic requiere que se encierren los campos en caracteres especiales que van a indicar al motor Jet cuál es el tipo de datos del campo que se está utilizando: Tipo de campo Carácter especial --------------------------------- Texto Comilla simple (') Fecha Símbolo de número (#) Numérico Ninguno NOTA: En las siguientes instrucciones de ejemplo, el guión bajo (_) al final de la línea se utiliza únicamente como un carácter de continuación de línea. Quite el guión bajo del final de la línea y déjela en una sola cuando escriba el código. Texto: "SELECT * FROM [Pedidos] WHERE [Ciudad destinatario]=' " & _ [MiCriterio] &" ' ;" Fecha: "SELECT * FROM [Pedidos] WHERE [Fecha de pedido]=# " & _ [MiCriterio] & "# ;" Numérico: "SELECT * FROM [Pedidos] WHERE [ID de Empleado]="&_ [MiCriterio] & ";" Para crear una función de ejemplo usando la técnica QBF para presentar los registros que cumplan un criterio específico, siga lo siguientes pasos: 1. Abra la base de datos de ejemplo NEPTUNO.MDB (situada en el directorio Ejemplos de Access). Cree un nuevo formulario en blanco basado en la tabla Pedidos. 2. Añada seis cuadros de texto al formulario. Establezca la propiedad Nombre de cada cuadro de texto de la siguiente forma: Cuadro de texto 1: Nombre: ID de Cliente Cuadro de texto 2: Nombre: Ciudad destinatario Cuadro de texto 3: Nombre: País destinatario Cuadro de texto 4: Nombre: ID de empleado Cuadro de texto 5: Nombre: Fecha inicial de pedido Cuadro de texto 6: Nombre: Fecha final de pedido 3. Añada un botón de comando al formulario y establezca la propiedad Título del botón como sigue: Título: Ejecutar Consulta 4. Teclee el siguiente procedimiento para el evento AlHacerClic del botón (propiedad Al Hacer Clic) del botón: Para Access 2.0: NOTA: En el siguiente procedimiento, el guión bajo (_) al final de la línea se utiliza únicamente como un carácter de continuación de línea. Quite el guión bajo del final de la línea (y déjela en una sola cuando escriba el código o lo copie). Sub Ejecutar_consulta_Click () Dim db As Database Dim QD As QueryDef Dim MiWhere As Variant Set db = dbengine.workspaces(0).databases(0) ' Borra la ConsultaDinamica si ya existe. ' Se hace un control de error en caso de que la consulta ' no exista On Error Resume Next db.querydefs.Delete ("ConsultaDinamica") On Error GoTo 0 ' Fíjese en la comilla simple alrededor de los campos ' [Ciudad destinatario] e [ID de cliente]. ' Fíjese que no hay carácter especial alrededor ' del campo numérico [ID de Empleado] MiWhere = Null MiWhere = MiWhere & (" AND [País destinatario]= '" + _ Me![País destinatario] + "'") MiWhere = MiWhere & (" AND [ID de cliente]= '" + Me![id _ de cliente] + "'") MiWhere = MiWhere & (" AND [Id de empleado]= " + Me![id _ de empleado]) ' La siguiente sección evalúa la Ciudad destinatario que ' se introdujo. 'Si el primer o el último carácter del criterio es el ' asterisco (*) la función utiliza el operador "LIKE" in ' la instrucción SQL en vez de el igual (=). If Left(Me![Ciudad destinatario], 1) = "*" Or _ Right(Me![Ciudad destinatario], 1) = "*" Then MiWhere = MiWhere & (" AND [Ciudad destinatario] _ like '" + Me![Ciudad destinatario] + "'") Else MiWhere = MiWhere & (" AND [Ciudad destinatario] = _ '" + Me![Ciudad destinatario] + "'") End If ' Notar que los símbolos de número # rodean al campo de ' fecha [fecha de pedido]. If Not IsNull(Me![fecha de pedido final]) Thenç MiWhere = MiWhere & (" AND [fecha de pedido] between _ #" & Me![fecha de pedido inicial] + "# AND #" + _ Me![fecha de pedido final] + "#") Else MiWhere = MiWhere & (" AND [fecha de pedido] >= #" + _ Me![fecha de pedido inicial] + "#") End If ' Elimine el siguiente mensaje si no quiere visualizar la ' instrucción SQL MsgBox "Select * from orders " & (" WHERE " + _ Mid(MiWhere, 6) + ";") Set QD = db.CreateQueryDef("ConsultaDinamica", "Select * _ from Pedidos " & (" WHERE " + Mid(MiWhere, 6) + ";")) DoCmd OpenQuery "ConsultaDinamica" End Sub Para Access 7.0: Es prácticamente igual, simplemente cambian los nombres de los campos y el comando DoCmd. Private Sub Ejecutar_consulta_Click() Dim db As DATABASE Dim QD As QueryDef Dim MiWhere As Variant Set db = DBEngine.Workspaces(0).Databases(0) ' Borra la ConsultaDinamica si ya existe. ' Se hace un control de error en caso de que la consulta no ' exista On Error Resume Next db.QueryDefs.Delete ("ConsultaDinamica") On Error GoTo 0 ' Fíjese en la comilla simple alrededor de los campos ' [Ciudaddestinatario] e [IDcliente]. ' Fíjese que no hay carácter especial alrededor ' del campo numérico [IDEmpleado] MiWhere = Null MiWhere = MiWhere & (" AND [Paísdestinatario]= '" + Me![_ País destinatario] + "'") MiWhere = MiWhere & (" AND [IDcliente]= '" + Me![id de _ cliente] + "'") MiWhere = MiWhere & (" AND [Idempleado]= " + Me![id de _ empleado]) ' La siguiente sección evalúa la Ciudad destinatario que se ' introdujo. 'Si el primer o el último carácter del criterio es el ' asterisco (*) la función utiliza el operador "LIKE" in la ' instrucción SQL en vez de el igual (=). If Left(Me![Ciudad Destinatario], 1) = "*" Or _ Right(Me![Ciudad Destinatario], 1) = "*" Then MiWhere = MiWhere & (" AND [Ciudaddestinatario] _ like '" + Me![Ciudad Destinatario] + "'") Else MiWhere = MiWhere & (" AND [Ciudaddestinatario] = _ '" + Me![Ciudad Destinatario] + "'") End If ' Notar que los símbolos de número # rodean al campo de ' fecha [fechapedido]. If Not IsNull(Me![fecha de pedido final]) Then MiWhere = MiWhere & (" AND [fechapedido] between _ #" & Me![fecha de pedido inicial] + "# AND #" + _ Me![fecha de pedido final] + "#") Else MiWhere = MiWhere & (" AND [fechapedido] >= #" + _ Me![fecha de pedido inicial] + "#") End If ' Elimine el mensaje siguiente si no desea visualizar ' la instrucción SQL MsgBox "Select * from orders " & (" WHERE " + _ Mid(MiWhere, 6) + ";") Set QD = db.CreateQueryDef("ConsultaDinamica", "_ Select * from Pedidos " & (" WHERE " + Mid(_ MiWhere, 6) + ";")) DoCmd.OpenQuery "ConsultaDinamica" End Sub 5. Muestre el formulario en Modo presentación Formulario. 6. Para ejecutar la consulta, introduzca el siguiente criterio de ejemplo en los cuadros de edición: Ciudad destinatario: Madrid Id de Empleado: 1 Fecha de pedido inicial: 1/1/91 El método en este ejemplo tiene las siguientes características: - El operador AND se usa para evaluar el criterio en el cuadro de texto. Por ejemplo, si introduce "BONAP" en el cuadro ID de Cliente, y 1 en el cuadro ID de cliente. La consulta resultante presenta los registros en los que el [ID de Cliente]=BONAP Y [ID de Empleado]=1. - Si introduce un asterisco al principio o al final de un valor en el cuadro Ciudad destinatario, el asterisco se interpreta como un carácter comodín, y el operador LIKE se utiliza en la instrucción SQL. Por ejemplo, si introduce "Sea*" en el cuadro Ciudad destinatario, la consulta resultante presenta registros en los que la ciudad de destino es Seattle. - Después de que introduzca el criterio en el formulario y seleccione el botón de comando, la consulta se construye y se ejecuta. También podría usar esta función para imprimir un informe basado en la consulta. - Si no introduce ningún criterio, la consulta resultante presentará todos los registros. DLOOKUP() USO, EJEMPLOS Y SOLUCIaN A PROBLEMAS En este apartado se describe cómo utilizar la función Dlookup() (Dbúsq()). Se comentará la sintaxis de la función y su uso con distintos tipos de criterios. NOTA: A lo largo de este apartado hablaremos de la función Dlookup() en vez de Dbúsq() (nombre en castellano). Se pueden utilizar ambas excepto en módulos que siempre debe utilizarse Dlookup(). FUNCIaN DLOOKUP(): SINTAXIS Y USO --------------------------------- La función DLookup() se puede utilizar en una expresión o en una función definida por el usuario para devolver un valor de un campo en un dominio o bien un conjunto específico de registros. La sintaxis de la función DLookup() es la siguiente: DLookup(Expresión, Dominio [,Criterios]) La función tiene, por tanto, tres argumentos: la expresión, el dominio y el criterio (este último es opcional). - El argumento Expresión se utiliza para identificar el campo que contiene el dato en el dominio que se quiere devolver o se usa para llevar a cabo cálculos usando los datos de ese campo. - El argumento Dominio es el nombre del recordset que identifica el dominio. Puede ser el nombre de una tabla o una consulta. - El argumento Criterio el una expresión de cadena opcional que se usa para restringir el rango de datos sobre el que la función DLookup() está actuando. La función DLookup() devuelve un valor de un único campo incluso aunque más de un registro satisfaga el criterio. Si ningún registro satisface el criterio, o si el dominio no contiene ningún registro, la función DLookup() devuelve Nulo. DLOOKUP(): EJEMPLOS ------------------- Los siguientes ejemplos demuestran cómo usar la función DLookup() para encontrar o devolver valores de una tabla o consulta. Estos ejemplos se refieren a la base de datos de ejemplo Neptuno.mdb y se pueden introducir en la propiedad Origen del control de un cuadro de texto en un formulario o informe. NOTA: En los siguientes ejemplos, el guión bajo (_) al final de la línea se utiliza únicamente como un carácter de continuación de línea. Quite el guión bajo del final de la línea (y déjela en una sola cuando escriba el código o lo copie). 1. Uso de la función sin criterios: Este ejemplo demuestra cómo utilizar la función DLookup() sin especificar ningún criterio. Este ejemplo devuelve el valor contenido en el campo Apellidos del primer registro de la tabla Empleados: =DLookup("[Apellidos]";"Empleados") NOTA: Verifique el separador de lista que tenga configurado en Windows; si tienen configurado el punto y coma, debe usar la sintaxis anterior excepto en módulos que deberá colocar siempre la coma como separador de argumentos. 2. Especificar criterios numéricos: Para encontrar el apellido del empleado con Id de empleado 7, especifique el criterio para limitar el rango de registros: =DLookup("[Apellido]";"Empleados";"[IDEmpleado]=7") NOTA: En Microsoft Access 2.0 el campo se llama [ID de Empleado]. 3. Especificar criterios numéricos que provienen de campos de formulario: Puede utilizar un parámetro en el criterio si no quiere especificar un valor constante en la expresión (como en el ejemplo de arriba). Los siguientes ejemplos indican cómo especificar criterios de otros campos del formulario actual. Puede introducir estos ejemplos en el formulario Pedidos de la base de datos Neptuno. =DLookup("[apellidos]";"Empleados";"[IDEmpleado]=form!_ [idEmpleado]") =DLookup("[apellidos]";"Empleados";"[IDEmpleado]=" _ & [IDEmpleado]) =DLookup("[apellidos]";"Empleados";"[IDEmpleado]=" & _ [Formularios]![Pedidos]![idEmpleado]) Los tres ejemplos de arriba producen el mismo resultado. En el primer ejemplo, form![idEmpleado] aparece entre las comillas del criterio. "Form" le dice a Microsoft Access que el control [idEmpleado] se encuentra en el formulario actual. Si se omitiera, Microsoft Access compararía IDEmpleado consigo mismo en la tabla Empleados y devolvería el primer registro de la tabla Empleados (es decir, el mismo resultado que si no se especificara ningún criterio). Esto es debido a que el primer registro de la tabla Empleados tiene un 1 en el campo IDEmpleado por lo tanto el argumento "[IDEmpleado]=[IDEmpleado]" se computaría como "1=1" y devolvería el apellido del primer registro. El criterio para los dos últimos ejemplos se hacen concatenando dos expresiones de cadena con el signo &. En el tercer ejemplo, el criterio termina con la referencia completa al campo del formulario. Cuando se evalúa el criterio, primero se evalúa las partes individuales del criterio y luego se concatenan. Si el valor actual en el campo [IDEmpleado] en el formulario Pedidos es 7 la expresión original del criterio: "[IDEmpleado]=" & [IDEmpleado] se evaluaría como "[IDEmpleado]=" & 7 que concatenado sería: "[IDEmpleado] = 7" Si no especifica la referencia completa al formulario, como en el caso del ejemplo anterior, Microsoft Access asume que se trata del formulario actual. El siguiente ejemplo se deriva del tercer ejemplo anterior: =DLookup("[apellidos]";"Empleados";"[IDEmpleado]= _ [Formularios]![Pedidos]![idEmpleado]") En este caso, la referencia completa al formulario se incluye dentro de las comillas. En este caso, Microsoft Access busca correctamente el valor cuando el formulario se abre por primera vez, pero solamente se actualiza cuando se cambia de registro o se añade uno nuevo. Si se cambia el valor del [IDEmpleado] del registro activo, Microsoft Access no recalculará automáticamente el valor del campo. Puede recalcular manualmente el campo pulsando la tecla F9. Si quiere que el campo se actualice automáticamente cuando cambie el criterio, utilice cualquiera de los tres métodos de concatenación anteriores. Fíjese que en este caso, aparecerá #Error en el campo si no introduce ningún valor en el campo [IDEmpleado]. 4. Especificar criterios de texto: Si los campos para el criterio son de texto, debe poner este texto entre comillas simples tal y como se muestra en el siguiente ejemplo: =DLookup("Tratamiento";"Empleados";"[Apellidos]='Callahan' ") Puede utilizar dobles comillas en vez de la comilla simple pero es preferible la comilla simple. Utilice dobles comillas para reemplazar una comilla simple. El siguiente ejemplo utiliza dobles comillas y es equivalente al ejemplo de arriba: =DLookup("Tratamiento";"Empleados";[Apellidos]="Callahan" _ " ") 5. Especificar criterios de texto que provienen del campo de un formulario: El siguiente ejemplo demuestra cómo encontrar el nombre de un contacto de un cliente en el formulario Pedidos de Neptuno. El campo IDCliente es un campo de texto clave para el criterio, por lo tanto al instrucción DLookup() es: =DBúsq("[NombreContacto]";"Clientes";"[IDCliente]=' " _ & [IDCliente] & " ' ") o bien: =DBúsq("[NombreContacto]";"Clientes";"[IDCliente]=' " _ & Forms![Pedidos]![IDCliente] & " ' ") El criterio, por tanto, se construye concatenando tres cadenas, la primera es "[IDCliente]=' ", la segunda es el valor contenido en el campo [IDCliente] del registro actual del formulario y la tercera es " ' ", es decir, una comilla simple entre comillas. 6. Especificar criterios de fecha: Si el campo del criterio son valores de fecha u hora, hay que encerrar el valor entre el símbolo de número (#). Para encontrar un empleado cuyo cumpleaños sea una fecha dada, utilice el siguiente criterio: =DLookup("[Apellido]";"Empleados";"[FechaNacimiento]= _ #27/1/66#") Para tomar como criterio un campo de formulario sería igual a los ejemplos vistos anteriormente. 7. Especificar múltiples campos en un criterio: La expresión de un criterio puede ser cualquier cláusula WHERE válida de una instrucción SQL (sin la palabra clave WHERE). Por lo tanto, se pueden utilizar más de un campo como criterio en la función DLookup(). Por ejemplo, para encontrar el ID de Pedido para uno de los pedidos vendido por el empleado "Andrew Fuller", que tiene como ID de Empleado el 2 (Numérico), para el cliente "Simons Bistro", con un ID de Cliente SIMOB (texto), utilice la siguiente instrucción: =DLookup("[IDPedido]";"Pedidos"; _ "[IDCliente]= 'SIMOB' AND [IDEmpleado]=2") Esta instrucción devuelve el ID de pedido 10556 que es el primer ID de Pedido que cumple el criterio; el ID de Pedido 10669 también cumple el criterio. El ejemplo de arriba utiliza un código de empleado y un código de cliente específico. Aparte de utilizar campos de formulario para establecer criterios variables y que se recalculen en cada nuevo registro, puede también utilizar un procedimiento de Visual Basic para establecer criterios variables. 'Declaración de variables Dim ClienID As String Dim EmplID as String Dim Result ClienID="SIMOB" EmpID=2 Result=DLookup("[IDPedido]","Pedidod", _ "[IDCliente]='"& ClienID & "' AND [IDEmpleado]=" & EmpID) MsgBox Result Si la función DLookup() no encuentra ningún valor devolverá Nulo. Puede utilizar el siguiente ejemplo en un procedimiento para encontrar un empleado cuyo cumpleaños sea hoy: =DLookup("[Apellidos]","Empleados"; _ "month([fechanacimiento])=" & Month(Date) & "and _ Day([fechanacimiento])=" & Day(Date)) SOLUCIONAR PROBLEMAS CON DLOOKUP() ---------------------------------- Cuando la función DLookup() devuelva algún error o algún resultado inesperado, lo mejor es dividirla en componentes y analizarlos en la Ventana de Depuración. La ventana de depuración es una herramienta que le puede servir para depurar módulos de Access Basic o Visual Basic para aplicaciones. Puede utilizar la Ventana de depuración para testear y evaluar expresiones independientemente del formulario o macro donde vaya a ser utilizada la expresión. Puede escribir directamente expresiones en la Ventana de depuración y ver el resultado inmediatamente. El siguiente ejemplo demuestra una estrategia que puede utilizar para dividir una expresión DLookup() en componentes pequeños que puede examinar en la Ventana de depuración. Suponga que tiene dificultad con la siguiente expresión: =DLookup("[IDPedido]";"Pedidos"; "[IDCliente]=' "& _ Forms![MiFormulario]![IDCliente] &" ' AND [IDEmpleado]=" & _ Forms![MiFormulario]![IDEmpleado]) El criterio incluye dos campos, el primero de texto y el segundo numérico. Para estudiar esta expresión suponiendo que le falle intente lo siguiente: 1. Abra o cree un módulo. Del menú Ver, seleccione Ventana de depuración. 2. Escriba la función sin ningún criterio. Teclee la siguiente línea en la Ventana de depuración y pulse Enter: ?DLookup("[IdPedido]","Pedidos") Microsoft Access presentará el resultado en la siguiente línea. 3. Asegúrese de que la referencia a los datos del formulario es correcta. Teclee cada una de las siguientes líneas en la Ventana de depuración y pulse Intro: ?Forms![MiFormulario]![IDCliente] Y ?Forms![MiFormulario]![IDEmpleado] 4. Intente separar los criterios para verificar que independientemente funcionan tecleando lo siguiente en la Ventana de depuración: ?DLookup("[IDPedido]","Pedidos","[IDCliente]='SIMOB' ") Y ?DLookup("[IDPedido]","Pedidos","[IDEmpleado]=2 ") 5. Intente utilizar únicamente un campo del formulario. Para ello, teclee lo siguiente: ?=DLookup("[IDPedido]";"Pedidos"; "[IDCliente]=' "& _ Forms![MiFormulario]![IDCliente] &" ' ") ?=DLookup("[IDPedido]";"Pedidos"; "[IDEmpleado]= "& _ Forms![MiFormulario]![IDEmpleado]) PRECAUCIaN: CUALQUIER UTILIZACIaN POR SU PARTE DEL CaDIGO O MACRO INCLUIDO EN ESTE ART+CULO SE HAR¦ A SU CUENTA Y RIESGO. Microsoft facilita este código o macro "tal cual" sin garantía de ningún tipo, ya sea explícita o implícita, incluyendo expresamente en tal exención de responsabilidad y, a efectos meramente enunciativos y no limitativos, las garantías legales mercantiles implícitas y/o la adecuación a un propósito o finalidad en particular. La información de este artículo se refiere a:
| Otros Recursos Otros sitios de soporte
ComunidadesObtener ayuda ahora
|






















Volver al principio