Actualizar 2 o más tablas con código VB en Access

En una aplicación desarrollada en Access con procedimientos en Visual Basic, necesito actualizar el campo unidades disponibles de la tabla Stocks cada vez que se procesa una factura de compra o de venta.
El formulario desde el que se introducen los datos de compra o venta tiene como tabla origen del registro la tabla de compras o la de ventas, según corresponda, y en estas se guardan todos los detalles de dichas facturas de compra o venta.
Se trata en definitiva de actualizar la tabla Stocks, que contiene la referencia del artículo, descripción, unidades, almacén y ubicación en el almacén.
Una vez introducidas las unidades del artículo que se procesa, al salir de campo cantidad, no se actualiza la tabla y se produce el error "3061 en tiempo de ejecución. Pocos parámetros. Se esperaba 1". La línea donde rompe el procedimiento es BD. Execute ...
El código utilizado es el siguiente:
Private Sub CANTIDAD_Exit(Cancel As Integer)
Dim ConsultaSQL As String, Datos As Recordset, BD As Database
Set BD = CurrentDb
ConsultaSQL = "SELECT CREF FROM STOCKS WHERE CREF='" & Me.CREF & "'"
Set Datos = BD.OpenRecordset(ConsultaSQL)
BD.Execute ("Update Stocks Set NSTOCK = NSTOCK + Me.CANTIDAD Where CREF = '" & Me.CREF & "'")
Datos. Close
BD. Close
End Sub
---------------------------------------------------------------------------------------------
CREF: Campo código del artículo que se va a actualizar en la tabla Stocks
Me. CREF: La variable que contiene el código que se acaba de procesar en el formulario
NSTOCK: Campo unidades a actualizar en la tabla Stocks

1 respuesta

Respuesta
2
Mara aurë!
Vamos a ver... te salta el error porque no le estás pasando ninguna cantidad a actualizar en NSTOCK. Es decir, que aunque tú "veas" que le estás pasando NSTOCK + Me. CANTIDAD ni la mecánica ni la sintaxis son correctas.
La mecánica no es correcta porque no estás cogiendo en ningún momento el valor NSTOCK que tienes en tu tabla STOCK, por lo que, a efectos de Access (y con la sintaxis correcta) eso sería una variable no definida y sin valor.
Para asignar un valor a tu consulta de actualización deberías pasar ese parámetro (nunca mejor dicho, je, je...) o bien como una cantidad directamente o bien como una cantidad a través de una variable.
Por ejemplo, imagínate que quieres pasarle el importe del campo CANTIDAD. La sintaxis correcta para ello sería:
BD.Execute ("Update Stocks Set NSTOCK = " & Me.CANTIDAD & " Where CREF = '" & Me.CREF & "'")
Ahora sí le estás pasando un parámetro, representado por Me. Cantidad. ¿Ves la diferencia? ;)
Te he querido soltar este "rollazo" porque pienso que es mejor explicar los motivos de un mal funcionamiento que darte la solución directamente y obligar a que, en esos momentos de ocio, uno piense una y otra vez: Sí, pero... ¿por qué me daba error? Je, je...
Una cosilla más, por si puede ser de tu interés: cuando creas un recordset creas una conexión, para que me entiendas, y ocupas memoria RAM. Para cerrar las conexiones utilizamos rst. Close (como tú muy bien has hecho), pero la RAM queda ocupada (y eso consume recursos). Si quieres liberar la RAM tienes que añadir al código Set rst=Nothing. Simplemente como curiosidad ;)
La solución es cambiar el código que tienes por este otro (te lo pongo comentado para que veas qué hace cada cosa):
---
Private Sub CANTIDAD_Exit(Cancel As Integer)
Dim ConsultaSQL, Datos As Recordset, BD As Database
Dim vStock As Integer
Set BD = CurrentDb
'Creamos la consulta para que nos devuelva el valor del stock filtrado
'por número de producto
ConsultaSQL = "SELECT NSTOCK FROM STOCKS WHERE CREF='" & Me.CREF & "'"
'Creamos el recordset sobre la consulta anterior
Set Datos = BD.OpenRecordset(ConsultaSQL)
'Asignamos el valor del stock a la variable vStock
vStock = Datos.Fields(0).Value
'Modificamos la cantidad del stock sumándole el valor del campo [CANTIDAD]
vStock = vStock + Me.CANTIDAD.Value
'Ejecutamos la actualización con vStock como parámetro
BD.Execute ("Update Stocks Set NSTOCK = " & vStock & " Where CREF = '" & Me.CREF & "'")
'Cerramos conexiones
Datos.Close
BD.Close
'Liberamos memoria
Set Datos = Nothing
Set BD = Nothing
End Sub
---
Otra reflexión "filosófica", por si puede también serte de ayuda. Imagínate que el stock inicial es de 10 unidades. Tú creas la entrada y escribes 5 unidades. Al salir de CANTIDAD automáticamente en tu tabla stock ahora ya tendrás NSTOCK con 15 unidades. Pero, ¿y si me he equivocado al escribir 5 unidades y eran 6? Pues nada, borro el 5 y pongo un 6. ¿Qué pasará? El stock "real" serian 6 unidades, pero en tu tabla Stock te aparecerá un sotck de 21 unidades, y eso no es correcto.
Para corregir eso podrías, por ejemplo, poner una línea de código antes del cierre de conexiones de esta manera.
---
Me. CREF. SetFocus 'Para sacar el enfoque del campo cantidad y evitar errores de bloqueo de código
Me.CANTIDAD.Enabled=False
---
Así bloqueas el campo y obligas al usuario, a que si se ha equivocado, deba hacer un movimiento de salida equivalente para no alterar el stock real, por ejemplo.
Y al evento de formulario "Al cambiar registro" deberías ponerle este código:
---
Private Sub...
If Me.CANTIDAD.Enabled = False Then Me.CANTIDAD.Enabled = True
End Sub
---
Para, si añades un nuevo registro, el campo CANTIDAD ya no te aparezca bloqueado
O este otro:
---
Private Sub...
If isnull(Me.CANTIDAD) Then
Me.CANTIDAD.Enabled = True
Else
Me.CANTIDAD.Enabled = False
End If
End Sub
---
Que te previene de cambios al ir recorriendo los registros.
Bueno, lo anterior es sólo una idea ;)
Espero que te vaya bien. Ante cualquier problemilla me comentas.
Muchas gracias. Está todo muy claro y detallado. Las reflexiones perfectas. En definitiva, muy por encima de mis expectativas. Me habría conformado con salir del atasco de las variables y parámetros. Tus conocimientos son obvios, pero tu implicación en la respuesta es encomiable. Te felicito.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas