Usar DLast en formulario

Y decir que mis conocimientos de ACCESS son muy básicos.
Necesito comprobar un campo del último registro asociado a un cliente, todo ello desde un formulario y con el fin de "calcular" un control del mismo form.
Me explico:
- En el formulario, cuyos datos van a TABLA_A, necesito autocompletar un control con una u otra palabra ("Entrada" y "Salida"), pero para ello necesito consultar primero en la tabla si el último registro del cliente que tengo activado en el formulario, en el campo correspondiente (se llama TIPO) tiene una u otra, para autorrellenar con la contraria.
Me encontré con un pedazo de código por ahí, que no logro saber si está completo o no, ni mucho menos hacerlo funcionar:
If DLast("TIPO", "TABLA_A", "IDCLIENTE = " & Me.IDCLIENTE) = "Salida" Then
Me.TIPO = "Entrada"
Else
Me.TIPO = "Salida"
End If
Otra cosa, si logro hacerlo funcionar, podría colocarlo en el formulario, ¿en el evento DESPUÉS DE ACTUALIZAR del control IDCLIENTE por ejemplo?

3 Respuestas

Respuesta
1
¿Cómo sabes cual es al último registro asociado a ese cliente? ¿Es por un campo fecha y sería la última? O bien ¿tienes un contador?
Me cuentas.
Bueno, no sé muy bien como explicarme, te explico un poco más detallado:
Se trata de un "apartado" dentro de la bd dedicado a un pequeño control de horas de mis empleados.
Verás, hay 1 tabla, T_PICADAS, y un formulario, llamado PICADAS.
T_PICADAS contiene los campos siguientes:
ID (Autonumérico) 1, 2, 3, 4, 5, 6.....
CBARRAS (Texto) Mediante un lector de códigos de barras leo las tarjetas de los empleados, y aquí se almacena su identidad, o más bien, el valor que lo relaciona con la tabla EMPLEADOS.
FECHA (Fecha corta) Aquí se almacenan las fechas de las picadas con las tarjetas.
HORA (Hora corta) Aquí se almacenan las horas de las picadas con las tarjetas.
TIPO (Texto) Aquí indico si el movimiento se trata de una ENTRADA o una SALIDA. Este campo, en el formulario, es el que quiero tratar.
El formulario PICADAS tiene más o menos esta estructura:
Control ID: se autocompleta
Control CBARRAS: lo completo yo cuando leo las tarjetas de los empleados. Es el único control que está habilitado para introducir datos, lo demás es automático.
Control FECHA y control HORA: se completan después de actualizar CBARRAS con la función Now() y distintas máscaras para que deje solo fecha o solo hora.
Control TIPO: aquí está el problema. Necesito que, igual que FECHA y HORA, cuando se actualice el control CBARRAS este control se complete. Para ello tiene que evaluar, en la tabla T_PICADAS, el campo TIPO del último registro que haya con el CBARRAS igual al que acabo de introducir en el formulario. Si pone "ENTRADA" en la tabla quiero que ponga "SALIDA" en el formulario, y si es al revés pues lo contrario.
Para eso estaba intentando usar la función DLast() que dije al principio, aunque no sé si es lo adecuado.
Por lo tanto, respondiendo a tu pregunta, decirte que el CBARRAS del formulario, que va a la tabla T_PICADAS, está relacionado con el CBARRAS del empleado que sea en la tabla EMPLEADOS. Y con respecto al último registro, como precisamente marco la fecha y hora, creo que puedo decir que se sacaría cronológicamente (DLast() para esto igual no me sirve).
Supongo que el formulario es de entrada de datos y que los cuadros de texto se llaman igual que los campos de la tabla. En el cuadro de texto Tipo pondrías, en la acción Al recibir el enfoque ---> Procedimiento de Evento ---> Picas en el cuadrado de la derecha, el de los ... y pones:
Private Sub Tipo_GotFocus()
Dim db As Database
Dim rs As Recordset
Dim rs1 As Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("Select Max(Fecha) as MaxFecha, Max(Hora) as MaxHora From T_Picadas where cBarras='" & Form!CBarras.Value & "'")
Set rs1 = db.OpenRecordset("Select Tipo From T_Picadas where Fecha=cdate('" & rs!MaxFecha & "') and Hora=cdate('" & rs!MaxHora & "') and cBarras='" & Form!CBarras.Value & "'")
If rs1!Tipo = "Entrada" Then
Form!Tipo.Value = "Salida"
Else
Form!Tipo.Value = "Entrada"
End If
End Sub
Me cuentas.
Buenas Ángeles.
El código que me apuntas va más allá de mi "comprensión" dado mi nivel de conocimientos de VBA, pero me ha gustado mucho que me introduzcas en el tema de recorsets, nunca lo había tocado.
Decirte que ayer, tras mucho trastear la sintaxis de la función que puse en el primer post, conseguí hacer que el formulario hiciera lo que yo quería, buscar, evaluar y almacenar si es "Entrada" o "Salida". Todo ello usando la función DLast().
Bien, pero como en estos días de búsqueda he podido leer bastante acerca de dicha función, me he dado cuenta de que en ciertos foros se la considera una función poco práctica. Me surgen dudas respecto a ella porque no sé si eso de buscar POR cosa en el "último" registro según un criterio lo hace correctamente, no sé como lo hace y, francamente, si hago un control de asistencia y algo se me escapa me va a costar un tremendo trabajo repararlo.
Así que me he puesto, he duplicado la bd y he puesto a trabajar tu código.
Comparándolos, tras resolver un pequeño problema que me daba (ahora te contaré), me ha dado incluso la sensación de que el tuyo es más rápido.
Pero me genera dos problemas:
1º - Si el código de barras que marco aún no ha sido introducido por primera vez en la tabla T_PICADAS me genera el error '3464', "No coinciden los tipos de datos en la expresión de criterios".
2º - En mi DLast() famoso, yo había añadido más código, un DCount para evaluar si el código de barras existía en la tabla EMPLEADOS, con un msgbox y todo eso. Ese detalle en tú solución no se contemplaba, no por nada, sino porque ni yo mismo lo sabía cuando pregunté y es obvio que tampoco podías saberlo tú.
Aún así, si es solucionable, me fío más de ti que del DLast(), que oye, no le gusta a la gente demasiado.
He corregido el código porque teníamos un error, ya que no tiene porque ser la mayor fecha y la mayor hora en el mismo registros, por lo que hay que hacer un recordset más.
Por otro lado ya controla si exite el código o no. Para ello tendrás que poner el código que te mando en el cuadro de texto cBarras en la acción Al perder el enfoque.
Private Sub CBarras_LostFocus()
Dim db As Database
Dim rs As Recordset
Dim rs1 As Recordset
Dim rs2 As Recordset
Dim rs3 As Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("Select cBarras from T_Picadas where cBarras='" & Form!CBarras.Value & "'")
If rs.EOF = True Then
Form!Tipo.Value = "Entrada"
Else
    Set rs1 = db.OpenRecordset("Select Max(Fecha) as MaxFecha From T_Picadas where cBarras='" & Form!CBarras.Value & "'")
    Set rs2 = db.OpenRecordset("Select Max(Hora) as MaxHora From T_Picadas where Fecha=cdate('" & rs1!MaxFecha & "') and cBarras='" & Form!CBarras.Value & "'")
    Set rs3 = db.OpenRecordset("Select Tipo From T_Picadas where Fecha=cdate('" & rs1!MaxFecha & "') and Hora=cdate('" & rs2!MaxHora & "') and cBarras='" & Form!CBarras.Value & "'")
    If rs3!Tipo = "Entrada" Then
        Form!Tipo.Value = "Salida"
    Else
        Form!Tipo.Value = "Entrada"
    End If
End If
End Sub
Respecto de lo que me dices de la función DLast() pues tampoco lo se bien, a mi me gustan más los recordset que las funciones, creo que funcionan mejor, pero... ya sabes, cada maestrillo tiene su librillo.
Me cuentas.
Le añadí, antes de los recorsets, un IF con el DCount() que tenía antiguo para que compruebe antes de hacer nada si en la tabla EMPLEADOS está dado de alta ese código (siempre cabe la posibilidad de realizar una lectura errónea con el lector de códigos de barras).
Ese detallín y lo que tú me has enviado han solucionado perfectamente mi problema.
Ángeles, de nuevo muchas gracias, fantástica solución y atención.
Respuesta
1
La sentencia esta bien. Respecto lo de poner después de actualizar también lo podrías poner.
Respuesta
Si quieres pasarme tu bd para analizarle y ayudarte con tu problema
[email protected]
En version 2003

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas