Access - Recorrer cada registro del subformulario

 
Vista:
sin imagen de perfil

Recorrer cada registro del subformulario

Publicado por GERMAN EDUARDO (10 intervenciones) el 19/06/2024 18:18:13
Buen día, Tengo el siguiente problemita en Access, he realizado un proyecto y no he logrado conseguir que haga lo siguiente. Tengo un Formulario frmTpv y dentro de el dos Subformularios SubFrmTpv y SubFrmTpv1. Desde el Subformulario SubFrmTpv1 donde están los datos de los productos los paso uno por uno según lo requerido por el "Cliente" al Subformulario SubFrmTpv. En el momento que quiera pasar un Producto repetido, no lo duplique sino que en el que ya he pasado aumente la cantidad. Muchas gracias por LAS AYUDA.


Foro
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Recorrer cada registro del subformulario

Publicado por Anonimo (3359 intervenciones) el 19/06/2024 20:36:22
Lo mas eficaz es utilizar el RecordsetClone del subformulario, el dato a localizar (generalmente el ID) se conoce, solo hay que localizarlo en el 'clone' del subformulario y se pueden dar dos resultados, est o no esta.

Si esta (se localizo), se edita el registro, se le añade una unidad y tras ello se guarda (problema resuelto)
Si no esta (no se localizo) se utiliza el método actual para añadirlo.

Utilizare With para simplificar el codigo (y escribir menos)
En el cuadro de texto (XDato) introduzco un id (en tu diseño: el evento click y el ID será el campo ID) en el ejemplo el evento 'después de actualizar' del cuadro de texto (para poder experimentar)

Si encuentra el ID en el subformulario, aumenta en una unidad el cuadro de texto [Dato], si no lo encuentra envia un mensaje (en tu aplicación y con el metodo que se presupone ya hay, se añade un nuevo registro en el subformulario

1
2
3
4
5
6
7
8
9
10
11
12
Private Sub XDato_AfterUpdate()
With Me.[nombre del subformulario].Form.RecordsetClone
FindFirst "id = " & Me.XDato
If Not .NoMatch Then
    .Edit
    .Dato = .Dato + 1
    .Update
    Else
   MsgBox "Se añade un nuevo registro"
   End If
End With
End Sub
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Recorrer cada registro del subformulario

Publicado por GERMAN EDUARDO (10 intervenciones) el 19/06/2024 21:05:15
Gracias por responder, pero me aparece el siguiente error.

Te explico en el Subformulario SubFrmTpv1 la llave principal es IdProducto y en el Subformulario SubFrmTpv la llave principal es IdProducto.

Librerias1
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Recorrer cada registro del subformulario

Publicado por GERMAN EDUARDO (10 intervenciones) el 19/06/2024 21:07:37
El codigo lo escribi de la siguiente manera de acuerdo a tu ayuda.

With Forms!frmTpv![SubFrmTpv].Form.RecordsetClone
FindFirst "IdProducto = " & Me.IdProducto
If Not .NoMatch Then
.Edit
.IdProducto = .IdProducto + 1
.Update
Else
MsgBox "Se añade un nuevo registro"
End If
End With
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Recorrer cada registro del subformulario

Publicado por GERMAN EDUARDO (10 intervenciones) el 19/06/2024 21:11:58
El codigo lo tengo de la siguiente manera :

Dim rst As Recordset
Dim respuesta As Integer
Set rst = Me.RecordsetClone
If DCount("IdProducto", "tblMovimiento", "[IdProducto]=Forms!frmTpv![SubfrmTpv]![IdProducto] And [Codigo_Mov] = Forms!frmTpv![SubfrmTpv]![Codigo_Mov]") >= 1 Then
DoCmd.CancelEvent
respuesta = vbOK
If respuesta = vbOK Then
Forms!frmTpv![SubFrmTpv].SetFocus
DoCmd.GoToControl "SubFrmTpv"
DoCmd.GoToRecord , , acGoTo, Forms!frmTpv![SubFrmTpv]![Cantidad]
Forms!frmTpv![SubFrmTpv]!txtControl.SetFocus
DoCmd.RunCommand acCmdUndo
DoCmd.OpenForm "frmAviso"
End If
End If
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Recorrer cada registro del subformulario

Publicado por Anonimo (3359 intervenciones) el 20/06/2024 01:00:46
Al trasvasar el código que utilice se perdió el punto que antecede a FindFirst.

Ese punto (como lo tiene por ejemplo EDIT) le indica a Access que le añada antes del punto lo que se indica en With (solo se escribe una vez y solo hay que corregir en un único sitio)

Sin With y sin Me

Forms.fmrTpv.SubfmrTpv.Form.RecordsetClone.FindFirst "id = " & Forms.fmrTpv.IdProducto
If Not Forms.fmrTpv.SubfmrTpv.Form.RecordsetClone.NoMatch Then
Forms.fmrTpv.SubfmrTpv.Form.RecordsetClone.Edit
Forms.fmrTpv.SubfmrTpv.Form.RecordsetClone.Cantidad= Forms.fmrTpv.SubfmrTpv.Form.RecordsetClone.Cantidad + 1
Forms.fmrTpv.SubfmrTpv.Form.RecordsetClone.Update
Else
****
Aquí
el
código
que
actualmente
añade
los
productos
que
NO
hay
*****
End If

Ejemplo utilizando una línea y referencias absolutas:
Forms.fmrTpv.SubfmrTpv.Form.RecordsetClone.FindFirst "id = " & Forms.fmrTpv.IdProducto

Si utilizamos Me (que equivale a Forms.fmrTpv) la línea queda así (el resto la imitan)
Me.SubfmrTpv.Form.RecordsetClone.FindFirst "id = " & Me.IdProducto

Si Definimos With solo se necesita el punto, Access añade lo definido mientras no se alcance el End With.
With Forms.fmrTpv.SubfmrTpv.Form.RecordsetClone
también vale así:
With Me.SubfmrTpv.Form.RecordsetClone

La línea de ejemplo queda así (y el resto la imitan):
.FindFirst "id = " & Me.IdProducto

Aplicando lo anterior si se activa el evento Click del objeto CODIGO:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Private Sub Codigo_Click()
With Me.SubfmrTpv.Form.RecordsetClone
.FindFirst "id = " & Me.IdProducto
If Not .NoMatch Then
    .Edit
    .Cantidad= .Cantidad + 1
    .Update
    Else
   ****
    Aquí el código que actualmente añade los productos que NO hay
   *****
    End If
End With
End Sub
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Recorrer cada registro del subformulario

Publicado por GERMAN EDUARDO (10 intervenciones) el 20/06/2024 01:46:28
Perfecto muchas gracias el código me sirvió, le agradezco, hasta la próxima.....
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Recorrer cada registro del subformulario

Publicado por GERMAN EDUARDO (10 intervenciones) el 20/06/2024 02:27:45
Otra pregunta, para situar el Cursor en la Línea del Producto, que código debo utilizar.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Recorrer cada registro del subformulario

Publicado por Anonimo (3359 intervenciones) el 20/06/2024 09:27:24
Para posicionar (enviar el control) a un objeto solo se precisa enviarle el foco.

La condición es que el objeto sea accesible (si el destino no esta en el mismo formulario pueden ser necesarios pasos adicionales).

Una vez que el objeto tiene el foco (si el objeto que lo recibe ya tiene contenido) existe la posibilidad de enviar el cursor al principio, al final o a un punto especifico (por defecto si hay contenido lo selecciona todo).

En base a la imagen publicada, si el foco esta en el cuadro de texto [nombre del producto] y se quiere enviar al objeto [importe] el comando es:

1
Me.[Importe].SetFocus

Si estamos en el objeto [cantidad] (o cualquier otro) y deseamos que el foco se desplace al objeto [nombre del producto] :
1
Me.[nombre del producto].SetFocus

Si el objeto que tiene que recibir el foco esta en el subformulario son necesarios dos pasos: el primero enviar el foco al subformulario, el segundo enviar el foco al objeto.

1
2
Me.SubFormTpv.SetFocus
Me.Cantidad.SetFocus

El código correcto depende del flujo del programa (donde estoy .... donde deseo/necesito ir)

Nota: los corchetes ([]) solo son indispensables si el nombre contiene espacios (una muy mala practica de programación) lo mínimo es añadirles un guion bajo o la alternativa de utilizar mayúsculas:
nombre del producto ====>>>> nombre_del_producto // NombreDelProducto
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Recorrer cada registro del subformulario

Publicado por GERMAN EDUARDO (10 intervenciones) el 20/06/2024 17:11:38
Al colocar el codigo como me dices el foco se me va a un registro nuevo pero si en el campo indicado.


With Forms!frmTpv![SubFrmTpv].Form.RecordsetClone
.FindFirst "IdProducto = '" & Me.IdProducto & "'"
If Not .NoMatch Then

'Forms!frmTpv![SubFrmTpv].SetFocus
'Forms!frmTpv![SubFrmTpv]!Cantidad.SetFocus
.Edit
Forms!frmTpv![SubFrmTpv].SetFocus
Forms!frmTpv![SubFrmTpv]!Cantidad.SetFocus
.Cantidad = .Cantidad + 1
.Update
'.MoveNext

Else

Forms!frmTpv![SubFrmTpv].SetFocus
DoCmd.GoToRecord , , acNewRec
Forms!frmTpv![SubFrmTpv]!IdProducto = strCriteria
Forms!frmTpv![SubFrmTpv]!Cantidad = 1

End If
End With
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Recorrer cada registro del subformulario

Publicado por Anonimo (3359 intervenciones) el 20/06/2024 22:42:51
Te sere sincero, he borrado la respuesta que tenia preparada porque se aprecia en tu mensaje que no tienes claro lo que necesitas.

Intenta aclararlo para encontrar una solución adecuada.

Nota:
Borra las líneas en negrita de tu mensaje (o cámbialas de sitio) para que el código haga lo que tiene que hacer, porque ese código no se entromete con lo que estés viendo en la pantalla (excepto el campo cantidad si el registro afectado esta visible).

Si te funciona el código que has publicado para añadir registros (el que hay entre el Else y el End IF) ... pues habrá que creérselo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Recorrer cada registro del subformulario

Publicado por GERMAN EDUARDO (10 intervenciones) el 20/06/2024 23:59:27
Tienes razón, que pena, en que lugar del código definitivo coloco esta instrucción.

Me.SubFormTpv.SetFocus
Me.Cantidad.SetFocus


ESTE ES EL CÓDIGO DEFINITIVO

With Forms!frmTpv![SubFrmTpv].Form.RecordsetClone
.FindFirst "IdProducto = '" & Me.IdProducto & "'"
If Not .NoMatch Then
.Edit
.Cantidad = .Cantidad + 1 '/// PARA QUE CUANDO ENCUENTE DETERMINADO REGISTRO, LO SELECCIONE Y HAGA LA SUMA
.Update
'.MoveNext

Else

Forms!frmTpv![SubFrmTpv].SetFocus
DoCmd.GoToRecord , , acNewRec
Forms!frmTpv![SubFrmTpv]!IdProducto = strCriteria
Forms!frmTpv![SubFrmTpv]!Cantidad = 1

End If
End With
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Recorrer cada registro del subformulario

Publicado por Anonimo (3359 intervenciones) el 21/06/2024 02:49:39
Incrementar las unidades si el registro ya existe en el subformulario esta resuelto, pero lo de añadir registros (en mi opinion) no es funcional.
Se supone que si se crea un nuevo registro, se le ha de dar valor a todos sus campos y el código expuesto no parece hacerlo.
¿Funciono alguna vez?.

Aparece un nuevo elemento (strCriteria) que asumo es una variable, de la que se desconoce su contenido ni donde fue declarada..

En el origen de datos del subformulario hay como mínimo cuatro campos (el quinto es un valor calculado que supongo no se guarda).

Esta línea carece de sentido (no es valida esa referencia)

1
Forms!frmTpv![SubFrmTpv]!IdProducto = ...

Para asignarle un valor al campo [IdProducto] del subformulario [SubFmrTpv] la referencia correcta seria:
1
Forms!frmTpv![SubFrmTpv]!Form!IdProducto = ....

Y como el dato a copiar es el ID no localizado ([IdProducto]), seguirá siendo Me.IdProducto y la linea queda asi:
1
Forms!frmTpv![SubFrmTpv]!Form!IdProducto =  Me.IdProducto

Pero también hay que asignarle valores a [Producto], [Precio] y [cantidad], [SubTotal] no lo necesita es un valor calculado, una vez finalizadas las asignaciones hay que guardarlo.

Un par de consejos (que libremente puedes ignorar):
.- No manipules lo que funciona
.- Antes de manipular lo conseguido hasta ayer >>>> hoy (y antes de empezar): haz una copia de seguridad
(si ocurre un desastre, no se partirá de cero)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar