Necesito insertar datos en una tabla desde un SubFormulario

Y disculpen tantas consultas seguidas que estoy haciendo.
Tengo una tabla llamada Cuenta_135 con los siguientes campos:

idC_135, Fecha,  Debe, Haber, Desc.

Tengo un Formulario Instrumentos con un Sub Formulario Detalle_Instrumento que tienen los siguientes campos:

Formulario Instrumentos: id_Instrumento, Fecha, Valor, idCliente

SubFormulario Detalle_Instrumento: idInstrumento, idOferta, Importe

Necesito que al adicionar un instrumento, que puede pagar varias Ofertas, por cada Oferta se inserte en la Tabla Cuenta_135 el idC_135 que seria el idOferta, la Fecha, el Debe en 0, el Haber en el Importe del SubFormulario Detalle_Instrumento, y en Desc el idCliente del Formulario Instrumentos.

No se si se entiende lo que pregunto.

Respuesta

I. Hola Dinorah, disculpe que de nuevo le responda sin conocer la respuesta, vi su consulta y a pesar de parecerme muy compleja debido a mi ignorancia, sentí curiosidad sobre si fuese posible recabar información y tuve creo la fortuna de ver una información que tal vez pudiese serle de alguna utilidad mientras le atiende un experto o experta de primera mano.

Aunque ya lo conocerá, llegado el caso quizás pueda serle de utilidad el programa Pseint.

Perdone por el trastorno de tantísima lectura, la imprecisión y la manera de responderle. Ánimo.


https://www-experts--exchange-com.translate.goog/articles/33939/Using-multiple-instances-of-a-sub-form-in-a-single-form.html?_x_tr_sl=en&_x_tr_tl=es&_x_tr_hl=es&_x_tr_pto=sc

https://nolongerset-com.translate.goog/insert-into-query/?_x_tr_sl=en&_x_tr_tl=es&_x_tr_hl=es&_x_tr_pto=sc

https://stackoverflow.com/questions/6796476/how-to-add-new-record-to-subform

https://www-devhut-net.translate.goog/ms-access-vba-appendinsert-record-into-another-external-database/?_x_tr_sl=en&_x_tr_tl=es&_x_tr_hl=es&_x_tr_pto=sc

https://www.access-programmers.co.uk/forums/threads/how-to-make-a-subform-bounded-to-a-query-field-updateable.324723/

https://p2p.wrox.com/access-vba/28555-need-copy-add-new-records-table.html

https://stackoverflow.com/questions/33730890/manually-inserting-record-into-linked-table-ms-access


*Para lograr que al agregar un instrumento de pago (como un cheque o transferencia) desde un subformulario en Microsoft Access, este se aplique a varias Ofertas y se genere un asiento automático en la tabla Cuenta por cada una de ellas, debes utilizar VBA (Visual Basic for Applications).

La mejor forma de hacerlo es programar el evento AfterInsert (Después de insertar) del subformulario donde registrarás el instrumento.

https://training.genexus.com/es/aprendiendo/pdf/eventos-de-disparo-de-reglas-en-transacciones-pdf 

Solución con VBA paso a paso

- Asumiendo que tienes una forma de seleccionar o saber qué Ofertas se están pagando (por ejemplo, a través de una tabla intermedia, un cuadro de lista de selección múltiple, o un saldo pendiente), el código debe recorrer esas Ofertas y ejecutar una consulta INSERT INTO por cada una.

Aquí tienes la estructura del código que debes adaptar:

idInstrumento = Me.IdInstrumentoPago ' Cambia por el nombre real de tu campo
Set db = CurrentDb
' 2. Abrir un recordset con las ofertas que este instrumento debe pagar
' NOTA: Ajusta esta consulta según cómo vincules el instrumento con las ofertas
strSQL = "SELECT IdOferta, MontoAAplicar FROM subTablaOfertasAPagar WHERE IdTemporal = " & Me.IdTemporal
Set rsAsignaciones = db.OpenRecordset(strSQL)

1. Capturar el ID del instrumento que se acaba de guardar

 En caso de errores, asegurar que la base de datos no quede corrupta
On Error GoTo Err_Transaccion
DBEngine. BeginTrans
' En caso de errores, asegurar que la base de datos no quede corrupta
On Error GoTo Err_Transaccion
DBEngine. BeginTrans
' 3. Recorrer cada Oferta e insertar en la tabla Cuenta (Debe)
Do While Not rsAsignaciones.EOF
' Consulta para insertar en la tabla Cuenta
' Ajusta los nombres de campos (IdOferta, IdInstrumento, Debe, CuentaContable, etc.)

idInstrumento = Me.IdInstrumentoPago ' Cambia por el nombre real de tu campo
Set db = CurrentDb
' 2. Abrir un recordset con las ofertas que este instrumento debe pagar
' NOTA: Ajusta esta consulta según cómo vincules el instrumento con las ofertas
strSQL = "SELECT IdOferta, MontoAAplicar FROM subTablaOfertasAPagar WHERE IdTemporal = " & Me.IdTemporal
Set rsAsignaciones = db.OpenRecordset(strSQL)
strSQL = "INSERT INTO Cuenta (IdOferta, IdInstrumento, Debe, Fecha) " & _
"VALUES (" & rsAsignaciones!IdOferta & ", " & _
idInstrumento & ", " & _
rsAsignaciones!MontoAAplicar & ", " & _
"#" & Format(Date, "yyyy-mm-dd") & "#);"
db.Execute strSQL, dbFailOnError
rsAsignaciones.MoveNext
Loop

' Confirmar los cambios en las tablas si todo salió bien
DBEngine.CommitTrans
MsgBox "Asientos generados exitosamente en la tabla Cuenta.", vbInformation, "Éxito"

Exit_Sub:
' Limpiar objetos de memoria
On Error Resume Next
rsAsignaciones.Close
Set rsAsignaciones = Nothing
Set db = Nothing
Exit Sub
Err_Transaccion:
' Si algo falla, deshace todas las inserciones para no dejar datos incompletos
DBEngine.Rollback
MsgBox "Error al generar los movimientos: " & Err.Description, vbCritical, "Error"
Resume Exit_Sub
End Sub

-- Puntos clave para que funcione:

Relación de datos:

Para que el código funcione, necesitas que el usuario elija previamente qué ofertas va a pagar antes (o durante) la creación del instrumento. Si usas casillas de verificación (Checkbox) en un listado de ofertas pendientes, la consulta del paso 2 debe filtrar aquellas donde Seleccionado = True. Transacciones (BeginTrans / CommitTrans): Esto es crucial. Si el instrumento debe pagar 3 ofertas, y el sistema falla al insertar la tercera, la transacción hace un Rollback (marcha atrás) para que no queden las dos primeras registradas a medias.

El Evento Correcto: Usa AfterInsert del subformulario del instrumento. Esto garantiza que el instrumento ya tiene un ID autonumérico asignado en la base de datos antes de intentar relacionarlo en la tabla Cuenta.



https://www.access-programmers.co.uk/forums/threads/how-to-show-debit-and-credit-amount-based-on-account-type.316919/

https://www-teachucomp-com.translate.goog/add-records-to-a-table-in-datasheet-view-in-access-instructions/?_x_tr_sl=en&_x_tr_tl=es&_x_tr_hl=es&_x_tr_pto=sc

https://www.youtube.com/watch?v=I994YhgbeNE

https://post-bytes-com.translate.goog/forum/topic/access/579000-append-table-with-records-in-recordset-via-vba?_x_tr_sl=en&_x_tr_tl=es&_x_tr_hl=es&_x_tr_pto=sc

https://accessdeveloper-net.translate.goog/how-to-use-subforms-in-ms-access?_x_tr_sl=en&_x_tr_tl=es&_x_tr_hl=es&_x_tr_pto=sc&_x_tr_hist=true

https://subjectguides-york-ac-uk.translate.goog/access/design?_x_tr_sl=en&_x_tr_tl=es&_x_tr_hl=es&_x_tr_pto=sc


Para lograr que se inserte automáticamente un registro en una tabla por cada Oferta existente al momento de añadir un nuevo Instrumento, la mejor opción en Microsoft Access es utilizar una Macro de Datos (Data Macro) de tipo After Insert en la tabla de Instrumentos, o bien ejecutar una consulta de datos anexados (Append Query) mediante código VBA en el formulario donde registras el instrumento. Aquí tienes las dos soluciones detalladas para que elijas la que mejor se adapte a tu base de datos:

- Opción 1: Macro de Datos (Recomendado y Automático)Las macros de datos se ejecutan directamente en la tabla. No importa si añades el instrumento desde un formulario, una consulta o directamente en la hoja de datos; la inserción se realizará siempre.

Abre la tabla Instrumentos en la Vista Diseño.

En la pestaña Diseño de tabla, haz clic en Macros de datos y selecciona Después de insertar (After Insert).Configura la macro con la siguiente estructura lógica:Selecciona la acción Por cada registro en (For Each Record In).En Nombre de tabla, elige Ofertas.Dentro de ese bloque, añade la acción Crear registro (Create Record).En Nombre de tabla, elige tu TablaDestino (la tabla intermedia donde se vinculan).Usa Establecer campo (SetField) para asignar los valores:CampoIdInstrumento = [Instrumentos].[Id]CampoIdOferta = [Ofertas].[Id]Opción 2: Código VBA en el FormularioSi utilizas un formulario para dar de alta los instrumentos, puedes programar el evento Después de insertar (After Insert) del propio formulario para lanzar una consulta SQL que duplique los registros.Añade este código en el módulo del formulario:vbaPrivate Sub Form_AfterInsert()
Dim sql As String
' Desactivar avisos de Access para que no pregunte "Va a anexar X filas"
DoCmd.SetWarnings False
' Consulta para insertar el nuevo Instrumento con cada una de las Ofertas
sql = "INSERT INTO NombreTablaDestino ( IdInstrumento, IdOferta ) " & _
"SELECT " & Me.IdInstrumento.Value & " AS InstId, Ofertas.Id " & _
"FROM Ofertas;"
DoCmd.RunSQL sql
' Volver a activar los avisos
DoCmd.SetWarnings True
End Sub


https://www-fmsinc-com.translate.goog/microsoftaccess/query/snytax/append-query.html?_x_tr_sl=en&_x_tr_tl=es&_x_tr_hl=es&_x_tr_pto=sc

https://www.youtube.com/watch?v=bPIMmJ3utjQ

https://www.youtube.com/watch?v=IDndYdN8XJs


Para lograr que al adicionar un instrumento se inserte automáticamente una fila en tu tabla por cada Oferta existente, la mejor solución es utilizar un desencadenador (Trigger) a nivel de base de datos o un bucle (Loop) en tu lógica de programación.

A continuación, te presento las dos formas más comunes de implementarlo. Asumiré una estructura relacional estándar donde tienes una tabla Instrumento, una tabla Oferta y una tabla intermedia (por ejemplo, Instrumento_Oferta o Detalle_Tabla).

- Opción 1: Mediante un Trigger (Base de Datos SQL)Esta opción es la más eficiente porque se ejecuta automáticamente en el servidor de la base de datos cada vez que se inserta un nuevo instrumento.sqlCREATE TRIGGER tg_InsertarOfertasPorInstrumento
AFTER INSERT ON Instrumento
FOR EACH ROW
BEGIN
-- Inserta en la tabla destino combinando el nuevo Instrumento con todas las Ofertas
INSERT INTO Tu_Tabla_Destino (instrumento_id, oferta_id, fecha_registro)
SELECT NEW.id, o.id, NOW()
FROM Oferta o;
END;


Opción 2: Desde el Backend (Código de Programación)Si prefieres controlar esta lógica desde el código de tu aplicación (por ejemplo, en Node.js, Python o C#), debes seguir estos tres pasos secuenciales:Insertar el instrumento y obtener el ID generado.

Consultar todas las ofertas activas de la base de datos. Recorrer las ofertas e insertar cada combinación en la tabla final.

Ejemplo lógico (Pseudo-código / JavaScript):javascript// 1. Insertar el nuevo instrumento
const nuevoInstrumento = await db.instrumentos.create(datosInstrumento);

// 2. Obtener todas las ofertas existentes
const ofertas = await db.ofertas.findAll();

// 3. Insertar en la tabla intermedia por cada oferta
const inserciones = ofertas.map(oferta => {
return db.tuTablaDestino.create({
instrumento_id: nuevoInstrumento.id,
oferta_id: oferta.id
});
});

1 respuesta más de otro experto

Respuesta

Lo mas usual es utilizar una consulta de inserción (en definitiva: una SQL), lo que me intriga es que los datos en/de la tabla [Cuenta_135] carezcan de un índice que impida las repeticiones que la hagan inservible.

Una consulta de inserción es sencilla y se puede crear con el generador grafico de consultas que tiene Access, se comienza creando una consulta de selección que nos devuelva los datos (se utilizan las tablas asociadas al origen de datos del formulario y/o subformulario).
Una vez que devuelvan los datos correctos se modifica de consulta de selección a consulta de inserción (solicitara la tabla destino).

Aparecerá una línea en la que bajo cada campo un desplegable permite seleccionar uno de los campos de la tabla destino, generando una asociación entre el origen y su destino, al ejecutar la consulta se añadirán correctamente (si la tabla de destino los permite) y lo permitirá siempre que cumplan las reglas que tenga la tabla de destino [Cuenta_135].
Lo que aprecio en la exposición del problema, es que falta por definir un campo en el formulario/subformulario: el de [descuento] que aparece solo en la tabla [Cuenta_135].

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas