EJERCICIO 09 · PARTS Y FACTBOXES
Parts y FactBoxes
Dificultad: 6/10Ejercicios anteriores
¿Qué tienes construido hasta ahora?
- Modelo de datos completo:
"Maquinaria","Cabecera Alquiler","Linea Alquiler"y"Historial Estado Maquina"con triggers, FlowFields, FlowFilters y TableRelations. - Pages completas:
"Maquinaria List"y"Maquinaria Card"(con grupos,Importance,CardPageIdyOnAfterGetRecord). "Cabecera Alquiler List","Alquileres Activos List"y"Cabecera Alquiler Card"."Historial Maquina Part"(ListPart) y"Maquinaria Stats Part"(CardPart) ya creadas en el ejercicio anterior y embebidas en"Maquinaria Card".
Ya tienes las Parts básicas en pie. En este ejercicio vas a profundizar en SubPageLink,
añadir Parts donde aún faltan y conectar el lado de Cabecera Alquiler con toda su
información relacionada. El resultado final será una interfaz completa donde el usuario puede ver
las líneas de un alquiler y el resumen de la máquina sin salir de la pantalla actual.
Este es el wireframe de la pantalla que construirás en el ejercicio:
Cabecera Alquiler Card — grupo General
No.
Descripcion
No. Maquina Principal
Fecha Inicio
Fecha Fin
Estado
Creado Por
Modificado Por
ListPart — "Lineas Alquiler Part" (nueva)
No. Linea | No. Maquina | Fecha Inicio | Fecha Fin | Dias Alquiler
No. Linea | No. Maquina | Fecha Inicio | Fecha Fin | Dias Alquiler
No. Linea | No. Maquina | Fecha Inicio | Fecha Fin | Dias Alquiler
ListPart (zona principal)
FactBoxes (columna lateral)
Ejercicio 01
ListPart · SubPageLink
Crea el ListPart de líneas de alquiler
Objetivo: Construir el subformulario de líneas y embebarlo directamente
en el layout principal de
"Cabecera Alquiler Card" (no en FactBoxes), para
reproducir el patrón clásico de cabecera → líneas que tienen los documentos de BC.
Instrucciones
- Crea
LineasAlquilerPart.Page.al(ID 50109):PageType = ListPart,SourceTable = "Linea Alquiler". Muestra los campos"No. Linea","No. Maquina","Fecha Inicio","Fecha Fin"y"Dias Alquiler". Recuerda: en unListPartno se usarepeater. - Abre
CabeceraAlquilerCard.Page.aly añade unpartdentro delarea(Content), después del grupoGeneral, apuntando a"Lineas Alquiler Part". - Configura el
SubPageLink: el campo"No. Alquiler"de"Linea Alquiler"debe enlazarse con el campo"No."de"Cabecera Alquiler".
Pista de Código
AL — LineasAlquilerPart.Page.al
page 50109 "Lineas Alquiler Part"
{
PageType = ListPart;
ApplicationArea = All;
SourceTable = "Linea Alquiler";
layout
{
area(Content)
{
// ⚠️ Sin repeater — el ListPart ya lo implica
field("No. Linea"; Rec."No. Linea") { ApplicationArea = All; }
field("No. Maquina"; Rec."No. Maquina") { ApplicationArea = All; }
field("Fecha Inicio"; Rec."Fecha Inicio") { ApplicationArea = All; }
field("Fecha Fin"; Rec."Fecha Fin") { ApplicationArea = All; }
field("Dias Alquiler"; Rec."Dias Alquiler") { ApplicationArea = All; }
}
}
}
AL — CabeceraAlquilerCard.Page.al (layout con
part)
layout
{
area(Content)
{
group(General)
{
// ... campos existentes
}
// Part embebido en el cuerpo principal (no en FactBoxes)
part(LineasAlquiler; "Lineas Alquiler Part")
{
ApplicationArea = All;
Caption = 'Líneas de Alquiler';
SubPageLink = "No. Alquiler" = field("No.");
}
}
}
💡 Recuerda: La diferencia entre poner el
part en
area(Content) y en area(FactBoxes) es visual. En
Content aparece integrado en el cuerpo principal de la ficha (patrón
cabecera/líneas); en FactBoxes aparece en la columna lateral derecha.
Para un subformulario de líneas, siempre va en Content.
Ejercicio 02
FactBoxes · CardPart · SubPageLink
Añade FactBoxes a Cabecera Alquiler Card
Objetivo: Reutilizar las Parts ya construidas en ejercicios anteriores para
enriquecer
"Cabecera Alquiler Card" con dos FactBoxes laterales: el resumen
estadístico de la máquina y su historial de estados, conectados a través del campo
"No. Maquina Principal".
Instrucciones
- En
CabeceraAlquilerCard.Page.al, añade unarea(FactBoxes)después delarea(Content). - Añade el
partque apunte a"Maquinaria Stats Part"(ya existe del ejercicio anterior). ElSubPageLinkdebe conectar el campo"No."de"Maquinaria"con el campo"No. Maquina Principal"de"Cabecera Alquiler". - Añade un segundo
partque apunte a"Historial Maquina Part"(también ya existe). ElSubPageLinkdebe conectar"No. Maquina"de"Historial Estado Maquina"con"No. Maquina Principal"de"Cabecera Alquiler".
Pista de Código
AL — CabeceraAlquilerCard.Page.al (area
FactBoxes)
area(FactBoxes)
{
// Reutilizamos "Maquinaria Stats Part" del ejercicio anterior
part(EstadisticasMaquina; "Maquinaria Stats Part")
{
ApplicationArea = All;
Caption = 'Estadísticas de la Máquina';
// "No." en tabla Maquinaria = "No. Maquina Principal" en Cabecera Alquiler
SubPageLink = "No." = field("No. Maquina Principal");
}
// Reutilizamos "Historial Maquina Part" del ejercicio anterior
part(HistorialMaquina; "Historial Maquina Part")
{
ApplicationArea = All;
Caption = 'Historial de Estado';
// "No. Maquina" en Historial = "No. Maquina Principal" en Cabecera Alquiler
SubPageLink = "No. Maquina" = field("No. Maquina Principal");
}
}
⚠️ Ojo con el SubPageLink: El campo de la izquierda siempre pertenece
a la tabla de la Part (tabla hija). El campo de la derecha, dentro de
field(),
pertenece a la tabla de la page padre. Si los intercambias, BC no lanzará error de
compilación pero el filtro no funcionará y el panel mostrará todos los registros.
Ejercicio 03
SubPageLink compuesto
SubPageLink con clave primaria compuesta
Objetivo: Practicar el
SubPageLink con más de un campo,
necesario cuando la tabla hija tiene una clave primaria compuesta.
Añadirás una page de tipo ListPart al historial que filtre simultáneamente
por máquina y por tipo de origen.
Instrucciones
- Crea
HistorialAlquilerPart.Page.al(ID 50110):PageType = ListPart,SourceTable = "Historial Estado Maquina". Muestra"Entry No.","Estado Anterior","Estado Nuevo","Fecha Cambio"y"No. Origen". - Añade este ListPart como segunda Part en el
area(FactBoxes)de"Cabecera Alquiler Card", reemplazando al"Historial Maquina Part"que ya estaba. Configura unSubPageLinkcompuesto con dos condiciones:"No. Maquina"=field("No. Maquina Principal")"Tipo Origen"=const(Alquiler)
- De este modo el panel lateral mostrará solo los cambios de estado que ocurrieron durante un alquiler, no los manuales.
Pista de Código
AL — HistorialAlquilerPart.Page.al
page 50110 "Historial Alquiler Part"
{
PageType = ListPart;
ApplicationArea = All;
SourceTable = "Historial Estado Maquina";
Editable = false;
layout
{
area(Content)
{
field("Entry No."; Rec."Entry No.") { ApplicationArea = All; }
field("Estado Anterior"; Rec."Estado Anterior") { ApplicationArea = All; }
field("Estado Nuevo"; Rec."Estado Nuevo") { ApplicationArea = All; }
field("Fecha Cambio"; Rec."Fecha Cambio") { ApplicationArea = All; }
field("No. Origen"; Rec."No. Origen") { ApplicationArea = All; }
}
}
}
AL — SubPageLink compuesto en
CabeceraAlquilerCard
part(HistorialAlquiler; "Historial Alquiler Part")
{
ApplicationArea = All;
Caption = 'Historial de Estados (Alquiler)';
SubPageLink = "No. Maquina" = field("No. Maquina Principal"),
"Tipo Origen" = const(Alquiler);
// const(Alquiler) filtra directamente por el valor del Option
// sin necesidad de que sea un campo de la tabla padre
}
💡 Recuerda: En un
SubPageLink puedes mezclar
field() (valor del registro padre) con const() (valor
fijo hardcodeado). Esto permite filtrar la Part por una combinación de contexto
dinámico y condición estática, sin necesidad de crear una page separada para cada caso.
💡 Bonus: Ahora tienes
"Historial Maquina Part"
(todos los cambios) y "Historial Alquiler Part" (solo los de alquiler).
Podrías añadir ambas en "Maquinaria Card" como dos FactBoxes independientes:
una con todos los cambios y otra filtrada solo por const(Manual) para
ver las revisiones manuales. El usuario tendría una vista completa del ciclo de vida
de cada máquina sin salir de su ficha.