Como ingresar varios registros con campos en común
Espero me puedan ayudar. Tengo una tabla de ordenes de compra cuyos campos son: numeroOC, Fecha, Producto, Cantidad y Precio. Con esto para ingresar una orden de compra con por ejemplo 5 productos debo ingresar 5 registros, los cuales van a tener el mismo numeroOC y Fecha.
Entonces quiero crear un formulario en el que se deba ingresar solo una vez el numeroOC y Fecha y después varios registros con producto, cantidad precio. Intenté con los formularios de varios elementos pero debo ingresar el numeroOC y Fecha apra cada registro y no es la idea.
Entonces quiero crear un formulario en el que se deba ingresar solo una vez el numeroOC y Fecha y después varios registros con producto, cantidad precio. Intenté con los formularios de varios elementos pero debo ingresar el numeroOC y Fecha apra cada registro y no es la idea.
Respuesta de Neckkito Nck
1
1
Hay varias maneras de hacer lo que comentas. Te indico por encima la primera, pero no te la explicaré en profundidad, y sí te explicaré la segunda. Evidentemente, si te decantas por la primera y no la sabes hacer me lo comentas y ya te la explicaré con detalle.
La primera sería dividir la tabla que tienes en dos tablas, una que recogiera los campos numeroOC y Fecha, que sería la "principal", y otra que recogería un campo autonumérico, numeroOC, Producto, Cantidad y Precio, que sería la "secundaria".
Ahora tendrías que crear un formulario basado en la tabla principal, y después, dentro de ese formulario, un subformulario basado en la tabla secundaria.
Lo dicho, si te gusta este sistema y no sabes cómo hacerlo me lo comentas y yo te lo explico "con pelos y señales" ;)
---
El segundo sistema requiere un poquito de programación. Te lo voy explicando paso a paso:
1.- Con el formulario en vista diseño creas un botón de comando en el formulario, le pones de titulo algo así como "Seguir con la misma OC" (o el que más te guste).
2.- Le das, sobre ese botón, click con el botón derecho del ratón, y después seleccionas "Generar evento..." En la pantalla que te sale le dices que quieres generar código.
3.- En la nueva pantalla que te aparece escribes el siguiente código:
---
Dim intOC As Variant
Dim dtmFecha As Variant
intOC = Me.numeroOC.Value
dtmFecha = Me.Fecha.Value
If IsNull(intOC) Then Exit Sub
If IsNull(dtmFecha) Then Exit Sub
DoCmd.GoToRecord acDataForm, Me.Name, acNewRec
Me.numeroOC.Value = intOC
Me.Fecha.Value = dtmFecha
Me. Producto. SetFocus
---
Ojo: todo esto debe estar comprendido entre la primera línea que te sale, que debe ser algo así como "Private Sub comandoX_Click()" y la última, que pone "End Sub"
En el código he supuesto que:
-Los nombres de los campos que nombrabas en tu consulta son los nombres originales. Si, por ejemplo, el campo Fecha en realidad fuera FechaOC tendrías que cambiar la palabra "Fecha" por FechaOC (ojo, sólo cuando la palabra fuera FECHA. Por ejemplo, dtmFecha no deberías cambiarlo).
-También he supuesto que el orden de los campos en el formulario es el que apuntabas en tu consulta. Es decir, la secuencia es numeroOC->Enter->El foco se te pone en Fecha->Enter->El foco se te pone en Producto. Lo comento porque la línea de código "Me.Producto.SetFocus" lo que hace es que, al ir a un nuevo registro, hace "saltar" el enfoque por encima de los campos numeroOC y fecha para que puedas directamente rellenar el Producto y siguientes.
Y eso es todo amigos...!
Espero no haberte liado demasiado. Ante cualquier duda que te surja me dices cosas.
La primera sería dividir la tabla que tienes en dos tablas, una que recogiera los campos numeroOC y Fecha, que sería la "principal", y otra que recogería un campo autonumérico, numeroOC, Producto, Cantidad y Precio, que sería la "secundaria".
Ahora tendrías que crear un formulario basado en la tabla principal, y después, dentro de ese formulario, un subformulario basado en la tabla secundaria.
Lo dicho, si te gusta este sistema y no sabes cómo hacerlo me lo comentas y yo te lo explico "con pelos y señales" ;)
---
El segundo sistema requiere un poquito de programación. Te lo voy explicando paso a paso:
1.- Con el formulario en vista diseño creas un botón de comando en el formulario, le pones de titulo algo así como "Seguir con la misma OC" (o el que más te guste).
2.- Le das, sobre ese botón, click con el botón derecho del ratón, y después seleccionas "Generar evento..." En la pantalla que te sale le dices que quieres generar código.
3.- En la nueva pantalla que te aparece escribes el siguiente código:
---
Dim intOC As Variant
Dim dtmFecha As Variant
intOC = Me.numeroOC.Value
dtmFecha = Me.Fecha.Value
If IsNull(intOC) Then Exit Sub
If IsNull(dtmFecha) Then Exit Sub
DoCmd.GoToRecord acDataForm, Me.Name, acNewRec
Me.numeroOC.Value = intOC
Me.Fecha.Value = dtmFecha
Me. Producto. SetFocus
---
Ojo: todo esto debe estar comprendido entre la primera línea que te sale, que debe ser algo así como "Private Sub comandoX_Click()" y la última, que pone "End Sub"
En el código he supuesto que:
-Los nombres de los campos que nombrabas en tu consulta son los nombres originales. Si, por ejemplo, el campo Fecha en realidad fuera FechaOC tendrías que cambiar la palabra "Fecha" por FechaOC (ojo, sólo cuando la palabra fuera FECHA. Por ejemplo, dtmFecha no deberías cambiarlo).
-También he supuesto que el orden de los campos en el formulario es el que apuntabas en tu consulta. Es decir, la secuencia es numeroOC->Enter->El foco se te pone en Fecha->Enter->El foco se te pone en Producto. Lo comento porque la línea de código "Me.Producto.SetFocus" lo que hace es que, al ir a un nuevo registro, hace "saltar" el enfoque por encima de los campos numeroOC y fecha para que puedas directamente rellenar el Producto y siguientes.
Y eso es todo amigos...!
Espero no haberte liado demasiado. Ante cualquier duda que te surja me dices cosas.
Una cosa más, que he dado por supuesta y quizá no debería. Cuando crees el botón se te iniciará el asistente. Simplemente tienes que cancelarlo.
Suerte!
Suerte!
Muchas Gracias! Pero no me funciona jaja debo estar haciendo algo mal. Mira no me queda muy claro un tema, ¿el formulario que creo debe ser común y corriente o uno de varios elementos?
Lo otro, ¿en teoría debería ingresar el primer registro y después apretar el botón e ingresar el segundo? ¿O cómo sería el procedimiento para ingresar varios? ¿Debería crear un segundo botón para guardar?
Cambié un poco lo que me pegaste pa ajustarlo a mi tabla y quedó así:
Dim intEmbarque As Variant
Dim intPO As Variant
Dim dtmFechaEmbarque As Variant
Dim dtmFechaArribo As Variant
intEmbarque = Me.numeroEmbarque.Value
intPO = Me.numeroPO.Value
dtmFechaEmbarque = Me.fechaEmbarque.Value
dtmFechaArribo = Me.fechaArribo.Value
If IsNull(intEmbarque) Then Exit Sub
If IsNull(intPO) Then Exit Sub
If IsNull(dtmFechaEmbarque) Then Exit Sub
If IsNull(dtmFechaArribo) Then Exit Sub
DoCmd.GoToRecord acDataForm, Me.Name, acNewRec
Me.numeroEmbarque.Value = intEmbarque
Me.numeroPO.Value = intPO
Me.fechaEmbarque.Value = dtmFechaEmbarque
Me.fechaArribo.Value = dtmFechaArribo
Me.producto.SetFocus
Espero me puedas seguir ayudando porque no creo estar tan lejos.
Gracias!
Lo otro, ¿en teoría debería ingresar el primer registro y después apretar el botón e ingresar el segundo? ¿O cómo sería el procedimiento para ingresar varios? ¿Debería crear un segundo botón para guardar?
Cambié un poco lo que me pegaste pa ajustarlo a mi tabla y quedó así:
Dim intEmbarque As Variant
Dim intPO As Variant
Dim dtmFechaEmbarque As Variant
Dim dtmFechaArribo As Variant
intEmbarque = Me.numeroEmbarque.Value
intPO = Me.numeroPO.Value
dtmFechaEmbarque = Me.fechaEmbarque.Value
dtmFechaArribo = Me.fechaArribo.Value
If IsNull(intEmbarque) Then Exit Sub
If IsNull(intPO) Then Exit Sub
If IsNull(dtmFechaEmbarque) Then Exit Sub
If IsNull(dtmFechaArribo) Then Exit Sub
DoCmd.GoToRecord acDataForm, Me.Name, acNewRec
Me.numeroEmbarque.Value = intEmbarque
Me.numeroPO.Value = intPO
Me.fechaEmbarque.Value = dtmFechaEmbarque
Me.fechaArribo.Value = dtmFechaArribo
Me.producto.SetFocus
Espero me puedas seguir ayudando porque no creo estar tan lejos.
Gracias!
En primer lugar el formulario puede ser tanto normal como un formulario de varios elementos. En el formulario deberías tener como mínimo los siguientes elementos:
- Los campos para introducir la información
- Un botón para añadir un nuevo registro
- El botón que has creado para añadir un nuevo registro, pero que te copie la información que tienes en pantalla.
El proceso debería ser el siguiente:
Empiezas a rellenar los campos hasta que los tienes todos. Si quieres añadir una NUEVA orden de compra DIFERENTE a la que acabas de rellenar deberías hacer click en el botón de añadir nuevo registro. Si lo que quieres es añadir una NUEVA orden de compra CON LOS MISMOS DATOS DUPLICADOS tienes que darle al botón que hemos creado con el código. En teoría, debería añadirte un nuevo registro y rellenarte automáticamente los campos.
Por lo que respecta al código en principio no veo nada extraño más que hay una línea de código que no has cambiado, que es "Me.Producto.SetFocus". Si no tienes ningún campo llamado "Producto" el código te dará un error porque no encontrará el campo en cuestión. O bien cambias "Producto" por el nombre de alguno de tus campos o bien eliminas la línea del código (aunque sin conocer tu BD no puedo estar seguro del comportamiento del cursor).
Échale un vistazo y dime cosas. Si te da algún error dime qué es lo que pone ese error, a ver si me da alguna pista de lo que puede pasar.
- Los campos para introducir la información
- Un botón para añadir un nuevo registro
- El botón que has creado para añadir un nuevo registro, pero que te copie la información que tienes en pantalla.
El proceso debería ser el siguiente:
Empiezas a rellenar los campos hasta que los tienes todos. Si quieres añadir una NUEVA orden de compra DIFERENTE a la que acabas de rellenar deberías hacer click en el botón de añadir nuevo registro. Si lo que quieres es añadir una NUEVA orden de compra CON LOS MISMOS DATOS DUPLICADOS tienes que darle al botón que hemos creado con el código. En teoría, debería añadirte un nuevo registro y rellenarte automáticamente los campos.
Por lo que respecta al código en principio no veo nada extraño más que hay una línea de código que no has cambiado, que es "Me.Producto.SetFocus". Si no tienes ningún campo llamado "Producto" el código te dará un error porque no encontrará el campo en cuestión. O bien cambias "Producto" por el nombre de alguno de tus campos o bien eliminas la línea del código (aunque sin conocer tu BD no puedo estar seguro del comportamiento del cursor).
Échale un vistazo y dime cosas. Si te da algún error dime qué es lo que pone ese error, a ver si me da alguna pista de lo que puede pasar.
Te explico una cosa del código, que quizá por eso pueda darte la sensación de que no te está funcionando.
¿Ves todas las líneas que ponen "If IsNull(Campo) Then Exit Sub? Esas líneas lo que hacen es chequear que hayas escrito algún valor en los campos correspondientes, porque si no estuvieran ahí te saldría un error que te diría "Uso no válido de Null".
Si alguno de los campos está vacío esos If se dan cuenta y salen del procedimiento, y entonces el resto de código no se ejecuta.
Si tienes alguna duda me lo comentas.
¿Ves todas las líneas que ponen "If IsNull(Campo) Then Exit Sub? Esas líneas lo que hacen es chequear que hayas escrito algún valor en los campos correspondientes, porque si no estuvieran ahí te saldría un error que te diría "Uso no válido de Null".
Si alguno de los campos está vacío esos If se dan cuenta y salen del procedimiento, y entonces el resto de código no se ejecuta.
Si tienes alguna duda me lo comentas.
Gracias! Ahora me esta funcionando para el caso normal, tengo un solo problema, el campo producto esta relacionado a otra tabla que se llama productos y además es parte de la clave primaria de la tabla entonces si agrego un producto que esta dentro de la tabla productos y no esta ignresado funciona bien, pero si no está dentro de la lista de productos o si ya esta ingresado (violando la clave) me arrija un error en la linea:
DoCmd.GoToRecord acDataForm, Me.Name, acNewRec
Y dice error 2105 en tiempo de ejecución : no se puede ir al registro especificado.
Igual me suena lógico, pero no se como arreglarlo, ¿crees qué me podrías ayudar con eso?
Gracias!
DoCmd.GoToRecord acDataForm, Me.Name, acNewRec
Y dice error 2105 en tiempo de ejecución : no se puede ir al registro especificado.
Igual me suena lógico, pero no se como arreglarlo, ¿crees qué me podrías ayudar con eso?
Gracias!
Vamos a ver: si entiendo bien lo que dices la tabla "Productos" debe tener una clave principal. ¿Qué campo es la clave principal?
Por otra parte, la otra tabla (que no sé cómo se llama) donde recoges esos campos (numeroEmbarque, numeroPO, etc.) parece que también tiene una clave principal. ¿Qué campo es la clave principal?
A ver si así puedo aclararme con lo que me explicas, porque la verdad es que no acabo de entender bien lo que me comentas.
Cuando lo tenga claro ya nos "meteremos" con ese error :)
Por otra parte, la otra tabla (que no sé cómo se llama) donde recoges esos campos (numeroEmbarque, numeroPO, etc.) parece que también tiene una clave principal. ¿Qué campo es la clave principal?
A ver si así puedo aclararme con lo que me explicas, porque la verdad es que no acabo de entender bien lo que me comentas.
Cuando lo tenga claro ya nos "meteremos" con ese error :)
Disculpa quizás no me exprese bien: las tablas son 2:
Producto: nombre, vida útil, lumens, watts. --> Clave principal nombre.
embarques: numeroEmbarque, numeroPO, fechaEmbarque, fechaArribo, producto, cantidad, precio. --> clave principal numeroEmabrque, producto.
Ademas existe una relación del tipo 1-infinito entre producto(nombre)->embarques(producto).
Entonces, con lo que tu me explicaste me funciona bien el formulario si ingreso un registro en el formulario de embarques, cuyo producto esta dentro de la tabla "productos" y siempre que no exista otro registro anterior con igual numeroEmbarque y registro.
Pero si alguna de estas 2 codniciones no se cumple, es decir si ingreso un producto que no esté en la tabla productos o que este repetido me tira el error que te escribí.
Tienes alguna idea como solucionar para que en vez del error pase algo diferente, que te diga producto invalido o por ultimo que no haga nada no se.
Gracias!
Producto: nombre, vida útil, lumens, watts. --> Clave principal nombre.
embarques: numeroEmbarque, numeroPO, fechaEmbarque, fechaArribo, producto, cantidad, precio. --> clave principal numeroEmabrque, producto.
Ademas existe una relación del tipo 1-infinito entre producto(nombre)->embarques(producto).
Entonces, con lo que tu me explicaste me funciona bien el formulario si ingreso un registro en el formulario de embarques, cuyo producto esta dentro de la tabla "productos" y siempre que no exista otro registro anterior con igual numeroEmbarque y registro.
Pero si alguna de estas 2 codniciones no se cumple, es decir si ingreso un producto que no esté en la tabla productos o que este repetido me tira el error que te escribí.
Tienes alguna idea como solucionar para que en vez del error pase algo diferente, que te diga producto invalido o por ultimo que no haga nada no se.
Gracias!
Los números de embarque (que corresponderían al campo "numeroEmbarque"), ¿se pueden repetir? Es decir, supongamos que el número de embarque sea el 123. Entonces, en situación normal, tú meterías un registro que sería:
- NumeroEmbarque: 123
- NumeroPO: 333
- Etc...
Y después meterías un segundo registro que sería:
- NumeroEmbarque: 123
- NumeroPO: 334
- Etc.
Y así sucesivamente.
¿Es así como quieres que funcione la introducción de registros?
Ya me dirás cosas. Ánimo, que esto está hecho!
- NumeroEmbarque: 123
- NumeroPO: 333
- Etc...
Y después meterías un segundo registro que sería:
- NumeroEmbarque: 123
- NumeroPO: 334
- Etc.
Y así sucesivamente.
¿Es así como quieres que funcione la introducción de registros?
Ya me dirás cosas. Ánimo, que esto está hecho!
Si funciona tal cual como me dices, pueden tener el mismo... acabo de cachar que quizás tengo un par de problemas con el diseño de la tabla, pero igual me gustaría que me ayudaras con esto porque cuando la modifique voy a necesitar que haga lo mismo.
Gracias!
Gracias!
Cuando, en una tabla, metes un campo como clave principal, lo que hace esa clave principal es fijar ese campo como identificador inequívoco del registro. Esto simplemente significa que la clave principal te "protege" para que, por error, no haya duplicidades.
Si tú, al campo numeroEmbarque, lo pones como clave principal, le estás diciendo a Access que sólo vas a poder meter un registro que contenga un único número de embarque. Si el número de embarque es el 123, sólo vas a poder meter un registro con ese número, porque si intentas crear un registro nuevo e introducir otra vez 123 lo más seguro es que te salga un mensaje de error.
La solución más normal para estos casos en los que quieres que el número de embarque se pueda repetir es poner la tabla en vista diseño, añadir una fila (que quedará en primer lugar, arriba del todo) y poner un nuevo campo que se suele llamar Id, de tipo autonumérico. Pones ese Id como clave principal y se la quitas al campo numeroEmbarque. Ahora sí podrás ir repitiendo ese 123 sin problemas.
También, desde mi punto de vista, no tiene sentido que en la tabla "embarques" el campo "producto" sea clave principal, porque sí se tiene que poder repetir.
Lo que sí está bien, si no quieres utilizar un código de producto, es que en la tabla "producto" el campo "nombre" sea clave principal, porque aquí sí que no te interesa duplicar la información.
Bueno. Ya me irás diciendo cosas de cómo te va. Y, evidentemente, estaré encantado de contestar las dudas que puedas tener (¡si las sé!) ;)
Si tú, al campo numeroEmbarque, lo pones como clave principal, le estás diciendo a Access que sólo vas a poder meter un registro que contenga un único número de embarque. Si el número de embarque es el 123, sólo vas a poder meter un registro con ese número, porque si intentas crear un registro nuevo e introducir otra vez 123 lo más seguro es que te salga un mensaje de error.
La solución más normal para estos casos en los que quieres que el número de embarque se pueda repetir es poner la tabla en vista diseño, añadir una fila (que quedará en primer lugar, arriba del todo) y poner un nuevo campo que se suele llamar Id, de tipo autonumérico. Pones ese Id como clave principal y se la quitas al campo numeroEmbarque. Ahora sí podrás ir repitiendo ese 123 sin problemas.
También, desde mi punto de vista, no tiene sentido que en la tabla "embarques" el campo "producto" sea clave principal, porque sí se tiene que poder repetir.
Lo que sí está bien, si no quieres utilizar un código de producto, es que en la tabla "producto" el campo "nombre" sea clave principal, porque aquí sí que no te interesa duplicar la información.
Bueno. Ya me irás diciendo cosas de cómo te va. Y, evidentemente, estaré encantado de contestar las dudas que puedas tener (¡si las sé!) ;)
Gracias, pero la verdad si se como funcionan las claves y todo el tema, hice un par de cursos de BD (Sql, no access) en la universidad, mi tema es que el código que me enviaste tira un error cuando alguien intenta infringir la clave de seguridad, lo que esta bien que no lo deje, ¿pero mal que salga un error me entiendes?
Mi idea es que si alguien intente meterun producto que no se encuentre en la tabla productos, no lo deje pero que haga algo un poco menos feo que arrojar un error que es lo que hace ahora el código., una forma de ponerle un mensaje o algo por el estilo. Mi problema es que no me manejo mucho en Access ni VBA.
¿Se te ocurre como hacerlo?
Mi idea es que si alguien intente meterun producto que no se encuentre en la tabla productos, no lo deje pero que haga algo un poco menos feo que arrojar un error que es lo que hace ahora el código., una forma de ponerle un mensaje o algo por el estilo. Mi problema es que no me manejo mucho en Access ni VBA.
¿Se te ocurre como hacerlo?
Prueba de hacer esto. Te vas, con el formulario en vista diseño, al combo donde puedes seleccionar los productos (ese campo "producto") y sacas sus propiedades. Te vas a la pestaña Eventos y al evento "Al no estar en la lista" le copias el siguiente código:
---
Private Sub producto_NotInList(NewData As String, Response As Integer)
MsgBox "El producto seleccionado no está dado de alta" & _
vbCrLf & "Debe seleccionar un producto de la lista" _
, vbExclamation, "PRODUCTO INEXISTENTE"
Response = acDataErrContinue
Me.producto.Undo
End Sub
---
El texto que te he marcado en negrita (que está entre comillas) es el texto del mensaje. Evidentemente puedes poner el mensaje que quieras.
El comando "vbCrLf" lo que hace es agregarte un salto de línea, para que el mensaje no se vea tan "apiñado".
Ya me dirás qué tal te ha ido ;)
---
Private Sub producto_NotInList(NewData As String, Response As Integer)
MsgBox "El producto seleccionado no está dado de alta" & _
vbCrLf & "Debe seleccionar un producto de la lista" _
, vbExclamation, "PRODUCTO INEXISTENTE"
Response = acDataErrContinue
Me.producto.Undo
End Sub
---
El texto que te he marcado en negrita (que está entre comillas) es el texto del mensaje. Evidentemente puedes poner el mensaje que quieras.
El comando "vbCrLf" lo que hace es agregarte un salto de línea, para que el mensaje no se vea tan "apiñado".
Ya me dirás qué tal te ha ido ;)
- Compartir respuesta
- Anónimo
ahora mismo