Validación de campos de tabla dependiente

Como siempre agradeciéndoles el tiempo y conocimiento que comparten con los que no sabemos.

Tengo un problema que espero con su apoyo lo pueda resolver. Tengo una pequeña base de datos con las tablas que se ven en la imagen y con su relación.

Mi problema es que tengo un formulario con origen de control la tabla resultados y necesito que luego de seleccionar el id_intervalo y al ingresar el id_empleado verifique si el empleado pertenece a ese intervalo, si no es así me muestre un mensaje que diga que ese empleado no coincide con el intervalo seleccionado, si coinciden me permita guardarlo.

También necesito que verifique si el empleado ya fue registrado, si ya fue registrado me muestre un mensaje diciendo que ya fue ingresado anteriormente y no me permita registrarlo nuevamente.

En la imagen del formulario resultados ingreso el id_empleado numero 4 y dicho id no existe sin embargo no me muestra ningún mensaje, adicionalmente si ingreso un id que si existe me permite registrarlo varias veces, cosa que no debería de ser así.

Lo logré solucionar pero con Dfirst el problema es que Dfirst solo me permite campos tipo texto y yo necesito que los id sean numéricos.

He intentado con Dcount, le he dado mil vueltas pero no logro solucionarlo...

1 respuesta

Respuesta
2

Vamos por partes. Primero mira mi ventana de relaciones

Además, en tu ventana de relaciones la tabla Resultados no tiene Idempleado.

Por el hecho de que una tabla vaya a "usar" datos de otra no quiere decir que deban estar relacionadas. Si tu te subes a un taxi modelo Mercedes, lo estás usando, pero eso no quiere decir que debas tener una relación con el taxista, le pagas y adios, y mucho menos con la casa Mercedes.

En la tabla Detalles el único empleado que no repite ¿quincena? Es el 3, por eso en el formulario voy a elegirlo a él

Al aceptar el cursor se vuelve al control Idempleado para que lo cambies. El código del evento Antes de actualizar del combinado es

Private Sub IdEmpleado_BeforeUpdate(Cancel As Integer)
If Nz(DCount("*", "detalle", "idempleado=" & Me.IdEmpleado & " and idintervalo='" & Me.IdIntervalo & "'")) = 0 Then
MsgBox "Te digo que ese empleado no pertenece a ese intervalo", vbOKOnly + vbExclamation, "No te lo digo más"
DoCmd.CancelEvent
End If
End Sub

Por último, a partir de "también necesito..." no he entendido absolutamente nada.

¡Gracias! Julian con tu respuesta ya resolví la parte del problema con lo de los empleados e intervalos .

Efectivamente en la tabla Resultados no tengo idempleado, ese es un texto independiente que utilizo para nombrar al empleado que va a ser ingresado en resultatos (necesito que se haga con una caja de texto y en tu ejemplo lo haces con un cuadro combinado).  Teniendo el idintervalo y el idempleado me muestre automáticamente el iddetalle.

Dicho esto, no quiero que el iddetalle no se pueda volver ingresar ejemplo: 

la otra parte del problema es que puedo ingresar mas de una vez la misma información, entonces necesito que verifique si ya fue registradoy si ya fue ingresada antes  me muestre un mensaje diciendo que ya fue ingresado anteriormente y no me permita registrarlo nuevamente.

Espero hoy si me haya explicado bien

Al no saber como está construido el formulario es difícil dar una solución concreta, pero si el formulario Resultados depende de la tabla Resultados puedes hacer, al menos, dos cosas

1º Poner los campos IdIntervalo e IdDetalle como claves. Por lo que cuando sucediera(verás que el conjunto Idresultado e Iddetalle se repiten en el registro 3, te deja escribir, pero cuando fueras a guardar el registro

La otra forma, que creo que es la mejor, ¿para qué esperar a terminar el registro? No pongas los campos como clave y en el formulario, en el evento Antes de actualizar del cuadro de texto IdDetalle le pones

Private Sub IdDetalle_BeforeUpdate(Cancel As Integer)
If DCount("*", "resultados", "idintervalo='" & Me.IdIntervalo & "' and iddetalle=" & Me.IdDetalle & "") >= 1 Then
MsgBox " De eso nada, monada, no se pueden repetir", vbOKOnly + vbCritical, "No lo repito más"
DoCmd.CancelEvent
End If
End Sub

Y te pasaría esto

Al pulsar Enter después de poner 1 en IdDetalle

Y el cursor se vuelve a IdDetalle para que lo cambies.

Perfecto Julián, haz sido de mucha ayuda. Gracias a ti lo pude resolver.

Lo resolví creando una consulta con el idresultado, idintervalo, iddetalle, idempleado y en el formulario utilizo en el texto idempleado el código de las dos respuestas que me distes, solo que para evitar repetir  los datos guardados utilizo el código de tu segunda respuesta haciendo referencia a la consulta en vez de la tabla , pero tu respuesta era lo que necesitaba.

Ya con esto me doy por servido

Pero quiero aprovechar para consultarte algo mas: 

De la tabla detalles los registros 1 y  2  están relacionados con el intervalo 2020-07-01 y de la tabla detalles los registros 3, 4 y 5 están relacionados  con el intervalo 2020-07-02 

Quisiera saber si hay alguna manera de mostrar un mensaje donde  avise que en la tabla resultados el iddetalle numero 2 con intervalo 2020-07-01 no ha sido registrado aun y que el iddetalle numero 3 y 4 del intervalo 2020-07-02 aun no han sido registrados en la tabla resultados..

Entenderé si no se puede realizar

Se puede hacer casi de todo, lo que hay que saber es ¿cuándo pretendes que te avise? ¿Cuándo el control Idintervalo reciba al cursor? En ese caso, ¿como sabe el sistema que vas a escribir 2020-07-01 otra vez.

Se podría saber si, por ejemplo, en el evento Antes de actualizar del cuadro de texto IdIntervalo pones algo como, y suponiendo que tengas 3 empleados

dim i as byte

i=3 - Dcount("*","Resultado","idintervalo='" & me.idintervalo & "'")

msgbox"Ahora mismo hay " & i & " libres"

¡Gracias! Pero la cantidad de empleados no es tres,  de hecho puede variar por bajas o incorporaciones.

 Te comento que lo pensaba hacer con la fecha actual y la fecha de finalización del intervalo,  es decir que si la fecha actual es mayor que la fecha de finalización del intervalo me avisara que quedaron tantos registros de iddetalles sin registrar en resultados.

Donde yo he puesto 3 tu puedes poner

Dcount("*","empleados") y así esa cantidad siempre estará al día

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas