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

Respuesta
1

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

2 respuestas más de otros expertos

Respuesta
1

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

Si no le funciona porque se me olvidó decirle que tenía que activar los eventos del teclado antes que los eventos del formulario. Le envíe a su correo todo bien explicado.

Respuesta
1

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

En la tabla de origen esta como numero

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, 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.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas