With Power Fx buttons, it’s now easier to add custom buttons to model-driven apps. We take a look how cloning rows of data can be achieved.
Adding custom buttons to model-driven apps used to be a complex task, including third party tools and custom code, but since the introduction of the ability to edit the Command Bar in a model-driven app, it’s now possible for non-developers to introduce custom functionality to their apps with just a few lines of Power Fx. This blog post looks at three scenarios for cloning a record; it won’t go into the detail of every function, but is intended to give general guidance.
Cloning a single record
This is the simplest example – taking an individual record and creating a copy of it.
When adding a button to a main form of a model-drive app, the record you’re currently viewing is stored in an object called Self.Selected.Item and individual fields and related records can be accessed via this object. By referencing this object, we can easily clone our record.
Patch (
Accounts,
Defaults(Accounts),
{Name: Self.Selected.Item.'Account Name'. & " (clone)"}
)
Tip
Ensure that any mandatory fields are also being set or your record creation with failIn the above example, we’re simply cloning an Account record using the Patch command which sets the name of the new record to that of the existing one, plus ” (clone)” to help differentiate between the two records. Once the record has been cloned, you could add to the above Power Fx with a Navigate function to take to the newly-created record.
Cloning a record that has related child records
Often, a record will have related records associated to it; for instance, an Account might have multiple associated contacts. When cloning a parent record, you might want to also clone its child records and have them associated with the new parent record. This can also be achieved with Power Fx.
While a Canvas App has the full suite of Power Fx commands, including variables, Power Fx has a subset of these commands, so methods that might have been utilised in a Canvas App may not be suitable here. However, with the With function, we are able to create a record and use the resulting record in future steps.
With (
{
clonedrecord: Patch (
Accounts,
Defaults(Accounts),
{
'Account Name': Acc.'Account Name' & " (cloned)",
}
),
selectedchildrecords: Filter(
ChildTable,
Accounts.accountid = Self.Selected.Item.accountid
)
},
ForAll(
selectedchildrecords As selectedchildrecord,
Patch(
ChildTable,
Defaults(ChildTable),
{
Name: selectedchildrecord.Name & " (cloned)",
Account: clonedrecord
}
)
)
)
Although the above example is more complicated, the principle is straightforward. Inside the With function, we’re creating temporary variables – clonedrecord is the newly-created Account record and selectedchildrecords are the child records of the original Account. We then need to loop through all of these child records, creating clones of each one, but instead of the original parent Account, we set the Account to the new account, clonedrecord.
Cloning a record that has related grandchild records
A more complex example is where you might have top-level Account, which has child records associated with it, but then those child records have child records of their own. By extended the above example, we can cater for this Parent > Child > Grandchild structure too:
With(
{
clonedrecord: Patch(
Accounts,
Defaults(Accounts),
{
Name: Self.Selected.Item.Name & " (Clone)"
// Additional column values can be set here
}
),
selectedchildrecords: Filter(
ChildTable,
Accounts.accountid = Self.Selected.Item.accountid
)
},
(ForAll(
selectedchildrecords As selectedchildrecord,
With(
{
createdchildrecord: Patch(
ChildTable,
Defaults(ChildTable),
{
Name: selectedchildrecord.Name & " (Clone)",
Account: clonedrecord
// Additional column values can be set here
}
),
selectedgrandchildrecords: Filter (
GrandChildTable,
ChildLookup.uniquefieldid = selectedchildrecord.uniquefieldid
)
},
ForAll(
selectedgrandchildrecords As selectedgrandchildrecord,
Patch(
GrandChildTable,
Defaults(GrandChildTable),
{
Name: selectedgrandchildrecord.Name & " (Clone)",
ChildTableLookup: createdchildrecord
// Additional column values can be set here
}
)
)
)
))
)
This is the most complex example of the three, but can be explained as:
- Clone the original parent record and store the result as clonedrecord
- Build a list of the child records that need to be cloned
- Clone these child records, but set the parent of these as clonedrecord
- Build a list of the grandchild records that need to be cloned based on a matching lookup field (selectedchildrecord.uniquefieldid in the above example)
- After cloning each child record, process the matching grandchild records and create clones of these, with a parent of the new child record (using createdchild as a temporary variable)
Tip
The above examples can also be used in a Canvas app by replacing Self.Selected.Item with a record variable.Summary
Cloning records would have traditional been carried out with custom code or workflows, but with the flexibility of Power Fx, non-developers can now use its power to build additional functionality into their model-driven apps. If you are an existing Strategy 365 client and wish to discuss the capabilities of Power Fx buttons with one of our experts, please get in touch.