EJERCICIO 04 · TABLERELATIONS

TableRelations

Dificultad: 5/10
Ejercicios anteriores

¿Qué tienes construido hasta ahora?

  • Enum "Rental Status" con los estados de la maquinaria, extensible con "Vendido".
  • Tabla "Maquinaria" (ID 50100): campos "No.", "Descripcion", "Estado", "Categoria", "Fecha Alta". PK sobre "No.", SK sobre "Estado" y "Categoria".
  • Tabla "Linea Alquiler" (ID 50101): PK compuesta "No. Alquiler" + "No. Linea", SK sobre "No. Maquina".
  • Tabla "Historial Estado Maquina" (ID 50102): PK con AutoIncrement, SK con MaintainSiftIndex.
  • Pages "Maquinaria List" y "Maquinaria Card" con OnValidate y acción de filtro.

Modelo de datos actual

Antes de empezar, visualiza cómo quedarán conectadas las tablas una vez añadas las relaciones:

Maquinaria ("No." PK) ▲ ▲ │ └────────────────────── "No. Maquina" ──► Historial Estado Maquina "No. Maquina" ──► Linea Alquiler (PK compuesta) "No. Alquiler" ──► Cabecera Alquiler (nueva)
Ejercicio 01
TableRelation simple

Vincula Linea Alquiler con Maquinaria

Objetivo: Añadir integridad referencial al campo "No. Maquina" de la tabla "Linea Alquiler", de forma que solo se puedan introducir máquinas que existan realmente en la tabla "Maquinaria".

Instrucciones

  • Abre LineaAlquiler.Table.al.
  • Al campo "No. Maquina" (Code[20]) añádele la propiedad TableRelation = "Maquinaria"; dentro de sus llaves.
  • Asegúrate de que ValidateTableRelation queda en su valor por defecto (true): no hace falta declararlo, pero entiende qué implica.
  • Compila y verifica que el campo genera la lupa de búsqueda en la page de líneas.

Pista de Código

AL — LineaAlquiler.Table.al (fragmento)
        field(3; "No. Maquina"; Code[20])
        {
            TableRelation = "Maquinaria"; // solo acepta "No." que existan en Maquinaria
        }
💡 Recuerda: El tipo y tamaño del campo (Code[20]) debe coincidir exactamente con el de la PK de la tabla relacionada. Si difieren, el compilador lanzará un error.
Ejercicio 02
Nueva tabla + TableRelation

Crea la tabla Cabecera Alquiler y vincúlala

Objetivo: Crear la tabla cabecera del alquiler y conectarla con "Linea Alquiler" usando TableRelation, cerrando así el modelo cabecera → líneas que ya tienes en los ejercicios anteriores.

Instrucciones

  • Crea CabeceraAlquiler.Table.al con ID 50103 y nombre "Cabecera Alquiler".
  • Campos: "No." (Code[20]), "Descripcion" (Text[100]), "Fecha Inicio" (Date), "Fecha Fin" (Date) y "Estado" (Enum "Rental Status").
  • PK simple sobre "No.".
  • Ahora vuelve a LineaAlquiler.Table.al y añade TableRelation = "Cabecera Alquiler"; al campo "No. Alquiler", de modo que cada línea deba pertenecer a una cabecera existente.

Pista de Código

AL — CabeceraAlquiler.Table.al
table 50103 "Cabecera Alquiler"
{
    fields
    {
        field(1; "No.";          Code[20])              { }
        field(2; "Descripcion";  Text[100])             { }
        field(3; "Fecha Inicio"; Date)                  { }
        field(4; "Fecha Fin";    Date)                  { }
        field(5; "Estado";       Enum "Rental Status") { }
    }
    keys
    {
        key(PK; "No.") { }
    }
}
AL — LineaAlquiler.Table.al (campo actualizado)
        field(1; "No. Alquiler"; Code[20])
        {
            TableRelation = "Cabecera Alquiler"; // debe existir en la cabecera
        }
Ejercicio 03
TableRelation condicional

Relación condicional en el Historial de Estado

Objetivo: Ampliar la tabla "Historial Estado Maquina" con un campo "Tipo Origen" (Option) que indique si el cambio viene de un alquiler o de una revisión manual. Según el tipo, el campo "No. Origen" apuntará a "Cabecera Alquiler" o quedará libre.

Instrucciones

  • Abre HistorialEstado.Table.al y añade dos campos nuevos: "Tipo Origen" (Option con valores Alquiler y Manual) y "No. Origen" (Code[20]).
  • En el campo "No. Origen" configura una TableRelation condicional: si "Tipo Origen" = Alquiler, relacionarlo con "Cabecera Alquiler"; en caso contrario no aplicar relación.
  • Cuando "Tipo Origen" = Manual, el campo debe poder dejarse vacío sin error: usa ValidateTableRelation = false fuera del bloque condicional para cubrirlo.

Pista de Código

AL — HistorialEstado.Table.al (campos nuevos)
        field(6; "Tipo Origen"; Option)
        {
            OptionMembers = Alquiler,Manual;
            OptionCaption = 'Alquiler,Manual';
        }
        field(7; "No. Origen"; Code[20])
        {
            ValidateTableRelation = false;
            TableRelation = if ("Tipo Origen" = const(Alquiler)) "Cabecera Alquiler";
            // Si Tipo Origen = Manual no se valida contra ninguna tabla
        }
⚠️ Ojo: ValidateTableRelation = false desactiva la comprobación de integridad referencial para todos los valores del campo. Úsalo solo cuando hay casos legítimos en los que el valor no necesita existir en ninguna tabla.
💡 Bonus: Vuelve al trigger OnValidate del campo "Estado" en MaquinariaCard.Page.al. Ahora que el historial tiene "Tipo Origen" y "No. Origen", ¿podrías rellenarlos automáticamente al insertar la fila de historial? Pista: si la máquina tiene líneas en "Linea Alquiler", el tipo será Alquiler y el origen será el "No. Alquiler" de la última línea activa.
← Volver a Ejercicios