Table temporaire à partir d’une non temporaire

Il se peut, que vous ayez besoin un jour de trier une table à partir d’une sélection.

Prenons un exemple pour illustrer mon propos.

Vous avez une forme, prenons SalesTable. Vous faites une multisélection de plusieurs ligne d’en-tête et vous générez un rapport que vous avez créé.
Seulement, dans ce rapport, vous devez trier suivant un champ spécifique.
Or dans votre rapport, ayant ramener la dataSource de la forme SalesTable, vous ne savez trier celle-ci sur le champ requis.
La solution est en fait assez simple : créer une variable SalesTable et la définir comme temporaire et la remplir avec la dataSource et ensuite refaire une sélection sur celle-ci.

Dans le code suivant, je vais vous montrer comment récupéré la dataSource et faire le triage

public class ReportRun extends ObjectRun
{
    FormDataSource      callerDataSource;    
    SalesTable          salesTable;
}
public void init()
{
    if (element.args().dataset() != tableNum(SalesTable))
    {
        throw Error(error::missingRecord(tableId2Pname(tableNum(SalesTable))));
    }
    
    callerDataSource = element.args().record().dataSource();
    
    super();
}
public boolean fetch()
{
    SalesTable salesTableLoc;
    ;
    
    //Définir la table en temporaire
    salesTableLoc.setTmp();
    
    for (salesTable = callerDataSource.getFirst(true)
                    ? callerDataSource.getFirst(true)
                    : callerDataSource;
         salesTable;
         salesTable = callerDataSource.getNext())
    {
        salesTableLoc.data(salesTable.data());
        salesTableLoc.insert();
    }

    while select salesTableLoc order by DlvMode
    {
        element.send(salesTableLoc);
    }
                            
    return true;
}

Il se peut, que vous ayez besoin un jour de trier une table à partir d’une sélection.

Prenons un exemple pour illustrer mon propos.

Vous avez une forme, prenons SalesTable. Vous faites une multisélection de plusieurs ligne d’en-tête et vous générez un rapport que vous avez créé.
Seulement, dans ce rapport, vous devez trier suivant un champ spécifique.
Or dans votre rapport, ayant ramener la dataSource de la forme SalesTable, vous ne savez trier celle-ci sur le champ requis.
La solution est en fait assez simple : créer une variable SalesTable et la définir comme temporaire et la remplir avec la dataSource et ensuite refaire une sélection sur celle-ci.

Dans le code suivant, je vais vous montrer comment récupéré la dataSource et faire le triage

public class ReportRun extends ObjectRun
{
    FormDataSource      callerDataSource;    
    SalesTable          salesTable;
}
public void init()
{
    if (element.args().dataset() != tableNum(SalesTable))
    {
        throw Error(error::missingRecord(tableId2Pname(tableNum(SalesTable))));
    }
    
    callerDataSource = element.args().record().dataSource();
    
    super();
}
public boolean fetch()
{
    SalesTable salesTableLoc;
    ;
    
    //Définir la table en temporaire
    salesTableLoc.setTmp();
    
    for (salesTable = callerDataSource.getFirst(true)
                    ? callerDataSource.getFirst(true)
                    : callerDataSource;
         salesTable;
         salesTable = callerDataSource.getNext())
    {
        salesTableLoc.data(salesTable.data());
        salesTableLoc.insert();
    }

    while select salesTableLoc order by DlvMode
    {
        element.send(salesTableLoc);
    }
                            
    return true;
}

Affichage des dimensions

Rendre paramétrable l’affichage des dimensions de stock dans un formulaire.

La forme

Votre formulaire doit contenir la dataSource InventDim liée à votre dataSource principale.

Il faut ensuite rajouter le “Groupe de dimensions de stock”.
Allez dans le formulaire InventTrans, recopier le groupe “InventoryDimensionsGrid” (présent dans : Design \ Tab \ Overview \ Grid \) dans votre formulaire.

Bouton permettant de paramétrer les dimensions de stock à afficher :
Ajouter le menuItem display “InventDimParmFixed” en tant que bouton dans le formulaire.

Le code dans la forme

Déclarer une nouvelle variable dans la méthode classDeclaration :

public class FormRun extends ObjectRun()
{
    InventDimCtrl_Frm_activeRightClick  inventDimFormSetup;
}

Créer les méthodes suivantes sur le formulaire :

Object inventDimSetupObject()
{
    return inventDimFormSetup;
}
void updateDesign(InventDimFormDesignUpdate mode)
{
    inventDimParm   inventDimParm;
    switch (mode)
    {
        case InventDimFormDesignUpdate::Init          :
            inventDimSetupGrid::initInventDimParmInventTrans(InventDimParm);
            if (!inventDimFormSetup)
            {
                inventDimFormSetup  = new InventDimCtrl_Frm_activeRightClick(element);
            }
            inventDimFormSetup.parmDimParmVisibleGrid(inventDimParm);
            inventDimFormSetup.formSetControls(true);
            break;
    }
}

