venerdì 28 marzo 2014

AX 2012 - Lookup su dialog SSRS: Utilizzo classe UI Builder

In moltissimi casi può sorgere la necessità di aggiungere un parametro che esegua una lookup su un campo di una tabella nella finestra di dialog di un report.

Per prima cosa occorre modificare (o creare in caso non esista) la classe UI builder del report. Questa classe è necessaria quando si desidera personalizzare la dialog di un report.
In sintesi ci consente di aggiungere controlli (visibilità, abilitazione...) e lookup personalizzati ai parametri impostati nella classe Data contract del report stesso. Si presuppone la creazione quindi del metodo parm nella data contract del campo che vogliamo "lookupare".

La classe builder che andremo a creare (se non esiste già) deve innanzitutto estendere SrsReportDataContractUIBuilder. Vediamo, con un banalissimo esempio, la creazione di questa classe per un report che ha come parametro il codice cliente. Si vuole visualizzare una lookup nella SalesTable di tutti gli ordini di quel cliente

 class SimpleDemoUIBuilder extends SrsReportDataContractUIBuilder  
 {  
   DialogField dialogCustAccount;
   DialogField dialogSalesOrders;  
   SimpleDemoContract contract;  
 }  

Può essere utile effettuare l'override del metodo build per impostare la data contract e il dialog field dichiarati nella class declaration...

 public void build()  
 {  
   contract = this.dataContractObject();  
   dialogCustAccount = this.addDialogField(methodStr(SimpleDemoContract,parmCustAccount),contract);
 }  

...piuttosto che eseguire tutto nel metodo postBuild:

 public void postBuild()  
 {  
   DialogField             dialogCostingVersionId;  
   SimpleDemoContract      contract;
  
   super();
  
   contract= this.dataContractObject();  
   dialogCustAccount = this.addDialogField(methodStr(SimpleDemoContract,parmCustAccount),contract);
   dialogSalesOrders = this.addDialogField(methodStr(SimpleDemoContract,parmSalesOrders),contract);   
   .....
   dialogSalesOrders.registerOverrideMethod(methodStr(FormStringControl, lookup), methodStr(SimpleDemoUIBuilder, salesOrdersLookup), this);
  
 }  

dove l'ultima riga servirà proprio a far si che la dialog esegua il metodo di lookup sottostante:

  private void salesOrdersLookup(FormStringControl _salesOrdersLookup)  
 {  
      Query query = new Query();  
      QueryBuildDataSource qbds_SalesTable;  
      SysTableLookup sysTableLookup;  
    
      if (_salesOrdersLookup != null)
      {
                 sysTableLookup = SysTableLookup::newParameters(tableNum(SalesTable), _salesOrdersLookup);  
                 qbds_SalesTable = query.addDataSource(tableNum(SalesTable)); 
                 sysTableLookup.addLookupfield(fieldnum(SalesTable, SalesId), true);
     
                 qbds_SalesTable.addRange(fieldNum(SalesTable,CustAccount)).value(queryValue(contract.parmCustAccount());
                 sysTableLookup.parmQuery(query);  
                 // Perform the lookup  
                 sysTableLookup.performFormLookup();  
      }
 }    

Dove si effettuerà il range con il metodo parm (che in questo caso funge da getter), creato nella data contract.