Passing a record and filtering the query

Task

Passing a record from “MCROrderNotes” form and filtering the query by it on “SysOutgoingEmailTable” form.

Since both of the objects were standard forms, I had to use extensions.

That is why passing a record by code slightly changed since the previous versions of Dynamics AX.
However, passing it by a menu item button stayed the same as before.

To get the record and filter the query by it also got modified a bit.
You cannot use the “element” related methods, because you are writing the code in classes, instead of form methods.
For classes you have the help of the “sender” parameter and the FormRun class to achieve the desired functionality.

Complication

Modifying a standard form in D365 F&O is simple. You just have to create an extension and you can add more datasources and form controls. Adding or modifying methods is a bit more complicated.

Solution

For that, you have to create a class.
It is advised to name it the same as the form with the model’s name somewhere in it and an “_Extension” postfix.
You have to specify that it is an extension of a form. Also, the class must be “final”.

Passing a record

I created a menu item button. I filled out the Data Source property with the DocuRef table – since I want to pass the RefRecId and RefTableId fields. Note that the DocuRef table is the data source of the form.

With a menu item button, passing a record is that easy.

Pass DocuRef record

Alternatively, you can also pass a record by code:

After creating the class, copy the event handler method that you want to subscribe to. There are event handler methods for a lot of scenarios. Though, there are not as many as overridable methods.

This image has an empty alt attribute; its file name is image-1.png
Copy OnClicked event handler method

I pasted my button’s OnClicked method to the class and added the logic.
It opens the SysOutgoingEmailTable form and passes the current DocuRef table record.

[ExtensionOf(formstr(MCROrderNotes))]
final class MCROrderNotes_Extension
{
    /// 
    ///
    /// 
    /// 
    /// 
    [FormControlEventHandler(formControlStr(MCROrderNotes, 
        OutgoingEmailBtn), FormControlEventType::Clicked)]

    public static void OutgoingEmailBtn_OnClicked(FormControl sender, 
        FormControlEventArgs e)
    {
        FormRun fr = sender.formRun();
        FormDataSource docuRef_ds = 
            fr.dataSource(formDataSourceStr(MCROrderNotes, DocuRef));
        DocuRef docuRef = docuRef_ds.cursor();

        Args args = new Args();
        args = fr.args();
        args.record(docuRef);
        new MenuFunction(menuItemDisplayStr(SysOutgoingEmailTable), 
            MenuItemType::Display).run(args);
    }
}

As you can see, passing a record by code is more complicated than using a menu item button for it.
Also, you can set up security permissions on menu items.
Because of these reasons, I strongly advise using menu item buttons in this scenario, instead of basic buttons if possible.

Filtering the query

I pasted the “OutgoingEmail” datasource’s “OnQueryExecuting” event handler method to my class.
Note that RefRecId and RefTableId fields exist on this table only because I’m using an extension of SysOutgoingEmailTable.
The code filters the form datasource’s query by the received record’s fields.

[ExtensionOf(formstr(SysOutgoingEmailTable))]
 final class SysOutgoingEmailTable_Extension
 {
     ///      ///     /// 
     /// 
     /// 
     [FormDataSourceEventHandler(formDataSourceStr(SysOutgoingEmailTable, 
         OutgoingEmail), FormDataSourceEventType::QueryExecuting)]

     public static void OutgoingEmail_OnQueryExecuting(FormDataSource 
         sender, FormDataSourceEventArgs e)
     {
         RefRecId refRecId;
         RefTableId refTableId;
         DocuRef docuRef;
         FormRun fr = sender.formRun(); 

         if(fr.args() && fr.args().record())
         {
             docuRef = fr.args().record();
             refRecId = docuRef.RefRecId;
             refTableId = docuRef.RefTableId;
         }

         sender.query().dataSourceName(sender.name()).addRange(fieldnum
             (SysOutgoingEmailTable, RefRecId)).value(queryValue(refRecId));

          sender.query().dataSourceName(sender.name()).addRange(fieldnum
             (SysOutgoingEmailTable, RefTableId)).value(queryValue(refTableId));
     }
}

Additionally, you can also use Chain of Command to achieve this functionality.
You can find some articles about it on our blog on the following link:
https://daxvisionerp.com/tag/chain-of-command/

Summary

In previous Dynamics AX versions, you could pass a record similarly with a menu item button.
If you want to do it by code, you have to do it differently now, in case you are using extended forms.

Getting the record and using it for filtering the query is also a bit different now.
You cannot use the “element.args()”, because you are extending form methods with classes, instead of just adding a new method to the form.
You have to use the “sender” parameter and the FormRun class in order to achieve the same functionality.

Leave a Reply

Your email address will not be published. Required fields are marked *