Dans la méthode init, après le super(), ajouter ce code :

public void init()
{
    super();
    element.updateDesign(InventDimFormDesignUpdate::Init);
}

Rendre paramétrable l’affichage des dimensions de stock dans un formulaire.

La forme

Votre formulaire doit contenir la dataSource InventDim liée à votre dataSource principale.

Il faut ensuite rajouter le “Groupe de dimensions de stock”.
Allez dans le formulaire InventTrans, recopier le groupe “InventoryDimensionsGrid” (présent dans : Design \ Tab \ Overview \ Grid \) dans votre formulaire.

Bouton permettant de paramétrer les dimensions de stock à afficher :
Ajouter le menuItem display “InventDimParmFixed” en tant que bouton dans le formulaire.

Le code dans la forme

Déclarer une nouvelle variable dans la méthode classDeclaration :

public class FormRun extends ObjectRun()
{
    InventDimCtrl_Frm_activeRightClick  inventDimFormSetup;
}

Créer les méthodes suivantes sur le formulaire :

Object inventDimSetupObject()
{
    return inventDimFormSetup;
}
void updateDesign(InventDimFormDesignUpdate mode)
{
    inventDimParm   inventDimParm;
    switch (mode)
    {
        case InventDimFormDesignUpdate::Init          :
            inventDimSetupGrid::initInventDimParmInventTrans(InventDimParm);
            if (!inventDimFormSetup)
            {
                inventDimFormSetup  = new InventDimCtrl_Frm_activeRightClick(element);
            }
            inventDimFormSetup.parmDimParmVisibleGrid(inventDimParm);
            inventDimFormSetup.formSetControls(true);
            break;
    }
}

Dans la méthode init, après le super(), ajouter ce code :

public void init()
{
    super();
    element.updateDesign(InventDimFormDesignUpdate::Init);
}

MenuFunction par code

Les formes

Nous nous trouvons dans une forme avec comme DataSource : dataSource1.
Il nous faut, via un bouton, appeller une forme, par exemple : PriceDiscTable. Et nous voulons lui passer en paramètre la table VendTable.

Il faudra écrire ceci dans la méthode clicked du bouton que l’on aura créé.

Attention : le bouton doit-être de type Button.

public void run()
{
    Args            args        = new Args();
    FormRun         formRun;
    ;

    args.name(formStr(SalesTable));
    args.record(custTable);
    args.caller(this);

    formRun         = ClassFactory::formRunClassOnClient(args);
    formRun.init();
    formRun.run();
    formRun.detach();
}
 void clicked() 
{
   Args            args;
   MenuFunction    menuFunction;
   Object          formRun;
   ;
   args            = new Args();
   menuFunction    = new MenuFunction(menuItemDisplayStr(PriceDiscTable_EndDiscPurch), MenuItemType::Display);
   args.record(VendTable::find(vendAccount));
   super();
   formRun = menuFunction.create(args);
   formRun.init();
   formRun.run();
   //formRun.reSelect(); //est quelques fois nécessaire
   //formRun.detach();   //est quelques fois nécessaire
} 

En appellant une méthode spécifique de la forme

Si vous voulez, par exemple, ouvrir la table des commandes clients en mode simple. Il vous faut exécuter la méthode toggle de la forme. Pour ce faire, procédez comme suit :

void openSalesTable(SalesTable _salesTable) 
{
   Args            args;
   Object          salesTableForm;
   MenuFunction    menuFunction;
   ;
   Args = new Args();
   args.record(_salesTable);
   salesTableForm = new MenuFunction(menuItemDisplayStr(SalesTable), MenuItemType::Display).create(args);
   salesTableForm.init();
   salesTableForm.toggelSimpleAdvanced(false);
   salesTableForm.run();
} 

Les classes

Voici le code si l’on doit lancer l’exécution d’une classe (extends RunBase) via un bouton par exemple.

public void callClass() 
{
   Args            args;
   MenuFunction    menuFunction;
   FormDataSource  formDataSource;
   ;
   Args            = new Args();
   menuFunction    = new MenuFunction(menuItemActionStr(SuppItemCalc_Sales), MenuItemType::Action);
   args.record(SalesTable);
   menuFunction.run(args);
} 

Réservation d’une quantité

Voici le code si l’on veut mettre une certaine quantité en réservation.

Ici je prendrais l’exemple d’une commande client à partir de laquelle on a crée un ordre de transfert et où l’on souhaite faire une réservation sur la quantité transférée.

