Como comprar 6 cuadros de texto en un formulario
Tengo 6 cuadros de texto en un formulario independiente que guardan sus datos en 6 columnas diferentes de una tabla.
El control de valor repetido con respecto a la tabla ya lo tengo resuelto, me falta que compare con los 5 casillero restantes en el formulario al perder el foco o actualizar, si ese dato ya figura.
Es una seguridad mas para que el usuario no tenga que corroborar visualmente si ya ingreso ese numero de documento.
1 Respuesta
David: Para salir del paso, momentaneamente y en cada evento al perder el Foco, pones:
If Me.Txt01.Value = Me.Txt02 Or Me.Txt01.Value = Me.Txt03 Or Me.Txt01.Value = Me.Txt04 Or Me.Txt01.Value = Me.Txt05 Then
msgBox " El valor que acabas de Introducir está repetido",vbCritical,"VALOR EXISTENTE"
End If
Esto lo repites en el Resto, comparando con los otros que no son él mismo.
Miraré de prepararte algo más cientifico. Saludos >> Jacinto
David: He recordado que hace tiempo preparé un ejemplo de ésti tipo, que está en éste enlace:
http://www.mediafire.com/download/9tc3o78f7sb44f5/DuplicadoEnOtroCampo.rar
Mira el duplicado en el Formulario y en la Tabla, en los datos ya guardados. Mira si es de tu interés. Saludos >> Jacinto
revise tu ejemplo y antes que nada muchas gracias por tu respuesta.
es similar al mi método te muestro lo que estaba haciendo porque tengo otro problema con los duplicados en el formulario.
Private Sub TxtDocAcadE_AfterUpdate()
Dim elValor As String
Dim miSql As String
Dim i As Long
Dim losCampos(1 To 6) As String
Dim intx As Variant
elValor = Nz(Me.TxtDocAcadE.Value, "")
If elValor = "" Then Exit Sub
CurrentDb.Execute ("DELETE FROM TAux")
losCampos(1) = "DocAcadE"
losCampos(2) = "DocCAF"
losCampos(3) = "DocCPF"
losCampos(4) = "DocLM"
losCampos(5) = "DocIC"
losCampos(6) = "DocLL"
For i = 1 To 6
miSql = "INSERT INTO TAux (DocAcadEAux, DocCAFAux, DocCPFAux, DocLMAux, DocICAux, DocLLAux)" _
& "SELECT TDocumentos.DocAcadE, TDocumentos.DocCAF, TDocumentos.DocCPF, TDocumentos.DocLM, TDocumentos.DocIC," _
& " TDocumentos.DocLL FROM TDocumentos" _
& " WHERE TDocumentos.[" & losCampos(i) & "] LIKE '*" _
& elValor & "*'"
CurrentDb.Execute (miSql)
Next i
intx = DCount("*", "TAux")
If intx <> 0 Then
MsgBox "El Nº de documento ya existe", vbCritical, "VALOR EXISTENTE"
Me.TxtDocAcadE.Value = Null
Me.TxtID.SetFocus
Me.TxtDocAcadE.SetFocus
Else
If Me.TxtDocAcadE.Value = Me.TxtDocCAF Or Me.TxtDocAcadE.Value = Me.TxtDocCPF Or Me.TxtDocAcadE.Value = Me.TxtDocLM Or Me.TxtDocAcadE.Value = Me.TxtDocIC Or Me.TxtDocAcadE.Value = Me.TxtDocLL Then
MsgBox "El Nº de documento ya existe", vbCritical, "VALOR EXISTENTE"
Me.TxtDocAcadE.Value = Null
Me.TxtID.SetFocus
Me.TxtDocAcadE.SetFocus
End If
End If
End Sub
Tengo que aclarar que es muy probable que use tu código, si lo puedo adaptar ya que lo veo mas simplificado y nunca me gusto tener que involucrar una TAux como yo hice.
Hasta ahí funciona muy bien ingresando los datos 1 por 1 pero tengo un botón que genera automáticamente los 6 códigos, busca el mayor código de la tabla le suma uno y lo ingresa en la primera celda luego en cascada suma uno en las siguientes.
Cuando genero automáticamente y luego modifico alguno de los casilleros no me acusa el valor repetido en el formulario.
agrego el código de generación:
Private Sub cmdRenumera_Click()
CurrentDb.Execute ("DELETE FROM TGenerador")
DoCmd.OpenQuery "Consulta1"
DoCmd.OpenQuery "Consulta2"
miSql = ("SELECT Max FROM TGenerador")
Set rst = CurrentDb.OpenRecordset(miSql)
With rst
.MoveLast
Me.TxtMax.Value = Nz(rst("Max"))
End With
Me.TxtDocAcadE = Me.TxtMax + 1
Me.TxtDocCAF = Me.TxtDocAcadE + 1
Me.TxtDocCPF = Me.TxtDocCAF + 1
Me.TxtDocLM = Me.TxtDocCPF + 1
Me.TxtDocIC = Me.TxtDocLM + 1
Me.TxtDocLL = Me.TxtDocIC + 1
If Not rst Is Nothing Then
rst.Close
Set rst = Nothing
End If
End Sub
Muchas gracias por tu ayuda.
Por favor revisa la parte del generador de código que no me funciona la solución que me pasaste. ¿me estará faltando una actualización de datos?
David: Supongo que te refieres a mi primera recomendación.
Si es así, yo pondría el código en el Evento de BeforeUpdate, y no te olvides de activarlo en las Propiedades Eventos.
Private Sub Txt01_BeforeUpdate(Cancel As Integer)
If Me.Txt01.Value = Me.Txt02 Or Me.Txt01.Value = Me.Txt03 Or Me.Txt01.Value = Me.Txt04 Or Me.Txt01.Value = Me.Txt05 Or Me.Txt01.Value = Me.Txt06 Then
MsgBox " El valor que acabas de Introducir está repetido",vbCritical,"VALOR EXISTENTE"
Me. Txt01. Undo
DoCmd. CancelEvent
End If
End Sub
En tu caso el Txt01 seria segun veo el TxtDocAcadE
Evidentemente lo has de repetir en cada uno de los TextBox, cambiando los Nombres de sondeo.
Si no lo he interpretado bien me lo comentas por favor. Saludos > Jacinto
Jacinto sigue sin funcionar.
Este es el código en tu formato
'------------------------------------------------------------------------------------------------ 'Procedimiento Cmmprueba datos repetidos Documentos '------------------------------------------------------------------------------------------------ Private Sub TxtDocAcadE_BeforeUpdate(Cancel As Integer) 'Ejemplo desarrollado por JTrillo en Julio 2015 'Para la evaluación del Campo TxtDocAcadE con respecto a él mismo y a los 5 Restantes On Error GoTo TxtDocAcadE_BeforeUpdate_Err 'Con ésta Evaluación se coteja el Numero Introducido con los Almacenados en TDocumentos >> Falta hacerlo contra los TextBox If (Eval("DLookUp(""[DocAcadE]"",""[TDocumentos]"",""[DocAcadE] = Form.[TxtDocAcadE] "") Is Not Null")) Or (Eval("DLookUp(""[DocCAF]"",""[TDocumentos]"",""[DocCAF] = Form.[TxtDocAcadE] "") Is Not Null")) _ Or (Eval("DLookUp(""[DocCPF]"",""[TDocumentos]"",""[DocCPF] = Form.[TxtDocAcadE] "") Is Not Null")) Or (Eval("DLookUp(""[DocLM]"",""[TDocumentos]"",""[DocLM] = Form.[TxtDocAcadE] "") Is Not Null")) _ Or (Eval("DLookUp(""[DocIC]"",""[TDocumentos]"",""[DocIC] = Form.[TxtDocAcadE] "") Is Not Null")) Or (Eval("DLookUp(""[DocLL]"",""[TDocumentos]"",""[DocLL] = Form.[TxtDocAcadE] "") Is Not Null")) Then Beep MsgBox "El Nº de documento ya existe", vbCritical, "VALOR EXISTENTE" 'Vuelve al control TxtDocAcadE. Me.TxtDocAcadE.Undo DoCmd.CancelEvent Else 'Si no está repetido en los Campos ya Grabados puede estarlo en algun Cuadro de Texto sin guardar 'Si cambiamos un Número en un Cuadro de Texto, y mientras no se guarda cambiamos otro tenemos que detectarlo If Me.TxtDocAcadE.Value = Me.TxtDocLL.Value Or Me.TxtDocAcadE.Value = Me.TxtDocCAF.Value Or Me.TxtDocAcadE.Value = Me.TxtDocCPF.Value Or Me.TxtDocAcadE.Value = Me.TxtDocLM.Value Or Me.TxtDocAcadE.Value = Me.TxtDocIC.Value Then Beep MsgBox "El Nº de documento ya existe", vbCritical, "VALOR EXISTENTE" 'Vuelve al control TxtDocAcadE. Me.TxtDocAcadE.Undo DoCmd.CancelEvent End If End If TxtDocAcadE_BeforeUpdate_Exit: Exit Sub TxtDocAcadE_BeforeUpdate_Err: MsgBox error$ Resume TxtDocAcadE_BeforeUpdate_Exit End Sub
Funciona perfecto hasta que genero los códigos automáticos y quiero modificar solo uno de los generados , es como que el cuadro de texto no toma el valor que el generador le asigna .
'------------------------------------------------------------------------- 'Procedimiento para Generar códigos. '------------------------------------------------------------------------- Private Sub cmdRenumera_Click() CurrentDb.Execute ("DELETE FROM TGenerador") DoCmd.OpenQuery "Consulta1" DoCmd.OpenQuery "Consulta2" miSql = ("SELECT Max FROM TGenerador") Set rst = CurrentDb.OpenRecordset(miSql) With rst .MoveLast Me.TxtMax.Value = Nz(rst("Max")) End With Me.TxtDocAcadE.Value = Me.TxtMax.Value + 1 Me.TxtDocCAF.Value = Me.TxtDocAcadE.Value + 1 Me.TxtDocCPF.Value = Me.TxtDocCAF.Value + 1 Me.TxtDocLM.Value = Me.TxtDocCPF.Value + 1 Me.TxtDocIC.Value = Me.TxtDocLM.Value + 1 Me.TxtDocLL.Value = Me.TxtDocIC.Value + 1 If Not rst Is Nothing Then rst.Close Set rst = Nothing End If End Sub
"Consulta1" = busca el valor máximo en cada columna
"Consulta2" = evalúa cual es el valor máximo de los 6 obtenidos de la "Consulta1"
Aquí tampoco me gusta lo que realice pasando los datos a TGenerador pero soy novato en esto y no se me ocurrió otra cosa, si tiene un consejo o critica sera muy bien recibido.
Saludos, David.
David: Déjame mirarlo dedicándole un poco tiempo, porque la verdad es que te he ido comentando sobre la marcha.
Si no malentiendo lo que te ocurre es:
El Código del BeforeUpdate >> OK
El Código de Renumera >> OK
Me ayudaría saber lo que ocurre al modificar uno de los TextBox, si el valor coincide con otro:
A) No hace nada
B) Sale el error Numero ...
C) Sale el Mensaje...
D) Se queda to bloqueado... y .
Me comentas por favor y seguimos. Saludos >> Jacinto
Jacinto: tomate tu tiempo, yo puedo seguir trabajando en otra sección de la BD.
Ocurre la opción A, una prueba que realice es la siguiente.
genero los códigos Aut. y los casilleros muestran estos valores
txt1: 200 / txt2: 201 / txt3: 202 / txt4: 203 / txt5: 204 / txt5: 205
Luego modifico por ejemplo el txt5: 205 => 201 y no hace nada, lo toma como correcto y no acusa error, pero si yo después de apretar el botón de generación de código paso por los cuadros tipeando el mismo numero que se genero osea:
txt1: 200 / txt2: 201 / txt3: 202 / txt4: 203 / txt5: 204 / txt5: 205
y realizo nuevamente el cambio txt5: 205 => 201 si funciona correctamente acusando el error y funciona con todos los casilleros.
Por eso te comentaba que parece que debería actualizar algo después de generar los códigos pero no se que.
Saludos, David.
David: Prueba sustituyendo el código de Renumerar por éste otro>>
Private Sub cmdRenumera_Click() Dim I As Integer, MaxIndex As Integer Dim Max1 As Long, Max2 As Long, Max3 As Long, Max4 As Long, Max5 As Long, Max6 As Long, MaxActual As Long Max1 = DMax("[DocAcadE]", "TDocumentos") Max2 = DMax("[DocCAF]", "TDocumentos") Max3 = DMax("[DocCPF]", "TDocumentos") Max4 = DMax("[DocLM]", "TDocumentos") Max5 = DMax("[DocIC]", "TDocumentos") Max6 = DMax("[DocLL]", "TDocumentos") 'Declaramos la Matriz de Maximos, con los valores Obtenidos Dim MatrizMaximos As Variant MatrizMaximos = Array(Max1, Max2, Max3, Max4, Max5, Max6) MaxIndex = 0 'De aquí sacamos el Valor Máximo de los Maximos For I = 1 To UBound(MatrizMaximos) 'suponemos indice desde 0 a n If MatrizMaximos(I) > MatrizMaximos(MaxIndex) Then MaxIndex = I End If Next MaxActual = MatrizMaximos(MaxIndex) 'Y ahora llenamos los TextBox Me.TxtDocAcadE.Value = MaxActual + 1 Me.TxtDocCAF.Value = MaxActual + 2 Me.TxtDocCPF.Value = MaxActual + 3 Me.TxtDocLM.Value = MaxActual + 4 Me.TxtDocIC.Value = MaxActual + 5 Me.TxtDocLL.Value = MaxActual + 6 'Por si acaso Me.Refresh End Sub
Ya me contarás. saludos >> Jacinto
Jacinto: Gracias código , lo probé y sigue actuando de la misma forma. no acusa error .
Voy a probar cambiar el momento del evento haber si puedo hacerlo testear después de actualizar.
Cualquier novedad te comento.
Saludos, David.
De acuerdo David: Algo raro hay porque yo lo he probado, pero solo con el Evento Before Update del Primer TextBox.
Quizá ya los tienes, pero por si acaso, te concreto que tienes que tener 6 BeforeUpdate, uno para cada TextBox contra los demás.
Y asegurate de que está activado el [Procedimiento de evento] en las Propiedades.
Ya me contarás. Saludos >> Jacinto
Jacinto: Disculpa pero ahora dudo, ¿a que te refieres con que este activado?
¿esta correcto así?
Funcionan los códigos por separado, pero cuando modifico uno de los que se generan automáticamente por un código que ya esta en el formulario no acusa error .
Otra consulta sobre tu código , ayer encontré que salta el mensaje de error vuelve a al comando pero si tabulas conserva el valor repetido y continua , yo probé poner un GoTo al inicio para que siempre que salga del casillero compruebe pero me queda un bucle infinito ya que el valor de ese textbox se conserva y siempre controla con ese valor.
¿De que forma podría, al hacer esto Me.TxtDocAcadE.Undo darle un valor nulo ó cero?
'------------------------------------------------------------------------------------------------ 'Procedimiento Cmmprueba datos repetidos Documentos '------------------------------------------------------------------------------------------------ Private Sub TxtDocAcadE_BeforeUpdate(Cancel As Integer) 'Ejemplo desarrollado por JTrillo en Julio 2015 'Para la evaluación del Campo TxtDocAcadE con respecto a él mismo y a los 5 Restantes On Error GoTo TxtDocAcadE_BeforeUpdate_Err 'Con ésta Evaluación se coteja el Numero Introducido con los Almacenados en TDocumentos >> Falta hacerlo contra los TextBox If (Eval("DLookUp(""[DocAcadE]"",""[TDocumentos]"",""[DocAcadE] = Form.[TxtDocAcadE] "") Is Not Null")) Or (Eval("DLookUp(""[DocCAF]"",""[TDocumentos]"",""[DocCAF] = Form.[TxtDocAcadE] "") Is Not Null")) _ Or (Eval("DLookUp(""[DocCPF]"",""[TDocumentos]"",""[DocCPF] = Form.[TxtDocAcadE] "") Is Not Null")) Or (Eval("DLookUp(""[DocLM]"",""[TDocumentos]"",""[DocLM] = Form.[TxtDocAcadE] "") Is Not Null")) _ Or (Eval("DLookUp(""[DocIC]"",""[TDocumentos]"",""[DocIC] = Form.[TxtDocAcadE] "") Is Not Null")) Or (Eval("DLookUp(""[DocLL]"",""[TDocumentos]"",""[DocLL] = Form.[TxtDocAcadE] "") Is Not Null")) Then Beep MsgBox "El Nº de documento ya existe", vbCritical, "VALOR EXISTENTE" 'Vuelve al control TxtDocAcadE. Me.TxtDocAcadE.Undo DoCmd.CancelEvent Else 'Si no está repetido en los Campos ya Grabados puede estarlo en algun Cuadro de Texto sin guardar 'Si cambiamos un Número en un Cuadro de Texto, y mientras no se guarda cambiamos otro tenemos que detectarlo If Me.TxtDocAcadE.Value = Me.TxtDocLL.Value Or Me.TxtDocAcadE.Value = Me.TxtDocCAF.Value Or Me.TxtDocAcadE.Value = Me.TxtDocCPF.Value Or Me.TxtDocAcadE.Value = Me.TxtDocLM.Value Or Me.TxtDocAcadE.Value = Me.TxtDocIC.Value Then Beep MsgBox "El Nº de documento ya existe", vbCritical, "VALOR EXISTENTE" 'Vuelve al control TxtDocAcadE. Me.TxtDocAcadE.Undo DoCmd.CancelEvent End If End If TxtDocAcadE_BeforeUpdate_Exit: Exit Sub TxtDocAcadE_BeforeUpdate_Err: MsgBox error$ Resume TxtDocAcadE_BeforeUpdate_Exit End Sub
¿Se entiende mi consula?
Saludos, David.
David: Tal como me envías la figura es correcto.
Si ya tienes un Before Update en cada uno de los TextBox, OK.
En cuanto a lo segundo:
Tal como está el código, permanece en el TextBox, hasta no recibir un Valor distinto a los existentes.
Si ves que te esfuerzas y no sale lo que quieres, igual es una pequeña modificación, y no llego a verla, porque no tengo delante los Objetos.
Si quieres pon un enlace aquí, con tu BD y datos ficticios, o me la envías a [email protected]
Veamos si así salimos del atasco. Saludos >> Jacinto
- Compartir respuesta