lunedì 23 settembre 2013

AX 2012 - Jobs

In questo post pubblico due job che ho scritto per un cliente e che possono risultare utili:

Il primo job prende come input il nome di una tabella e salva su file CSV la lista dei campi e le principali prorietà ("Field Name","Label","Help text", "Base type", "EDT") più lunghezza della stringa se il campo è di tipo testo:

 static void CRTableInfoExport(Args _args)  
 {  
   int     i,fieldId;  
   DictTable  DictTable;  
   DictField  DictField;  
   TableId   TableId;  
   str     strFieldName;  
   Commaio   file;  
   container  line,header;  
   str     filename;  
   #File  
   ;  
   TableId = tableNum(CustTable); //inserici il nome della tabella  
   DictTable = new DictTable(TableId);  
   filename = @'C:\Temp\'+tableId2name(TableId)+'.csv'; //percorso  
   file = new Commaio(filename , 'W');  
   file.outFieldDelimiter(';');  
   if(DictTable)  
   {  
     header = ["Field Name","Label","Help text", "Base type", "EDT", "String lenght"];  
     file.writeExp(header);  
     for (i=1; i <= DictTable.fieldCnt(); i++)  
     {  
       fieldId     = DictTable.fieldCnt2Id(i);  
       DictField    = new DictField(TableId, fieldId);  
       strFieldName  = (DictField ? DictField.name() : "");  
       line = [strFieldName,DictField.label(),DictField.help(),strFmt("%1",DictField.baseType())];  
       if(extendedTypeId2name(DictField.typeId()))  
       {  
         line    += extendedTypeId2name(DictField.typeId());  
       }  
       else  
         line    += enumId2Name(DictField.enumId());  
       if(strFmt("%1",DictField.baseType()) == "String")  
         line    += DictField.stringLen();  
       else  
         line    += '';  
       file.writeExp(line);  
     }  
   }  
   info("Terminato");  
 }  

Il secondo job analizza un progetto shared e per ogni elemento del progetto salva su file cvs il tipo di elemento, il nome, il livello più basso, quello più alto, l'user che ha creato l'oggetto, la data di creazione, l'eventuale user che ha apportato la modificato e la data di modifica:

 static void CRProjectScan(Args _args)  
 {  
   ProjName        projName;// = "projectName";  
   ProjectListNode   list = infolog.projectRootNode().AOTfindChild("Shared");  
   TreeNodeIterator    ir = list.AOTiterator();  
   ProjectNode      pnProj;  
   ProjectNode      pn;// = list.AOTfindChild(projName);  
   struct         prop;  
   str     strFieldName;  
   Commaio   file;  
   str     filename;  
   container  line,header;  
   Dialog   dialog;  
   DialogField field;  
   #properties  
   utilelements getElementSysInfo (Description nodeType, Description NodeName)  
   {  
     utilelementtype uet;  
     utilelements sue;  
     ;  
     switch(nodeType)  
     {  
       case "BaseEnums":  
         uet = utilelementtype::Enum;  
       break;  
       case "Tables":  
         uet = utilelementtype::Table;  
       break;  
       case "ConfigurationKeys":  
         uet = utilelementtype::ConfigurationKey;  
       break;  
       case "Maps":  
         uet = utilelementtype::TableMap;  
       break;  
       case "ExtendedDataTypes":  
         uet = utilelementtype::ExtendedType;  
       break;  
       case "Views":  
         uet = utilelementtype::ViewQuery;  
       break;  
       case "Queries":  
         uet = utilelementtype::Query;  
       break;  
       case "Classes":  
         uet = utilelementtype::Class;  
       break;  
       case "Forms":  
         uet = utilelementtype::Form;  
       break;  
       case "Reports":  
         uet = utilelementtype::Report;  
       break;  
       case "Jobs":  
         uet = utilelementtype::Job;  
       break;  
     }  
     select firstonly sue where sue.recordType == uet && sue.name == NodeName;  
     return sue;  
   }  
   void searchAllObj(projectNode rootNode)  
   {  
     #TreeNodeSysNodeType  
     TreeNode          childNode;  
     TreeNodeIterator      rootNodeIterator;  
     utilelements        result;  
     ;  
     if (rootNode)  
     {  
       rootNodeIterator = rootNode.AOTiterator();  
       childNode = rootNodeIterator.next();  
       while (childnode)  
       {  
         if (childNode.AOTgetNodeType() == #NT_PROJECT_GROUP)  
           searchAllObj(childNode);  
         else  
         {  
           result = getElementSysinfo(rootNode.AOTname(),childNode.AOTname());  
           line = [rootNode.AOTname(),childNode.AOTname(),enum2str(result.utilLevel),enum2str(childNode.applObjectLayer()), result.createdBy, result.createdDateTime, result.modifiedBy, result.modifiedDateTime];  
           file.writeExp(line);  
         }  
         childNode = rootNodeIterator.next();  
       }  
     }  
   }  
   ;  
   dialog = new Dialog();  
   dialog.addText("Select Project:");  
   field = dialog.addField(typeid(ProjName));  
   dialog.run();  
   if (dialog.closedOk())  
   {  
     //info(field.value());  
     projName = field.value();  
   }  
   pn = list.AOTfindChild(projName);  
   if (pn)  
   {  
     filename = WinAPI::getSaveFileName(0, ['TEXT FILE', '*' + '.CSV'], @'C:\', 'Save file as','',projName,0);//@'C:\Users\axservice\Desktop\'+tableId2name(TableId)+'.csv'; //percorso  
     file = new Commaio(filename , 'W');  
     file.outFieldDelimiter(';');  
     header = ["Group", "Name", "Lower Level","Highest level", "CreatedBy", "CreatedDateTime", "ModifiedBy", "ModifieddateTime"];  
     file.writeExp(header);  
     // info(strFmt("Projet %1:", projName));  
     pnProj = pn.loadForInspection();  
     searchAllObj(pnProj);  
     pnproj.treeNodeRelease();  
   }  
   else  
     error("Projet not found");  
 }  

lunedì 16 settembre 2013

AX 2012 - Global cache

AX 2012 mette a disposizione un potente strumento per memorizzare dei valori e recuperarli quando necessario: la Global chace. Può essere considerato come una speciè di "mappa" in cui posso memorizzare un valore associato ad una chiave e recuperare il valore tramite la chiave:

per inserire un valore nella global cache:

  globalCache.set(str owner , anytype key , anytype value );   

owner e key possono essere, liberi. Tipicamente si usa come owner lo username

es:

 SysGlobalCache globalCache = Appl.globalCache();  
 ;  
 globalCache.set(curUserId(), 4, "Somari su AX");   

per recuperare un valore:

 value = globalCache.get(str owner , anytype key);  

es:

  SysGlobalCache globalCache = Appl.globalCache();  
  str s;  
  ;  
  s = globalCache.get(curUserId(), 4); //s conterrà la stringa "Somari su AX"