La page sopra la source table
Una page è l’oggetto AL che espone dati e comandi all’utente: non contiene dati, li legge da una source table dichiarata con SourceTable, eventualmente ristretta da SourceTableView o resa temporanea con SourceTableTemporary. Ne discende la regola che l’esame usa più spesso: se un campo non esiste sulla tabella non può comparire sulla page, e per aggiungerlo a una tabella standard serve prima una table extension. Le proprietà InsertAllowed, ModifyAllowed, DeleteAllowed ed Editable governano cosa l’utente può fare; ApplicationArea e UsageCategory decidono se l’oggetto è visibile e ricercabile in Tell Me.
Scegliere il page type
Il PageType non è un dettaglio estetico: determina layout, navigazione e comportamento del client.
- Card: un solo record alla volta, campi organizzati in group; è la pagina di dettaglio tipica di un’anagrafica.
- List: molti record in un repeater; con
CardPageIdapre la Card sul record selezionato. - Document: testata più righe, dove le righe sono una part di tipo ListPart legata alla tabella delle righe. È il pattern di ordini, fatture e documenti in genere.
- Worksheet: lavoro a griglia con filtri e campi sopra il repeater, tipico di journal e fogli di lavoro.
- RoleCenter: la home del profilo, fatta di parts (headline, cue group, liste) e di aree di azione che costruiscono la navigazione del ruolo; si assegna all’utente tramite un oggetto profile.
- API: esposizione dati alle integrazioni, con
APIPublisher,APIGroup,APIVersion,EntityName,EntitySetNameeDelayedInsert.
Esistono poi tipi di supporto — CardPart e ListPart per FactBox e sottopagine, NavigatePage per le procedure guidate — che non si usano come pagina autonoma.
Layout, azioni e trigger
Il blocco layout si divide in area: Content per il corpo, FactBoxes per i riquadri laterali. Dentro le area stanno i group, i field, le part e, sulle liste, il repeater. Il blocco actions ha le proprie area — Processing, Navigation, Reporting, Creation — e ogni action espone il trigger OnAction. La promozione decide che cosa compare sulla barra dei comandi: nelle versioni recenti si dichiara un’area Promoted con gruppi che referenziano azioni già definite altrove, mentre le vecchie proprietà di promozione sulla singola action sono deprecate. La promozione resta comunque una scelta di UX separata dalla definizione dell’azione.
I trigger di page più ricorrenti sono OnInit e OnOpenPage all’apertura, OnAfterGetRecord a ogni record letto, OnAfterGetCurrRecord quando cambia il record corrente, OnNewRecord per i default, OnInsertRecord, OnModifyRecord e OnDeleteRecord per intercettare la scrittura, OnQueryClosePage e OnClosePage in chiusura. A livello di controllo ci sono OnValidate, OnLookup, OnDrillDown e OnAssistEdit. Regola di progetto che l’esame verifica: la validazione che deve valere sempre sta sulla table, perché la page non è l’unico modo di scrivere il dato.
Page extension, request page e Role Center
La page extension estende una pagina esistente senza toccarne il codice base: aggiunge campi e azioni con addfirst, addlast, addafter, addbefore, sposta controlli con le move, cambia proprietà con modify e può dichiarare trigger propri. Non cambia il PageType né la SourceTable e non cancella un controllo standard: al massimo lo nasconde con Visible = false.
La request page non è un oggetto page a sé, ma un blocco dichiarato dentro un report o un XMLport per chiedere filtri e opzioni prima dell’esecuzione; i filtri suggeriti si impostano sul dataitem. La Role Center chiude il cerchio come punto d’ingresso: da lì l’utente raggiunge liste, documenti e report del proprio ruolo.
Trappole tipiche d’esame
- Aggiungere un campo custom alla Customer Card → table extension più page extension: la page extension da sola non crea storage, il campo deve prima esistere sulla tabella estesa.
- Nascondere un campo standard che il cliente non usa →
modifyconVisible = false: nel layout di una page extension non esiste la rimozione di un controllo di base. - Logica da eseguire quando l’utente si sposta di riga →
OnAfterGetCurrRecord, nonOnAfterGetRecord: il secondo scatta per ogni record letto e su una list pesa sulle prestazioni. - Impedire la chiusura finché i dati non sono coerenti →
OnQueryClosePage: ritorna un Boolean e può annullare la chiusura, mentreOnClosePageviene eseguito quando la decisione è già presa. - Esporre entità a un client REST esterno → page con
PageType = API: una List pubblicata come web service dà OData, ma le convenzioni delle API richiedono publisher, group e version dichiarati sulla page. - Chiedere parametri all’utente prima di stampare → request page del report: non si crea una page separata da aprire con RunModal per poi passare i valori al report.