Artículo Formularios Maestro-Detalle con Visual Basic
Autor / Fuente Harvey Triana
Tema Bases de datos
Creado Marzo 8 de 1998

Formularios Maestro-Detalle con Visual Basic

Implementación Segura


Introducción

Mi primera publicación en Internet, hace más o menos un año, fue una implementación Form-SubForm para VB4, genéricamente Formulario Maestro-Detalle. Este artículo presenta la implementación para VB5 contra una Base de Datos Jet 3.5, con una visión más sólida del código y algunos detalles adicionales. Una de mis primeras impresiones con VB5 fue que trae un complemento para lograr formularios Maestro-Detalle, no obstante después de probarla me di cuenta que al Complemento le falta mucho para lograr una solidez para un software de nivel, de hecho la falla fundamental es que no mantienen la integridad de una relación Uno a Varios como era de esperarse. Posiblemente el propósito de Complemento es servir de plantilla, o quizá el programador del mismo no tubo en cuenta varios detalles importantes.

La siguiente gráfica muestra una implementación sencilla:


Un Formulario Maestro Detalle

 

Objetivo

Se trata de lograr una implementación de formularios Maestro-Detalle de manera que mantengan la Integridad Referencial y que soporten errores inducidos de datos. Los principales errores que hay que controlar provienen de la ausencia de registros. Puntualmente al crear un registro de la parte de Maestro se deja el Recordset subyacente en el aire, sin soporte a la clave del Recorset Padre, hasta que este no se archive en la Base de Datos. Este y otros detalles producen la caída de la aplicación generalmente por errores del lado del motor, y es la parte que muchos programadores no ven. La implementación que presento soporta estas fallas con holgura.

Otro de los objetivos principales es lograr que esto sea lo más flexible posible, es decir, que no sea necesario adentrarse en el código para lograr la implementación desde una fuente de registros cualquiera. El ejemplo que suministro es un avance en este tema.

De hecho, bastaría cambiar las siguientes líneas para que trabaje:

    Dim f As New frm_MaestroDetalle
    
    '//Configuración
    ChDir App.Path '//Asume BD en la trayectoria de la aplicación
    With f
        .DBName = "Mundo97.mdb"
        .LinkName = "ID Continente"
        .ParentRS = "Continentes"
        .ChildRS = "SELECT * FROM [Paises] WHERE [" & .LinkName & "] = ?;"
        .Show
    End With

Personalmente, he programado una automatización de configuración en tiempo de ejecución para cualquier fuente de datos. Posiblemente en un articulo futuro presentare esto, ya que es muy potente (en particular automatiza el empleo de soporte a datos a través de listas desde una Base de Datos de catálogos).


Requerimientos Previos

Una Base de Datos Access 97 con dos tablas que mantienen una relación Uno a Varios, con Integridad Referencial. Si aun no identifica estos términos, los expongo brevemente. En otro caso, salte este tema.

Observe la siguiente consulta de datos:

Continentes.ID Continente Continente Paises.ID Continente Pais
7 Europa 7 España
7 Europa 7 Portugal
7 Europa 7 Francia
7 Europa 7 Polonia
9 América del Sur 9 Colombia
9 América del Sur 9 Argentina

Se trata del el ejemplo clásico de uno a varios entre Continentes y Países. La clave de la relación se basa en dos aspectos: primero, un Campo relacionado entre las dos tablas (ID Continente), y segundo, la creación del objeto Relation.

  1. Para el primer aspecto doy un consejo (es un estándar de Access), El nombre del Campo en las dos tablas es el mismo, y conserve estas características:
Campo Enlace Tabla Padre (Maestro) Tabla Hijo (Detalle)
ID Nombre Normalmente Clave Principal de la Tabla y de tipo Contador (Autonumerico) Campo de tipo Entero Largo
  1. Crear el objeto de Relación. Esto se hace muy fácil desde Access. En Access 97 es Menú Herramientas, Relaciones, luego arrastra el campo desde Maestro a Detalles, y establece la integridad referencial para actualizar y eliminar. La relación también se puede crear desde código VB al crear un objeto Relation en la base de datos. Finalmente aparecerá:


Ventana Relaciones de MS Access

 

Código Visual Basic

El código Basic resulta algo extenso. He sido cuidadoso de documentar el ejemplo de manera que se puedan aclarar dudas. Sin embargo, puntualizo detalles.

Las líneas al principio de este documento servirán para una implementación rápida. Atención a la asignación de ChildRS, es un SQL con un carácter interrogación en la cláusula WHERE, esto es particular y sirve para que se inserte el parámetro cuando se cambia el registro de la tabla Padre. Incluí un modulo sencillo para demostrar la utilidad, que las líneas las puede usar desde Form_Load (limitaría el formulario a un conjunto constante de fuente de datos). No obstante, como esta el ejemplo, si quisiera cambiar la fuente de datos, tendría que modificar los controles enlazados al Data Padre en el formulario, es decir, esta a un paso (puede escribirme si tiene problemas).

Como una particularidad de la solidez del código, es el control de desencadenamiento de eventos que se sucede al agregar o eliminar registros. Sin esto, el código es bastante débil y susceptible de fallar.

Esta implantación también se hace en donde el Recordset Padre es de solo lectura. Esto reduce dramáticamente las líneas de código, de hecho se elimina todo lo referente a la variable Reposition (responsable de controlar el desencadenamiento de eventos).

 

dbSubForm.zip (95k). El ejemplo incluye un proyecto Visual Basic 5.0 con una Base de Datos Access 97 sencilla. El código del formulario esta debidamente documentado para alguna modificación pertinente.

Los programadores de VB4 pueden aprovechar la implementación al usar Copy-Paste del código y usar como Referencias la biblioteca DAO 3.5.


Harvey Triana
Derechos Reservados. Autorización solo para programación