Reestablecer correlativo de linea en subformulario
Necesito agilizar un poco este código que tengo para reestablecer una linea en el subformulario al ir agregando productos. Este código funciona al hacer doble clic en la linea. Por ejemplo, tengo 4 líneas ingresadas y me doy cuenta que la tercera linea el producto no corresponde por lo que elimino la linea y me quedan la linea 1-2-4 entonces para restablecer hago doble clic y se reestablece a 1-2-3, pero me ha pasado que muchas veces después que he elimina la línea no hago el doble clic y se bloque el programa y no puedo salir hasta que debo cerrar el programa y volverlo a abrir. Entonces coloque este código en el evento al eliminar, pero no funciona.
Este es el codigo
Hector, no sé como eliminas un registro, ni como determinas la línea, así que te pongo un ejemplo, por si te da una idea. Si tengo un formulario con subformulario, al que le he puesto un botón Eliminar
Si pulso el botón de Eliminar del registro 3, me queda como
Digamos que ha renumerado la Línea. En mi caso, pero se puede hacer de más formas,
el código del botón es
Private Sub Comando28_Click() DoCmd.DoMenuItem acFormBar, acEditMenu, 8, , acMenuVer70 DoCmd.DoMenuItem acFormBar, acEditMenu, 6, , acMenuVer70 Dim b As Byte DoCmd.GoToRecord , , acFirst For i = 1 To Me.Recordset.RecordCount - 1 Linea = Me.CurrentRecord End Sub
Las dos primeras eliminan el registro y las otras le va asignando a Línea el número de registro.
Estimado, el código lo tengo en el evento al eliminar y lo hago de esta forma, selecciono la línea y oprimo el botón suprimir.
y lo cambie por el que tú tienes en el botón, pero me sale este aviso
Lo presiono y vuelve a salir el mismo mensaje durante cuatro ocasiones.
Así tengo el código que me enviaste
Héctor, yo el código lo tengo puesto en el botón Eliminar. Vamos a analizar la situación en términos de eficiencia. Tu seleccionas el registro y luego pulsas el botón, Son dos acciones. En el caso del botón de eliminar mío, es sólo una acción. Pulso directamente el botón del registro que me de la gana.
Y como le puedo agregar un botón a cada línea del subformulario. Debo crear un cuadro de texto, y si fuera así debo colocarlo el código en algún evento en particular
En los formularios continuos, caso del subformulario DetalleCompra, sólo hay una línea de registro, por tanto, si le añado un botón de comando, me parecerá en todos los registros.
Si lo abro
No te fijes en el valor que aparece en Línea, ya que debería estar abierto dentro del formulario Compras . Ten en cuenta, que en los formularios continuos o en vista hoja de datos sólo tiene existencia "real" el que está señalado con la punta de flecha(registro activo). Los demás son imágenes virtuales que sólo tendrás existencia cuando sean el registro activo.
De todas formas, si quieres, repito, si quieres, mándame un mensaje a [email protected] y te mando el ejemplo, que es como se ve mejor
- Compartir respuesta
2 respuestas más de otros expertos
Puede utilizar lo siguiente:
1. Crear un campo texto en el formulario (Continuo) para llevar la numeración consecutiva.
A este cuadro de texto le asigna en Origen de datos como muestra la figura
Copie este código en un módulo a nivel del formulario
Public Function lngContador() As Long On Error GoTo lngContador_err Me.RecordsetClone.Bookmark = Me.Bookmark lngContador = 1 + Me.RecordsetClone.AbsolutePosition Exit Function lngContador_err: If Err = 3021 Then 'no hay registro activo lngContador = 0 Else Exit Function End If End Function
Debe quedar algo como:
La columna en color rojo es el consecutivo.
Don Eduardo, agregue lo que menciona, pero no me funciona. a lo mejor hice algo mal. le indico los cambios que hice
primero, creamos el cuadro de texto que menciona y le agregue en el origen del control lo que menciono
luego agregue el codigo en un modulo asi
y por último agregue el campo de los primeros, pero se ve así
El código debe ir en un módulo, pero a nivel del formulario, no en un módulo general. Ahora, el ejemplo corresponde a un formulario CONTINUO. Se pregunta se refiere a un Subformulario y según la imagen no lo es.
Corrijo no había observado bien la imagen, el problema está en que el código debe pasarlo es dentro el formulario y NO en un módulo global.
Ya don Eduardo. Abrí el formulario en vista diseño
Luego selecciono el subformulario y abro la hoja de propiedades
selecciono la hoja de eventos y abro al evento "Al eliminar"
y coloco el código que me dio en la parte superior
Luego guardo todos los cambios y cierro VBA, abro el formulario, pero sigue saliendo así
Siendo "Linea" un campo de la tabla no sirve el código que le suministre, solo sirve para campos sin origen de datos. Pero mirando la tabla que suministró le preparé la eliminacion de 2 formas:
1. Eliminando como quiere con la tecla "SUPRIMIR".
Me ubico en cualquier campo del campo linea 4 y oprimo la tecla "SUPRIMIR".
Hago clic en SÍ, obtengo:
Entonces NO utilizo el evento del Subformulario "Al eliminar" sino el evento "Al bajar una tecla"
Código del evento "Al bajar una tecla", del subformulario.
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) Dim cuenta As Long Dim miRS As Recordset If KeyCode = 46 Then 'Tecla Suprimir If MsgBox("Esta seguro que elimina el registro línea : " & Me.Linea, vbQuestion + vbYesNo + vbDefaultButton2, "Le pregunto") = vbYes Then DoCmd.RunCommand acCmdDeleteRecord Set miRS = Me.RecordsetClone cuenta = 0 miRS.MoveFirst Do Until miRS.EOF cuenta = cuenta + 1 miRS.Edit miRS!Linea = 1 + Me.RecordsetClone.AbsolutePosition miRS.Update miRS.MoveNext Loop Else Exit Sub End If End If End Sub
2. Eliminando como quiere con el botón Borrar
Private Sub btnEliminar_Click() Dim cuenta As Long Dim miRS As Recordset If MsgBox("Esta seguro que elimina el registro", vbQuestion + vbYesNo + vbDefaultButton2, "Le pregunto") = vbYes Then DoCmd.SetWarnings (False) DoCmd.RunCommand acCmdDeleteRecord Set miRS = Me.RecordsetClone cuenta = 0 miRS.MoveFirst Do Until miRS.EOF cuenta = cuenta + 1 miRS.Edit miRS!Linea = 1 + Me.RecordsetClone.AbsolutePosition miRS.Update miRS.MoveNext Loop End If End Sub
Ya es cuestión de gusto, no me gusta utilizar el botón porque es antiestético. Si quiere el ejemplo lo puede solicitar a [email protected]
Eso es lo que ando buscando, la opción uno me gusta. Copie el código donde usted me dice
Guardo los cambios realizados y abro el formulario, selecciono la línea 3 del subformulario,
Presiono la tecla supr, pero no se restablece el correlativo. Algo debo estar haciendo mal pero no se lo es. El código no responde
- Compartir respuesta
Te propongo esta modificación:
Private Sub Form_BeforeDelConfirm(Cancel As Integer, Response As Integer) With Me.RecordsetClone .MoveFirst Do Until .EOF .Edit !Linea = .AbsolutePosition + 1 .Update .MoveNext Loop End With End Sub Private Sub Form_Delete(Cancel As Integer) Beep If MsgBox("Deseas eliminar la linea seleccionada", vbYesNo + vbQuestion, "Estas a punto de eliminar la línea seleccionada") = vbNo Then Cancel = True End Sub
Gracias por lo que me indicas, así que copie y pego eliminado el código que tenía, pero no funciona, sigue quedando la linea 1-2-4 al momento de eliminar la linea 3
Sinceramente el numerar las líneas no tiene sentido para mi.
Si necesito 'un orden', ocupa lo mismo el numero uno que el 4258,5258 que representa a una fecha (y se puede aplicar como correlativo ascendente para ordenar).
?format(4258.5258,"dddd\, dd mmmm \d\e yyyy hh:nn:ss") lunes, 28 agosto de 1911 12:37:09 ?format( 44988.481712963 ,"dddd\, dd mmmm \d\e yyyy hh:nn:ss") Viernes, 03 marzo de 2023 11:33:40
Y en un informe, se añade un cuadro de texto, como valor =1, se activa su propiedad 'suma continua' y se generan solos.
Lo que he publicado lo he copiado directamente de la ventana de VBA en el código de un formulario continuo al que añadí en su origen de datos un campo mas [Línea] del tipo 'entero largo' (el que ofrece por defecto al definir como numérico un campo).
En tu exposición inicial el dato que le asignas ¿Es un texto o un número?:
Linea= 0 & "." & Me.CurrentRecord
Un detalle de capital importancia:
¿Es un formulario o un subformulario?
Dónde esta ubicado el código que publique (si el objeto con los datos a manipular es un subformulario)
Si el borrado se produce en el subformulario, el código ha de ir en el evento del subformulario (el formulario principal no se 'entera' de si borran o no un registro en un subformulario, al menos de forma directa).
Para verificar si esta en la ubicación correcta, añade en cada evento una línea de control:
Private Sub Form_BeforeDelConfirm(Cancel As Integer, Response As Integer) MsgBox "Evento Form_BeforeDelConfirm" ...
(También vale un punto de interrupción o una sentencia STOP que en tiempo de ejecución se salta con 'F5')
Si sale el mensaje es que 'pasa por el evento' si no hay mensaje verifica que el 'Sub 'esta asociado a su origen (esta activado) porque según lo publicado se utilizo un Copy&Paste (y eso no asocia los eventos si no se compila el código y aun así: se debe de verificar la asociación)
Si, eso lo tengo claro. El código está en el evento al eliminar del subformulario.
Aquí está el formulario principal en vista diseño
aquí aparece la hoja de propiedades del formulario
luego cambio al subformulario con su hoja de propiedades
luego selecciono la opción de eventos y abro el evento al eliminar
y ahí coloco el código que me enviaste
Pero cuando me voy al formulario y quiero eliminar una línea, la selecciono y presiono suprimir
Algo que me llama la curiosidad es que no te moleste que vuelva a confirmar el borrado del registro (el mensaje del sistema).
Ese mensaje se puede sustituir por el mensaje personalizado si se utiliza en el evento:
Private Sub Form_BeforeDelConfirm(Cancel As Integer, Response As Integer) Response = acDataErrContinue Beep If MsgBox("Deseas eliminar la linea seleccionada", vbYesNo + vbQuestion, "Estas a punto de eliminar la linea seleccionada") = vbNo Then Cancel = True: Exit Sub With Me.RecordsetClone .MoveFirst Do Until .EOF .Edit !Linea = .AbsolutePosition + 1 .Update .MoveNext Loop End With End Sub
Y sea como formulario o subformulario, elimina el registro (aun no renumero) y si acepto renumera y aparece el nuevo orden, si no acepto: recupera el registro y mantiene el orden
¿Por qué digo que lo elimina y 'aun no renumero'?:
Porque en el formulario principal tengo un cuadro de texto que visualiza el Id del registro activo del subformulario, cuando hace la pregunta de confirmación:
1. Desaparece el registro del subformulario (no lo muestra).
2. El cuadro de texto del principal se queda en blanco .
3. Hay un salto en la numeración (falta el numero del registro 'borrado')
Si acepto:
1. El cuadro de texto presenta el ID del que sustituye al registro que fue borrado
2. La numeración no presenta huecos.
Si no acepto:
1. El registro borrado recupera su posición
2. El orden es el mismo que antes de iniciar la acción de borrar.
Copie el código que me enviaste pero ahora ni si quiera sale el mensaje para confirmar si quiero eliminar o no la línea, y sigue sin actualizar el correlativo
Luego abro el formulario selecciono la línea 3, la elimino, pero nada, sigue sin funcionar
Si no sale el mensaje (y además no hace nada), quedan dos opciones:
A.) No se pasa por el evento (un punto de interrupción, un mensaje, o un STOP lo delatara).
B.) Lo anterior causado por una rutina de control de errores global que 'mete debajo de la alfombra' cualquier posible error (por ejemplo: que una relación de ese registro lo impida y aborte la acción).
Dado que solo tu conoces el entorno real, tendrás que hacer un clásico seguimiento 'paso paso' [F8], para ver donde se bifurca la ejecución.
Que no hubieras apreciado que había doble mensaje (el personalizado y el del sistema), siempre me hizo sospechar que no 'pasaba por el evento' y aun sigo en esa sospecha.
- Compartir respuesta