Subformulario que oculta el registro introducido

Tengo un formulario con un subformulario:

Cuando introduzco un artículo en el subformulario, y paso al siguiente registro, solo me muestra el registro nuevo.

Antes, utilizaba este código:
Private Sub Form_AfterInsert()
    DoCmd. RefreshRecord
    DoCmd. GoToRecord,, acNewRec
    DoCmd. RefreshRecord
    DoCmd. GoToRecord,, acFirst
    DoCmd. GoToRecord,, acNewRec
    Me. Cantidad. SetFocus
    Me. Articulo. SetFocus
    If Nz(Me.Cantidad.Value, "") <> "" Then Me.Cantidad.Value = 1: Me.Cantidad.Value = 0
End Sub

Pero resulta que me das más problemas que otra cosa solo para que se vean los registros continuos.

En el código del subformulario no hay nada raro que, a mi entender, pueda interferir:

Option Compare Database
Public cmbArticulo As New FindAsYouTypeCombo
Private Sub Articulo_AfterUpdate()
    Me.CodigoArticulo = Me.Articulo.Column(2)
    [PVPModificado] = [PVP]
    If Me.TxtCategoria.Value = "Recargas" Then
        Me.TxtCodigoRecarga.Visible = True
        Me.TxtCodigoRecarga.TabStop = True
        Me.TxtTelefonoMovil.Visible = True
        Me.TxtTelefonoMovil.TabStop = True
        Call DarFormatoCondicionalALasRecargas(Nz(Me.TxtCategoria))
    Else
        Me.TxtCodigoRecarga.Visible = False
        Me.TxtCodigoRecarga.TabStop = False
        Me.TxtTelefonoMovil.Visible = False
        Me.TxtTelefonoMovil.TabStop = False
        Call DarFormatoCondicionalALasRecargas(Nz(Me.TxtCategoria))
    End If
    Me.Articulo.Value = ""
End Sub
Private Sub Articulo_GotFocus()
    Call BloquearCampos(Me, Forms![F10TPV]!ChkBloquear.Value, True)
End Sub
Private Sub Cantidad_AfterUpdate()
    If Forms![F10TPV]![ChkDeposito] = -1 Then
        [Deposito] = [Importe] * DLookup("PorcentajeDeposito", "T00Configuracion")
    Else
        [Deposito] = 0
    End If
End Sub
Private Sub Form_Open(Cancel As Integer)
    Call AplicarDiseño(Me, "CabeceraYPie", False)
    Call DarFormatoCondicionalALasRecargas(Nz(Me.TxtCodigoRecarga))
    Call AvisoDeBloqueo(Me, True)
    Call BloquearCampos(Me, Forms![F10TPV]!ChkBloquear.Value, True)
End Sub
Private Sub Form_Load()
    cmbArticulo.InitalizeFilterCombo Me.Articulo, "Articulo1", AnywhereInString, True, True
End Sub
Private Sub Form_Click()
    If Me.Form.AllowDeletions = False Then
            MsgBox "Este registro está bloqueado y no lo puedes modificar.", vbInformation, NombreBD
    End If
End Sub
Private Sub Form_Current()
    Call BloquearCampos(Me, Forms![F10TPV]!ChkBloquear.Value, True)
End Sub

Y una segunda pregunta. ¿Cómo puedo guardar el formulario principal desde el subformulario? El formulario principal consta de tres campos, a los que, cuando añades un nuevo registro, te añade como valor predeterminado sus valores correspondientes; pero, si no haces ningún cambio, en cuanto salgas, te borra el registro principal, con todo lo que hayas añadido en el subformulario.

2 Respuestas

Respuesta
1

Yo comprobaría que el subformulario no tiene la propiedad "Entrada de datos" en Sí.

Revisa también si en alguno de todos esos procedimientos modificas esa propiedad.

Es lo único que se me ocurre que pueda estar pasando, combinado con algún requery que tengas por ahí.

En cuanto a la segunda cuestión, desde el subformulario no puedes, o eso creo. Tienes que pasar el foco a algún control del formulario principal (por ejemplo Me. Parent. CodigoTicket) y luego forzar el guardado (por ejemplo con DoCmd. RunCommand acCmdSaveRecord)

Hola. Muchas gracias.

Estoy revisando y tengo la propiedad entrada de datos en No. He buscado en todo el código de la base de datos esa propiedad, y tampoco la tengo. Por último, tampoco tengo ningún requery. Así que no sé qué puede estar pasando. Lo que no sé es si habrá algún código para mostrar x registros, como sí se puede hacer en Excel.

Por otro lado, respecto a la segunda cuestión, no funciona. En el subformulario, después de actualiar el artículo le pongo Me.Parent.Fecha, y luego, en el formulario principal, en fecha, pongo DoCmd. RunCommand acCmdSaveRecord y no lo guarda porque sigue estando el valor predeterminado.

Un saludo.

Este es el código de Excel que te digo:

    Application.Goto Sheets(ActiveSheet.Name).Cells(Rows.Count, 1).End(xlUp).Offset(-2, 0), True
    Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Select

Claro, lo segundo no te funciona porque me olvidé de ponerle el foco al control:

Me. Parent. Fecha. SetFocus

Si no le dices que te ponga el foro en el formulario principal, te guarda los datos del subform. Fallo mío.

Hasta donde yo sé, no hay forma de indicarle el número de registros a mostrar en un formulario continuo. Imagino que el problema no estará en el alto del subform que no te deja visualizar más de un registro, ¿no? Tampoco que el alto de la sección Detalle del subformulario no es tan grande como para que solo muestre uno de cada vez...

A ver.

En el subformulario tengo puesto, después de actualizar artículo, Me. Parent. Fecha. SetFocus

En el formulario principal, al recibir el enfoque del campo fecha, DoCmd. RunCommand acCmdSaveRecord

Creo que no lo guarda porque sigue estando el valor predeterminado.

Luego, con respecto al número de registros. Este es el diseño que tengo:

Valora tú mismo...

¡Gracias!

Tienes que hacerlo todo en el mismo evento:

En el subformulario, después de actualizar artículo:

Me. Parent. Fecha. SetFocus

DoCmd. RunCommand acCmdSaveRecord

Y luego si quieres que te vuelva para el subformulario, le vuelves a pasar el fofo a continuación:

Me.NombreControlSubform.Form.Articulo.SetFocus

Pero todo en el mismo evento.

En cuanto a lo de los registros del subformulario, ya no se me ocurre qué más sugerirte...

Private Sub Articulo_AfterUpdate()
    Me.Parent.Fecha.SetFocus
    DoCmd.RunCommand acCmdSaveRecord
End Sub

Eso es lo que tengo puesto en el Artículo del subformulario. No me guarda porque no he editado ningún campo del formulario principal, porque solo se han rellenado con el valor predeterminado. ¿Cómo puedo hacer para que sí me lo guarde con esos valores predeterminados?

En cuanto a lo de los registros del subformulario, no creo que sea por el AllowDeletions, ¿no? Es lo único que tengo así. Tengo un módulo de clase para filtrar los registros del desplegable a medida que vas escribiendo, y lo tengo en otras bases de datos, también en subformularios, y no da este problema.

Hay algo con lo que me pierdo... tanto el formulario principal como el subformulario, son dependientes directamente de tablas o consultas. Como cualquier formulario dependiente, los datos se guardan solos, sin necesidad de hacer nada, ya sea al cerrar el formulario, cambiar de registro o ir a uno nuevo, salvo, que por código o macro le digas que se deshagan los cambios (con me. Undo), canceles el guardado en algún evento, o pulses ESC varias veces.

Además, como supongo que el subformulario está vinculado con el principal por algún campo, es necesario que en la tabla (y por tanto en el formulario) principal exista el registro para poder rellenar los registros en la tabla vinculada (subformulario). Y si el registro de la principal existe, es que se guardó...

Es más, si no existe un registro en el formulario principal, no te debería dejar añadir registros en el subformulario (porque quedarían sin vincular), salvo que al hacer la relación no exijas integridad referencial, lo que en mi opinión es un grandísimo error.

Si vas a un registro nuevo en el formulario principal, los campos cogerán los valores predeterminados y al cambiar al subformulario, el registro ya se guarda automáticamente para que lo puedas vincular.

Por eso no termino de entender lo de que no te guarde el registro...

En cualquier caso, prueba pasando primero el foco al formulario Parent, luego al control Fecha y luego poniendo la linea de guardado.

Y en cuanto a lo del subformulario, AllowDeletions es solo para permitir o no borrar registros, no afecta para nada al número de ellos que se visualice. El módulo de clase entiendo que tampoco tendría que afectar, más si dices que en otras aplicaciones lo usas y no tienes este problema.

Para descartar cosas, yo comentaría todas las líneas de código del subformulario, y probaría a ver si se ven o no todos los registros. Luego iría descomentándolas una a una, y probando a ver si localizas el evento o código donde deja de funcionar como es debido.

Por cierto, ¿tu formulario tiene la barra de desplazamiento vertical? Igual es problema de espacio y el registro recién creado se te va para arriba, y al no tener barra no lo ves... Por apuntar algo que se me acaba de ocurrir.

Ya sé dónde está el error. Como es largo de explicar por escrito, te he grabado un vídeo:

https://www.dropbox.com/s/16trtbiud6lycwa/Video1.mp4?dl=0 

Espero que me entiendas lo que te explico.

Muchas gracias.

Te dejo más cosas que he probado:

https://www.dropbox.com/s/87hdxsvtd1f8it2/Video2.mp4?dl=0 

El problema por el que no se muestre más de un registro en el subformulario es por el desplegable independiente. Cuando le asigno a uno de los campos de la subtabla, me muestre un segundo registro al empezar a introducir valores.

Solo me queda arreglar el problema de que guarde el formulario principal, como te mostré en el vídeo.

La solución es muy sencilla:

Olvídate de los valores predeterminados y asígnale esos valores por código, por ejemplo, en el evento "al activar registro":

If Me.NewRecord Then
Me.Fecha=Now
Me.CodigoTicket=tuFunción
Me.CodigoCliente=2
End If

Así sí te debería coger un ID nuevo. Prueba y me comentas, que no estoy en el ordenador para comprobarlo

Efectivamente, funciona. De esta forma, añade un registro.

Ahora bien, te pongo en situación. Lo he montado como tú me dijiste: en la tabla principal, un ID autonumérico entero largo (IDTPV) y un campo texto para el CodigoTicket; en la subtabla (o detalles como tú la llamas), tengo el campo IDTPV numérico largo, y no está el CodigoTicket, porque ya no lo necesito.

Ahora, aquí viene la pregunta del millón.

Puedo evitar que añada un registro con la propiedad Ciclo, pasarla a Registro activo, así no pasa a un registro nuevo. Pero si, por error, le da añadir registro -factura, ticket o presupuesto-, no puede cancelarlo (volviendo al campo anterior ni dando escape). Entonces, ¿cómo controlo eso para que no me de error el código -factura, ticket o presupuesto- (porque tiene que ser consecutivo)?

¡Muchas gracias!

Pues simplemente necesitas un botón para cancelar (borrar) el registro creado por error, y que al pulsarlo borre el registro actual, ya sea con DoCmd.RunCommand acDeleteRecord (al algo así) o con una SQL del tipo DELETE * FROM Tabla WHERE ID=IDFormulario, o de cualquier otra forma.

Como el código factura (o ticket o presupuesto) es el último, al borrar ese registro en el siguiente que crees te volverá a generar el mismo.

Buenos días.

El botón para borrar no me funciona de ninguna de las maneras. Ni así

Private Sub CmdBorrar_Click()
    CurrentDb.Execute "DELETE * FROM T11Presupuesto WHERE IDPresupuesto =" & Me.IDPresupuesto1
    Me.Requery
End Sub

Ni así:

Private Sub CmdBorrar_Click()
    DoCmd.RunCommand acCmdSelectRecord
    DoCmd.RunCommand acCmdDeleteRecord
    Me.Requery
End Sub

Creo el séptimo registro, y me debería dejar en seis, pero lo único que hace es moverse al primer registro (uno).

¿Seguro seguro que no te lo borra? Cuando haces un requery, siempre se va al primer registro que muestra el formulario, por eso se te va al registro uno.

Si quieres que se quede en el último, tienes que decirle, además, que se vaya a él (DoCmd. GotoRecord,, acLast)

Pues no. Estoy probando con debub.print, y el SQL que crea está bien, porque si me voy a una consulta y lo pego, elimina el registro. El formulario, por un motivo que desconozco, no lo borra.

Ya sé dónde está el problema.

Como le tengo puesto que, al activar registro, añada el CodigoTicket, la Fecha, y el CodigoCliente, claro, al eliminar el registro crea uno nuevo. Entonces, lo que he hecho ha sido irme al primero antes de eliminar.

Private Sub CmdBorrar_Click()
Dim ID As Integer
    ID = Me.IDTPV
    DoCmd.GoToRecord , , acFirst
    CurrentDb.Execute "DELETE * FROM T10TPV WHERE IDTPV=" & ID
End Sub

No sé si habrá una opción más acertada, pero esta me funciona.

Así mejor

Private Sub CmdBorrar_Click()
Dim ID As Integer
    ID = Me.IDTPV
    DoCmd.GoToRecord , , acFirst
    CurrentDb.Execute "DELETE * FROM T10TPV WHERE IDTPV=" & ID
    Me.Requery
    DoCmd.GoToRecord , , acLast
End Sub

Ya me parecía raro que no te borrara ni te diera error...

El código que tienes en "al activar registro", solo te debería añadir esos campos si estás en un registro nuevo, por lo que al borrar un registro, no te debería saltar ese evento ni rellenarte los campos. Pero la tuya no es mala solución.

Respuesta
2

El registro anterior el combinado se queda en blanco porque probablemente tengas puesto como columna dependiente la 1, pero en ancho de columnas tengas puesto 0;5 Cuando se va a otro registro "querría" mostrarte el, por ejemplo, Idproducto, pero como su anchura es 0 cm, por eso no lo muestra.

Hola, Julián. Es un campo independiente, en que la columna dependiente es la 2. Mira:

De todas maneras, no entiendo tu razonamiento.

Ya sé dónde está el problema.

Como le tengo puesto que, al activar registro, añada el CodigoTicket, la Fecha, y el CodigoCliente, claro, al eliminar el registro crea uno nuevo. Entonces, lo que he hecho ha sido irme al primero antes de eliminar.

Private Sub CmdBorrar_Click()
Dim ID As Integer
    ID = Me.IDTPV
    DoCmd.GoToRecord , , acFirst
    CurrentDb.Execute "DELETE * FROM T10TPV WHERE IDTPV=" & ID
End Sub

No sé si habrá una opción más acertada, pero esta me funciona.

Si a tí te funciona ni mil palabras más. El único que sabe exactamente lo que necesitas eres tú. Los demás tenemos que imaginarlo.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas