Entidades

Para el mantenimiento de entidades de la BD, podríamos usar un solo formulario y conmutar entre las vistas dataview y el modo formview. Sin embargo, si el formulario requiere de subformularios o de algún control no estándar, es más práctico usar dos formularios. Además podríamos usar una vista para el listado y la propia tabla para el detalle.

Por ejemplo, si vamos a hacer el mantenimiento de la tabla COMUNEROS, haremos los siguientes pasos:

  1. Vincularemos la tabla COMUNEROS.
  2. Le cambiamos el nombre de dbo_COMUNEROS a COMUNEROS.
  3. Creamos una formulario a partir de la tabla creada, lo llamaremos Comuneros (seleccionamos la tabla, y desde el menú Crear, elegimos la opción Formulario). Este formulario es el que usaremos para añadir y editar entidades de este tipo.
  4. Ponemos la propiedad Permitir vista Hoja de Datos a No.
  5. Podemos poner la propiedad Modal a Si según se explica en Aplicaciones heredadas - Ventanas de edición modales.
  6. Ponemos el Nombre de la banda de opciones a Detalle, ya que esta banda es genérica.
  7. Cambiamos la propiedad Título y ponemos el nombre de la entidad en singular, en nuestro caso Comunero.
  8. En principio dejamos el resto de opciones hasta que veamos la forma de presentar los datos con mas detalle.
  9. Creamos una formulario a partir de la tabla creada, lo llamaremos ComunerosList (seleccionamos la tabla, y desde el menú Crear, elegimos la opción Mas formularios y Hoja de datos). Este formulario es el que usaremos para añadir y editar entidades de este tipo.
  10. Ponemos la propiedad Permitir vista Formulario a No.
  11. Ponemos el Nombre de la banda de opciones a Comuneros, por lo que previamente la habremos tenido que crear. Lo veremos en la siguiente sección.
  12. Cambiamos la propiedad Título y ponemos el nombre de la entidad de forma correcta, separando espacios y demás, en nuestro caso Comuneros.
  13. Cambiamos las propiedades Permitir agregar, Permitir eliminación y Permitir ediciones a No, salvo que queramos permitir la edición al ser una entidad muy sencilla (caso de las tablas de Lookup en las que sólo tendremos un formulario de listado para todas las operaciones), o lo deseemos de forma particular. De esta forma tenemos todos los eventos en VBA y mediante formularios. La eliminación se podría permitir, pero se podría disparar la integridad referencial.
  14. En principio dejamos el resto de opciones hasta que veamos la forma de presentar los datos con mas detalle.
  15. Eliminaremos los campos que no sean relevantes, en el caso de los Comuneros podemos elegir mostrar sólo NombreCorto o NombreLargo ya que en la edición se podrán cambiar los dos.
  16. Por último, personalizaremos los títulos de los campos para que sea más fácil la lectura de los mismos.

En el caso de los formularios para los listados, se podría dar el caso de que se preferible usar una vista en lugar de una tabla, por ejemplo en casos en que tengamos campos calculados. Se procedería de la misma forma anteriormente citada, pero con la vista correspondiente. También podríamos cambiar el origen de datos del formulario y añadir los campos que tenga la vista.

Para la banda de opciones de los formularios de detalle de cada entidad, de momento sólo tenemos dos opciones:

  • Aceptar. Esta opción ejecuta el código:

            DoCmd.RunCommand acCmdSaveRecord
            DoCmd.Close , , acSaveYes
            DoCmd.Requery

  • Cancelar. Esta opción ejecuta el código:

            DoCmd.RunCommand acCmdUndo
            DoCmd.Close , , acSaveNo
Este código se ejecuta para todas las entidades, son genéricas. En el código del botón Aceptar se ha usado DoCmd.Requery en lugar de DoCmd.RefreshRecord porque estamos trabajando con dos formularios.

Para la banda de opciones de los listados de cada entidad, tendremos las opciones:

  • Cerrar. Esta opción ejecuta el código:

            DoCmd.Close , , acSaveNo

  • Añadir. Esta opción ejecuta el código:

            DoCmd.OpenForm "Comuneros", acNormal, , , acFormAdd

  • Editar. Esta opción ejecuta el código:

            DoCmd.OpenForm "Comuneros", acNormal, , "NumeroSocio='" & Forms("ComunerosList")!NUMEROSOCIO & "'", acFormEdit

  • Borrar. Esta opción ejecuta el código:

            If MsgBox("¿Está seguro de eliminar el regisro actual?", vbOKCancel, "Eliminar") = vbOK Then
                DoCmd.RunCommand acCmdDeleteRecord
            End If

  • Columnas. Esta opción ejecuta el código:

            DoCmd.RunCommand acCmdUnhideColumns

  • Buscar. Esta opción ejecuta el código:

            DoCmd.RunCommand acCmdFind

  • Imprimir. Esta opción ejecuta el código:

            DoCmd.RunCommand acCmdPrint

  • Vista Previa. Esta opción ejecuta el código:

            DoCmd.RunCommand acCmdPrintPreview

Las acciones para Añadir y Editar son de momento específicas de cada entidad, Borrar se puede hacer genérica, y el resto de las acciones se ejecutan para todas las entidades, son genéricas.

En caso de poner genérica la opción Borrar, el código quedaría como sigue:

            DoCmd.RunCommand acCmdDeleteRecord
Además, en el formulario de listado pondremos el siguiente código, que también nos valdrá para las acciones desde el propio grid:
Private Sub Form_Delete(Cancel As Integer)
    If MsgBox("¿Está seguro de eliminar el regisro actual?", vbOKCancel, "Eliminar") = vbOK Then
        Cancel = False
    Else
        Cancel = True
    End If
End Sub

En caso de que queramos usar tareas genéricas para las acciones de los formularios de listado, sólo cambiaremos los botones de Añadir y Editar:

  • Añadir. Esta opción ejecuta el código:

            DoCmd.OpenForm Screen.ActiveForm.Tag, acNormal, , , acFormAdd

  • Editar. Esta opción ejecuta el código:

            DoCmd.OpenForm Screen.ActiveForm.Tag, acNormal, , , acFormEdit
Para poder saber qué formulario hay que abrir para editar los registros, el nombre lo guardamos en la propiedad Tag del formulario de listado. Por ejemplo, en la propiedad Tag del formulario ComunerosList, almacenamos el valor Comuneros.

En caso de que queramos usar tareas genéricas para las acciones de los formularios de listado, sólo cambiaremos los botones de Añadir y Editar:

  • Añadir. Esta opción ejecuta el código:

            DoCmd.OpenForm Screen.ActiveForm.Tag, acNormal, , , acFormAdd

  • Editar. Esta opción ejecuta el código:

            DoCmd.OpenForm Screen.ActiveForm.Tag, acNormal, , , acFormEdit
Para poder saber qué formulario hay que abrir para editar los registros, el nombre lo guardamos en la propiedad Tag del formulario de listado. Por ejemplo, en la propiedad Tag del formulario ComunerosList, almacenamos el valor Comuneros.

En este caso, sólo dejaremos el botón Añadir y el Borrar genérico:

  • Añadir. Esta opción ejecuta el código:

            Screen.ActiveForm.Recordset.AddNew

  • Borrar. Esta opción ejecuta el código:

            DoCmd.RunCommand acCmdDeleteRecord
El editar, se hace sobre el propio grid.

En ambos casos, es preferible usar Option Explicit.

Para que se seleccione la cinta contextual al abrir o activar un formulario, hay que poner este código ene el evento Activate:

Private Sub Form_Activate()
    On Error Resume Next
    
    If Not gobjRibbonDet Is Nothing Then
        gobjRibbonDet.ActivateTab "tabDet"
    End If
End Sub

Además, podemos cambiar el título del formulario en función del modo en que nos encontremos, para ello hay que poner este código ene el evento Load:

Private Sub Form_Load()
    If Me.NewRecord Then
        Me.Caption = "Añadir " & Me.Caption
    Else
        Me.Caption = "Editar " & Me.Caption
    End If
End Sub

Para que al hacer doble click sobre el formulario se edite el elemento actual, hay que poner este código ene el evento DblClick:

Private Sub Form_DblClick(Cancel As Integer)
    If (Me.SelHeight = 1) And (Me.SelWidth > 0) Then
        DoCmd.OpenForm "Comuneros", acNormal, , "NumeroSocio='" & Forms("ComunerosList")!NUMEROSOCIO & "'", acFormEdit
    End If
End Sub
En este código, el if se usa para chequear si se ha hecho doble click en el selector de fila (tal y como se detalla en Menús contextuales), por lo demás este código es similar al que vimos como respuesta al botón btn_ComuEdit, por lo que se debería pensar en algún método para que el código se ejecutara en un sólo punto.

Si se usa sólo un formulario de listado, como en algunas tablas auxiliares, el evento no será necesario, ya que no se tiene un formulario de detalle.

En caso de usar un formulario de listado para seleccionar elementos, lo normal es que se visualice como Dialog, con lo que el código cambiará a :

Private Sub Form_DblClick(Cancel As Integer)
    If (Me.SelHeight = 1) And (Me.SelWidth > 0) Then
        If IsFormDialog(Me) Then
            'Acción si seleccionamos el elemento
        Else
            DoCmd.OpenForm "Comuneros", acNormal, , "NumeroSocio='" & Forms("ComunerosList")!NUMEROSOCIO & "'", acFormEdit
        End If
    End If
End Sub
Aquí se usa la función IsFormDialog, que hace uso del API de Windows para verificar si el objeto es dialog. Se podría usar otro tipo de condición como por ejemplo que el formulario sea Modal. En la acción por ejemplo se puede cerrar el formulario o seleccionar el campo actual.

También podemos hacer que se seleccione la cinta contextual al abrir o activar un formulario, hay que poner este código ene el evento Activate:

Private Sub Form_Activate()
    On Error Resume Next
    
    If Not gobjRibbonCont Is Nothing Then
        gobjRibbonComu.ActivateTab "tabComu"
    End If
End Sub

Por último, si no permitimos que se pueda borrar desde el menú contextual, preguntaremos antes de que se borre:

Private Sub Form_Delete(Cancel As Integer)
    If MsgBox("¿Está seguro de eliminar el regisro actual?", vbOKCancel, "Eliminar") = vbOK Then
        Cancel = False
    Else
        Cancel = True
    End If
End Sub
En el caso de que permitamos la eliminación de registros desde elDatasheet, Access nos los preguntará igualmente, por lo que no sería necesario.

Con lo que el código para el botón de borrar quedará:

        Case "btn_Delete"
            ' Button
            ' In Tab:
            ' In Group:
            DoCmd.RunCommand acCmdDeleteRecord
En este caso he usado un código genérico, con lo que sólo son específicos de momento los códigos para Añadir y Editar.

Además, habría que añadir los eventos MouseUp y Open necesarios para los Menús contextuales.