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

Nota acerca de su sistema operativoEste artículo se aplica a un sistema operativo distinto al que usa. El contenido del artículo que puede que no sea importante para usted, se deshabilitará
Este artículo se publicó anteriormente con el número E10612
Expandir todo | Contraer todo

Resumen



En 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ón



Este 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:
  • Microsoft Access 2.0 Standard Edition
  • Microsoft Access 95 Standard Edition
Palabras clave: 
access dinamic query KB550662
Retired KB ArticleRenuncia a responsabilidad de los contenidos de la KB sobre productos a los que ya no se ofrece asistencia alguna
El presente artículo se escribió para productos para los que Microsoft ya no ofrece soporte técnico. Por tanto, el presente artículo se ofrece "tal cual" y no será actualizado.