venerdì 31 ottobre 2014

AX 2012 - parm di lookup multiselezione su data contract

Piccola pillola per chi utilizza lookup multiselezione sui SOF (SysOperationFramework).

Per pilotare i parametri di una lookup multiselezione nella vostra dialog di tipo SOF tramite la classe di contratto, dovrete gestire il valore tramite lista e aggiungere il seguente codice nell'intestazione del metodo di parm per non incappare in errori:

 AifCollectionTypeAttribute("return",Types::String)  

Esempio su StackOverflow:

http://stackoverflow.com/questions/18498128/report-multivalue-parameter

mercoledì 8 ottobre 2014

AX 2009 - Abilitare i filtri (Ctrl +g) su lookup via X++

In questo post vediamo come abilitare via codice i filtri wildcard sui controlli grid delle lookup di AX 2009. In questo caso la richiesta è di poter vedere di default i filtri aperti non appena si apre la lookup sul campo selezionato. La difficoltà stà nel fatto che non abbiamo un vero e proprio form, ma solo il form generato da standard quando si apre una look up. Per fare ciò occorrerà modificare la classe SysSetupFormRun che rappresenta l'unico punto in cui intercettare l'apertura della lookup: il post presente Quì è stato di grande aiuto =)

Per prima cosa effettuiamo l'override del metodo Run della classe SysSetupFormRun  :

 public void run()  
 {  
   object     obj;  
   SysSetupFormRun SysSetupFormRun;  
   int       i,classId;  
   FormControl   control;  
   #define.Ctrl_g(2855)  
   ;  
   super();  
   obj = this.args().caller();  
   if(obj)  
   {  
     classId = classIdget(obj);  
   }  
   if(classId == className2id(classStr(SysSetupFormRun)))  
   {  
     SysSetupFormRun = obj;  
     control = SysSetupFormRun.selectedControl();  
     if(SysSetupFormRun.name() == formStr(<form string>l))  
     {  
       if(control.id() == <id del controllo nel form> && this.CRFindTopmostGrid())  
       {  
         this.task(#Ctrl_g);  
       }  
     }  
   }  
 }  
Il metodo CRFindTopmostGrid() cicla i tutti i controlli del form chiamante:
 private boolean CRFindTopmostGrid()  
 {  
   FormControl fc;  
   int i;  
   ;  
   for (i=1;i<=this.design().controlCount();i++)  
   {  
     fc = this.design().controlNum(i);  
     if (this.CRFindGrid(fc))  
     {  
       return true;  
     }  
   }  
   return false ;  
 }  
mentre il metodo CRFinfGrid() verifica se il controllo passato è di tipo Grid:
 private boolean CRFindGrid(FormControl fc)  
 {  
   FormGridControl fgrc;  
   FormGroupControl fgc;  
   FormTabControl ftc;  
   FormTabPageControl ftpc;  
   str controlStr,s;  
   int i, controlId;  
   Struct struct;  
   ;  
   // check to see what kind of control it is  
   controlStr = fc.toString();  
   if(strScan(controlStr,"FormGridControl",1,strLen(controlStr)))  
   {  
     if (fc.visible())  
     {  
       fgrc = fc;  
       fgrc.enter();  
       return true;  
     }  
   }  
   else if(strScan(controlStr, "FormGroupControl",1,strLen(controlStr)))  
   {  
     fgc = fc;  
     for (i=1;i<=fgc.controlCount();i++)  
     {  
       if (this.CRFindGrid(fgc.controlNum(i)))  
       {  
         return true;  
       }  
     }  
   }  
   //  
   else if(strScan(controlStr, "FormTabControl",1,strLen(controlStr)))  
   {  
     ftc = fc;  
     for (i=1;i<=ftc.controlCount();i++)  
     {  
       if (this.CRFindGrid(ftc.controlNum(i)))  
       {  
         return true;  
       }  
     }  
   }  
   else if(strScan(controlStr, "FormTabPageControl",1,strLen(controlStr)))  
   {  
     ftpc = fc;  
     for (i=1;i<=ftpc.controlCount();i++)  
     {  
       if (this.CRFindGrid(ftpc.controlNum(i)))  
       {  
         return true;  
       }  
     }  
   }  
   return false;  
 }  
Per ottenere l'id del controllo che apre la lookup possiamo usare il seguente job che dato un form ci fornisce gli id e i nomi di tutti i componenti grafici:
 static void recurseOverAllFormControls(Args _args)  
 {  
   Form form = new Form(formstr(CLU_VendInvoiceJournal));  
   void recurse(Object _parent, int _depth = 1)  
   {  
     int   i;  
     str   name;  
     str   caption;  
     str   dashes;  
     int   id;  
     ;  
     // Used for making it pretty  
     //-->  
     i = _depth;  
     while (i)  
     {  
       dashes += '-';  
       i--;  
     }  
     //<--  
     // Used for example of how to use data  
     //-->  
     if (SysTest::hasMethod(_parent, identifierStr(caption)))  
       caption = _parent.caption();  
     if (SysTest::hasMethod(_parent, identifierStr(name)))  
       name = _parent.name();  
      if (SysTest::hasMethod(_parent, identifierStr(id)))  
       id = _parent.id();  
     info(strfmt("%1%2[%3](%4)(%5)", _depth, dashes, name, caption, id));  
     //<--  
     // Escape condition!  
     if (_parent.controlCount() == 0)  
       return;  
     // Recursive statement  
     for (i=1; i<=_parent.controlCount(); i++)  
       recurse(_parent.controlNum(i), _depth+1);  
   }  
   ;  
   recurse(form.design());