How to default usage data to a form from previous user input using a single line of code
When you open a form in Microsoft Dynamics 365, sometimes field values seem to default based on how you previously set them. This functionality is oftentimes solved from a framework called SysLastValue. There are two ways to implement this, and usually when we research how to use it, we’re greeted with the pattern that takes several lines of code and multiple methods (pack / unpack). This is also cumbersome to implement on an existing form on Dynamics 365 because we’re no longer allowed to overlayer but must achieve this via extension.
Today, I will show you how to implement SysLastValue in a single line, and show you examples on how to do this via extension. See our previous blog on extensibility and its importance.
Default the warehouse based on previous user’s selection. The code below is using a controller class named envBinTransferJournalController which is an extension instance registered on FormRun. This code can also be implemented using event handlers.
Storing the value in usage data
This code should be executed after formRun.close().
// Get the value from the form so you can put it in sysLastValue InventLocationId localInventLocationId = FormRun.Control(FormRun.controlId(formControlStr(envBinTransferJournal, InventLocationId))).valueStr(); // It requires you store the value as a container, so you can easily store
more than one value if you wanted to xSysLastValue::putValue([localInventLocationId], curExt(), curUserId(), UtilElementType::Class, classStr(envBinTransferJournalController));
Getting the value from usage data
This code should be executed after formRun.init().
InventLocationId localInventLocationId; // You’re getting the value as a container because that is what you stored
it in (required data type) [localInventLocationId] = xSysLastValue::getValue(curExt(), curUserId(), UtilElementType::Class, classStr(envBinTransferJournalController)); // You now have the last value used and can default a control with it FormStringControl localWarehouseControl = FormRun.Control(FormRun.controlId(formControlStr(envBinTransferJournal, InventLocationId))); localWarehouseControl.text(localInventLocationId);
Notes on Implementation
When using this single line method, you will have two parameters on both the Set and Get. They are passing in the element type and the ID of which to store as the key to retrieve or store. We strongly recommend using intrinsic functions as this will eliminate the chance of a runtime error if the object name changes because the error will happen when you compile.
While the example above shows storing a single value from user input, we recommend storing a data contract to support extensibility. We also recommend hydrating the data contract in the controller class that supports extension / subscription, allowing the next developer to add defaulting values.
A place where sysLastValue is NOT needed
Keep in mind that when you’re building out a report / SysOperation, the fields on the prompt are automatically kept in SysLastValue, and you don’t need to implement the pattern discussed above.
In this blog, we have shown how to implement SysLastValue for defaulting values and provided examples of getting and setting values from unbound controls. We have also discussed the proper code placement and instances where this pattern is not required.
Deep Expertise in Dynamics AX and D365 Development
enVista is dedicated to helping the Microsoft community by continuously sharing our in-depth knowledge of X++ and Microsoft Dynamics 365 development. If you are struggling with Dynamics AX or D365 development, contact us, and we will connect you with one of our in-house experts.
Read our other topics in our D365 Developer Series:
Do you have a question about Dynamics 365 development or X++ best practices? Leave us a comment below and we will try to cover it in a future blog!