Wednesday, November 20, 2013

Purger les données d'utilisations

En cas de migration, il convient parfois de devoir supprimer certaines données d'utilisations des utilisateurs afin que des ensembles variables soit correctement utiliser par le système.

Les reports par exemple nécessitent en cas de modification de version d'AX sur leur classe de contrôle, une purge des données des utilisateurs de l'ancienne version.

Voici un exemple de job permettant de faire l'opération. L'exemple créé un formulaire permettant de choisir un filtrage sur une colonne de la SysLastValue DesignName ou RecorType pour choisir les entrées à supprimer.



static void deleteUsageData(Args _args)
{
    Dialog                  dialog;
    DialogField             dlgRange1,dlgRange2;
    DialogField             dlgbox1;
    SysLastValue            sysLastValue;
    int i = 0;
    #OCCRetryCount
    ;
    dialog                      = new Dialog("Usage Data Deletion");
    dlgRange1                   = dialog.addField(extendedTypeStr(Range),"DesignName");
    dlgRange2                   = dialog.addField(extendedTypeStr(Range),"RecordType");
 // Need to declare TypeofSysLastValueRange Enum with two values : designName & RecordType
    dlgbox1                     = dialog.addField(enumStr("TypeofSysLastValueRange"),"Colonne de filtrage");

    dlgRange1.value("*Report*");
    // ou
    dlgRange2.value("!userSetupQuery");

    dlgbox1.value(TypeofSysLastValueRange::designName);
    if (dialog.run())
    {
        try
        {
            ttsbegin;
            if(dlgbox1.value() == TypeofSysLastValueRange::designName)
            {
                while select forUpdate SysLastValue
                where sysLastValue.designName like dlgRange1.value()
                {
                info(strFmt("Delete information : company : %1, designName : %2, element Name : %3, User : %4",
                                    sysLastValue.company,
                                    sysLastValue.designName,
                                    sysLastValue.elementName,
                                    sysLastValue.userId));
                SysLastValue.delete();
                i++;
                }
            }
            else
            {
                while select forUpdate SysLastValue
                where sysLastValue.recordType like dlgRange2.value()
                {
                info(strFmt("Delete information : company : %1 , DesignName : %2, Element Name : %3, User : %4",
                                    sysLastValue.company,
                                    sysLastValue.designName,
                                    sysLastValue.elementName,
                                    sysLastValue.userId));
                SysLastValue.delete();
                i++;
                }
            }


        ttsCommit;
        }
        catch (Exception::Deadlock)
        {
            retry;
        }
        catch (Exception::UpdateConflict)
        {
            if (appl.ttsLevel() == 0)
            {
                if (xSession::currentRetryCount() >= #RetryNum)
                {
                    throw Exception::UpdateConflictNotRecovered;
                }
                else
                {
                    retry;
                }
            }
            else
            {
                throw Exception::UpdateConflict;
            }
        }
        catch (Exception::Error)
        {
            ttsabort;
            throw error("@SYS93835");
        }

        info(strFmt("Total deleted lines : %1",i));
    }
}

Tuesday, July 2, 2013

CU6 AX RTM/FP = CU2 AX R2 !



Fin juin 2013, le customer/Partner Source propose une CU6 pour Ax Dynamics 2012 RTM, Feature Pack, et pour AX Dynamics R2 :-/.
Les dénominations sont parfois trompeuses chez Microsoft : La CU6 nécessite la mise à jour R2 et la CU5 sera donc la dernière cumulative update des versions RTM et Feature Pack - a priori (afin d'inciter les clients à migrer ?).

Néanmoins, le CU6 n'est pas cumulative sur la R2, donc nécessite d'appliquer les CU1 à 5 pour bénéficier des correctifs de AX RTM/FP... de quoi s'y perdre!
Si j'ai bien tout compris, l'idéal serait un AX2012 FP CU 1 à 5 puis une migration en R2 + CU6 (ouf !)

Lien vers la CU6 (Customer/Partner Source)

De quoi nous donner un peu de travail.






Tuesday, June 18, 2013

Utiliser les services AIF d'AX dynamics

La couche AIF de Microsoft AX Dynamics sert générallement à l'échange de données entre des systèmes externes et l'ERP AX Dynamics. Microsoft a simplifié l'implémentation des services personnalisés sous 2012.

Cette couche permet d'accéder en entrée ou en sortie à des classes dédiées aux services de votre AOS.

Voici un exemple de l'implémentation et de l'utilisation d'un service sous DAX2012 : lien

Cet exemple simpliste est très bien fait : Il montre la facilité d'interaction entre l'extérieur et AX.
Vous pouvez imaginer toute sorte d'application des services AIF pour votre système d'information :
- Echange de données entre les applications externes et AX (données référentes par exemple)
- Déclenchement de traitement à distance via une application C# et piloté par un ordonnanceur
- Mise à jour d'AX après un traitement externe.
- Permettre des accès via de l'informatique mobile (PDA, système industriel etc...)

Un ERP n'étant jamais seul dans son environnement urbanisé, la couche AIF devient une solution SOA très intéressante et facile à mettre en oeuvre par rapport à des communications asynchrones.

Reste à étudier l'impact de l'utilisation massive des services AIF sur les performances de l'AOS.

Wednesday, April 24, 2013

Code Review :Comparer les couches de développements AX

Une fois vos développements terminés et/ou lorsque plusieurs intervenants ont travaillés sur une plateforme commune, il est intéressant de faire une vérification des couches de développements d'AX, afin de s'assurer qu'aucun développement n'est présent dans une couche non souhaitée.

Pour cela, créer un projet (privé ou public), et cliquer sur l'outil de filtrage du projet.
Choisir l'ajout depuis l'AOA et sélectionner via la fenêtre de filtrage un SysModelLayer égal à la couche que vous souhaitez vérifier.

AX chargera les objets de l'AOA qui sont dans cette couche. Il n'y a plus qu'a les passer en revue via l'outil de comparaison inter-couche de MorphX (clic droit --> Comparer)



Voici un article de blog qui permet de faire d'autres vérifications utiles sous AX : Objets non utilisés, comparaison des couches de développements etc...

Tuesday, April 16, 2013

lookup et lookupReference sous AX 2012

Sous AX 2012, le système travaille sur beaucoup de tables avec des références de clés (RecID --> RefRecId). Contrairement à 2009, où les clés sont basées sur des Id indexés et non doublonnés, Ax 2012 avec son système de RecId permet d'homogénéiser les types de jointure entre les tables et également de faciliter l'affichage et la sélection sous forme de lookup par référence à une table.

C'est la différence entre un lookup (liste de choix) classique type "2009" et ceux de 2012 (LookupReference).

Pour créer un lookup sur clé classique (type Id), le lookup peut être implémenté par exemple dans un formulaire, directement dans le DataSource du champs ou directement en méthode de Designs.
Cette méthode ne renverra aucun objet car la requête est intrisèque au formulaire.
Dans les bonnes pratiques, vous appelerez si possible une méthode lookup de la table depuis le formulaire via un super().

Pour un lookup sur une référence (RefRecId), on utilise une méthode lookupReference qui renvoi un objet cette fois, l'objet de référence du recid (DirPartyTable par exemple).
Cet objet renvoyé par la méthode sera automatiquement retraité en recId par le referenceGroup de votre champ de formulaire et bénéficiera de l'affichage correspondant (souche par exemple).

Syntaxe :

public client static DirPartyTable lookupReferenceParty(FormReferenceControl _formRefControl,CustAccount _custAccount)
{
DirPartyTable dirPartyTable; // instancier un buffer
Query query =
new Query();
QueryBuildDataSource queryBuildDataSourceParty;
QueryBuildDataSource queryBuildDataSourceContact;
QueryBuildRange queryBuildRange;
SysReferenceTableLookup sysRefTableLookup;
;
 
//Create an instance of SysTableLookup with the form control passed in
sysRefTableLookup = SysReferenceTableLookup::newParameters(
tablenum(DirPartyTable), _formRefControl);

//Add the fields to be shown in the lookup form
sysRefTableLookup.addLookupfield(
fieldnum(DirPartyTable,Name));
//create the query datasource
queryBuildDataSourceParty = query.addDataSource(
tablenum(DirPartyTable));
queryBuildDataSourceContact = queryBuildDataSourceParty.addDataSource(
tableNum(ContactPerson));
queryBuildDataSourceContact.relations(
true);
queryBuildDataSourceContact.joinMode(JoinMode::ExistsJoin);
queryBuildRange = queryBuildDataSourceContact.addRange(fieldnum(ContactPerson, CustAccount));
queryBuildRange.value(
strFmt(_custAccount));

//add the query to the lookup form
sysRefTableLookup.parmQuery(query);
dirPartyTable = sysRefTableLookup.performFormLookup();
//alimenter le buffer
return dirPartyTable; // retourner l'objet
}

Ici un exemple de lookupReference qui va filtrer sur un client (méthode de table)

Dans la partie formulaire, l'appel sera fait ainsi :

public
 Common lookupReference(FormReferenceControl _formReferenceControl)
{
DirPartyTable dirPartyTable;
dirPartyTable = InventJournalTrans::lookupReferenceParty(_formReferenceControl, ProjTable.CustAccount);
return dirPartyTable;
}

Monday, April 15, 2013

Utiliser Notepad++ Portable pour modifier des XPO

Voici un post sous AxaptaPedia proposant d'utiliser NotePad++ pour utiliser Notepad++ avec des fichiers XPO ou code XPP (plus facile que sur le bloc note Windows).

Pour utiliser ceci avec une version portable de Notepad, voici les fichiers à modifier :

Par exemple, sous C:\Notepad++Portable\App\Notepad++\
Editer le stylers.xml et le langs.xml

Ajouter dans le stylers.xml :

        <LexerType name="xpo" desc="XPO" ext="xpo">
            <WordsStyle name="DEFAULT" styleID="11" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" />
            <WordsStyle name="FOLDEROPEN" styleID="12" fgColor="FF8040" bgColor="FFFFFF" fontName="" fontStyle="0" />
            <WordsStyle name="FOLDERCLOSE" styleID="13" fgColor="FF8040" bgColor="FFFFFF" fontName="" fontStyle="0" />
            <WordsStyle name="KEYWORD1" styleID="5" fgColor="000080" bgColor="FFFFFF" fontName="" fontStyle="1" />
            <WordsStyle name="KEYWORD2" styleID="6" fgColor="008040" bgColor="FFFFFF" fontName="" fontStyle="2" />
            <WordsStyle name="KEYWORD3" styleID="7" fgColor="FF0000" bgColor="FFFFFF" fontName="" fontStyle="1" />
            <WordsStyle name="KEYWORD4" styleID="8" fgColor="00FF00" bgColor="FFFFFF" fontName="" fontStyle="0" />
            <WordsStyle name="COMMENT" styleID="1" fgColor="00FF80" bgColor="FFFFFF" fontName="" fontStyle="0" />
            <WordsStyle name="COMMENT LINE" styleID="2" fgColor="00FFFF" bgColor="FFFFFF" fontName="" fontStyle="0" />
            <WordsStyle name="NUMBER" styleID="4" fgColor="00FF80" bgColor="FFFFFF" fontName="" fontStyle="1" fontSize="12" />
            <WordsStyle name="OPERATOR" styleID="10" fgColor="800000" bgColor="FFFFFF" fontName="" fontStyle="1" />
            <WordsStyle name="DELIMINER1" styleID="14" fgColor="008000" bgColor="CCFFFF" fontName="" fontStyle="0" />
            <WordsStyle name="DELIMINER2" styleID="15" fgColor="008000" bgColor="CCFFFF" fontName="" fontStyle="0" />
            <WordsStyle name="DELIMINER3" styleID="16" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" />
    </LexerType>
    <LexerType name="X++" desc="xpo" ext="xpo">
            <WordsStyle name="DEFAULT" styleID="11" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" />
            <WordsStyle name="FOLDEROPEN" styleID="12" fgColor="FF8040" bgColor="FFFFFF" fontName="" fontStyle="0" />
            <WordsStyle name="FOLDERCLOSE" styleID="13" fgColor="FF8040" bgColor="FFFFFF" fontName="" fontStyle="0" />
            <WordsStyle name="KEYWORD1" styleID="5" fgColor="000080" bgColor="FFFFFF" fontName="" fontStyle="1" />
            <WordsStyle name="KEYWORD2" styleID="6" fgColor="008040" bgColor="FFFFFF" fontName="" fontStyle="2" />
            <WordsStyle name="KEYWORD3" styleID="7" fgColor="FF0000" bgColor="FFFFFF" fontName="" fontStyle="1" />
            <WordsStyle name="KEYWORD4" styleID="8" fgColor="00FF00" bgColor="FFFFFF" fontName="" fontStyle="0" />
            <WordsStyle name="COMMENT" styleID="1" fgColor="00FF80" bgColor="FFFFFF" fontName="" fontStyle="0" />
            <WordsStyle name="COMMENT LINE" styleID="2" fgColor="00FFFF" bgColor="FFFFFF" fontName="" fontStyle="0" />
            <WordsStyle name="NUMBER" styleID="4" fgColor="00FF80" bgColor="FFFFFF" fontName="" fontStyle="1" fontSize="12" />
            <WordsStyle name="OPERATOR" styleID="10" fgColor="800000" bgColor="FFFFFF" fontName="" fontStyle="1" />
            <WordsStyle name="DELIMINER1" styleID="14" fgColor="008000" bgColor="CCFFFF" fontName="" fontStyle="0" />
            <WordsStyle name="DELIMINER2" styleID="15" fgColor="008000" bgColor="CCFFFF" fontName="" fontStyle="0" />
            <WordsStyle name="DELIMINER3" styleID="16" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" />
    </LexerType>



Ajouter dans langs.xml :

    <Language name="XPO" ext="xpo">
            <Keywords name="Delimiters">&quot;&apos;0&quot;&apos;0</Keywords>
            <Keywords name="Folder+">SOURCE { CLASS METHODS PROPERTIES CONTROL CONTAINER ARRAY INDEX FORM OBJECTBANK DATASOURCE OBJECTPOOL FIELDLIST JOINS DESIGN TYPEELEMENTS TYPEREFERENCES USERTYPE FIELDS GROUPS GROUPFIELDS GROUP DATAFIELD INDICES INDEXFIELDS REFERENCES REFERENCE FIELDREFERENCES DELETEACTIONS BEGINNODE MENUITEM MENU</Keywords>
            <Keywords name="Folder-">ENDSOURCE } ENDMETHODS ENDCLASS ENDPROPERTIES ENDCONTROL ENDCONTAINER ENDARRAY ENDFORM ENDOBJECTBANK ENDDATASOURCE ENDOBJECTPOOL ENDFIELDLIST ENDJOINS ENDDESIGN ENDTYPEELEMENTS ENDTYPEREFERENCES ENDUSERTYPE ENDFIELDS ENDGROUPS ENDGROUPFIELDS ENDGROUP ENDINDEXFIELDS ENDINDICES ENDFIELDREFERENCES ENDREFERENCE ENDREFERENCES ENDDELETEACTIONS ENDTABLE ENDNODE ENDPROJECT ENDDATAFIELD ENDMENUITEM ENDMENU</Keywords>
            <Keywords name="Operators">- ! # ( ) , . : ; ? [ ] + &lt; = &gt;</Keywords>
            <Keywords name="Comment">1/* 2*/ 0//</Keywords>
            <Keywords name="Words1">Formatversion: Configuration: language directory company user client fetchahead opencursors database dsn sqluser hint sqlbuffer log hassqlpwd sqlpwd sqlparm retry dbserversqltrace haswarnings warnings share bindir startupmsg servermask localappl localappldoc locallabel localsysdoc applshare applexclusive doclanguage startupcmd logdir hascompwd compwd hasserveridletimeout serveridletimeout connectionidletimeout querytimelimit extracmdline port createdsn createdsn_tcpipport aos allowunauth exposeserverprers useserverprers sqlformliterals sqlcomplexliterals sqloraclefirstrowsfix ignoredatasourceindex aosencryption xppdebug dbcli ociconnectservice ociservice ocihost ocidbid ocitcpipport ociuser hasocipwd ocipwd preloadthresholdmsec preloadthresholdrecords dbunicodeenabled newconnectionretrydelayms newconnectionretrycount cachesynctime _clientmode _clientadname application broadcast internet aol aolcode sql native dbserver sqltrace exposeserverprinters useserverprinters ***Element FRMVERSION str container int select firstonly where while for Filename if return void public super element Return Yes No Delayed&#x0D;&#x0A; First Auto Default Normal Watch Vertical NoAccess Main Column width None Outside Opaque Button face View Grid Window background Highlight text Left Right only Text info run Version Else error Args Raised height Horizontal flush right boolean Common QueryRun FormTreeItem class Set FormTreeControl map anytype Dialog SysDictField this New new Query QueryBuildRange else QueryBuildDataSource Array mapiterator ttsbegin ttscommit FileName SaxReader SaxErrorHandler SaxAttributes TextBuffer protected catch try Called from classDeclaration Arrow USERTYPEVERSION TABLEVERSION FIELD Integer Absolute AutoReport AutoLookup REFERENCETYPE NORMAL static Miscellaneous Delete Not specified String Memo Cascade PROJECTVERSION SHARED JOBVERSION NoYes private null count Map DictTable break ttsBegin ttsCommit Error Exception true sum server DictField Counter throw join abstract extends endif index continue false switch case Version Restricted InnerJoin Active Standard Display VERSION MNUVERSION</Keywords>
            <Keywords name="Words2">Text Int Name Table Index Company CounterField AllowCheck AllowEdit AllowCreate AllowDelete StartPosition AutoSearch AutoNotify AutoQuery OnlyFetchActive JoinSource LinkType DelayActive InsertAtEnd InsertIfEmpty Left Top Width Height Visible Caption TitleDatasource Frame WindowResize WindowType SaveSize SaveSize HideToolbar SetCompany ColorScheme CssClass ShowWebHelp BackgroundColor ImageName ImageResource Imagemode Mode SubmitMethod SupportReload LocalWebMenu AllowDocking Font FontSize Italic Underline Bold CharacterSet LabelFont LabelFontSize LabelItalic LabelUnderline LabelBold LabelCharacterSet DataSource TopMargin BottomMargin LeftMargin RightMargin ArrangeWhen ArrangeMethod Columns Columnspace ArrangeGuide HideIfEmpty AlignChildren AlignChild AllowUserSetup NeededAccessLevel AutoDeclaration VerticalSpacing Enabled Skip AlignControl HelpText ConfigurationKey SecurityKey DragDrop FrameType FramePosition BackStyle FrameOptionButton OptionValue DataGroup AutoDataGroup MultiSelect VisibleCols VisibleRows ShowColLabels ShowRowLabels HighlightActive ActiveBackColor ActiveForeColor GridLines LookupButton ReplaceOnLookup LimitText DisplayLength DisplayHeight Border Value Alignment SignDisplay RotateSign ShowZero DisplaceNegative AllowNegative ForegroundColor LabelForegroundColor ShowLabel Label LabelWidth LabelHeight LabelPosition LabelAlignment DataField Mandatory ArrayIndex SearchMode PasswordStyle ChangeCase MultiLine ExtendedDataType DataMethod ButtonDisplay NormalImage NormalResource DisabledImage DisabledResource ShowShortCut DefaultButton SaveRecord Tabs Tab TabAppearance ShowTabs TabPlacement TabLayout SelectControl TabAutoChange Extends RunOnFormHelp ArrayLength FormHelp ButtonImage StringSize Adjustment GroupPrompt SaveContents AliasFor AllowEditOnCreate FieldUpdate Type OldName AllowDuplicates Validate Field RelatedField TitleField1 TitleField2 Temporary TableContents Systemtable MaxAccessMode CreateRecIdIndex SaveDataPerCompany TableGroup PrimaryIndex ClusterIndex ModifiedDate ModifiedTime ModifiedBy ModifiedTransactionId CreatedDate CreatedTime CreatedBy CreatedTransactionId DeleteAction FormRef CacheLookup FILETYPE UTILTYPE UTILOBJECTID NODETYPE NAME EnumType Style RunOn AllowAdd Selection HideFirstEntry ComboType AppendNew SizeWidth SizeHeight MenuItemType MenuItemName DateValue DateFormat DateSeparator DateYear DateMonth DateDay RealValue ThousandSeparator DecimalSeparator NoOfDecimals AutoInsSeparator FormatMST Class Object Parameters EnumTypeParameter EnumParameter Web WebAccess WebSecureTransaction WebPage CountryConfigurationkey WebConfigurationkey WebTarget ProjectGroupType GroupMask PreventEditProperties</Keywords>
            <Keywords name="Words3">FRM GRID INTEDIT STRINGEDIT BUTTON TAB TABPAGE CLS CLSVERSION || &amp;&amp; UTI INT UTS STRING DBT TABLE PRN PROJECT END \\ JOB ENUM COMBOBOX CHECKBOX STATICTEXT BUTTONGROUP MENUITEMBUTTON MENUBUTTON WINDOW DATEEDIT REALEDIT SEPARATOR FTM MNU UTE</Keywords>
            <Keywords name="Words4">@</Keywords>
        </Language>
    <Language name="X++" ext="xpo">
            <Keywords name="Delimiters">&quot;&apos;0&quot;&apos;0</Keywords>
            <Keywords name="Folder+">SOURCE { CLASS METHODS PROPERTIES CONTROL CONTAINER ARRAY INDEX FORM OBJECTBANK DATASOURCE OBJECTPOOL FIELDLIST JOINS DESIGN TYPEELEMENTS TYPEREFERENCES USERTYPE FIELDS GROUPS GROUPFIELDS GROUP DATAFIELD INDICES INDEXFIELDS REFERENCES REFERENCE FIELDREFERENCES DELETEACTIONS BEGINNODE MENUITEM MENU</Keywords>
            <Keywords name="Folder-">ENDSOURCE } ENDMETHODS ENDCLASS ENDPROPERTIES ENDCONTROL ENDCONTAINER ENDARRAY ENDFORM ENDOBJECTBANK ENDDATASOURCE ENDOBJECTPOOL ENDFIELDLIST ENDJOINS ENDDESIGN ENDTYPEELEMENTS ENDTYPEREFERENCES ENDUSERTYPE ENDFIELDS ENDGROUPS ENDGROUPFIELDS ENDGROUP ENDINDEXFIELDS ENDINDICES ENDFIELDREFERENCES ENDREFERENCE ENDREFERENCES ENDDELETEACTIONS ENDTABLE ENDNODE ENDPROJECT ENDDATAFIELD ENDMENUITEM ENDMENU</Keywords>
            <Keywords name="Operators">- ! # ( ) , . : ; ? [ ] + &lt; = &gt;</Keywords>
            <Keywords name="Comment">1/* 2*/ 0//</Keywords>
            <Keywords name="Words1">Formatversion: Configuration: language directory company user client fetchahead opencursors database dsn sqluser hint sqlbuffer log hassqlpwd sqlpwd sqlparm retry dbserversqltrace haswarnings warnings share bindir startupmsg servermask localappl localappldoc locallabel localsysdoc applshare applexclusive doclanguage startupcmd logdir hascompwd compwd hasserveridletimeout serveridletimeout connectionidletimeout querytimelimit extracmdline port createdsn createdsn_tcpipport aos allowunauth exposeserverprers useserverprers sqlformliterals sqlcomplexliterals sqloraclefirstrowsfix ignoredatasourceindex aosencryption xppdebug dbcli ociconnectservice ociservice ocihost ocidbid ocitcpipport ociuser hasocipwd ocipwd preloadthresholdmsec preloadthresholdrecords dbunicodeenabled newconnectionretrydelayms newconnectionretrycount cachesynctime _clientmode _clientadname application broadcast internet aol aolcode sql native dbserver sqltrace exposeserverprinters useserverprinters ***Element FRMVERSION str container int select firstonly where while for Filename if return void public super element Return Yes No Delayed&#x0D;&#x0A; First Auto Default Normal Watch Vertical NoAccess Main Column width None Outside Opaque Button face View Grid Window background Highlight text Left Right only Text info run Version Else error Args Raised height Horizontal flush right boolean Common QueryRun FormTreeItem class Set FormTreeControl map anytype Dialog SysDictField this New new Query QueryBuildRange else QueryBuildDataSource Array mapiterator ttsbegin ttscommit FileName SaxReader SaxErrorHandler SaxAttributes TextBuffer protected catch try Called from classDeclaration Arrow USERTYPEVERSION TABLEVERSION FIELD Integer Absolute AutoReport AutoLookup REFERENCETYPE NORMAL static Miscellaneous Delete Not specified String Memo Cascade PROJECTVERSION SHARED JOBVERSION NoYes private null count Map DictTable break ttsBegin ttsCommit Error Exception true sum server DictField Counter throw join abstract extends endif index continue false switch case Version Restricted InnerJoin Active Standard Display VERSION MNUVERSION</Keywords>
            <Keywords name="Words2">Text Int Name Table Index Company CounterField AllowCheck AllowEdit AllowCreate AllowDelete StartPosition AutoSearch AutoNotify AutoQuery OnlyFetchActive JoinSource LinkType DelayActive InsertAtEnd InsertIfEmpty Left Top Width Height Visible Caption TitleDatasource Frame WindowResize WindowType SaveSize SaveSize HideToolbar SetCompany ColorScheme CssClass ShowWebHelp BackgroundColor ImageName ImageResource Imagemode Mode SubmitMethod SupportReload LocalWebMenu AllowDocking Font FontSize Italic Underline Bold CharacterSet LabelFont LabelFontSize LabelItalic LabelUnderline LabelBold LabelCharacterSet DataSource TopMargin BottomMargin LeftMargin RightMargin ArrangeWhen ArrangeMethod Columns Columnspace ArrangeGuide HideIfEmpty AlignChildren AlignChild AllowUserSetup NeededAccessLevel AutoDeclaration VerticalSpacing Enabled Skip AlignControl HelpText ConfigurationKey SecurityKey DragDrop FrameType FramePosition BackStyle FrameOptionButton OptionValue DataGroup AutoDataGroup MultiSelect VisibleCols VisibleRows ShowColLabels ShowRowLabels HighlightActive ActiveBackColor ActiveForeColor GridLines LookupButton ReplaceOnLookup LimitText DisplayLength DisplayHeight Border Value Alignment SignDisplay RotateSign ShowZero DisplaceNegative AllowNegative ForegroundColor LabelForegroundColor ShowLabel Label LabelWidth LabelHeight LabelPosition LabelAlignment DataField Mandatory ArrayIndex SearchMode PasswordStyle ChangeCase MultiLine ExtendedDataType DataMethod ButtonDisplay NormalImage NormalResource DisabledImage DisabledResource ShowShortCut DefaultButton SaveRecord Tabs Tab TabAppearance ShowTabs TabPlacement TabLayout SelectControl TabAutoChange Extends RunOnFormHelp ArrayLength FormHelp ButtonImage StringSize Adjustment GroupPrompt SaveContents AliasFor AllowEditOnCreate FieldUpdate Type OldName AllowDuplicates Validate Field RelatedField TitleField1 TitleField2 Temporary TableContents Systemtable MaxAccessMode CreateRecIdIndex SaveDataPerCompany TableGroup PrimaryIndex ClusterIndex ModifiedDate ModifiedTime ModifiedBy ModifiedTransactionId CreatedDate CreatedTime CreatedBy CreatedTransactionId DeleteAction FormRef CacheLookup FILETYPE UTILTYPE UTILOBJECTID NODETYPE NAME EnumType Style RunOn AllowAdd Selection HideFirstEntry ComboType AppendNew SizeWidth SizeHeight MenuItemType MenuItemName DateValue DateFormat DateSeparator DateYear DateMonth DateDay RealValue ThousandSeparator DecimalSeparator NoOfDecimals AutoInsSeparator FormatMST Class Object Parameters EnumTypeParameter EnumParameter Web WebAccess WebSecureTransaction WebPage CountryConfigurationkey WebConfigurationkey WebTarget ProjectGroupType GroupMask PreventEditProperties</Keywords>
            <Keywords name="Words3">FRM GRID INTEDIT STRINGEDIT BUTTON TAB TABPAGE CLS CLSVERSION || &amp;&amp; UTI INT UTS STRING DBT TABLE PRN PROJECT END \\ JOB ENUM COMBOBOX CHECKBOX STATICTEXT BUTTONGROUP MENUITEMBUTTON MENUBUTTON WINDOW DATEEDIT REALEDIT SEPARATOR FTM MNU UTE</Keywords>
            <Keywords name="Words4">@</Keywords>
    </Language>



 Enregistrer, fermer Notepad++ et profiter d'une coloration de votre code et export XPO !
Notepad++ permet entre autres de faire des recherches, remplacement sous forme d'expression régulière très pratique (un lien utile pour RegEx Notepad++)



Lien vers Notepad++

Paramètre de report SSRS sur PurchaseOrder.Report

Récemment, j'ai rencontré un problème SSRS - Dynamics 2012 sous Visual Studio, similaire à celui décrit ici , c'est à dire, un bug Microsoft sur le rafraichissement du DataSet du report PurchaseOrder.Report.

Ce Bug (présent sur la CU3 de 2012), ajoute au rafraichissement du DataSet sous Visual Studio 2010, 5 paramètres non requis pour ce report :

PurchPurchaseOrderDS_Location
PurchPurchaseOrderDS_MiscText
PurchPurchaseOrderDS_PrintHeader
PurchPurchaseOrderDS_ProdType
PurchPurchaseOrderDS_RecordId

Le déploiement est alors impossible sur l'AOT avec Visual Studio comme seul outil pour les reports SSRS.

A l'ajout des champs customisés sur ce report, un refresh du dataset est nécessaire pour la génération sans erreur.

La solution proposée par la community passe par la modification des propriétés de ces paramètres ajoutés en Nullable et en Blank = true.

Pour faire propre, la solution consiste sinon à exporter votre report en XPO, ouvrir l'XPO sur un bloc note puis nettoyer les lignes à la main :

> Partie DataSetParameter, Parameter de Parameter Group, ReportParameter du Body,  et ceux de la balise ReportParameters.



Wednesday, February 27, 2013

Créer un enum dynamique sous AX 2012


Voici un article intéressant de l'excellent Blog de Sreenath qui permet de manipuler un enum sous AX dynamiquement.

En effet, les enums peuvent parfois posés problème lorsque nous souhaitons les filtrer en fonction du contexte de connexion (user, entité juridique, rôles, groupes AX etc...)

Sous 2012, une nouvelle EnumDialogComboBox a été ajouté à l'AOT et permet cette manipulation plus simplement qu'en 2009.
Voici un autre article qui concerne une implémentation similaire sous DAX 2009 utilisant une classe customisée (SysCustomizedEnumComboBox).

Tuesday, January 29, 2013

Solution pour fusionner des PDF sous AX

Voici une solution intéressante pour fusionner des PDF sous AX Dynamics en utilisant une librairie C# de CodePlex (PDFSharp) : dynamicsaxgyan.wordpress.com/2012/08/15/merge-multiple-pdfs-in-to-single-pdf-report-using-x-in-dynamics-ax-2012/

Attention, il y a une petite coquille dans le code de sreenath qui a été relevé dans un commentaire de son article (cela donne une erreur de dépassement de boucle dans la librarie PDFSharp).


static void SR_MergePDFs(Args _args)
{
    PdfSharp.Pdf.PdfDocument outPutPDFDocument = new PdfSharp.Pdf.PdfDocument();
    PdfSharp.Pdf.PdfDocument inputPDFDocument = new PdfSharp.Pdf.PdfDocument();
    PdfSharp.Pdf.PdfPages pdfPages;
    container con = ["c:\\test2.pdf","c:\\test1.pdf"];
    // winapi::findfirstfile
    int i, j, pageCount;
    FileName pdfFile;
    InteropPermission permission;
    str errorMessage;
    ;
    try
    {
        permission = new InteropPermission(InteropKind::ClrInterop);
        permission.assert();
        for (i = 1; i <= conLen(con); i++)
        {
            pdfFile = conPeek(con,i);
            inputPDFDocument = PdfSharp.Pdf.IO.PdfReader::Open(pdfFile, PdfSharp.Pdf.IO.PdfDocumentOpenMode::Import);
            outputPDFDocument.set_Version(inputPDFDocument.get_Version());
            pageCount = inputPDFDocument.get_PageCount();
            pdfPages = inputPDFDocument.get_Pages();


// modification
            if (pageCount > 0)
            {
                for (j = 0 ; j < pageCount; j++)
                {
                outputPDFDocument.AddPage(pdfPages.get_Item(j));
                }

}

        }
        outputPDFDocument.Save("c\\mergedFile.pdf");
        CodeAccessPermission::revertAssert();
    }
    catch(Exception::CLRError)
    {
        // Get the CLR error before any other CLR operation
        errorMessage = AifUtil::getClrErrorMessage();
        CodeAccessPermission::revertAssert();
        throw error(errorMessage);
    }
}


Thanks to sreenath for this nice solution.

Configuration des emails sous DAX 2012

Voici un lien utile pour paramétrer les emails sous AX Dynamics 2012 : lien

Voici les pages également de référence coté Microsoft : Manage email

Ne pas oublier de gérer la partie batch qui s'occupe d'envoyer les notifications par mail (traitement par lot des mails dans System Administration).

Pour tester les emails en environnement de dev, un outil smtp/pop3 comme Argosoft + un thunderbird portable vous permettra de remplacer un système d'email coûteux.

Friday, January 25, 2013

Cache du client et multi environnement sous AX 2012

Un article très clair et détaillant la gestion du cache client par AX Dynamics.
L'auteur détaille notamment la manière de faire en cas de restauration d'environnement  AX sur plusieurs AOS (réinitialisation de la SYSSQMSETTINGS)

http://daxmusings.codecrib.com/2013/01/fixing-code-caching-on-ax-environment.html?showComment=1359104152828#c7999282833205874569


Wednesday, January 9, 2013

Problème de taille de table : Fractionner ou augmenter le buffer SQL ?

Recemment, je me suis retrouvé sur un problème lorsque j'ajoutais des champs sur une table temporaire dédié à un report SSRS :

La taille interne d'un enregistrement xxxxxxxxTmp est de 25296 octets, mais les performances de Microsoft Dynamics sont optimisées par défaut pour ne pas dépasser 24576 octets.

Il est vivement conseillé de fractionner la(es) table(s) en unités plus petites.

Vous pouvez également indiquer une valeur « Taille maximale de la marge » de 25 kilo-octets ou plus sous l'onglet « Réglage de la base de données » de l'utilitaire de configuration du serveur Microsoft Dynamics AX. La valeur par défaut est 24 kilo-octets.

Quittez immédiatement Microsoft Dynamics et suivez les instructions ci-dessus. L'utilisation des tables aura des résultats imprévisibles.

Deux solutions :
- Splitter la table
- Augmenter la taille du buffer sur le serveur OAS : Microsoft Dynamics AX Server Configuration Utility > Onglet Database Tuning > Champs Maximum Buffer Size qui est à 24 Kbytes par défaut.



Les conséquences de ce tuning sont minimes. La taille des tables proposés par Microsoft est choisie pour des raisons de performances. Leur augmentation dans la limite du raisonnable na pas d'impact surtout dans le cadre d'une table temporaire.

Théoriquement, voici ce qu'en dit Microsoft : Cliquez ici