Creating Records with Guids via Power Automate

Problem Scenario 1: There might be a situation where you deleted a list of data but due to some reason you want it back. We can get this list from the last backup taken. But then these records would need to be created again with the same guids. How can we do it ?

Solution: We can read the guids from the list and pass it here:

In the “Add a New row” step, expand the “Show Advanced Options”

& then fill in the unique identifier. This way you can create records with given guids.

While writing about it, another problem came to my mind, where what if i wanted to create a lead without filling in the Topic which is a mandatory field as because in the normal way, it throws an error if you do not write something.

Problem Scenario 2:We do have a scenario where we have to bulk data upload where we have to override the required fields. Here can be a Power Automate Solution to it where it can be put as a conditional check.

Well, some good Eidetic memory skills came in handy here. I remembered that Update Action does not require any field specifications. thus i got the idea to generate a random guid and pass it on.

Solution: Create a Compose action where you write the expression “guid()” – this basically creates a random guid for you & then use this guid in the update a row step. This basically acts like “UPSERT” where we do not have to fill in all the mandatory fields.

Woohoo! it works.

You can see the lead being generated here without the Topic & Last Name:

Also tried putting null in “add a new row” step.

Surprisingly it works- that was quite simple!

Find the lead generated here:

Hope you got some great tips today on how to create guids using the guids() expression? What can be the use cases?

& the Power Quote of the day is:

“Mastering others is strength. Mastering yourself is true power.”

Advertisement

Difference between Slice, Substring & Split

Today we are going to read about the 3 String Functions – Slice, SubString & Split.

PS: As the name suggests, String functions work only on strings.

  1. SLICE: This returns a substring by specifying the starting and ending position of the string inclusive of the Starting Index but not including the ending one.

slice(‘<text>’, <startIndex>, <endIndex>)

Example:

In the compose expression, i have written [slice(variables(‘String’),2,5)]

Thus the result here is: ali

Some interesting facts here would be:

  • If startIndex is greater than the string length, it returns an empty string.
  • If endIndex isn’t specified or greater than the string length, it takes up to the end of the string.
  • If startIndex or endIndex is negative, it calculates the index value as the sum of the string length and the Index and then calculates accordingly. Bet you did not know that.

Lets see some examples by using the following String!
S – 0
H – 1
A -2
L -3
I -4
N -5
E -6
E -7

Length of String: 8

slice(‘Shalinee’, 3) // Returns ‘linee’.
slice(‘Shalinee’, 30) // Returns ”.
slice(‘Shalinee’, 10, 2) // Returns ”.
slice(‘Shalinee’, 0) // Returns ‘Shalinee’.
slice(‘Shalinee’, 2, 5) // Returns ‘ali’.
slice(‘Shalinee’, 6, 20) // Returns ‘ee’.
slice(‘Shalinee’, -2) // Returns ‘ee’. [-2+8 = 6]
slice(‘Shalinee’, 3, -2) // Returns ‘lin’. [-2+8 =6 , thus 3,6)
slice(‘Shalinee’, 3, 3) // Returns an empty string -”.

2. SUBSTRING: This returns a substring starting from the specified index and goes till the number of characters that you want in the substring.

substring(‘<text>’, <startIndex>, <length>)

Example: substring(‘Shalinee’, 5, 3) gives nee

Some interesting facts here would be:

  • The start index should be a greater than or equal to 0 & cannot be negative as in the case of slice. Also it should be less than the length of the string otherwise you will get errors.
  • The length parameter is a positive number & is optional and if not provided, you will get an error.

3. SPLIT: This returns an array that contains substrings, separated by commas, based on the specified delimiter character in the original string.

split(‘<text>’, ‘<delimiter>’)

Example: split(‘Sha_li_nee’, ‘_’) gives [“Sha”,”li”,”nee”]

Some interesting facts here would be:

  • If no delimiter is provided, it gives an error.
  • If a delimiter is provided which is not present in the String, or if nothing is provided within the string, it gives the original string in an array form.

split(‘Sha_li_nee’, ”) gives [“Shalinee”]

Hope it helps!

& the Power Quote of the day is:

“Keep your face always toward the sunshine, and shadows will fall behind you.”

How to find difference between two DateTime fields in a Whole Number field with Duration as the Format Type

Business Scenario: We have to calculate the difference between two DateTime fields and store the result in a Whole Number field with the Format Duration to let us know the difference in minutes, hours,days accordingly.

Solution: Before getting into the direct solution, let us briefly know what a Duration Format Whole number field is, as because the solution lies there.

This format option can be used to display a list of duration options. But the data stored in the database is always a number of minutes. Here is the catch- whenever we are filling the data here, we gotta fill it in minutes and the rest will be taken care off.

Lets get into the code now!

function findDuration(eContext) 
{
    var formContext = eContext.getFormContext();
    var startDate = formContext.getAttribute("pm_startdate").getValue();
    var endDate = formContext.getAttribute("pm_enddate").getValue();
    var endDateFieldControl = formContext.getControl("pm_enddate");
    if (startDate != null && endDate != null) 
	{
        if (startDate > endDate) 
		{
            endDateFieldControl.setNotification("End Date should be greater than Start Date ", "EndDate");
        } 
		else 
		{
            endDateFieldControl.clearNotification("EndDate");            
			var date1 = new Date(startDate);
            var date2 = new Date(endDate);
            var duration = (date2 - date1) / 60000;
           formContext.getAttribute("pm_duration").setValue(duration);
        }
    }
}

Explanation: When we subtract two dates, we get the result in milliseconds,thus we have to convert it to minutes and put it in the whole number field which is why we divide it by 60000.[1 millisecond=1/(60*1000) min]. Simple isn’t it.

Lets see it in action

Hope it helps!

& the Power Quote of the day is:

The secret of change is to focus all of your energy not on fighting the old but on building the new.

Change of Owner – Want to specify for User or Team!?

Business Scenario: You want to trigger a flow when the owner of a record changes. Now Owner can point to both User or Team that is assigned to a user or team owned entity record. Say you want to run the action/flow on change of change of User only and not on change of Team, how do we do it?

Solution: Create an automated flow as below on Modification of Owner field:

then put a condition where check the type of the owner – You can select it dynamically as Owner(Type)

To make the condition for User, write

Otherwise to make it for teams, write

You may also choose Owner (Table Name) but remember to provide the Plural name there.

After this you may write your required set of Actions as per the Business Logic.

Your flow now runs only on Change of SystemOwner and not on change of TeamOwner.

Also you may use Filtering Conditon as stated in this Blog so the flow doesn’t even trigger on unwanted situations.

Hope it helps!

& the Power Quote of the day is:

“The only impossible journey is the one you never begin”

Delay vs Delay Until

Both of these are wait conditions used to delay processing in your flows. But what’s the difference? Let’s understand with an use case application.

Theoretically:
They come under the Schedule Action:


DELAY – Adds a fixed delay before the next step in a certain unit of measurement. Thus just tell the count in 1,2,3…… & choose the desired unit.

Power Tip 1: Here I would like to point out that I think Microsoft has just included the “Month” option for the sake of completion, but you should never use it. Flows have a 30 days max runtime, so after that time, regardless of what step you are, the Flow will timeout. So defining anything above that time will never be executed. Its like a complete NO NO to use.

DELAY UNTIL- adds the delay until a specific timestamp. Thus add the timestamp in ISO8601 format.

Power Tip 2:  The flow considers the Time in UTC timezone. Thus make sure to convert the Timezone to UTC before passing it in the delay until step. Below is the formula to help achieve this.

convertToUtc(‘timestamp’,’SourceTimeZone’,’yyyy-MM-ddTHH:mm:ssZ’)

Power Tip 3: The format of the date and time is very important here. If you use any different format, you will find that the Delay Until step fails with the following error.

Now lets see the application.

Business Scenario: Remember the example we took in my BLOG38 , where in a Lead we could dispose it off as “Call back required”. Well you may save the Call back Time in units of measurements like 10 mins, 30 mins, 1 hour etc as the Business Requirement is OR at a particular Time which the customer asks for.
Let’s explore both of these scenarios here.

Scenario 1: Say we give the Call back Time in a span of duration(the unit is predefined here).

Thus we see that the Delay Steps waits for 2 minutes before the next step.

Scenario 2: The Customer gives a proper timestamp to call them back.

Thus we see that the Delay Until Steps waits for till it is 10:38(IST-5 hours 30mins) before the next step. PS: The time is in UTC

So now you know how it works, but still it has certain improvisation to be done.

Problem 1: If the target date or duration is more than a month, then the flow fail would fail as the 30 day limit would be breached.

Problem 2: If the entry has been updated after the initial flow had been initiated (e.g. the Lead calls back and tells to call him back after 5 mins instead of 15), the initial flow would still be running and therefore continue to wait for the original target date/time & the new one will trigger a flow too. As the Callback time is not revised and 2 flows are running simultaneously to perform a single task, we should stop the initial flow somehow.

Well if there’s a problem, there’s a solution.

Solution for Problem 1: In such cases use a scheduled flow and run that at proper intervals suiting the Business Requirement.

Solution for Problem 2: Here use a flag field and change it on change of the Disposition.

Now check this field before and after the Delay Action. If its different, terminate the flow otherwise create a Phone Call .

Test Scenario: I am disposing the Lead twice now- first one with 5 min interval & another with 1 min.

Output: The flow with 5 min interval terminates because the flow with 1 min interval already ran before it.

The Flow with 1 min interval runs successfully.

Hope it helps!

& the Power Quote of the day is:

“The Mind is everything! What you think is what you become”

Closure of Opportunity when Work Order is created via Power Automate

Business Scenario: When an Opportunity is converted to “Work Order”, it should be closed.

Solution: Trigger would be on creation of Work Order

Take 1: I tried to change the Status of Opportunity directly by using “Update a row” action

It did not work!

Take 2: I tried to use the action “Perform an Unbound Action”-WinOpportunity.
Here I was presented with this gigantic amount of fields to be filled up which were not even clear.

Still I went ahead and tried to fill it with the values I needed for Opportunity Closure.

Still no Success!

Take 3: Finally I twisted this method and in the Action name, I selected the option of “Enter Custom Value”

Then I used the expression: trim(‘WinOpportunity’)

Please Note: The EntitySetName cannot be directly entered in the custom value textbox. The flow designer will render the step as the table-specific action with the parameters from the entity. If you use the expression builder and enter as a string literal (e.g. ‘WinOpportunity’), the flow designer will render the step as the table-specific step as in the previous case. To make sure that the step is rendered as a generic step, use a string function in the expression builder (e.g. trim(‘WinOpportunity’)  ) and the end result would be that the Action Parameters will become one single multiline textbox and populate it with a JSON object whose format is given below:

{
“OpportunityClose”: {
“opportunityid@odata.bind”: “opportunities(GUID)”,
“actualrevenue”: ,
“statuscode”: 2,
“actualend”: “”,
“description”: “Test Opportunity Close”
},
“Status”: 3
}

Let’s convert the Opportunity to Work Order now!

We see from the above image that the Work Order was created successfully.

Lets check the Flow now:

The Flow even ran successfully and we can see that the Opportunity is closed with the Status “Won”.

Hope it helps!

& the Power Quote of the Day is:

“If you get tired, Learn to Rest not to Quit”

Generate “Invoice” and change Work Order Status to “Posted” via Power Automate when the Booking Status is Completed

Business Scenario: When the Booking Status is Completed, first change the Work Order Status to “Posted” and then generate an Invoice via Power Automate. This should happen only in the case when the work order is generated from an Opportunity.

Solution: We are creating an automated cloud flow with the trigger as “When the Booking Status is modified for the Bookable Resource Bookings table”

Then we are checking if the Booking Status is “Completed”

If Yes, then we are changing the Work Order System Status to “Posted

I am terminating the flow if the Work Order is not generating from “Opportunity”

Then i am adding an Invoice record in “Invoices” table

Please note here the Price List field is referred to as: “pricelevels“.

Then we are listing all the “Work Order Products” related to that Work Order

Then we will apply to each work order product and get the Product Details

Then we will add it to “Invoice Products” with the given Invoice ID

Please note that the Units are referred as “uoms

Then we will list all “Work Order Services” related to the work order.

Get the Service Product details:

then add it to Invoice Products against the Invoice ID:

Let us now run the flow- The flow ran successfully:

Hope it helps!

& the Power Quote of the day is:

“The best way to predict your future is to create it” ~ Abraham Lincoln

Terminate a Flow

There are a lot of use cases when we have to terminate the Flow/Power Automate if the condition is not met OR when we have to test the flow and run just a part of it to see the results without going till the end of flow OR to end the flow correctly by declaring that it wasn’t successful instead of leaving the flow just like that.

Here the ‘Terminate’ control can be used to achieve all of this. It forces the flow to end wherever that action is placed and is executed in a branch.

The Terminate control gives us the option to set the status. We can set it to FailedSucceededCancelled, or even add a Custom Value.


If we select the Status as “Succeeded” or “Cancelled“, it will ask just for the Status Input simply.


Cancelled” status becomes useful to differentiate between successful flows and the flow which ran successfully without serving any purpose.

This also helps when we check the “Run History” of the flow – we get to know that the flow was Cancelled coz it faced certain conditions which didn’t meet the criteria.

If you select “Failed” , it gives you option to provide error code and error message.

If you choose “Enter custom value” for Status, It will throw an error while saving the flow. Hoping that Microsoft will fix this issue soon.

Thus you can just use the 3 OOB Statuses for the time being.

Note: Terminate control will terminate the entire flow and not any specific branch .

All things considered, the Terminate action control is indeed an essential element in Power Automate. There are times when user inputs don’t meet certain conditions and we tend to leave the flow like that. This is where the Terminate action control becomes useful. We can just use the Terminate control to properly end a flow run by declaring that it wasn’t successful.

There are a lot of cool things that we can do with this control!

Also, an important thing to note is that the control “Terminate” cannot be used inside an iterative control for example “Apply To Each”

Hope it helps!

& the Power quote of the day is:

“Never try to fit in, coz you are born to stand out”

Want to Save the form again after changing the field values to the same value in Dynamics CRM?

Business Scenario: Many a times the client asks for the scenario that whenever they are removing and then again saving the same value in a field, they should be able to save the form to do the activities which happens on save of that form. Say when we dispose off the same lead with the same disposition, how will CRM know?

In Dynamics365, we see that if you choose the same value again, it doesn’t let’s you save only as there is no change for it. What if we wanted the option of saving it!?

Well here is one of the ways, & do let me know if any other way is possible.

Use Case: In Call centres, the agents dispose off the calls of leads with certain dispositions which may or may not be same in consecutive call tries. In case it would be same, we need a save trigger.

Solution: What I have done is created a new “Single line of Text” type of field named “dispositiontrigger” and placed it on the form but have hidden it.

Now on change of the Required field(Disposition) I am populating a random guid on the Hidden field & hence the form calls for a Save and we get our “On Save” trigger. Also this flag field can be utilized to get trigger columns for Power Automate.

Code: Write the following JScript and trigger it on Change of “Disposition” field

function DispositionChange(eContext)
{
var formContext = eContext.getFormContext();
var field = formContext.getAttribute(‘new_disposition’);
if (field != null)
{
if(field.getValue() != null)
{
var str=gen() + gen() + ‘-‘ + gen() + ‘-‘ + gen() + ‘-‘ + gen() + ‘-‘ + gen() + gen() + gen();
formContext.getAttribute(‘new_dispositiontrigger’).setValue(str);
}
}
}
function gen()
{
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
}

Outcome: Let’s check out the results.

Thus we see that it is prompting as “unsaved” and is asking us to save the form again.

Hope it helps!

& the Power Quote of the day is:

“If its makes you happy, It doesn’t have to make sense to anyone else!”

Don’t want to Trigger Power Automate Flows unnecessarily to save the number of Flow Runs – Use Filtering Conditions

Well! we all write a lot of Flows in our project with triggers and then check for certain conditions, if it meets well and good, if not , we either terminate it or do nothing. But the fact is the flow still runs & is counted as an API call. When it goes to the actual Production with real-time number of runs, often we have seen that the flows are running and spending the quota very quickly. This is because of the unnecessary runs which are triggering without delivering any value . Trigger conditions protect us from that.

Trigger Conditions are basically like expressions to determine an outcome of TRUE or FALSE which will decide that whether the flow would be triggered or not !? 

For example, Remember the example we took of creating Email from Case record. Here we chose the Trigger as “When a row is added” and then checked whether the regarding type of entity is incident. Well in this case the flow is triggered every time an Email was created irrespective of whether it was created from an Account, Contact, Case , or any table or as a standalone Email. Thus the flow was triggered unnecessarily and was terminated eventually, adding no value and wasting the flow runs.

As a solution, what we will do is
Step 1: Go to the Trigger “When a row is added, modified or deleted” and click on the three dots, then click on the settings as shown below:

This image has an empty alt attribute; its file name is image.png


Step 2:Locate “Trigger Conditions” towards the end >> Click on “+Add”

This image has an empty alt attribute; its file name is image-33.png

Step 3:If you are an expert in writing Expressions, just go ahead and start writing if not then you can write it in the Expression provided in the Power Automate in any other step of the flow and copy it here. Just make sure you place the special character “@” in front of it always.

I have written the following Expression for comparing the RegardingType of Email to Entity Type ‘incident’ i.e. the Case:

@equals(triggerOutputs()?[‘body/_regardingobjectid_value@Microsoft.Dynamics.CRM.lookuplogicalname’],’incident’)

PS: I got the first parameter of Equals simply from the condition variable I used in the Condition Action- you may either hover on it to see the value or copy it directly.

This image has an empty alt attribute; its file name is image-35.png



Step 4:Click on Done and remove the condition step from beneath as you longer need to again check it and save the Flow.

This image has an empty alt attribute; its file name is image-34.png

Outcome: So now when we create an Email from case, we see that it runs successfully but when we create an Email from Contact, it doesn’t run at all. Thus saving us a mammoth amount of flow calls which are counted as API request. Thus saving us from reaching the API request limits faster.

We see that this is a much much more efficient way of writing Flows where the condition is checked at the onset rather than doing the check once the automation has started.

Additional Advantages:

1.Using trigger conditions, one can control the flow to execute or not. This also prevents generating unnecessary entries in RunHistory

2.If your Trigger Condition is not correct, the Flow will prompt you during Save.

3. You can also secure the trigger inputs/outputs in the run history of a cloud flow. To do this, you can turn on the secure input and/or secure output setting in the trigger.

This image has an empty alt attribute; its file name is image-37.png

Hope it helps! Explore other settings here too.

& the Power Quote of the day is:

“The world is full of obvious things which nobody by any chance ever observes” ~Sherlock Holmes