Cómo sumar y restar las existencias

Estoy haciendo una base de datos en access para llevar entradas y salidas de almacén, así como cálculo de existencias. Las tablas y los campos son los siguientes:
PRODUCTOS: RefProducto, DescripcionProducto, UnidadesEnExistencia
ALBARANES ENTRADA: IdAlbaran, FechaDeEntrada, NumAlbaran
DETALLE ALBARANES: IdDetalleAlbaran, IdAlbaran, RefProducto, Cantidad
SALIDAS: IdSalida, FechaSalida, NumSalida
DETALLE SALIDAS:IdDetalleSalida, IdSalida, RefProducto, Cantidad
He creado formularios para registrar las entradas y salidas de productos, pero no sé cómo hacer para que al registrarlos, se cambie la cantidad de "UnidadesEnExistencia", sumando o restando, según proceda, en este campo de la tabla PRODUCTOS.
No sé si me he explicado bien. Pregúntame lo que necesites pero.

2 Respuestas

Respuesta
2
Es bastante simple.
Usá la función Dsum(campo a sumar, Tabla o consulta, condición)
Por ejemplo en cada formulario de entrada o de salida agregás un cuadro de texto y le asignás a Origen del control lo siguiente:
=Dsum("Cantidad", "DetalleAlabanes","RefProducto = " & refProducto) -
Dsum("Cantidad", "DetalleSalidas","RefProducto = " & refProducto)
Acá estoy suponiendo que querrás la cuenta por RefProducto
Fíjate que donde pongas el cuadro de texto debe tener acceso al campo RefProducto, de no ser así deberás hacer la referencia correspondiente, por ejemplo:
Forms! FormularioPrincipal! SubFormulario.Form! RefProducto
Para no equivocarte te recomiendo usar el asistente de expresiones
Suerte y contame, Marciana
Gracias por atenderme, Marciana, pero he hecho lo que me dices, y me da Error.
En la tabla PRODUCTOS, la clave principal es RefProducto, pero el campo al que quiero sumar la cantidad es UnidadesEnExistencia.
Otra cosa: La función que yo tengo en mi generador de expresiones es
Dsuma. ¿Es lo mismo que Dsum?.
Saludos.
Deberías aclararme más sobre el error. Es mucho más fácil ayudar cuando el problema está claramente explicado, esto es cómo son las tablas, si el formulario es dependiente o no, los tipos de datos, la versión de Office. Pero claramente explicado es dar los datos necesarios y no más y no menos.
DSuma() es el nombre en castellano de la función DSum(), depende de como tenés configurada la instalación.
Esa solución tiene que funcionar, debe haber algún nombre que no coincide.
Te doy otra solución
Escribí esta función para que la ejecutes cada vez que se agrega o resta cantidad.
Hacé lo siguiente:
1) Desde la ventana Base de Datos pasá a la ficha Módulos
2) Creá un módulo nuevo (cualquier nombre) y pegá esta función:
Public Function ActualizaCantidad(refProducto As Long, Suma As Boolean, Cantidad As Long)
Dim rsOut As New ADODB.Recordset
Dim i As Integer
rsOut.Open "Productos", CurrentProject.Connection, adOpenDynamic, adLockPessimistic
rsOut.Find "RefProducto = " & refProducto
If rsOut.EOF Then
MsgBox refProducto & " No existe"
Exit Function
End If
If Suma Then
rsOut!unidadesEnExistencia = rsOut!unidadesEnExistencia + Cantidad
Else
rsOut!unidadesEnExistencia = rsOut!unidadesEnExistencia - Cantidad
End If
rsOut.Update
rsOut.Close
End Function
3)Desde la ventana del módulo hacé clic en Herramientas/Referencias
Fíjate si en la lista figura
"Microsoft ActiveX Data Objects 2.1 library"
(El número de versión puede ser otro)
Si no está buscala en la lista (es muy larga, está ordenada alfabéticamente) y tildá el casillero.
5) Fíjate el tipo de datos de refProducto yo le puse numérico no me dijiste qué tipo de datos es, si no es numérico cambialo.
6)(Este paso es para probar la función) Abrí la ventana Inmediato (Control + G) y en esa ventana escribí lo siguiente:
? ActualizaCantidad(3, false, 2)
Pero en lugar del 3 poné un código refProducto que exista
En false es para restar (si querés sumar cambiá por True)
En lugar del 2 poné la cantidad a sumar o restar.
Te explico la función actualizaCantidad:
Recibe 3 datos:
El primero es el código de producto sobre el que querés sumar o restar
El segundo puede tener dos valores "True" para sumar y "False" para restar.
El tercero es la cantidad a sumar o restar.
Si el código refProducto no existe en la tabla te manda un mensaje a la pantalla.
Pruébalo bien. Cada vez que lo pruebes fíjate en la tabla que haya cambiado el campo UnidadesEnExistencia. Pruébalo con un código que no existe.
Si funciona hasta aquí te falta llamar a la función en el formulario. Deberías hacerlo en el evento Después de actualizar del campo Cantidad de entrada. Cuando es entrada el segundo argumento debe ser "True".
Se supone que tenés disponible en el formulario el campo refProducto, fíjate que el nombre en el formulario se corresponda.
En el evento Después de actualizar correspondiente a entrada deberías poner:
Dim i as variant
i=actualizaCantidad(refProducto, true, Cantidad)
Donde Cantidad debería ser el nombre del control (cuadro de texto) donde está la cantidad.
Y refProducto debería ser el nombre del control (cuadro de texto) donde está la cantidad.
Esta solución funciona. Yo desarrollé un ejemplo y lo probé. Pero tiene muchos detalles que cuidar.
Estimada Marciana:
Estoy probando la segunda solución que me das, pero al llegar a la ventana de inmediato para probar la función, me sale el mensaje "ERROR DE COMPILACIÓN".
Los datos de RefProducto no son de tipo numérico, sino de texto, porque son códigos con números y letras, así que no puedo cambiarlos. ¿Qué hago?.
He intentado una vez más la primera solución que me diste, y me sale:
"Omitió un operando o un operador, introdujo un carácter o coma no válidos o introdujo texto sin encerrarlo en comillas".
Espero tu ayuda.
Gracias
Para la primer solución:
=Dsum("Cantidad", "DetalleAlabanes","RefProducto = '" & refProducto) & "'" -
Dsum("Cantidad", "DetalleSalidas","RefProducto = '" & refProducto) & "'"
La diferencia está en que al ser la clave de tipo texto requiere que el dato con que se compara (refProducto) vaya entre comillas.
La segunda solución.
El error de compilación debe ser porque te falta la referencia a la biblioteca.
Desde cualquier ventana de código clic en Herramientas/Referencias
fíjate si tenés tildado (las bibliotecas tildadas aparecen arriba)
Microsoft ActiveX Data Objects 2.1 library (el número de versión puede ser otro, si hay varios elegí el más grande)
Si no está buscalo en la lista, está ordenada alfabéticamente, cuando lo encuentres (la lista es larga) tildalo.
Por el tema de la clave de tipo texto hay que cambiar algo:
Public Function ActualizaCantidad(refProducto As string, Suma As Boolean, Cantidad As Long)
Dim rsOut As New ADODB.Recordset
Dim i As Integer
rsOut.Open "Productos", CurrentProject.Connection, adOpenDynamic, adLockPessimistic
rsOut.Find "RefProducto = '" & refProducto & "'"
If rsOut.EOF Then
MsgBox refProducto & " No existe"
Exit Function
End If
If Suma Then
rsOut!unidadesEnExistencia = rsOut!unidadesEnExistencia + Cantidad
Else
rsOut!unidadesEnExistencia = rsOut!unidadesEnExistencia - Cantidad
End If
rsOut.Update
rsOut.Close
End Function
Probá de nuevo.
Las soluciones tienen que funcionar. Hay muchos detalles que atender. Yo siempre protesto porque las consultas son muy vagas imprecisas e insuficiente. Cuanto más completas y claras más rápidamente se encuentra la solución.
Infórmame claramente los errores si aparecen y también contame si los resolviste. M
Para la segunda solución, para hacer la prueba hay que escribir:
? ActualizaCantidad("3", false, 2)
La clave entre comillas.
Me está costando, pero con tu ayuda lo conseguiré.
Te explico: La primera solución, después de cambiar lo que me dijiste, me sigue dando el mismo error, así que estoy trabajando con lo del módulo.
He probado la función en la ventana Inmediato y ¡FUNCIONA!, pero al llamarla en el formulario, algo falla.
Intentaré explicártelo bien:
En el campo "Cantidad" del formulario "Albaranes Detalle", en el evento "Después de actualizar", he pegado la función que me diste, pero cuando añado un nuevo registro, después de introducir la cantidad que entra y clicar, me sale el siguiente mensaje:
Microsoft Access no puede encontrar la macro "Dim i as variant
                                                                i=actualizaCantidad(refProducto, true, Cantidad)".
La macro (o su grupo de macros) no existe o la macro es nueva pero no se ha guardado. Obseve que cuando introduce la sintaxis nombre_grupo_macro.nombre_macro en un argumento, debe especificar el nombre con el que se guardó por última vez el grupo de macros de la macro.
Estoy entusiasmada porque creo que me falta poco para conseguirlo, por favor, contestame, y muchísimas gracias por tu ayuda.
Con tiempo y paciencia podemos lograrlo. Te comenté que hay muchos detalles que cuidar.
Segunda solución
Acabo de revisar mi ejemplo y funciona bien.
Releo los mensajes, decís:
EN el campo "Cantidad" del formulario "Albaranes Detalle", en el evento
"Después de actualizar", he pegado la función que me diste

La función debería estar en módulos, en todo caso no debería estar en el evento Después de actualizar.
En este evento solamente debe ir
Private Sub Cantidad_AfterUpdate()
Dim i As Variant
i = ActualizaCantidad(RefProducto, True, Cantidad)
End Sub
 (lo pegué desde mi código donde funciona bien)
------------------------------------------------------------------ 
hacé la siguiente prueba (después de probar borrá todolo que hayas agregado) debajo de 
i = ActualizaCantidad(RefProducto, True, Cantidad)
y antes de  
End Sub
Escribí de nuevo "ActualizaCantidad(" al escribir el paréntesis que abre debería aparecer la lista de argumentos con su tipo, si no aparece es que el nombre de la función no está bien escrita o "no ve" la función.
Escribí refproducto. Cuando escribís el punto debería aparecer una lista de propiedades si no aparece es que ese nombre no es el correcto.
Hacé lo mismo con Cantidad (el tercer argumento) al agregarle el punto la respuesta del sistema te indicará si ese nombre está disponible o no.
En ambos casos no olvides luego borrar lo que agregaste.
Si alguno de los nombres no están disponibles deberás ver si no se escribe diferente.
En todo caso copiá y pegá acá la función (recordá que debería estar en módulos)
Y el procedimiento Después de actualizar del cuadro Cantidad.
Me estoy desanimando por momentos.El fallo debe ser una tontería, pero yo no entiendo nada de VISUAL BASIC (ni siquiera sé inglés), y me estoy agobiando.
Una vez más, abusaré de tu paciencia y generosidad.
Intentaré explicártelo lo mejor que pueda: Lo que yo había pegado en el campo "Cantidad" del formulario "Albaranes Detalle" era el procedimiento que me diste, no la función (perdona, pero no estoy acostrumbrada a este argot). El problema era (eso creo), que lo había pegado directamente en el renglón "Después de Actualizar" que se abre en el icono "propiedades" del campo "cantidad". Ahora lo he puesto en una ventana de Visual Basic que se abre en ese mismo renglón cuando le das al "generador de códigos". ¿Es así?
Suponiendo que sea así, cierro el formulario, guardo los cambios, y entro para agregar datos. Agrego un nuevo registro, y al actualizar el campo en cuestión, me sale el siguiente mensaje:
"Error de compilación:
Se esperaba una variable o un procedimiento, no un módulo",
Y SE ME ABRE LA VENTANA DE VISUAL BASIC, DONDE ME REMARCA EN AZUL "ActualizaCantidad". Yo interpreto que no reconoce la función del módulo Actualiza Cantidad, pero por más que repaso los nombres y las expresiones, creo que está todo bien.
También he comrpobado lo que me dijiste de "Cantidad" y "refProducto", y esos están bien porque me aparecen las listas esa que me decías, aunque, como están en inglés, no entiendo nada.
Muchas gracias por tu inestimable ayuda.
Hacé lo siguiente:
1) Abrí el formulario que te da error.
2) Ponelo en modo diseño (clic en el botón que tiene una escuadra azul)
3) Ahora pasalo a ver código (Ver/código) luego tenés que ver ese código que tanto de disgusta
4) Copiá TODO el código que aparece y pégalo acá
5) Pasá a la solapa Módulos (desde la ventana Base de Datos clic en módulos)
6) Supongo que tendrás algo que dice "Módulo1" seleccionalo
7) Clic en Ver/código
8) Copiá y pegá acá TODO lo que te aparezca
No te olvides de hacer una línea entre las dos cosas que vas a pegar.
Private Sub Cantidad_AfterUpdate()
Dim i As Variant
i = ActualizaCantidad(RefProducto, Suma, Cantidad)
End Sub
________________________________________________________________________Option Compare Database
Public Function ActualizaCantidad(RefProducto As String, Suma As Boolean, Cantidad As Long)
Dim rsOut As New ADODB.Recordset
Dim i As Integer
rsOut.Open "Productos", CurrentProject.Connection, adOpenDynamic, adLockPessimistic
rsOut.Find "RefProducto = '" & RefProducto & "'"
If rsOut.EOF Then
MsgBox RefProducto & " No existe"
Exit Function
End If
If Suma Then
rsOut!UnidadesEnExistencia = rsOut!UnidadesEnExistencia + Cantidad
Else
rsOut!UnidadesEnExistencia = rsOut!UnidadesEnExistencia - Cantidad
End If
rsOut.Update
rsOut.Close
End Function
Hacé este cambio (fíjate que es una sola palabra en vez de Suma hay que poner True)
Private Sub Cantidad_AfterUpdate()
Dim i As Variant
i = ActualizaCantidad(RefProducto, True, Cantidad)
End Sub
En el formulario donde se resta deberás poner False 
Pruébalo y contame. M
No es eso, Marciana. Ya lo había probado primero con True, y me daba el mismo error. De todas formas, lo he sustituido y he vuelto a poner True como me dijiste.
Cuando me da el "Error de compilación: Se esperaba una variable o un procedimiento, no un módulo", Y SE ME ABRE LA VENTANA DE VISUAL BASIC, donde me remarca en azul ActualizaCantidad, si hago clic en el botón AYUDA me pone este mensaje:
Se espera una variable o un procedimiento, no un módulo
No existe una variable o un procedimiento con este nombre en el alcance actual, pero hay un módulo con este nombre. Las causas y posibles soluciones de este error son las siguientes:
El nombre de un módulo se utiliza como variable o procedimiento.
Verifique la ortografía del nombre de la variable o procedimiento y asegúrese de que el nombre al que desea referirse no sea privado de otro módulo. El nombre de un módulo puede ser un calificador pero no puede estar sólo.
Por favor, no te canses, estamos cerca. Mil Gracias.
Hacé lo siguiente:
Hacé un formulario nuevo (sin eliminar el otro) similar al que te da error. Agregale el código (con True) al evento después de actualizar.
Fíjate que no haya ningún control, ni formulario, ni subformulario que se llame ActualizaCantidad.
Otra cosa, cuando pegaste el código del formulario (yo te había pedido TODO) noto que no tiene una sentencia
Option Compare Database
Que sí aparece en el módulo. También debería haber otra:
Option explicit
Para que aparezca esta ultima hacé lo siguiente desde cualquier ventana de código: Clic en Herramientas/ Opciones/Editor y tildá el casillero "Requerir declaración de variables"
¿No hay otro código en el formulario? ¿Pegaste TODO?
Probá en el formulario nuevo y me contás.
Lo que creo que pasa es que hay algo que no funciona en tu formulario. Las expresiones están bien. Lo que dice el error me hace pensar que el problema no está en la función ActualizaCantidad.
Otra cosa para hacer:
Desde la ventana de Base de Datos: Herramientas/Utilidades de .../Compactar y reparar
Marciana:
¡LO TENGO!
¿Sabes cuál era el problema?
Pues que el nombre que yo le había puesto al módulo era ActualizaCantidad, o sea, el mismo del procedimiento, y por eso no lo reconocía.
Leyendo y releyendo las ayudas, se me ha encendido la lucecita, y como tú me hablaste de que suponías que el módulo se llamaría Módulo 1, pues le he cambiado el nombre por probar, y
¡Funciona!
Ahora tengo que hacer lo mismo en el formulario SALIDAS Detalle. Es todo igual, pero donde pone TRUE lo cambio por FALSE, ¿no?.
Muchíiiiisimas gracias. No tengo palabras para agradecerte tu ayuda, tu constancia, y tu paciencia conmigo. Es mavarilloso en este mundo tan individualista encontrar personas como tú, dispuestas a ayudar de manera altruista.
GRACIAS, GRACIAS, GRACIASSSSSSSSSSSSSSSSSSSSSSSS.
(¿Finalizo la pregunta o la dejo abierta por si vuelvo a necesitarte?)
Estaba clarísimo el mensaje... (cómo no se me ocurrió ja ja)
Cuanto me alegro. Primero probá el otro formulario y si todo anda bien finalizá la pregunta.
Tené en cuenta que todo se puede resolver (en Access al menos) con paciencia y no mucho esfuerzo y sobre todo teniendo muy en cuenta los DETALLES!
Estimada Marciana:
Ya he probado con el otro Formulario, y también funciona.
Muchas gracias de nuevo.
Tú dices que "todo se puede resolver (en Access al menos) con paciencia y no mucho esfuerzo ", y yo añado:
Todo se puede resolver en Access con paciencia y no mucho esfuerzo SI CUENTAS CON LA AYUDA DE UNA EXPERTA.
Por tu manera de expresarte, deduzco que eres argentina. Saludos cordiales y agradecidos desde Córdoba (España).
Pilar.
Respuesta
1
Fácil...
Crea una consulta de selección (QRY1)selecciona
la tabla 'Albaranes Entrada' y 'Detalle Albaranes'
Une, arrastra on relaciona en esta QRY1) IdAlbaran con IdAlbaran.
Incluye SOLO los campos 'RefProducto' y 'Cantidad'
Seguidamente dale al icono TOTALES (es
un dibujo de una E antigua o sumatorio)
En 'Total' del campo 'RefProducto' pones 'Agrupar por'
En 'Total' del campo 'Cantidad' pones 'Suma'
... y ejecuta la consulta.
Tengo que cerrar una hora.
Después sigo..
... sigue
Crea una consulta de selección (QRY2)selecciona en diseño
las tablas 'Salidas' y 'Detalle Salidas'
Une, arrastra o relaciona en esta QRY2 IdSalida con IdSalida.
Incluye SOLO los campos 'RefProducto' y 'Cantidad' de tabla 'Detalle Salidas'.
Seguidamente dale al icono TOTALES (es
un dibujo de una E antigua o sumatorio)
En 'Total' del campo 'RefProducto' pones 'Agrupar por'
En 'Total' del campo 'Cantidad' pones 'Suma'
Si la ejecutas debe funcionar.
Crea una tercera consulta de selección (QRY3) y en el
diseño incluye las consultas QRY2 y QRY1 y relaciona-une-arrastra
'RefProducto' entre ambas.Selecciona los campos 'RefProducto' y 'Cantidad' de QRY1 y de QRY2.(Esta vez,en qry3 no le des a totales!.)
Crea un campo calculado en QRY3...
CAMPO>>> Expr1:[EXISTENCIAS]=[QRY1.SumaDeCantidad]-[QRY2.SumaDeCantidad]
no recuerdo...si falla la sintaxis puede que se escriba...puedes probar:
CAMPO>>> Expr1:[EXISTENCIAS]=[QRY1].[SumaDeCantidad]-[QRY2].
[SumaDeCantidad]
¿Ok?

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas