INSERT INTO, no permitir agregar si ya existe registro

Gracias a vuestra ayuda sigo avanzando en mi access pero, ahora me ha surgido un problema con las entradas a almacén. Tengo un formulario independiente que graba los registros en la tabla ALMACEN, a través de un botón con el evento:

Private Sub GUARDAR_Click()
Dim ISERIE, FSERIE, Vcomprueba As String
Dim FECHA As Date
IANILLA = Me.InicioSerie
FANILLA = Me.FinSerie
For i = IANILLA To FANILLA
CurrentDb.Execute "INSERT INTO ALMACEN(FECHAENTRADA, INSCRIPCION, SERIE, TIPOENTRADA, OBSERVACIONES) VALUES (#" & Me.FECHA & "#, '" & Me.INSCRIPCION & "', '" & Format(i, "00000") & "', '" & Me.Concepto & "', '" & Me.OBSERVACIONES & "')"
Next i
MsgBox "ANILLAS DESDE " & IniAnilla & " HASTA " & FinAnilla & " GRABADAS EN SU ALMACEN ", vbInformation, "PROCESO COMPLETADO"
On Error Resume Next
For Each ctl In Me.Controls
If ctl.ControlType = acTextBox Or ctl.ControlType = acComboBox Or ctl.ControlType = acListBox Then ctl.Value = Null
Next ctl
End Sub

Los artículos (anillas) son únicos, nunca puede haber 2 Ud. Del mismo artículo. Había pensado poner en la tabla el campo "ANILLA" como clave principal, pero como es un campo calculado (INSCRIPCIÓN + SERIE) no me deja y no se cómo hacerlo mediante código, al no ser un único artículo, sino varios (desde IncioSerie- hasta FinSerie) los que graba.

Respuesta
2

Otra opción que tienes es comprobar si la Anilla existe antes de ejecutar la SQL, por ejemplo con DCount() o Dlookup():

...
For i = IANILLA To FANILLA
  If DCount("*","ALMACEN","[INSCRIPCIÓN]='" & Me.Inscripcion & "' AND SERIE='" & Format(i,"00000") & "'")= 0 Then
    CurrentDb.Execute "INSERT INTO ...."
  End IF
Next i
...

¡Gracias! Es justo lo que intentaba hacer, pero no sabía dónde poner la "i"...Funciona perfectamente.

...
For i = IANILLA To FANILLA
    If DCount("*", "ALMACEN", "[INSCRIPCION]='" & Me.INSCRIPCION & "' AND SERIE= " & Format(i, "00000") & "") <> 0 Then
MsgBox "ANILLAS DESDE " & IniAnilla & " HASTA " & FinAnilla & " YA EXISTEN EN SU ALMACÉN ", vbCritical, "PROCESO CANCELADO"
Else
CurrentDb.Execute "INSERT INTO ALMACEN(FECHAENTRADA, INSCRIPCION, SERIE, TIPOENTRADA, OBSERVACIONES) VALUES (#" & Me.FECHA & "#, '" & Me.INSCRIPCION & "', '" & Format(i, "00000") & "', '" & Me.Concepto & "', '" & Me.OBSERVACIONES & "')"
MsgBox "ANILLAS DESDE " & IniAnilla & " HASTA " & FinAnilla & " GRABADAS EN SU ALMACEN ", vbInformation, "PROCESO COMPLETADO"
End If
Next i
...

Lo he modificado para que no salga el aviso de grabadas si existen, y lo cambie por otro. 

No sé si hace así, pero después de varias pruebas, es como funciona.

Muchas gracias.

Perdona que te moleste, el Dcount que me has pasado funciona perfectamente, pero los cambios que he hecho yo no!!. Intentaba poner un mensaje para cuando graba y otro para cuando ya existen en almacén, y pensaba que me funcionaba,  pero al probarlo ahora con detenimiento no funciona. Lo he probado con un registro y funcionaba, pero si pongo más de uno me repite el mensaje tantas veces como registros graba, y si lo bajo al final me lo saca igualmente haya existencias o no .

Te agradecería si pudieras decirme dónde tengo que ponerlos. Muchas gracias. 

Si te sale el mensaje de confirmación en cada registro que agregas, es que tu código sí que funciona... Otra cosa es que no haga lo que quieres, que es distinto... XDD

¿Qué mensaje quieres lanzar, independientemente de que se actualice 1, varias o todas las anillas?

Lo que quiero es que si existen en el almacén (y no las graba, que eso lo hace bien) el mensaje sea, por ejemplo:

MsgBox "ANILLAS DESDE " & IniAnilla & " HASTA " & FinAnilla & " YA EXISTEN EN SU ALMACÉN ", vbCritical, "PROCESO CANCELADO"

Y si no existen y las graba:

MsgBox "ANILLAS DESDE " & IniAnilla & " HASTA " & FinAnilla & " GRABADAS EN SU ALMACEN ", vbInformation, "PROCESO COMPLETADO"

O algo así, el mensaje me da igual, pero que sea distinto para cada resultado. Para que quién lo grabe sepa que no se han grabado xq ya están o que todo ha ido bien  ;-)

Muchas gracias. 

Yo lo haría así, porque me parece un "peñazo" que te salgan muchos mensajes (y al usuario final tampoco le gusta...):

Dim anillasNoGrabadas as String
Dim anillasGrabadas as String
...'Por aquí tu código existente
For i = IANILLA To FANILLA
  If DCount("*","ALMACEN","[INSCRIPCIÓN]='" & Me.Inscripcion & "' AND SERIE='" & Format(i,"00000") & "'")= 0 Then
    CurrentDb.Execute "INSERT INTO ...."
    anillasGrabadas=anillasGrabadas & i & ", "
  else
    anillasNoGrabadas=anillasNoGrabadas & i & ", "
  End IF
Next i
anillasGrabadas=left(anillasGrabadas,len(anillasGrabadas)-2)
anillasNoGrabadas=left(anillasNoGrabadas,len(anillasNoGrabadas)-2)
MsgBox "Se han grabado las siguientes anillas: " & vbCrLf & anillasGrabadas & vbCrLf & vbCrLf _
       "Las siguientes anillas no se han grabado porque ya existen: " & vbCrLf & anillasNoGrabadas
... 'resto de código

1 respuesta más de otro experto

Respuesta
2

No sé si lo inscripción + serie, se refiere a que se sumen,, a que haya un signo + en medio, o lo que sea, pero si tengo una tabla

Y un formulario

Cuando pulso el botón

El código del botón es

Me había olvidado, puedes poner el campo Anilla de la tabla como Indexado sin duplicados

¡Gracias!

No sabía que se podían concatenar campos así. Me va a ser de gran ayuda, no sólo en este caso.

Muchas gracias, otra vez.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas