¿Alguien que pueda aclararme el error que estoy cometiendo al redactar un código en Access?

Necesito de su ayuda para resolver el siguiente problema:

  • Tengo una base de datos donde tengo una tabla de materiales con su respectivo stock
  • Una tabla Orden de Pedidos y una sub tabla detalle de Orden de pedido
  • Una tabla entrega de materiales con su sub tabla detalle entrega de materiales

Hasta ahí todo bien

Lo que deseo lograr es que cuando ingresen materiales a mi pañol:

  • Estos se sumen al stock (el código funciona a la perfeccion)
  • Y que estos a su vez, se descuenten de la orden de pedidos, mostrando asi, cuantos materiales de esa orden se entregaron y cuantos faltan entregar. (Aquí tengo el Problema de código)

El problema radica en:

Que cuando realizo la entrada de materiales a través de un formulario se descuentan los materiales de todas las Ordenes de Pedidos que poseen dentro de si mismos el mismo código de material. Lo que esta mal.

Dado que lo correcto sería, que solo se descuente el material correspondiente a de la Orden de Pedido que lo solicito puntualmente.

Hay que tener en cuenta que tengo diferentes ordenes de pedidos que solicitan el mismo material, pero el destino de cada orden de pedido es para una obra diferente.

Dentro del código, no se como colocar en la condición WHERE, que se debe sumar la entrega de la cantidad de un determinado material al que corresponda siempre y cuando el mismo corresponda a la Orden de Pedido realizada.

La resta de materiales pedidos que faltan entregar la realizo a través de una expresión.

Lo que necesito es que me vaya sumando la cantidad de materiales entregados correspondientes a una orden de pedido determinada para asi llevar el control de manera automática de que se entrego y de que falta entregar.

El código es el siguiente:

Private Sub Comando82_Click()

If MsgBox("¿Está seguro de realizar el Ingreso de materiales al Stock?", vbYesNo, "Aviso") = vbYes Then

With Me.Subfrm_Det_Entrada.Form.RecordsetClone

     .MoveFirst

     Do While Not .EOF

     CurrentDb.Execute ("UPDATE 2_Materiales set Cantidad=Cantidad+" & !Cantidad & " WHERE CodMat=" & !CodMat)

     .MoveNext

     Loop

     End With

 With Me.Subfrm_Det_Entrada.Form.RecordsetClone

     .MoveFirst

     Do While Not .EOF

     CurrentDb.Execute ("UPDATE Detalle_Pedido set Cantidad=Cantidad+" & !Cantidad & " WHERE CodMat=" & !CodMat)

     .MoveNext

     Loop

End With

End If

DoCmd.GoToRecord , , acNewRec

End Sub

2 respuestas

Respuesta
1

Quiero destacar que la tabla 2_Materiales, corresponde al listado de Materiales con su stock.

Y que la tabla Detalle_Pedido, corresponde a la sub tabla de Orden de Pedido de materiales donde se detallan los materiales solicitados con sus correspondientes Cantidades solicitadas .El nombre del campo Cantidad corresponde a la Cantidad de Material solicitado mediante la misma SubTabla.

Respuesta
1

Entiendo que en la tabla 2_Materiales tienes un campo (por ejemplo, OrdenPedido) que relaciona el número de pedido de la tabla con el número de pedido del formulario de la entrada de materiales.

En la condición WHERE deben cumplirse dos condiciones:

* Que el valor del campo CodMat de la tabla sea igual al valor CodMat del formulario (CodMat = CodMatForm) y

* que el valor del campo OrdenPedido de la tabla sea igual al valor OrdenPedido del formulario (OrdenPedido = OrdenPedidoForm)

Para que se cumplan las dos condiciones hay que poner:

WHERE CodMat = !CodMatForm AND OrdenPedido = !OrdenPedidoForm

He añadido la palabra "Form" a CodMat y OrdenPedido para que no se llamen igual que los campos de la tabla.

Te super agradezco Jesús la explicación y lo pronto de tu ayuda... lo voy a implementar y luego comento los resultados.

Jesus te cuento que he implementado el Código como tu bien me lo has explicado, pero me sigue tirando error de proceso. 

El mensaje de error de Compilación me dice:

Se esperaba: Separador de listas o)

Prueba poniendo paréntesis a las condiciones del WHERE: WHERE (CodMat = !CodMatForm AND OrdenPedido = !OrdenPedidoForm)

Estimado Jesús, ante todo, muchas gracias por la paciencia y la ayuda!, te cuento que me sigue tirando error... en la 1er foto que te subo del código luego de WHERE coloco IdPedido = IdPedido y el error me lo marca en este campo...

en la Segunda fotografía que te subo, reemplazo el campo IdPedido por el de IdDet ( que corresponde al Id del Subform Detalle de pedido donde se registran los productos y cantidades) y ante este caso el error de compilación me lo marca sobre WHERE.

En esta otra captura de pantalla, se encuentra el código fuente sin los (), marcándome toda la sintaxis como un error

Ahora bien si antes de WHERE LE COLOCO LAS COMILLAS " Y al Final de  CodMat también, no me tira error de sintaxis pero me suma a todos los ítems de todos los pedidos la cantidad ingresada de materiales... la verdad, es que he intentado de todas las maneras posibles de resolver el problema y no logro obtener la solución.

observa en las siguientes capturas en la columna correspondiente a las entregas realizadas de materiales denominada ENTREGO. Todas tienen registradas la misma cantidad de materiales entregados. Lo mismo me sucede en los distintos pedidos. Al ingresar la entrega de un material de un determinado numero de pedido, esta entrega se suma a todos los materiales de TODOS LOS PEDIDOS.

Te comento el siguiente código:

CurrentDb.Execute ("UPDATE Detalle_Pedido set Cantidad=Cantidad+" & !Cantidad & "WHERE IdPedido = IdPedido AND CodMat = CodMat")

Fuera de las comillas has de tener el valor que contiene el formulario, como has hecho con ! Cantidad. Es decir, por ejemplo, IdPedido ha de ser igual al nombre del cuadro de texto que contiene el valor de IdPedido en el formulario.

Por lo tanto, debería ser algo parecido a:

CurrentDb.Execute ("UPDATE Detalle_Pedido set Cantidad=Cantidad+" & !Cantidad & "WHERE (IdPedido =" & !IdPedido & " AND CodMat =" & !CodMat & ")"

Si el valor del IdPedido en el Subform Detalle de pedido está en el campo IdDet, has de poner:

"WHERE (IdPedido=" & Me.IdDet

Lo mismo habria que hacer con CodMat:

"WHERE (IdPedido=" & Me.IdDet & " AND CodMat=" & Me.IdCodMat & ")"

Dónde está escrito con letra cursiva, debes poner el nombre del campo del formulario/subformulario.

Me acabo de dar cuenta que estas haciendo un UPDATE en un RECORDSETCLONE:

With Me.Subfrm_Det_Entrada.Form.RecordsetClone

RecordsetClone es de sólo lectura, no permite ediciones. Por lo tanto, no te permitirá actualizar los valores de las tablas.

Te cuento Jesus, Probé con tu primer explicación, y me volvió a tirar error. Probe de poner un paréntesis de cierre. Y el error continuó.

Luego Probé con tu segunda explicación. El tema radica, en que estamos hablando de los campos de un SubForm. Porque el Subform detalle de pedido esta dentro del cuerpo del Form pedido. Es como si fuera una factura de venta, con la diferencia, de que en este caso es un remito de entrada de materiales.

A continuación te subo una captura de como es la ventana de operación.

Te super agradezco de todo corazón la voluntad y toda la onda que le estas poniendo para ayudarme a solucionar este problemita que me tiene trabada. Sos muy amable de tu parte!!!!...

Después quisiera que me contaras cómo solucionarías tú lo de RecordsetClone que es de sólo lectura y el cuál no permite ediciones, porque tampoco le encuentro la vuelta.

Vamos por partes:

Quieres actualizar el campo "Cantidad" de la tabla "Detalle_Pedido" con la cantidad existente en la tabla más la cantidad (¿! Cantidad?) Del formulario:

"UPDATE Detalle_Pedido SET Cantidad=Cantidad+" & nombre del campo cantidad en el formulario 

El nombre del campo cantidad en el formulario es ! ¿Cantidad?

Siempre y cuando el campo "IdPedido" de la tabla "Detalle_Pedido" sea igual al identificador del pedido (¿IdDet?) Del formulario (IdPedido=nombre del campo idpedido en el formulario):

& "WHERE IdPedido=" & nombre del campo IdPedido en el formulario

¿El nombre del campo IdPedido en el formulario es IdDet?

Y el campo "CodMat" de la table "Detalle_Pedido" sea igual al identificador del pedido (¿?) Del formulario (CodMat = nombre del campo CodMat en el formulario):

& "CodMat=" & nombre del campo CodMat en el formulario

¿Cuál es el nombre del campo CodMat en el formulario ?

Voy a intentar ser más prolija para explicarte la estructura de las tablas...

Por un lado Tenemos 2 tablas para registrar las diferentes ENTRADAS DE LOS MATERIALES PEDIDOS:

Tabla 1 : ENTRADA con su Key IdEntrada (donde registramos los datos de la entrada como ser la Orden de Compra que la generó, la Empresa Oferente que es la que entregó los materiales bajo esa Orden, el N° de Remito bajo la que se hace la entrega, el N° de Pedido [IdPedido] y la Fecha)

Tabla 2: DETALLE DE ENTRADA (donde se desglosa y se asienta el código de material ingresado y la cantidad. También aquí tenemos otros 3 campos los cuales me hacen de enlace con otras tablas, como ser IdPedidoIdDet e IdEntrada

Por otro lado tenemos las tablas referentes al pedido Realizado:

Tabla 3: PEDIDO MATERIALES (aquí registramos, el Tipo de documentación que originó la solicitud, si es un Suministro, una licitación publica o privada o una compra directa. La categorización, si es la 1er obra del año o la 2da, etc... Luego tenemos la Finalidad,  aquí va el tipo de obra de destino de los materiales solicitados, la fecha y el NI/NE que es un campo de enlace, este refiere al N° DE INTERNO DEL SUMINISTRO O AL N° DE EXPEDIENTE EN CASO DE SER UNA LICITACIÓN)

Cabe destacar, que el procedimiento es el siguiente:

1ERO......... SE HACE LA SOLICITUD DE PEDIDO DE MATERIALES (tablas Pedidos y Detalle de Pedido)

2DO.......... UNA VEZ REALIZADO EL PEDIDO, NOS DAN UN NÚMERO DE SUMINISTRO/LICITACIÓN  NI/NE y PROCEDEMOS AL ALTA DEFINITIVA DE LA SOLICITUD BAJO UN N° DE DOCUMENTACIÓN (Tablas Alta Suministro/Licitación)

3ERO........ Comienzan las entregas de materiales solicitados estas entregas pueden ser relaizadas de manera Total o Parcial.

Tabla 4: DETALLE DE PEDIDO (aquí colocamos los siguientes campos:

IdDet  &

IdPedido

Item

CodMat

TipoMarca

TipoModelo

CantPedido

PrecioUnitario

CostoTotal

Cantidad (Cuando tú me preguntas por el campo CANTIDAD, hace referencia a la Cantidad Entregada no al Stock de los Materiales que tengo en el Pañol, obviamente que al hacer la entrega se deben refrescar por un lado el STOCK DE MATERIALES EN EL PAÑOL, lo cual se realiza bajo la primer sentencia de UPDATE (este funciona correctamente)... pero por otro lado se tiene que refrescar la cantidad de materiales entregados dentro del DETALLE DE PEDIDO, para yo así saber cuantos materiales se entregaron y cuantos faltan entregar, para poder de esa manera llevar a cabo un correcto seguimiento de los Pedidos..... este procedimiento se realizada bajo la 2da. sentencia de UPDATE, que es en la que tengo el problema, dado que al actualizar, me actualiza todos los materiales bajo el mismo código que se solicito en todos los pedidos realizados, o bien al modificarla para evitar este error garrafal, me actualiza TODOS LOS MATERIALES DE TODOS LOS PEDIDOS así estos NO tengan el mismo Código... y estoy allí, encerrada en ese problemita sin poder solucionarlo)

FaltaEntregar (Este es un campo que cuando automatico, que cuando completa la entrega, 

                           automaticamente se coloca la palabra COMPLETO y se colorea de color rojo)

Estado

Actualizar (Este es un campo que debo eliminar, lo coloque porque intente solucionar el

                    problema utilizando una consulta de ACTUALIZACIÓN, pero tampoco me funciono)

por lo cual

los campos:

Cantidad de la Tabla Detalle de Entrada y Cantidad de la Tabla Detalle de Pedido --------> Hacen ambos referencia a la Cantidad Entregada de Materiales PEDIDOS.

Perdón cometí un ERROR al explicarte...

El campo FaltaEntregar -------> ES UN CAMPO CALCULADO que realiza la siguiente operación: 

                                                   Campos CantPedido - Cantidad (que representa la Cantidad

                                                                                                               Entregada) así de manera visual me

                                                                                                 mostraría cuantas unidades restan entregar.

El campo Estado --------> es el campo que cuando completa la entrega, automáticamente se coloca

                                          la palabra COMPLETO y se colorea de color rojo)

La información que necesitas saber está en el formulario.

En el código VBA que mostrabas tenias dos procedimientos:

Private Sub Comando82_Click() y Private Sub Comando95_Click()

que supongo pertenecen a la imagen del formulario que mostraste:

En este formulario, ¿cómo se llaman los campos que muestran los valores de "IdPedido" y "CodMat" de la tabla "1_Entrada_Detalle"?

Según tu código VBA, estas en:

Me.Subfrm_Det_Entrada.Form

¿El formulario que he mostrado en la imagen anterior se llama "Subform_Det_Entrada"?

En tu código VBA, estás en:

Me.Subfrm_Det_Entrada.Form

¿La imagen del formulario de la entrada anterior se llama "Subform_Det_Entrada ?

¿Por qué necesitas saber el nombre de los campos del formulario "Subfrm_Det_Entrada" que muestran los valores "Cantidad", "IdPedido" y "CodMat" de la tabla "1_Entrada_Detalle ?

Porqué es el código que tienes escrito en VBA. Lo que yo entiendo que quiere ejecutar tu codigo VBA es:

* Recorrer todos los registros del formulario "Subfrm_Det_Entrada"

With Me.Subfrm_Det_Entrada.Form.RecordsetClone

.MoveFirst

Do While Not .EOF

...

.MoveNext

Loop

End With

* Para actualizar la cantidad de la tabla "2_Materiales" sumandole la cantidad que muestra el formulario "Subfrm_Det_Entrada"

CurrentDb.Execute ("update 2_Materiales set Cantidad=Cantidad+" & NOMBRE DEL CAMPO CANTIDAD EN EL FORMULARIO SUBFRM_DET_ENTRADA

* Donde los campos "IdPedido" y "CodMat" de la tabla "2_Materiales" sean igual a los campos del formulario "Subfrm_Det_Entrada" que muestran los valores IdPedido y CodMat

& "where IdPedido=" & NOMBRE DEL CAMPO IDPEDIDO EN EL FORMULARIO SUBFRM_DET_ENTRADA & "and CodMat=" & NOMBRE DEL CAMPO CODMAT EN EL FORMULARIO SUBFRM_DET_ENTRADA

Muy importante: Este código VBA funcionará siempre y cuando el origen de los datos del formulario "Subfrm_Det_Entrada" sea, como mínimo, los valores de la tabla "1_Entrada_Detalle"

Realmente Jesús te agradezco mucho la colaboración y paciencia!

Te cuento, como no soy muy experta a la hora de escribir códigos de procedimientos, intente a todos los campos, tanto en tablas como en formularios, llamarlos de la misma manera, a los efectos de evitar confusiones y errores, por lo cual, el campo IdPedido se llama de la misma manera tanto en la tabla como en el formulario, lo mismo CodMat y Cantidad.

El subformulario se llama como bien lo especificaste "Subfrm_Det_Entrada".

en cuanto a la imagen a la cual me haces referencia se trata de un FORMULARIO CON UN SUBFORMULARIO DENTRO.

EL FORMULARIO SE LLAMA -------------> frm_Entrada

EL SUBFORMULARIO que contiene los campos Cantidad y CodMat se llama -----> Subfrm_Det_Entrada

Entonces, ¿IdPedido está en el formulario "frm_Entrada"?

Prueba el siguiente código VBA (te pongo solo la línea que has de modificar):

CurrentDb.Execute ("UPDATE Detalle_Pedido SET Cantidad=Cantidad+" & Me.Cantidad & "WHERE (IdPedido=" & Forms!frm_Entrada!Id.PedidoCodMat & "AND CodMat=" & Me.CodMat & ");"

Te detallo qué hace este código:

Actualiza el campo "Cantidad" de la tabla "Detalle_Pedido" con la cantidad que tiene almacenada más ("UPDATE Detalle_Pedido SET Cantidad=Cantidad+") [todo este código entre comillas dobles porque no necesita ningún dato del formulario]

la "Cantidad" que muestra el formulario "Subfrm_Det_Entrada" (Me.Cantidad) [sin comillas dobles porque es un campo del formulario. Se pone "Me" porque es un campo del formulario que estas analizando en el código: With Me.Subfrm_Det_Entrada]

donde el campo "IdPedido" de la tabla "Detalle_Pedido" es igual a ("WHERE IdPedido=") [todo este código entre comillas dobles porque no necesita ningún dato del formulario]

El "IdPedido" que muestra el formulario "frm_Entrada" (Forms!frm_Entrada! Id.PedidoCodMat) [sin comillas dobles porque es un campo del formulario. No se puede poner "Me" porque NO es un campo del formulario que estas analizando en el código: With Me.Subfrm_Det_Entrada. Por eso, hay que indicar que este campo está ubicado en el formulario "frm_Entrada": Forms!frm_Entrada]

y donde el campo "CodMat" de la tabla "Detalle_Pedido" es igual a ("AND CodMat=") [todo este código entre comillas dobles porque no necesita ningún dato del formulario]

el "CodMat" que muestra el formulario "Subfrm_Det_Entrada" (Me.CodMat) [sin comillas dobles porque es un campo del formulario. Se vuelve a poner "Me" porque es un campo del formulario que estas analizando en el código: With Me.Subfrm_Det_Entrada]

Ya me diras...

Disculpa he visto que había un error en el código que te he escrito. La línea de código correcto es:

CurrentDb.Execute ("UPDATE Detalle_Pedido SET Cantidad=Cantidad+" & Me.Cantidad & "WHERE (IdPedido=" & Forms!frm_Entrada!Id.Pedido & "AND CodMat=" & Me.CodMat & ");"

Estimado Jesús...

Ante todo muy buenos días!

Te cuento que aún sigo luchando con el código, me cuesta desistir hasta no conseguir una solución que dé respuesta a la instrucción de la operación que necesito realizar.

He probado de mil maneras diferentes, y no hay caso...

Te muestro a través de un screen de pantalla el error que me tira, según el código que mediante tu última recomendación me has enviado... me dice que falta UN OPERADOR, me reconoce el CodMat el cual en el caso del material ingresado es el n° 566 y el IdPedido el cual en este caso es el N° 14, PERO ME DICE QUE FALTA UN OPERADOR... ojala supieras dilucidar a cual hace referencia... porque sigo sin poder solucionarlo....

Me he creado una BBDD para recrear tu base de datos con el código y, efectivamente, me daba el mismo error que a ti. Pero lo he solucionado (poniendo espacios en blanco !). Te paso el código y una imagen del resultado:

Private Sub Form_Open(Cancel As Integer)
'Msgerr = MsgBox("Me.Det_Entrada!Cantidad: " & Forms!Formulario1!Det_Entrada!Cantidad & vbNewLine, vbExclamation, "") = vbOK
With Me.Det_Entrada.Form.RecordsetClone
'Msgerr = MsgBox("!Cantidad: " & !Cantidad & vbNewLine, vbExclamation, "") = vbOK
.MoveFirst
Do While Not .EOF
CurrentDb.Execute ("UPDATE Detalle_Pedido SET Cantidad = Cantidad + " & !Cantidad & " WHERE (IdPedido= " & !IdPedido & " AND CodMat= " & !CodMat & ");")
.MoveNext
Loop
End With
Exit Sub
End Sub

Si te fijas en el código, tengo unas instrucciones que comienzan por "Msgerr = ...". Son ventanas que me muestran el resultado que deseo. Es la forma que tengo de detectar errores y comprobar que el código hace lo que quiero que haga.

Si compruebas la imagen, el subformulario "Detalle_Pedido" muestra una cantidad de 400 para el pedido 14, que es la suma de las cantidades del subformulario "Det_Entrada" con IdPedido=14 y CodMat=566.

Supongo que lo tienes previsto pero, fíjate que ocurre en mi BBDD cuando ejecuto dos veces seguidas el formulario:

La cantidad del subformulario "Detalle_Pedido" es 800 (400 + 300 + 100) porque el valor anterior era 400 más las cantidades del subformulario "Det_Entrada" (Id 1: 300 + Id 6: 100). Es decir, me duplica los valores.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas