Tip #1422: Leave old stuff behind

Let me start 2022 slowly, with a tip how to avoid annual cleanup. It all started with this email:

Screenshot of the email that reads:

Hey,
 
Hope you are well and are going to get a break over Christmas!
 
I got a notification of you making changes in your Dropbox – feel free to remove me if you like (see attached)
 
Cheers
Richard
IT Engineering Team

Darn, I completely forgot about those folders and big thumbs up to Richard for reminding me. Richard is one in a million though, most would simply ignore the shared folders. Until such time when you drop some sensitive files in there.

How to avoid this unnecessary stress and reliance on Richards of this world to do the right thing? Simples:

Always set the expiration date when sharing folders or files

Thee Nabler

I don’t care what it is. Could be tomorrow, could be 5 years from now. But do set it and spare yourself potential embarrassment at best and the jail time at worst (I’ve seen it in a movie, totally plausible scenario). Almost like in the song:

Go ahead and share but trust no one. (So much for faith in humanity in 2022)

Cover image by Gerd Altmann

Tip #1421: Hide form selector in model-driven apps

Everybody take a seat. Tanguy WiTouzard has the floor. (You can grab everyone’s attention too by sending your useful tip to jar@crmtipoftheday.com)

Wizardry starts here

I don’t know if it was published before but I just found out that we were able to remove “forms” from “form selector” using Javascript. It’s really useful when you have many forms because you are creating forms for different purpose but don’t want users to be able to switch themselves to those forms.

Screenshot of a form in a model-driven app. Form selector is visible and shows multiple forms available to the user to select from.

So let’s say, I have so many forms for account entity (see screenshot), I can remove the form selector by using the following script.

function disableFormSelector(){
	formContext.ui.formSelector.items.forEach(
    function(f){
		  f.setVisible(false);
	  }
  );
}

Voila! Sans sélecteur de formulaire!

(Tanguy actually didn’t say anything here but I’m not missing the opportunity to flex my Google-inspired French skills – t.j.)

Screenshot of a the same form as before in a model-driven app. Form selector is no longer visible after the  javascript fragment execution.

(And I have no idea why Tanguy gets involved with piscines this time of the year. And why would swimming pools need a résumé? I guess he’s looking for a new job trying to finance his new swimming pool. 😈 – t.j.)

Cover image by PhilippT | Pixabay

Tip #1420: JSON Function and size limits in Power Apps

Power Fx (gotta use the cool keyword!) JSON function in Power Apps is pure magic, it’s like a compactor converting anything you throw into it into a neat text representation to send over the wire, engrave on a golden bullion, or stash it as an alphabet soup. It works great apart from the times when it does not.

Turns out, it’s got a 0.5MB size limit. Give it anything that produces longer string than that and get blank in return. No error, no messages, no trace. Nothing. Blank. Blankinness. Nothingness. Ouch.

Now you know.

Cover photo by Sarah Kilian on Unsplash

Tip #1419: Dual-write 404 error when metadata contains special characters

As Power Platform extends its reach beyond the realms of Dynamics 365 (CRM/CE/etc) and SharePoint, we’re starting to see some interesting integration challenges from Dataverse big brother – Finance and Operations. Today’s tip is from Parth Bhaidani. (Hey, you can have your name published here too – just drop your sizzling tip into jar@crmtipoftheday.com!)

Dual-write provides tightly coupled, bidirectional integration between Finance and Operations apps and Dataverse. However, at times it could be trickier to address the issues. Recently, I was working on a Dual-Write integration and one of the tasks was to add a new Table map. Prima facie the task was fairly straightforward until I stumbled upon the error, “The remote server returned an error: (404) Not Found. Unable to retrieve metadata for AX environment“. Turns out the name of the Table on the F&O side has a forward slash (/) in it (Country/regions) and that’s the reason for the error above.

To fix this issue, we would have to create a new Data Entity but without special characters. (Luckily, in F&O we can create multiple entities for the same underlying table – t.j.)

  1. In the F&O environment go to Data Management Workspace -> Data Entities
    F&O Data management interface with Data entities button highlighted.
  2. Search the Table name for which you are trying to add the Table Mapping (in my case Country/regions) and copy the Target entity name.
    Country/region table selected in the table mappings with Target entity column value highlighted.
  3. Click New and populate Target entity with the copied Target entity from the above step, everything else will be auto populated and leave those columns as is. Click Save.
    New table entry without special characters
  4. Add the Table Mapping using the new name (which is again the one copied in Step 2). Now, you should be able to add mapping without any issues.

Cover photo by Vincent van Zalinge on Unsplash

Tip #1418: In-app notifications in model-driven apps

Welcome to inaugural video shorts where all human knowledge is compressed into the bites of 60 seconds or less, to be consumed while waiting for the paint to dry.

In this episode we help Lisa to enable in-app notifications in model-driven Power Apps without any code using a freshly baked XrmToolBox tool by Ivan Fricko.

Links galore:

YouTube player

Cover photo by Prateek Katyal on Unsplash

Tip #1417: Power Excel in SharePoint

You’ve seen us in Tip #1415 doing some Microsoft Graph abracadabra to call Excel functions directly from Power Automate. To do that we use Excel spreadsheet located on OneDrive for Business. Documentation mentions in passing that “You can use Microsoft Graph to allow web and mobile applications to read and modify Excel workbooks stored in OneDrive for Business, SharePoint site or Group drive” but none of the examples uses SharePoint, everyone is obsessed with /me/drive/. Brian asks a fair question:

Is it possible to do with an excel document stored in a SharePoint document library?

Brian

Lo and behold. The syntax is similar except instead of /me/ you have to point to the site, i.e. /sites/root/lists/{list-id}/ (if your list is on the root site). For example this will calculate the average:

POST https://graph.microsoft.com/v1.0/sites/root/lists/33246232-feed-dead-beef-decaf5388770/drive/root:/your-workbook.xlsx:/workbook/functions/average
content-type: Application/Json 
authorization: Bearer {access-token} 

{
    "values": [1,2,3,4,5]
}

Cover photo by salvatore ventura from Pexels

Tip #1416: Power Platform PowerShell module includes unapproved verbs

tl;dr

No, Power Platform team didn’t sneak in any profanities into PowerShell module. It’s caused by the verb Apply, is by design, and can be safely ignored.

Longer version

I usually oblivious to any warnings produced by the command line tools. My attention is fully reserved for the word FATAL in Ferrari red (#ff2800 if you must know), the rest I make go away with a magic cls command.

Benedikt Bergmann is by far a more diligent developer and, while using the Power Platform Build Tools, got concerned that some steps get a warning:

##[warning]The names of some imported commands from the module 'Microsoft.Xrm.WebApi.PowerShell' include unapproved verbs that might make them less discoverable. To find the commands with unapproved verbs, run the Import-Module command again with the Verbose parameter. For a list of approved verbs, type Get-Verb.

Is the sky falling and we’re all doomed because PowerShell team from 1984 did not approve our choice of verbs? (Here’s the full list: Approved Verbs for PowerShell Commands – PowerShell | Microsoft Docs)

Nah, turns out none of the approved verbs was a good fit for apply solution upgrade action that ended up being Apply-SolutionUpgrade in PowerShell. If you use this action in your script, you might get the warning and it’s OK to ignore it.

Well, if you ask me I would have chosen something random and memorable, for example Mount-SolutionUpgrade, Measure-SolutionUpgrade, or even Resize-SolutionUpgrade. But now you know why I’m not in charge of naming PowerShell cmdlets.

Cover photo agracier – NO VIEWS, CC BY-SA 3.0, via Wikimedia Commons

Tip #1415: Call Excel functions from Power Automate

If you know Excel you’ll be very comfortable with Power Automate, they said. Except most of the Excel functions do not even have an equivalent in Power Automate.

But what if we could access all Excel functions in Power Automate? Say no mo

In the Episode 13 of Citizen Can Amey and George talk about broken giraffe, browsing Graph Explorer on Monday night, what is a holiday, and the magic of calling Excel functions from Power Automate.

watch the video

Tip #1414: Enforce unique email but ignore inactive records

Alternate keys are great way to enforce uniqueness of the column values. For example, if you want lead emails to be truly unique, just add an alternate key and no user will be able to bypass that (unlike the duplicate detection which is a fairly timid mechanism). The challenge is when you want that uniqueness to apply only to active records. Bear with me.

You thought that lead was lost forever and deactivated the record (you do not ever delete important records, right?). Now they are coming back, rejuvenated and refreshed and ready to buy not one but seven of your wonderful Jigamagigs. New lead is created but with the same email and that’s OK – we don’t hold grudges. What you don’t want is two active leads with the identical emails.

Alternate key using email are not going to work for you in this scenario, but you can enforce the uniqueness using a faux column that contains email for active records and null for inactive.

It works because alternate keys ignore null values.

The walkthrough below uses the contact table.

  1. Create a column large enough to hold email addresses. No need to make it searchable or enable audit.
    Screenshot of a new column properties. Column is called "I Am Unique" with the length of 250 characters.
  2. Create new real-time workflow (and you can do that from the new solution explorer)
    Screenshot of the expanded NEW menu in the new solution explorer. Submenus are opened as New srcset= Automation > Process > Workflow”>
    New workflow properties. DIsplay name is "Unique Email", table is contact, checkbox "Run workflow in the background" is cleared
  3. Set the workflow properties
    Screenshot of workflow properties as described
    • Check As an on-demand process if you have existing records in your Dataverse instance so that you can run it once to populate the values.
    • Start after Record is created, Record status changes, and Record fields change.
    • Select emailaddress1 as the field to trigger.
    • Set the workflow logic: If contact status is Active, set faux column created in Step 1 to emailaddress1 value. Otherwise clear the column.
  4. Create alternate key over the faux column
    Screenshot of an alternate key record that contains only I Am Unique column
  5. Run the workflow over all existing contact records to populate. Note: it may fail if your table contains active duplicates. Check for failed workflows, resolve the duplicates, run again.

Now, when a user tries to create a record with a duplicate email address they will see the error.

A screenshot of a sample error message with a caption "Business Process Error" and the message "A record that has the attribute values I Am Unique already exists. The entity key Unique Email requires that this set of attributes contains unique values. Select unique values and try again."

But users will be able to create the duplicates if only one of the records is active.

List of contacts where two of them have the same email address but one of them is inactive.

The good thing about this method is that it’s bulletproof against clever users importing via Excel online, sneaky developers updating using SDK, and even almighty administrators activating the existing records that contain the duplicates.

This tip wouldn’t be possible without my family, my parents, my sponsors, and David Yack who provided a sanity check where I needed it most.

Cover photo by Rupert Britton on Unsplash

Tip #1413: Components Required in the Solution for Relationship Mapping Deployment

Today’s winner is Linn Zaw “I always” Win. And you can be one too if you email your tip to jar@crmtipoftheday.com!

Have you ever added the 1:N or N:1 relationship into the solution, created new mappings in the solution and deployment the solution to another environment only to find out that the mappings are not deployed? Upon opening the customizations.xml of the solution, you might notice that the newly created mappings are not included under the <EntityMaps /> tag.

These are the components required in the solution to include the relationship mapping.

  1. Relationship which contains the mapping (obviously)
  2. Both Primary and Related tables of the relationship
  3. Target column of the mapping

Relationship

Screenshot of the classic interface for Relationship definition. Information tab is selected. The following screen elements are numbered: 
number 1 - Relationship name
number 2 - Primary Entity name
also number 2 - Related Entity name

Mapping

Screenshot of the classic interface for Relationship definition. Mappings tab is selected. The following screen elements are numbered: 
number 3 - row containing the mapping between source and target columns

Tables and target column

Screenshot of the classic interface for the solution components. Components > Entities node is expanded in the tree, Fields node under the target entity name is selected.
The following screen elements are highlighted and numbered: 
number 2 - Primary Entity and Related entities under Entities node in the tree.
number 3 - mapped target field selected in the list view in the right part of the screen.

Cover photo by Davies Designs Studio on Unsplash