void reservation(SalesLine _salesLine, InventTransferLine _inventTransferLine)
{
    InventMovement          inventMovement;
    InventUpd_reservation   inventUpd_Reserv;
    ;

    inventMovement   = InventMovement::construct(salesLine);
    inventUpd_Reserv = InventUpd_reservation::newInventDim(inventMovement, _salesLine.inventDim(), -_inventTransferLine.QtyTransfer);
    inventUpd_Reserv.updateNow(); 
}

Informations employé

Pour AX 2009 (v5)

Si vous souhaitez reprendre les informations reprise pour vos employés dans l’onglet Informations dans lequel vous retrouvez une grille avec les informations encodée.

Voici le code pour retrouver ces informations :

Phone getUserPhone()
{
    EmplTable                           emplTable;
    DirPartyECommunicationRelationship  dirPartyECommunicationRelationship;
    DirECommunicationAddress            dirECommunicationAddress;
    ;

    emplTable = emplTable::find(SysCompanyUserInfo::find(curUserId()).EmplId);

    select firstonly dirPartyECommunicationRelationship
     where dirPartyECommunicationRelationship.PartyId    == emplTable.PartyId
      join dirECommunicationAddress
     where dirECommunicationAddress.RecId                == dirPartyECommunicationRelationship.ValuesRecId 
        && dirECommunicationAddress.ECommunicationTypeId == "Phone";
    
    return dirECommunicationAddress.Phone;
}

New number sequence

We need to go to the class NumberSequence which manage the automatique numbering for group. We will make as example a new number sequence for the group CRM for the EDT CRMId.

Don’t forget to create the new EDT. For the sortField, always begin at 100.

Go to the class NumberSeqReference_CRM. In the method loadModule, we will put the following code:

protected void loadModule() 
{
   numRef.DataTypeId              = typeId2ExtendedTypeId(typeId(CRMId));
   numRef.ConfigurationKeyId      = configurationKeyNum(smmCRM);
   numRef.ReferenceHelp           = literalStr("@SYS81568"); 
   numRef.WizardContinuous        = true;
   numRef.WizardManual            = NoYes::No;
   numRef.WizardAllowChangeDown   = NoYes::No;
   numRef.WizardAllowChangeUp     = NoYes::No;
   numRef.SortField               = 100;
   numRef.WizardHighest           = 999999;
   this.create(numRef);
}

After that, the table smmParametersTable (setup table for the CRM), we will create the new method like this:

public client server static NumberSequenceReference numRefCRMId() 
{
   return NumberSeqReference::findReference(typeId2ExtendedTypeId(typeId(CRMId)));
}

We need to quit and restart the client for enable the new changement.
Once AX restarted, go to the module CRM > Configuration > Setup and go to the last tab. There are all number sequence for each EDT, go to the line for our CRMId field and make ‘Go to main table’. We will create a new number sequence called CRMIdSouche and as code we will write CRM######.
We come back to the other table and fill-in with our new number sequence id.

After that, we must specify to the table to increase the EDT. And put the following code in the method create or initValue:

public void initValue() 
{
   NumberSeq   numberSeq;
   ;
   numberSeq = NumberSeq::newGetNum(CRMParameters::numRefCRMId());
   if (numberSeq)
   {
       this.CRMId        = numberSeq.num();
   }
}

Les dimensions dans une forme (édition/masquage)

Il peut advenir que lorsque vous créez une forme, suivant tel(s) ou tel(s) condition(s), vous deviez rendre éditable/non éditable certaine(s) dimension(s).

Nous allons prendre pour exemple, la forme SalesTable.

SalesLine_ds.object(fieldid2ext(fieldnum(SalesLine, Dimension),
                    Dimensions::code2ArrayIdx(SysDimension::Center))).allowEdit(false);

Ligne à répéter suivant la dimension que l’on souhaite rendre éditable/non éditable, affichable/non affichable.

Méthode dans une requête standard

Dans la version 2009 d’AX, on peut faire référence à une méthode en plus d’une valeur dans les requêtes.
Ceci est très utile pour les traitements en batch.

Une application pratique :

Je veux lancer par batch mes prélèvements 5 jours avant la date d’expédition confirmée(impossible avant AX2009)

En utilisant la méthode ((day(5)) pour l’emplacement de la valeur.

Dans l’exemple ci-dessus, je lance une requête sur les commandes clients avec une date d’expédition confirmée à J+5. Or avant la 2009 c’était impossible.

Dans le même esprit il existe d’autres méthodes :

(GreaterThanDate(5)) = Retourne les dates > J + 5
(LessThanDate(5)) = Retourne les dates < J – 5

Etc…

La liste complète est dans la classe SysQueryRangeUtil

On peut évidement créer sa propre méthode et l’utiliser ainsi dans les requêtes standards.