** NORMAS DEL FORO **
Inicio del foro Inicio del foro > Access y VBA > Access y VBA
  Mensajes nuevos Mensajes nuevos RSS - Validar registro
  Preguntas frecuentes Preguntas frecuentes  Buscar en el foro   Eventos   Registro Registro  Iniciar sesion Iniciar sesion

Tema cerradoValidar registro

 Responder Responder
Autor
Mensaje
maserrano Ver desplegable
Colaborador
Colaborador


Unido: 02/Abril/2014
Localización: España
Estado: Sin conexión
Puntos: 683
Enlace directo a este mensaje Tema: Validar registro
    Enviado: 27/Noviembre/2019 a las 13:00
Buenos días.
Sé, de antemano, que sobre el tema propuesto hay mucha literatura y muchos ejemplos, pero, no obstante planteo la siguiente duda.

Se trata de validar un campo y que muestre un aviso de que existe, de existir, y no haga el registro, o bien que te lleve a ese registro existente.

El problema lo planteo al ser un campo calculado el que se tiene que comprobar. Este campo se forma con los dos campos anteriores (de tipo texto corto) y no se forma lógicamente hasta que no se ha salido del segundo campo. No sé cómo se puede hacer esa comprobación para que diga que existe y vuelva al segundo de los campos para que introduzca una secuencia diferente.

La segunda posibilidad es renunciar al campo calculado y hacer un campo de texto (tipo texto corto) que venga calculado mediante un evento tipo AfterUpdate, con un Recordset que me coja los valores del campo 1 y 2 de una forma determinada. Hasta ese punto lo puedo hacer, pero después no puedo hacer que me verifique si ese registro ya existe y que entonces vuelva a preguntar por el campo 2.  

Más o menos sería algo así:

Private Sub valor2_AfterUpdate()

Dim Rst As Recordset, _
    Marcador As Variant
Set Rst = Me.RecordsetClone

Rst.FindFirst "Id= '" & Me.Id & "'"
If Not Rst.NoMatch Then
Me.Bookmark = Rst.Bookmark
Else
    Me!Id = Left(Me!valor1, 2) & "/" & Mid(Me!valor1, 3, 2) & "." & Mid(Me!valor1, 5, 3) & "-" & Right(Me!valor2, 3)
    DoCmd.RunCommand acCmdSelectRecord
End If

Rst.Close

End Sub

Pues se trata de eso, de si el campo Id existe, que no lo grabe y vuelva a pedir un nuevo valor del campo valor2.
Muchas gracias por adelantado.

Arriba
VIMIPAS Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 06/Enero/2006
Localización: ESPAÑA
Estado: Sin conexión
Puntos: 5462
Enlace directo a este mensaje Enviado: 27/Noviembre/2019 a las 23:20
Hola buenas noches.

Tal vez con el evento de "Antes de actualizar" puedes comprobarlo:

Private Sub Texto5_BeforeUpdate(Cancel As Integer)

End Sub

En caso de que no corresponda, le dices Cancel=True y actúas en consecuencia, por ejemplo que no siga haciendo lo que debería hacer en el caso contrario.

Saludos.
Gracias
Arriba
maserrano Ver desplegable
Colaborador
Colaborador


Unido: 02/Abril/2014
Localización: España
Estado: Sin conexión
Puntos: 683
Enlace directo a este mensaje Enviado: 28/Noviembre/2019 a las 00:31
Buenas VIMIPAS.
Lo he probado y me da error.
Error 3022 en tiempo de ejecución. Los cambios solicitados en la tabla no se realizaron... valores duplicados...
Explico lo que hasta ahora tengo:

Una tabla (T1) con 4 campos:
Id (autonumérico) contador
V1 (texto corto) un valor alfanumeico
V2 (texto corto) otro valor alfanumeico
V3 (texto corto) Valor formado a partir de los otros dos. Propiedad sin duplicados

Un formulario F1 con tres cuadros:
C1 (valor V1)
C2 (valor V2)
C3 (valor V3, a partir de los anteriores
En C2 tengo el evento:

Private Sub C2_AfterUpdate()

Dim Rst As Recordset, _
    Marcador As Variant
Set Rst = Me.RecordsetClone

Rst.FindFirst "C3= '" & Me.C3 & "'"
If Not Rst.NoMatch Then
   Me.Undo
   Me.Bookmark = Rst.Bookmark
Else
    Me!C3 = Left(Me!C1, 2) & "/" & Mid(Me!C1, 3, 2) & "." & Mid(Me!C1, 5, 3) & "-" & Right(Me!C2, 3)
    DoCmd.RunCommand acCmdSelectRecord
End If

Rst.Close

End Sub

Este código me genera el valor V3 en el campo C3.

Para que no me genere un registro que ya existe, en el campo C3 pongo el evento antes de actualizar (colaboración de VIMIPAS, no sé si he podido meter algo la pata):

Private Sub C3_BeforeUpdate(Cancel As Integer)
 If (Not IsNull(DLookup("[C3]", _
        "T1", "[V3] ='" _
        & Me!C3 & "'"))) Then
        MsgBox "El registro ya existe"
        Cancel = True
        Me!C3.Undo
    End If
End Sub

..., pues no me hace nada y me da el error anterior. 
En la depuración me marca la línea:

DoCmd.RunCommand acCmdSelectRecord

..., con lo que creo que intenta grabarlo y no puede por las propiedades  del campo de no permitir duplicados y no haciendo caso al evento de antes de actualizar.

Ahora ando perdido, por si alguien ve algo y me puede ayudar. 
Gracias ante todo.


Editado por maserrano - 28/Noviembre/2019 a las 00:34
Arriba
guarracuco Ver desplegable
Moderador
Moderador


Unido: 24/Abril/2004
Localización: EEUU
Estado: Sin conexión
Puntos: 3239
Enlace directo a este mensaje Enviado: 28/Noviembre/2019 a las 05:40
Puedes controlar el error. Todo procedimiento debe llevar un tratamiento de errores

Private Sub C3_BeforeUpdate(Cancel As Integer)
On error goto lbl_error

 If (Not IsNull(DLookup("[C3]", _
        "T1", "[V3] ='" _
        & Me!C3 & "'"))) Then
        MsgBox "El registro ya existe"
        Cancel = True
        Me!C3.Undo
    End If

Lbl_exit:
Exit sub

lbl_error:
If err.number= 3022 then
   Cancel= true
Else
Msgbox err.description
End if
Resume lbl_exit
End Sub

Ojo:,escrito desde el dispositivo móvil




Editado por guarracuco - 28/Noviembre/2019 a las 05:41
Arriba
maserrano Ver desplegable
Colaborador
Colaborador


Unido: 02/Abril/2014
Localización: España
Estado: Sin conexión
Puntos: 683
Enlace directo a este mensaje Enviado: 28/Noviembre/2019 a las 08:03
Gracias guarracuco pero me sigue dando el mismo error.

Arriba
pitxiku Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 27/Septiembre/2017
Localización: En mi casa
Estado: Sin conexión
Puntos: 1510
Enlace directo a este mensaje Enviado: 28/Noviembre/2019 a las 14:58
Los eventos Antes y Después de Actualizar sólo se lanzan cuando es el usuario el que escribe en él control. Como al control C3 le asignas el valor mediante código VBA, nunca se lanzará su evento.

Tienes que usar él evento Antes de Actualizar de los otros controles.
Arriba
maserrano Ver desplegable
Colaborador
Colaborador


Unido: 02/Abril/2014
Localización: España
Estado: Sin conexión
Puntos: 683
Enlace directo a este mensaje Enviado: 28/Noviembre/2019 a las 15:55
No lo entiendo muy bien pitxiku;
El valor V3 en el campo C3 sí se genera y asigna, con el evento "Después de actualizar".
Lo que no hace es comprobar si existe y, de existir, borrarlo y pasar al campo anterior C2 otra vez para asignarle un nuevo valor distinto.
Eso, creo, es lo que me genera el error.
Me lo puede explicar con un poco más de detalle?
Gracias.
Arriba
pitxiku Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 27/Septiembre/2017
Localización: En mi casa
Estado: Sin conexión
Puntos: 1510
Enlace directo a este mensaje Enviado: 28/Noviembre/2019 a las 20:22
En él Antes de Actualizar de C3 estás comprobando si ese dato esta guardado. Pero ese evento no se va a lanzar nunca, porque él valor de C3 lo estás componiendo mediante código en él evento Después de Actualizar de C2.

Pero este evento tampoco tiene mucha importancia, porque él error aparece en él otro, que se lanza antes: una de las primeras cosas que haces es buscar un registro en base a los que hay en C3, pero en C3 NO hay nada porque todavía no has generado él valor.

En él evento Después de actualizar de C2 tienes que:

1. Generar él código y guardarlo en una variable (todavía no en C3).

2. Buscar en los registros en base a lo que hayas guardado en la variable.

3. Si no encuentras, asignas a C3 él valor de la variable

4. Si lo encuentras, cancelas cambios y te posiciona en él registro.

Editado por pitxiku - 28/Noviembre/2019 a las 20:23
Arriba
maserrano Ver desplegable
Colaborador
Colaborador


Unido: 02/Abril/2014
Localización: España
Estado: Sin conexión
Puntos: 683
Enlace directo a este mensaje Enviado: 28/Noviembre/2019 a las 20:46
Me pongo a ello y luego comento.
Gracias
Arriba
VIMIPAS Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 06/Enero/2006
Localización: ESPAÑA
Estado: Sin conexión
Puntos: 5462
Enlace directo a este mensaje Enviado: 28/Noviembre/2019 a las 22:27
Hola de nuevo.

Tal cual dice Pitxiku, tu primero elaboras el C3 en base a c1&c2, pero con VBA.

De que sirve poner un evento que no se va usar.... si ya lo has puesto con VBA, no salta el evento. Tan solo saltan los eventos, habitualmente, cuando se pulsa dentro del control que estemos, una tecla o se actúe en dicho control con el ratón..... nunca salta directamente con VBA.

Yo te puse dicho evento, pensando que tu entrabas con tus "manos" a dicho control y hacías algo en el, tecleando o con el ratón.

Saludos.
Gracias
Arriba
maserrano Ver desplegable
Colaborador
Colaborador


Unido: 02/Abril/2014
Localización: España
Estado: Sin conexión
Puntos: 683
Enlace directo a este mensaje Enviado: 28/Noviembre/2019 a las 23:44
Ok. Es perfecto. 
Gracias pitxiku; gracias VIMIPAS.
Realmente no sé si falta o sobra algo pero con el código que he puesto funciona de maravilla.

Private Sub C2_AfterUpdate()

Dim var As String
Dim Rst As Recordset, _
Marcador As Variant
Set Rst = Me.RecordsetClone

Me!C3 = Left(Me!C1, 2) & "/" & Mid(Me!C1, 3, 2) & "." & Mid(Me!C1, 5, 3) & "-" & Right(Me!C2, 3)
var = Me!C3
Rst.FindFirst "V3= '" & var & "'"

If Not Rst.NoMatch Then
   Me.Undo
   Me.Bookmark = Rst.Bookmark
   
End If

Rst.Close

If (Not IsNull(DLookup("[V3]", _
        "T1", "[V3] ='" _
        & var & "'"))) Then
        MsgBox "El registro ya existe"
        Cancel = True
        Me!C3.Undo

    Me.C3.Value = ""
    Me.C2.SetFocus
End If
    
End Sub


Muchas gracias de nuevo.
Arriba
maserrano Ver desplegable
Colaborador
Colaborador


Unido: 02/Abril/2014
Localización: España
Estado: Sin conexión
Puntos: 683
Enlace directo a este mensaje Enviado: 29/Noviembre/2019 a las 11:33
Vaya!
No me he dado cuenta, pero el código comete un fallito...
Cuando encuentra un valor que ya existe en la tabla, me cambia de registro y va a ese registro y borra el campo C3.
Debe permanecer en el nuevo registro creado, borrar el campo C3 y pasar el foco a C2 para renombrar a C3.

No sé cómo hacer que permanezca en el nuevo registro creado; ahora lo único que puedo hacer es eliminar del código:

Me.C3.Value = ""

porque me quita ese valor que ya estaba creado en tabla.

Realmente, he seguido al completo el consejo de pitxiku:
4. Si lo encuentras, cancelas cambios y te posiciona en él registro.

..., realmente no quiero posicionarme en el registro; sólo saber que existe y que me permita renombrar el valor de C2 (y así crear un C3 que no exista). En fin...

Alguna sugerencia ??


Editado por maserrano - 29/Noviembre/2019 a las 12:37
Arriba
pitxiku Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 27/Septiembre/2017
Localización: En mi casa
Estado: Sin conexión
Puntos: 1510
Enlace directo a este mensaje Enviado: 29/Noviembre/2019 a las 15:06
Desde tu primer código tienes esto:

If Not Rst.NoMatch Then
     Me.Bookmark = Rst.Bookmark

So no quieres posicionarte en un registro ya existente, para qué lo tienes?

Toma lápiz y papel, escribe a mano qué quieres que haga tu código, y luego crea él código en access, es mucho más sencillo.
Arriba
maserrano Ver desplegable
Colaborador
Colaborador


Unido: 02/Abril/2014
Localización: España
Estado: Sin conexión
Puntos: 683
Enlace directo a este mensaje Enviado: 30/Noviembre/2019 a las 01:09
Oído cocina.
Buen mensaje lo de pensar.
..., con quitarlo bastaba.
Salu2 y gracias.
Arriba
maserrano Ver desplegable
Colaborador
Colaborador


Unido: 02/Abril/2014
Localización: España
Estado: Sin conexión
Puntos: 683
Enlace directo a este mensaje Enviado: 01/Diciembre/2019 a las 00:47
Perdón no me di cuenta de mencionar que el hilo se puede cerrar. 
Arriba
 Responder Responder
  Compartir tema   

Ir al foro Permisos de foro Ver desplegable