Access - Validar campo en formulario Access

 
Vista:
sin imagen de perfil

Validar campo en formulario Access

Publicado por PabloBT (7 intervenciones) el 12/10/2022 10:25:49
Hola amigos.
Necesito crear una regla de valicación en un campo de un formulario de access, a ser posible utilizando generador de expresiones.
Comento:
Tengo un formulario, para control de pedidos, cuyos principales campos son Ejercicio - Serie - Npedido.
Se encuentran en la misma tabla BPedidos
El número de pedido ha de ser único y es la combinación de estos 3 campos Ej. 2022-40-321
La cuestión es que cuando introduzca el dato en el campo Npedido, no debería poder introudcirlo si ya ha un pedido que coincidad en los tres campos que combina. Es decir, si tengo 2022-40-321, al dar de alta otro, debería validarlo y no dejarme introducir de nuevo 2022-40-321. Al cambio de ejercicio, 2023, debería dejarme meter el pedido 2023-40-321.
Se que es posible, pero he buscado y rebuscado, y, salvo un código VBA que localicé en una web, que no logro comprender... no he encontrado solución.
Mis conocimiento son básicos, y poco a poco estoy preparando esta aplicación.

Gracias de antemano
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Validar campo en formulario Access

Publicado por Mbellido (306 intervenciones) el 14/11/2022 23:11:17
Si en la tabla pones los tres campos como clave múltiple no te dejará duplicarlo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Validar campo en formulario Access

Publicado por Anonimo (3316 intervenciones) el 15/11/2022 01:20:03
Crear una clave de este tipo es complicado mientras no se le encuentra la lógica, pero es una solución que aventaja por varios cuerpos a una llave compuesta por varios campos (cantidad no es calidad).

Si fuera un simple índice sería aceptable (le valdría a la tabla para no tener duplicados) pero como llave y con tres campos se volvería bastante restrictiva en su relación con otras tablas.

Para generar índices/llaves de este tipo (amplia literatura en muchos foros bajo el título 'Falsos autonuméricos) se necesita conocer de forma previa el segundo dato que lo compone.

.- El primero es el año (no supone un problema, se trata del actual)
.- El segundo es la serie y en principio se desconoce (y no habrá referencias si es un nuevo registro)
.- El tercero se da por supuesto que es el que continua al mayor (ultimo) que cumpla con las condiciones de pertenecer al mismo año y serie.

El año: Year (date)
La serie .... punto a resolver ¿un combo, un cuadro de texto para obtener ese dato?
El siguiente (bueno el actual para obtener el siguiente) el valor numérico de los tres últimos caracteres (cero si es el primero de la serie/año)

Como obtener el numero actual (se parte del supuesto de una tabla de nombre Facturas y un campo de texto de nombre FACTURA.

1
DMax("Val(Right(factura,3))", "Facturas", "left(Factura,7) = '" & Year(Date) & "-" & Serie & "'")

Si es el primero del año/serie el resultado sera un NULL, se le trata con NZ:
1
Nz(DMax("Val(Left(factura,3))", "Facturas", "Right(Factura,7) = '" & Year(Date) & "-" & Serie & "'"),0)

Y obtenido el dato se incrementa en una unidad:
1
Nz(DMax("Val(Left(factura,3))", "Facturas", "Right(Factura,7) = '" & Year(Date) & "-" & Serie & "'"),0) +1

Lo siguiente es que se le de un formato de tres digitos (en lugar de un 1, 2, 3, 22, 99 y 100 ==> 001, 002, 003, 022, 099 y 100)
1
Format (Nz(DMax("Val(Left(factura,3))", "Facturas", "Right(Factura,7) = '" & Year(Date) & "-" & Serie & "'"),0) +1,"000")

Ya hemos obtenido el número, creamos el código
1
Nuevo_Codigo =Year(Date) & "-" & Serie & "-" & Format (Nz(DMax("Val(Left(factura,3))", "Facturas", "Right(Factura,7) = '" & Year(Date) & "-" & Serie & "'"),0) +1,"000")

Las funciones utilizadas supongo que son conocidas, son las básicas de tratamiento de texto (Left, RIght), conversión de texto a número (Val) una función de dominio (DMax) tratamiento de valores NULL (NZ) y el año en curso (Year).
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Eduardo

Validar campo en formulario Access

Publicado por Eduardo (317 intervenciones) el 18/11/2022 00:28:51
Como le dicen si están en 3 campos puede crear un índice múltiple, si está en un solo campo puede indexar sin duplicados, pero si está en uno solo y quiere saber el siguiente pedido de acuerdo con el año, serie y pedido, ya no es fácil. Aprovecho una respuesta que presenté en TodoExpertos.

TABLA


existe_pedido_tabla

FORMULARIO


existe_pedido_form

CÓDIGO EVENTO BOTON VALIDAR
1
2
3
4
5
6
7
8
Private Sub btnValidaar_Click()
 
    If IsNumeric(Me.ctlAño) And IsNumeric(Me.ctlSerie) And IsNumeric(Me.ctlPedido) Then
     Me.ctlExiste = existe_pedido(Me.ctlAño, Me.ctlSerie, Me.ctlPedido)
     Me.ctlSigte = sgte_pedido(Me.ctlAño, Me.ctlSerie, Me.ctlPedido)
    End If
 
End Sub

CODIGO DE LAS FUNCIONES
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
Public Function existe_pedido(intEjercicio As Integer, intSerie As Integer, nropedido As Integer) As Boolean
 
 'Función para determinar si existe una cadena con formato nnnn-xx-yyy
 'en donde:
 '      nnnn es el año a tomar
 '      xx es el número de serie
 '      nropedido es el número de pedido
 'Preparado por: EDUARDO PEREZ FERNANDEZ
 'Fecha : 17/11/2022
 
  Dim rs As Recordset
  Dim strSQl As String
 
  'Requiere de la función extrae
 
  strSQl = "SELECT  Npedido" & vbCrLf
  strSQl = strSQl & "        FROM BPedidos" & vbCrLf
  strSQl = strSQl & "       WHERE Left(extrae([Npedido],1,""-""),4)=" & intEjercicio & vbCrLf
  strSQl = strSQl & "         AND extrae([Npedido],2,""-"")='" & intSerie & "'" & " AND  extrae([Npedido],3,""-"")=" & nropedido & ";"
 
 
  Set rs = CurrentDb.OpenRecordset(strSQl)
 
   If rs.BOF() And rs.EOF() Then
    existe_pedido = False
  Else
    existe_pedido = True
  End If
 
 
  rs.Close
  Set rs = Nothing
 
End Function
Public Function sgte_pedido(intEjercicio As Integer, intSerie As Integer, nropedido As Integer) As String
 
 'Función para determinar el siguiente pedido de una cadena con formato nnnn-xx-yyy
 'en donde:
 '      nnnn es el año a tomar
 '      xx es el número de serie
 '      nropedido es el número de pedido
 'Preparado por: EDUARDO PEREZ FERNANDEZ
 'Fecha : 17/11/2022
 
  Dim rs As Recordset
  Dim strSQl As String
 
  'Requiere de la función extrae
 
  strSQl = "SELECT nz(Max(extrae([Npedido],3,""-""))) + 1 AS sigte" & vbCrLf
  strSQl = strSQl & "        FROM BPedidos" & vbCrLf
  strSQl = strSQl & "       WHERE Left(extrae([Npedido],1,""-""),4)=" & intEjercicio & vbCrLf
  strSQl = strSQl & "         AND extrae([Npedido],2,""-"")='" & intSerie & "'" & ";"
 
  Set rs = CurrentDb.OpenRecordset(strSQl)
 
 
   sgte_pedido = intEjercicio & "-" & intSerie & "-" & rs.Fields("sigte")
 
  rs.Close
  Set rs = Nothing
 
End Function
 
Public Function extrae(pvstring As Variant, pipart As Integer, Optional psDeli As String = ",")
 
 'Functión para extraer parte de una cadena
 'Parámetros:
 '           pvstring=Cadena de texto a minipular
 '           pipart=Parte de cadena a extraer de acuerdo con el separador,
 '                  por ejemplo,1 primera parte, 2 segunda parte
 '           psdeli=Separador, opcional por defecto coma (,) pero puede ser otro como guion(-)
 'Elaborada por: Eduardo Pérez Fernández
 'Fecha: 06/09/2021
 'Ejemplos de llamada:
 '                    ?extrae("Eduardo, Pérez",1,",")   ------>> retorna Pérez elimina el espacio que hay antes de Pérez
 '                    ?extrae(", Pérez",2,",")         ------>> retorna Pérez elimina el espacio que hay antes de Pérez
 '                    ?extrae("Eduardo-Pérez",2,"-")    ------>> retorna Pérez. Observe que cambie el separador de cadena por -
 '                    ?extrae("Eduardo,Pérez",2)        ------>> retorna Pérez. No inclui el separador toma el separador por defecto ,
 '                    ?extrae("Eduardo,Pérez,Fernández",3) ----->> retorna el segundo apellido Fernández
 On Error Resume Next
 
  extrae = Null
 
  If Mid(pvstring, 1, 1) = psDeli Then
    pvstring = "nd" & pvstring
  End If
 
 If IsNull(pvstring) Then Exit Function
 
 extrae = Trim(Split(pvstring, psDeli)(pipart - 1))
 
End Function

Si quiere el ejemplo lo puede solicitar a [email protected]
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar