MB-400 Power Apps & Dynamics 365 Developer Exam

I haven’t usually been putting up posts around the exams that I take. A few months back I did decide to write one on the MB-600 exam (MB-600 Solution Architect Exam), which just took off! It was quite amazing (& pleasing) how many people were looking at it, & asking me questions around the exam.

As a result, I’ve decided to continue this, and am therefore now writing this post on the MB-400 exam.

There are several different ‘ranges’ of exams within the Dynamics 365/Power Platform space. These are aimed at different types of roles, or specific specialisation/s within a role. A good example of this is the MB-2xx range. It covers functional technology, and is split across the different ‘main’ areas of Dynamics 365.

The MB-400 (the only one in the range at the moment) is aimed at developers. According to the official description for the exam:

Candidates for this exam are Developers who work with Microsoft Power Apps model-driven apps in Dynamics 365 to design, develop, secure, and extend a Dynamics 365 implementation. Candidates implement components of a solution that include application enhancements, custom user experience, system integrations, data conversions, custom process automation, and custom visualizations.

Candidates must have strong applied knowledge of Power Apps model-driven apps in Dynamics 365, including in-depth understanding of customization, configuration, integration, and extensibility, as well as boundaries and constraints. Candidates should have a basic understanding of DevOps practices for Power Apps model-driven apps in Dynamics 365. Candidates must expose, store, and report on data.

Candidates should have development experience that includes JavaScript, TypeScript, C#, HTML, .NET, Microsoft Azure, Office 365, RESTful Web Services, ASP.NET, and Power BI.

As anyone who knows me will attest, I am NOT a developer. However I decided (for several reasons) to give this one a go, and see what would happen! I knew I’d be pushing myself out of my comfort zone, there would be things I wouldn’t understand/know at ALL, but hey – I was curious to see what would happen! Even more challenging, I decided to book & take it within a 24 hour period!

Now as this has been out for a little while (& isn’t in Beta), there’s thankfully some good resources on Microsoft Learn about it. Take a look at https://docs.microsoft.com/en-us/learn/certifications/exams/mb-400, where there are several learning paths that can be followed.

A big shout out as well to Julian Sharp & Joe Griffin who recently ran a multi-week course around it. The official Microsoft learning paths are great of course, but seem to miss out quite a bit of what’s actually needed to be known for this. The course that they ran covered a lot more. Hopefully there will be more courses like this run in the future!

When passing it (& assuming that you’ve passed the MB-200 as well), you get a lovely shiny badge!

Microsoft Certified: Power Apps + Dynamics 365 Developer Associate
I’m SO proud of this!

Once again, I sat the exam through the proctored option (ie from home). The experience went somewhat better than previous times. Amusingly I got told off by the proctor during the exam for ‘looking down at the keyboard’, rather than looking at the screen! I explained that I was using a different computer, & kept clicking the wrong mouse button on it (leaving aside that I was exhausted when doing it!).

So, as before, it’s not permitted to share any of the exam questions. This is in the rules/acceptance for taking the exam. I’ve therefore put an overview of the sorts of questions that came up during my exam. (Note: exams are composed from question banks, so there could be many things that weren’t included in my exam, but could be included for someone else!).

  • Model driven apps:
    • User experience
    • Show/hide fields
    • Change field labels
  • Canvas apps – functionality, online/offline capabilities, field types (including searching/filtering data)
  • Plugin debugging
  • Configuring security for system connections (security types)
  • D365 Web API – how it’s used, types of calls made from/to it
  • Azure API – making calls to/from it
  • Code for importing data (debugging, variables)
  • Advanced Find
  • Types of calls (synchronous, asynchronous, )
  • Data modelling
  • Creating & deploying solutions through different methods
  • Publisher versioning
  • Identifying code variables, and saying what would happen in given scenarios
  • Power Apps Component Framework (PCF) – how to use, how to package components, how to deploy
  • PCF components & classes
  • JavaScript – code examples, what happens when a given scenario happens
  • JavaScript functions
  • Dynamics 365 Ribbon – what it is, what you can do with it, different types of functionality & ways to do things with it
  • Security & Permissions, including roles, teams, field level security, business units
  • Workflows, Power Automate Flows (how they’re set up, different functionality within them, how to do things with them given a specific scenario)
  • Business Rules (what they can/can’t do, different scopes, etc)
  • Field types (eg option-sets, calculated fields, roll-up fields, multi-select, etc)
  • Importing solutions – requirements for this, versioning, deployment between environments
  • Compatibility with Microsoft Teams

Now many of these (as I said above) are outside of my comfort zone. In fact, I’d say that even with absolutely cramming for a whole day for the exam, I still felt that I was guessing the answer for at least 30% of the questions. Admittedly though, as Julian Sharp says, a ‘gut feeling’ answer is usually right most of the time, coming from what the subconscious has absorbed during revision.

I was REALLY happy that I got a passing mark for this, & admittedly was VERY relieved as well. So now another lovely shiny badge in my collection, and I’m now going to go and update it on LinkedIn as well!

If you have any questions on this, feel free to drop them below, and I’ll try to help out as best as I can!

AAD Security Teams, & saving personal views

Previously I’ve touched on how it’s possible to use Azure Active Directory for Dynamics 365 security. This can be of great benefit to an organisation, especially when needing to invite in external users. The details that I go into around it can be found at Dynamics 365 Security & AAD. As I point out there, it’s a very helpful feature, and can also help with onboarding new users within an organisation.

What I’ve found out about it, however, is that there can be some very interesting little quirks with how security actually works. Originally I thought it was a bug, and raised it with Microsoft Support, but it turns out not to be. Let me take you through the journey that I experienced last week…

The scenario is as follows. We had security set up in place, which was working perfectly (or so we thought). We’d gone through all of the following steps:

  1. Create Dynamics 365 security role/s with appropriate permissions
  2. Create AAD security group
  3. Create Dynamics 365 AAD Security Team, and link it to the AAD security group
  4. Assign users to the AAD security group

This was working exceptionally well (except, of course, when the external users hadn’t followed the setup instructions correctly). Users were logging in, searching for information, creating/updating records, etc. All was good…or so we thought.

Now, the users who are actually using the application don’t have a Dynamics 365 background. It’s the first time that they’re using the specific system, and as such, are going through a learning curve. We’re not expecting them to understand the advanced functionality at this point, though some of them are indeed venturing further/deeper into the capabilities that it brings.

The Learning Curve | Listen via Stitcher for Podcasts

One of these, of course, is the Advanced Find. Now, those experienced with Dynamics 365 will know all about it. There are good points, and there are not so good points. Functionality in it has expanded over time, though to be honest it’s still easier to run a SQL query/extract for more advanced information retrieval.

Users seemed to be fine with the Advanced Find. We showed them how it works, how to filter, set up columns, etc. We even showed them how to export data to Excel, and keep a live data connection back to refresh it! Brilliant – they were most pleased.

Then I got an email in from a user needing support. They reported that they weren’t able to save custom searches. This is of course very helpful, in order to avoid having to set up the same search/layout every time. This seemed puzzling to me, and I started to take a look into it.

Always download the error log file – it can be SO useful!

I was able to replicate the problem immediately with a test user, having assigned it the same security role. Opening the log file (which can be extremely helpful at times with troubleshooting), I looked to see what the issues were. I was thinking it was a problem with security permissions – if I assigned the system administrator role to my user, everything worked just fine.

Incidentally, there’s a really good blog post at https://www.powerobjects.com/blog/2015/02/13/access-denied-identify-fix-security-role-issue/ which covers troubleshooting security role issues. I’ve used it on several occasions previously.

In my error log, there were repeated references to ‘ObjectTypeCode”:4230’. This is the View settings in the security role. I therefore went to the security role, and ensured that it was set to allow access to Saved View across all permissions:

It’s only possible to set User-level permissions for Saved Views

Right – permissions set, all should be good. Let’s go ahead & try to save an Advanced Find as a view…but no! It’s still not working, and showing the same error message!

What I then tried to do was apply the security role directly to the user, rather than through the AAD security team. To my surprise (well, not really, actually), it worked. I was able to save Advanced Find views. I changed back to the user getting permissions through the security group (ie not directly), and again I had the issue.

OK – so I thought I had discovered a bug. As far as I was aware, I couldn’t see any reason why the user wouldn’t be able to save the Advanced Find view. After all, they’re able to create & save records within the system. There surely shouldn’t be any difference between saving records, and saving an Advanced Find view?

Stressful woman looks with puzzled expression into screen, wears formal shirt, busy with making financial report, feels worried about deadlines, feels headache from recieving bad news Premium Photo

My next step was to raise a support ticket with Microsoft, and then carry out the obligatory ‘show & tell’ to the support agent. Ivan (the agent assigned to my case) was very helpful, understood exactly what I was trying to accomplish, and what the issue seemed to be. I left him with the support case, and focused on trying to find a workaround for the situation.

After a few days, Ivan came back to me with a resolution. It wasn’t a bug in the system (which was a shame – I was looking forward to having it attributed to me!), but rather a specific case of permissions.

See, there’s something called ‘privilege inheritance’. In a nutshell, there are two ways of giving access through a security role:

  1. User privileges. This is when the user is given the permissions directly
  2. Team privileges. This is when the user is given the permissions as a member of the team. If they don’t have User privileges of their own, they can only create records with the team as the owner

There’s a good article on this at https://docs.microsoft.com/en-gb/power-platform/admin/security-roles-privileges#team-members-privilege-inheritance

So what was actually happening was as follows:

  • Users were able to read, create, update records without issues, as the team was the owner of these records
  • However as views need to be owned by a user (though they can be shared with a team), the user was unable to save them!

Thankfully it’s quite easy to fix – on the security role itself, you change it here:

With this then in place, everything then worked just fine. The user was still getting the role through the Security Team, but was now able to save these directly.

Quite an interesting little quirk, but one that is likely to come in useful when looking at other functionality within the system.

Have you come across this before? Have you found anything else that seems a little strange? Comment below – I’d love to hear!

Canvas Apps, Patch command, & Business Rules

Recently I’ve been doing a LOT of work with canvas apps. As I think I’ve mentioned before (at least once or twice!) my background is the traditional ‘model’ style app. As a result, it’s been quite a steep curve to skill up, but I think I’m handling it alright. I’m (slowly) getting used to the way that canvas apps work, the ability to put different controls on the screens, and reference each other.

Heck, I’m even starting to play with more advanced navigation concepts, based on some REALLY great ideas that I’ve seen (Clarissa, I can’t say how grateful I am to you for all of your assistance & guidance!).

Gradient Adventure

Amongst all of this incredible & wonderous journey, I’ve also been learning some code. Yup – you heard me correctly! I’ve always said that I’m not a developer – I respect them greatly, but I don’t develop code.

True, I’ve picked up some SQL here & there, and will freely admit that running SQL queries against the Dynamics 365 database is SO much more powerful than running an Advanced Find. Of course, it’s necessary to know the joins, conditions & such. Redgate’s SQL Helper has been amazing along the way. With moving to cloud systems, things got a little more….complicated. XrmToolBox has the SQL4CDS tool which I’ve used several times, but I was really excited by the recent announcement/release of being able to (properly) run SQL commands against the CDS database from SQL Management Studio….

Anyhow, I’m digressing. So, I’ve been needing to learn canvas app style code. It’s like Excel commands, though (slightly) different at times. Things don’t always make sense (to me, at least) – I STILL haven’t figured out why some expressions need to be in a certain order. After all, according to mathematical principles it doesn’t matter if you write A>B, or B<A. Going to still need to wrap my mind around all of this.

Simplifying Algebraic Expressions - Math 7 Quiz - Quizizz

So, one of the commands that I’m using quite frequently is the Patch command. If you’re really interested, you can check this out in detail at https://docs.microsoft.com/en-us/powerapps/maker/canvas-apps/functions/function-patch.

In short, Patch allows you to set record values from places other than a form table to the data that you’re saving. It also allows you to save field values that aren’t available on the canvas form table (due to limitations). I’ve referred to this previously at https://thecrm.ninja/canvas-app-record-set-regarding-field/. The scenario that I talk about there is just one of the things that can be done in this way. Since that post, we’ve come a long way, and are doing most things with Patch statements (due to the scenario requirements).

So that’s all well & good. However, there IS actually a reason for me writing this blog post….crazy, right? And it’s not to waffle on and on about patch statements. It’s about a very specific scenario that we hadn’t come across to date, but that came up last week.

Now, obviously you’re now VERY interested in hearing all about it, and learning for your own situations. I mean, otherwise you wouldn’t have stuck with me through this article for so long. So, let me set out what happened.

As mentioned above, we’re mostly using patch statements throughout this specific app. That’s….quite a lot of patch statements (especially as we also have IF statements governing which one is being used, as it’s not possible to use IF inside a patch statement, but I’m digress…). I’d say we’re pretty familiar with this now.

However, even with being familiar with it, we suddenly had a problem. One of the forms that we’re saving down started to NOT save down. Records weren’t being saved, which obviously is a problem!

Bear in mind here that we hadn’t touched the code for this specific action for a few weeks. Nothing had changed in our code, and nothing had changed from a platform perspective (ie Microsoft hadn’t changed any of the underlying functionality.

Going into the statement, we immediately started testing it out, and saw something interesting. We were getting an error that a required field could not be NULL:

This was quite puzzling – although in a model app we can set fields as required, and users can’t save the record until they populate it, this isn’t true in a canvas app (well, when using Patch, at least). See, it’s technically possible to use a Patch statement to create/update a record, but you don’t have to pass in required field (values). It’s a sort of workaround (& can be used in some scenarios for benefit, actually). So this happening all of a sudden was quite strange to us.

It was even stranger as we hadn’t been using the field on the form at all. The field that was being referred to was being used for a totally different process, in a different team, & not surfaced into the canvas app at all. This really was causing us to scratch our heads, and try to think (more) out of the box. It didn’t seem to be the code (we could set a value in code, but didn’t want to as it wasn’t relevant), yet we weren’t able to ignore it. Really frustrating!

With all of this in mind, I decided to go back to absolute basics after a few hours of troubleshooting. The field that seemed to be causing all of these issues was a relatively new addition, so I checked all of the details around it:

  • Was the field type correct for what it should be? Yes
  • Was it set as required on the CDS field definition? No (not that I thought this would help, but still checked)
  • Was the field on the entity form? Yes
  • Was the field set as required on the entity form? No (again, I didn’t think I’d get any joy from this)
    • Hold on….on the form designer it’s not set as Required. But when I open the form, and put some values in, suddenly it IS required.

Aha! OK – I’m now starting to see some light shining on this. I headed over to Business Rules to check out what might be there. Lo & behold, there was a business rule that set the field as required (when certain conditions were filled). An example of this would be:

Now this field hadn’t been in place when the code was developed (as mentioned above) – it had come in since. I was very curious if a Business Rule could require canvas apps to set the value, and so did some testing.

Disabling the business rule removed the error from the patch statement. Re-enabling it caused the issue again. OK – so we’ve found what’s been causing this, and could put in an adequate solution to handle it.

So in short, if you’re setting a field as being required through a Business Rule, you’re going to need to address it in any canvas app as well (that’s saving data down to the same form that it’s appearing on). Why it actually happens, when just setting it as Required on the form doesn’t, I have NO idea.

But it’s a good concept to keep in the back of your mind, I believe. Especially if there are multiple people working on developing a single entity, as otherwise you could find yourself in exactly the same scenario that we did!

Have you come across anything like this, or a different piece of strange behaviour? Comment below – I’d love to hear about i!

Workflows & Managed Solutions

This is about some interesting behaviour around workflows & managed solutions, which I’ve recently discovered. Let me give a bit of background first.

Currently I’m working on several COVID-19 apps for local authorities, to be able to help them assist people in need. As part of this, each local authority has a portal within the solution. The portal itself is a Power App Portal, and I haven’t really had exposure to them before.

blog.atwork.at | Hello, PowerApps Portals (and external users)!
Default portal view, not the one we implemented!

Installing a Power Apps Portal comes with quite a large number of solutions in order to get it to work. More on this below.

Due to the way in which we’re engaging with our clients, the solutions are built in a single tenancy (different environments, of course!). We’re then inviting the users in as guests through Azure Active Directory, to be able to access functionality etc. This works well – we don’t need to worry about managing user accounts, AAD permissions, etc. However it also means that we don’t have any Office 365 licenses within the environment itself.

Now we have workflows that are sending emails out around the portal – registrations, password resets, etc. These are being generated automatically by the system, but as there’s no Office 365 mailbox for the user, they’re queuing up.

It’s not possible to authenticate a mailbox belonging to an external user (we tried!), as the system needs a native (full) user with an active mailbox to be able to send out emails. This is of course unlike Power Automate, where you can create a Send Email action and use specified credentials for logging in to send an email.

So, we did what any normal system administrator/configurator would do. We opened up the relevant (managed) solution, and from there opened up the workflow that we needed to modify. Things looked normal at first – we deactivated the workflow, and started poking around it to see what made it tick.

We came across the part that actually took user credentials to send the email that was being generated, and modified this accordingly. Then we saved the workflow, which was successful. However, upon trying to then reactivate the workflow, we got the following error message (helpful, isn’t it!):

Nicely it gives the option to download the log file around the error. This can usually be quite helpful (at times), so we thought we’d take a look at it. Behold the following (I’ve had to shrink the screenshot to allow it to fit on the screen!):

Isn’t that ‘beautiful’. Don’t worry if you can’t actually make out the error information – none of it makes any sense, at least not in a practical sort of way.

Being stuck at this, I thought to reach out to one of the community Power App Portal champions, Mario Trueba. I’ve known him for a while, and he’s just simply amazing. Having asked if I could jump on a call with him for 15 minutes to diagnose (& hopefully find an answer!), we spent almost an hour!

He suggested trying to use the classic interface, as I had been doing all of this through the new UI. So off I went to open up Classic (I’ve missed this, I will freely admit). Through there, we opened up the solution, opened up the workflow, and re-activated it. Or not, as it happens – even through the Classic UI, we weren’t able to do so. We tried a variety of things, but to no avail. It just simply wasn’t happening!

I was slightly concerned that there was an underlying issues with Portals, perhaps from some legacy CafeX code. I had tried searching with Mario for error details contained within the log file, but we couldn’t find anything that would fix it.

The next morning on waking up & checking Twitter, I noticed someone tweeting around Portals, and engaged with them. They turned out to be on the Portals development team, and told me to shoot them over an email with the details, which I did. They then replied to me, saying that it wasn’t anything specific to Portals, and that I should raise a support ticket. That crossed one item off my list (a Portals issue), but I was still needing to get things resolved.

So I went off & raised a support ticket. A few hours later, a very nice tech support person called Siva gave me a call to discuss the issue. We hopped into Teams, and in what I can only describe as the SHORTEST period of time that I’ve ever experienced, the issue was resolved (it took 7 minutes in total. Yes, I know…). Don’t worry – I’m not going to leave you hanging here!

See, what the ‘issue’ (and I’m deliberately putting it in quotes) was turned out to be something quite simple, yet quite strange.

Essentially opening the workflow from the managed solution somehow (& I don’t know HOW) inherits the ‘managed’ property. This is whether we open it from the new UI, or the classic UI. As a result we’re able to deactivate it, but we CAN’T reactivate it due to the system thinking that we’re modifying a managed component (as an aside, it is interesting how I did manage to save it though?). This was what was causing things to fall over, and the error message was really not helpful at all.

It’s also not a matter of being a Microsoft (or ISV) managed solution. I’ve replicated this happening with a solution that I’ve built, exported as managed, & then imported.

So how did we do it? Well, there are two ways in which this can be dealt with:

Either we can go to System/Processes, find the workflow there, open it up, and then reactivate it:

Or we can open up the Default solution, navigate to processes, select the workflow, and then reactivate it:

Both methods work just fine, and as mentioned earlier on, I’ve since replicated this on workflows in other managed solutions.

To me, this is somewhat strange, and should work regardless. According to Siva, it’s the desired system behaviour, though I have no idea why someone should want it to work in one way, and not in another.

So if you’re reading this, and you might just happen to know someone in the necessary Microsoft engineering/development team who’d be able to answer this, could you point them my way? I’d love to engage them to find out why, how, and if they could pretty please change this?

Updating User Settings with Power Automate

Here’s a scenario that could be all too familiar to us. We’re on-boarding users (to either Dynamics 365 or a Power Platform app), & they’re new to the environment that it’s deployed to. So they’re set up, and all ready to go. Suddenly they start asking why records created (or modified) by colleagues show up as having the wrong time on them.

Reverse Wall Clock Unusual Numbers Backwards Modern Decorative ...

Does this sound familiar? I’m sure it does to quite a few people out there!. See, there’s no way to set a default system-wide time zone in Dynamics 365 (or Power Platform). At least not that I’ve come across – if you know of one, please comment below with instructions as to how to do this!

As a result, users are given the default timezone, and need to change it. This is easily done through the Personalization settings area in the app. Users click here, and then select their appropriate time-zone. Brilliant…or so you’d think.

See, when it’s one or two users, it’s generally OK to tell them to do that. However, when it’s 200 or 2000 users, you’re going to get push-back. The last thing you want is for a large number of them to start contacting you to work out how to do it (read the instructions, perhaps?).

User queue stock photo © zam ri (OneO2) (#258450) | Stockfresh

I’ve had this scenario over the last week, where the client actually told us that they didn’t want us to tell users to update it manually. They wanted a better solution.

Well, there is a solution out there to update users. It’s the ‘User Settings Utility’ app that’s in the XrmToolBox (https://www.xrmtoolbox.com/plugins/MsCrmTools.UserSettingsUtility/). Really neat & nifty, and does just what it says on the box. Simple enough to select users (or all of them at a time), select the time-zone you’re wanting to apply to them, and click a button. Hey presto – it’s been updated

Hmm. But what if you didn’t want to have to do this manually. Or (and this is what I was dealing with), there were decent enough number of users being added to the app every few days, & I didn’t want to have to do this as a manual task.

So I started digging into how the time-zone setting was actually stored. It turns out that there’s an entity called ‘User Settings’, which is associated with a User record. Oh, and if you’re going to want to take a look at this entity to see what it contains, it’s NOT available through the front end. You can’t go into the entity list and just display it (though if you’ve found a way to do this through the Power Platform NATIVELY, drop me a line, please?).

Anyhow, back to things. There’s a value for ‘TimeZoneCode’, which maps to a specific time-zone. Aha, I thought! Right – now what’s the best way that I could work out to do this automatically. Checking in with some contacts in the tech community (thanks BlackOps etc!), Power Automate was suggested, so I started to see about how I could go about it…

So, I created a Power Automate Flow (haha…I got the name right there!). On creation of a new user record, it would programmatically go away and update the value to the one for the time-zone that I wanted it to be set as. This actually worked really well.

The only drawback is that through the user interface, it’s not actually shown as being updated, though it has been. Or sometimes it changes, but doesn’t reflect it accurately. This is somewhat annoying, and caused me quite some confusion between checking the front end to see if things were working, & confirming through the back end (& opening records up) to see that it was. I still have NO idea why this was happening.

Before changing my settings
After changing my time zone to USA (EST)

For my specific scenario, all of the users are in the UK, so I set it to update every user on creation to the UK time-zone. Obviously if you have users in different time-zones, you’d want to set this differently. This shouldn’t be an issue though, as you can expand the Power Automate Flow and add logic conditions/branches to be able to do this.

Now I think that this is pretty cool, and I couldn’t find anything out there for this. I’ve therefore decided to release this in a small solution, for others to be able to use. Part of this is the entire list of time-zones with their specific codes, so that you can update to whichever one you need to.

I hope that this helps solve a small but annoying problem (at least it did for me). Please do provide feedback if you want to!

Thoughts around the Connection entity

I decided to write this post due to currently looking at the Connections entity. This is for a current project with a very specific purpose. When this came up, my thoughts went back to a previous project some years back when we also looked to use the Connections entity. I therefore thought that it would be good to recap & share my experience.

What are Connections?

Now, the Connections entity truly is a wonderful piece of work. It’s one of the core features that doesn’t actually get much time or effort devoted to it! However, it underpins a lot of the way that Dynamics 365 has been built to work over time.

The best way to summarise Connections is:

Connections are a very easy way to connections records without needing to have to create a custom relationship in the system. Connections can be used between records from the same entity, or from different entities.

See, you are able to connect one record to another record within the system. This could be account to account, account to contact, or contact to a custom entity. There are practically no limits, apart from the extent of your mind! All of this is done by leveraging the functionality that Connections brings to the table.

Note that I’m not talking about lookup fields here, which are also great, but work differently, and require creating a relationship between entities (or even within the same entity).

Just a quick reminder here that custom entities need to be enabled for connections – it doesn’t happen as standard when creating them. You can either do this when creating it, or you can edit the settings for it later:

How to use Connections

In order to connect one record to another, you need to open the first record & click the Connect button on the toolbar:

You’ll then be presented with the New Connection screen, where you’ll select the record that you want. Click the ‘All Records’ item at the top & then ‘Change View’ to select the actual entity that you’re wanting to look for:

You then select the record that you’re wanting, and save. Hey presto, the two records are now connected! To see the connected records, look at the associated ‘Connections’ setting from either record:

OK, so this is really all brilliant. For the absolute majority of situations, it works, and works well. There’s nothing better for it. There are a few small issues, such as the fact that you can’t use Business Process Flows or Business Rules for custom logic, but instead need to use Javascript, but for the most part they work well.

Edge case scenarios & issues

However, there are some edge case scenarios that I’ve come up against, which is the whole purpose for writing this blog post.

What happens if you’re trying to use Connections to establish a hierarchy of records. Eg one record is a parent of another record. Well, you could use a lookup field instead, but if you wanted to define specific attributes for the actual relationship, that wouldn’t work.

Here’s the scenario. You’re needing to capture the relationship between different people, along with certain attributes (eg if they’re a legal guardian, or a trustee, or have power of attorney, etc). You’d think that Connections would work brilliantly for this. After all, you can modify the actual Connections entity to add custom fields onto it. So for example, you could have something like the following:

Note: I’m not referencing Connection Roles, as you can only have a single connection role per connection. In the scenarios I’m handling, I’m needing to have multiple attributes per connection.

So you create the connection between the two records, and you set the attributes that you require. All good. What’s also good to remember is that Connections are bi-directional. You can view them from either ‘side’ of the connection. Eg:

Record 1

Record 2

That’s actually really helpful & useful in the normal scheme of things. You can easily see connections from either side.

But there’s a catch, or even (in our case above), an issue. If we open up each of the two Connection records, we’ll see the following data.

Joe Bloggs connecting to Helen Sommers:

Helen Sommers connecting to Joe Bloggs:

Can you spot the issue? Of course you can! On BOTH of the connection records, the custom fields that we set have the same values. We originally connected Joe Bloggs to Helen Sommers as the Legal Guardian, Power of Attorney & Trustee. Well, if we open up the connection record from Helen Sommers, we’re seeing the same values set, just in the opposite direction!

This is actually due to how Connections work. When you create a connection Record A to Record B, the system automatically creates a mirror Connection record from Record B to Record A. When it does this, it copies all of the values that you’ve set over to this mirror record.

So when you look at the data, you can’t actually see how the structure should work. It’s an issue. Especially if you’re passing the data to other system/s that may need to evaluate it. They just can’t understand this properly, and you’ll get some VERY unwanted results out of this.

Now, there is actually a field within Connections that shows which record is the ‘master’ (ie the one you actually created), and which one is the ‘mirror’ that the system created:

However even with this in place, we’ve found issues when using it:

  • If you’re relying on people looking at the record to see the information, they’re going to make mistakes (ie not checking this value). With the fact that the values are also displayed on the mirror record, this is very prone to user error, and isn’t a good way to do things
  • If passing information to another system (ie the record & the values), you need to program it to only allow it to pass records with this flag set correctly. If the other system is writing back data, it also needs to be configured to write back to the same record.

Summary

With all of this in mind (& especially considering that users may create connections from the ‘wrong direction’, which is quite possible to happen), it’s important to think of the best way to architect systems for regulatory purposes. Financial, legal & other judicatory requirements need to have a system that can handle them properly & accordingly, and not leave room for error.

Therefore, if you’re looking to handle these sorts of scenarios, I’d recommend to look at implementing a custom entity for those specific connections.

Another benefit of this is to separate out these connections from the general connections entity. That way, you’ll also be able to handle security appropriately, which is usually applicable in these sorts of situations. It will allow you to easily allow only a subset of users access (read and/or write) to this data, rather than trying to apply it to Connections (which is going to be a major headache!)

Canvas Apps & renaming field labels

Today I want to share with you something that I’ve realised. Changing field labels can have unintended consequences!

Let’s cast our minds back to the days of ‘traditional’ Microsoft CRM, or as it’s so lovingly referred to nowadays, ‘model-driven’ apps. What you had were a number of entities (eg Accounts, Contacts, etc), all of which contained fields. Fields could be different types (text, integer, boolean etc), and have varying properties on them. You could set them to be required (or not), searchable (or not), and have so much fun.

At the heart of a field is the name that it has. Well, technically there are two names. One is the actual database name. Once a field was created & saved, this was effectively written in stone. The only way to handle a situation where you spelled this incorrectly was to delete it, and then recreate it. Even then, it could still be floating around in the back-end database in its original form.

The second name is the Display name (or Display label). This was the text used on the entity form itself, & could be changed as desired. This was actually really useful – many a time a business unit would say something like ‘we don’t want the field to show as Zip/Postal Code’; we want it to say ‘Postcode’. Well, that was easy enough to address – simply go ahead, load up customisations, & change the display name property for the field. Everyone was impressed & happy, and could get on with their work.

There were of course times that Business Unit A would say ‘I want ‘ABC’ as the display name’, and then Business Unit B would say ‘Ah, but I want ‘XYZ’ as the display name!’. To handle this, it was very possible to customise the label on the form itself, which would then override the display name value. This, of course, would only be valid for that specific form, so it was then imperative to have different forms for the different business units.

Now, in the good old days we use to create SQL queries against the database, SSRS reports, etc. In order to do this, we needed to know the actual underlying (database) field name. We could of course open up customisations, & start trawling through, but there are better methods for doing this. One of these is Level Up by Natraj Yegnaraman. This can be found at https://github.com/rajyraman/Levelup-for-Dynamics-CRM, and is an extension which can be run on Chrome, Edge on Chromium, & FireFox).

Using this amazing tool, it was possible to merely load an entity form up in an existing system, and then TADA! At the click of a button (well, two clicks actually), the underlying database name was revealed. This was an absolute lifesaver, so many times.

So there we’ve been, toddling along for many years like this. It worked, and worked well. All was good.

Then came along canvas apps. Now I’m not a canvas app guru by any means – I’m quite new to them, and still trying to wrap my head around the ‘special’ way in which they operate. Thankfully there are quite a few gurus in the community who have given me help in one way or another to learn how to carry out various functions, and I think that I may JUST be starting to get the hang of it.

With the current COVID-19 situation, I’ve been working on a series of apps for work, to help local authorities. One of these is a canvas app for call centres, to record information easily & quickly. We chose to go down the canvas route due to being able to have a clean layout, as well as being able to display information for the operators to read. This would have been much more difficult in a traditional model-driven app, especially as such things as dialogues have been deprecated.

One of the functions that I’ve had to learn to do this has been to use the ‘Patch’ function (see https://docs.microsoft.com/en-us/powerapps/maker/canvas-apps/functions/function-patch for more information on this. The following is an example of one of the Patch statements that I was using:

This was working remarkably well – it was creating the task record, and setting all of the different values that I needed. For those who are curious as to why I was using a Patch statement, rather than submitting the form, it was due to needing to set the ‘Regarding’ field, which has some very special behaviour!

Then someone on the team said ‘Hold on – we’re only storing one address. Let’s change the field display names to remove the ‘Address 1′ part, so that we don’t confuse users’. OK – I didn’t INITIALLY see any issue with this. I bet that you can see what’s coming through…

Yes – you’re right. The patch statement isn’t referring to the field database name. It’s referring to the field display name! The reason for this is that this is the syntax that Canvas Apps use – there doesn’t seem to be a way to refer to the actual underlying field database name

Of course, I only actually discovered this when I ran through the canvas app again. And indeed, it was whilst demonstrating it to other people! Oh joys – what a wonderful time for it to happen.

So, I then had to figure out what had happened – thankfully that didn’t take too much time. What DID take time was going through every single place in the canvas app that had code referring to the specific fields, and update them to the new (correct) values. This therefore ended up looking like:

So, the vitally important lesson to learn here is be VERY careful when changing field display names, especially if you have one (or more) canvas apps that are referencing them. The last thing that you want is a major headache in having to go back through every place that refers to them, and changing/updating the values.

The only workaround that I’d suggest, is that if you’re wanting to change how fields display in the canvas app itself, change the ‘Text’ value for the field:

That way, HOPEFULLY, nothing will break moving forward.

I hope that you’ve found this useful. If you have a different way in which you’ve handled this situation, feel free to leave a comment below!

Canvas App record set Regarding field

For the last few days, I’ve been working on an app. Not just any app – it’s a canvas app! (It actually happens to be a COVID-19 related app, for local authorities to use to contact vulnerable people & check they’re OK etc).

Now, my background isn’t canvas apps – it’s the model-driven app approach. I’ve been doing this for years – after all, my experience goes back to Microsoft CRM 3.0! So that’s all really nice & easy for me (even with some of the more modern ‘tweaks’ that have been brought in). Canvas apps, on the other hand, are very different from what I’m used to, and are taking quite a bit of getting used to.

See, the following example is easy in a traditional model-driven app:

Create a contact, save various attributes to the contact record. Then create a task, and set the Task Regarding field to the contact that you’ve just created

Looking at that, my mind says ‘easy-peasy’!. I create the fields required for the contact entity (& task entity as well, if needed). I then add them to the entity form/s (creating or modifying the form view/s as well). Finally, I create a Business Process Flow for users on the contact entity, and append the task creation to it. Simple, and done – not much time needed to be spent.

But when needing to do this as a canvas app, things change around QUITE a bit. I can’t create that business process flow, and I have multiple screens to have all of the information on.

Now, if I could add the ‘Regarding’ field to the edit form grid, and apply formatting to it, I could hopefully then just submit & save the grid. However, that unfortunately doesn’t work. I can add the field, but when I do so, I get the following:

So that doesn’t work. Hmmm – how then should I go around doing it?

I did (obviously!!) take a look online. Here I came across this wonderful article all about polymorphic lookups (https://docs.microsoft.com/en-us/powerapps/maker/canvas-apps/working-with-references). Having read, & re-read through it, I’m STILL not understanding what exactly I should be doing by this!

So I was stumped. Thankfully we have an amazing community, and on reaching out to someone within it (thanks Eric!), I was helped out. I therefore thought to write this post up, so that it can help others as well.

There are two parts to this, for my specific scenario:

  • Saving the contact record down. This is a matter of using (in my case) the command ‘SubmitForm.ContactInformation’ on my contact form screen. I can then also set a variable if I want to, to refer to the Contact record GUID (hey – I’m trying to be cool here & show that I can!)
  • Finding a different way to save my task record. I accomplished this using the Patch statement – this thankfully wasn’t too difficult for me to grasp how it worked.

So, how did I go about using the Patch statement? Well, the function is referenced here – https://docs.microsoft.com/en-us/powerapps/maker/canvas-apps/functions/function-patch. With Eric’s help, I soon started to see how to do it.

What I did was add the following line in my Patch statement when I was wanting to save the task: ‘Regarding:ContactForm.LastSubmit’ (‘ContactForm was the name of the form for the contact information). What this did was write into the record the GUID for the contact record that I last saved.

An alternative to this would be to use a variable instead, and set it there.

Thankfully this all worked. I’m now able to create Task records and set their Regarding field value to the Contact that I set up before them – which is the exact thing that I was trying to do!

I hope that this has been helpful – leave a note in the comments if you’ve found another way of doing this.

Wave 1 2020 – Search Behaviour Changes

Having applied the Wave 1 2020 release to several of my test environments, I was browsing around to see the new functionality within it, which is pretty good. However, there was something that I wasn’t expecting, which was a little startling to see! This is around the way that the search behaviour is now working within the system.

What am I talking about? Well, for years, users have asked me if they could search within a specific view. Ie if we had a view set up for ‘My accounts’, where the user is set as the account manager, it would show only the accounts where that condition applies. However when using the search functionality, the system would search & return ALL results that match the search criteria (eg if searching for ‘Apple’, it would return all accounts with the word ‘apple’ in them, regardless if the user was set up as the account manager or not).

Explaining this to users was probably the most complicated thing, in my experience (well, that, and having to then trawl through hundreds, if not thousands of records, where it’s a common word). But for the most part, they accepted it. OK – we all moved on.

Let’s see an example of this. The screenshot below shows an account that exists within one of my Sandbox environments (which has the Wave 1 2020 update applied to it):

I’m now going to search for it within the entity itself (more about Global Search at the end of this post):

Hold on – it’s not showing up! What is happening here – is the system OK???

Let me explain what’s happening. Previously (before the Wave 1 2020 update was applied) it would indeed show up in the search results.

But this has now changed! The system is now performing searches ONLY within the view that the user is using. The reason why it’s not showing up here? Well, it’s because I’m not set as the owner of the account – a different user is (and I’m using the ‘My Accounts’ view, as seen in the previous screenshot):

If I now change my view to ‘All Accounts’ and repeat the search again, the record now shows up:

I hadn’t come across this in my perusal of the release notes. On going back to it and digging deep, I found the mention here – https://docs.microsoft.com/en-us/power-platform-release-plan/2020wave1/microsoft-powerapps/improvements-quick-find-search-experience-grid.

Amusingly there’s actually even a little hint within the system for this. If you look at the entity search box, this is now the text that’s being displayed within it:

There’s also an additional feature as part of this – if you’ve prefiltered a view using column value, searching within the entity will RESPECT the pre-filtering!. OK – now this is indeed incredible:

My thoughts on this is that it’s going to be a double-edged sword. For years, we’ve been educating customers about how searching works, and now this has the potential to change things up.

Thankfully it’s actually possible to turn this off, and revert back to the way that searching has always worked – this is likely to be needed to be done quite a bit. To do this, go to Settings, Administration, System Settings, and change the value for Categorised Search to ‘Yes’ (it’s about 1/3 of the way down the page):

It would have been nice if Microsoft had made people more aware of this, in my opinion.

Please note that this only applies to searching within an entity itself. Global Search (for the moment) still uses the Quick Find view, and returns all results (regardless of filters).

MB-600 Solution Architect Exam

I haven’t really touched very much on any exams that I’ve taken so far during the lifetime of this blog. I’ve mentioned them a few times (ie how important they can be), but haven’t really gone into detail.

However, having seen various comments online recently around the MB-600 exam, I thought I’d do a post on it with my thoughts and comments!

So, what is the MB-600 exam? Well, it’s sort of the ‘Holy Grail’ for Dynamics 365/Power Platform. This is due to the actual full name for it – ‘Exam MB-600: Microsoft Power Apps + Dynamics 365 Solution Architect’. Indeed – assuming you pass it (and you’ve already passed the MB200, and either the MB210. MB220, MB230, MB240), you can officially refer to yourself as being a Microsoft certified ‘Solution Architect Expert’.

Impressive!

The exam was being talked about at the beginning of 2020, and went live (in beta) on Jan 27th 2020. If you’re wanting to book it, do so at https://docs.microsoft.com/en-us/learn/certifications/exams/mb-600.

I sat it several days after it went live, and to be honest found it quite challenging. Why was that? Well, when I sat it, there were no learning paths on Microsoft Learn for it at all. Thankfully that’s now changed – there’s a massive amount of great material at https://docs.microsoft.com/en-us/learn/certifications/power-apps-and-d365-solution-architect-expert. If you’re looking to go ahead and do the exam, I’d highly recommend you go through everything that’s there.

I’ve taken quite a few exams since early 2019, and have now taken the general approach to take exams in Beta. Although there can be some waiting until the results are announced, they’re cheaper, and give you an understanding of what’s going on.

I sat the exam through the Proctored option. I’m not going to say too much about that (you can look up online what this is about), other than to say that I feel that Microsoft really should be doing something about the proctored experience. Pearson Vue is in charge of this, but it can be really bad at times (having taken a dozen or so exams this way in the last year, I feel I’m quite qualified to be able to judge this!). I hope that things do get better for this.

So, to the exam itself. Well, I was lucky – there were no Labs in it (yet!). Several case studies, and lots of questions. Quite hard questions as well – make no mistake, they’re out to seriously test your knowledge.

The first thing that I ‘loved’ when starting the exam was the general briefing, which included something along the lines of this absolute gem (this isn’t word for word, as I’m not allowed to write it down during the exam, but it gives the gist of it):

Some question sets may have more than one solution, while others might not have a correct solution at all

Right. So tell me – if there’s no correct solution, what am I supposed to do? I’m still waiting for someone to enlighten me on this matter, as I haven’t found anyone who’s able to explain it….

Now, part of the exam rules state that it’s not allowed to share any of the exam questions. What I’ve therefore included below is an overview of the sorts of things that were covered for my exam (Note: exams are composed from question banks, so there could be many things that weren’t included in my exam, but could be included for someone else!).

  • Data imports – what they are, how to go about them, troubleshooting them, etc. Also covering different types of sources
  • Security models, permissions, security types (field level, role, user, team etc)
  • Teams integration. How it’s set up, configured & used
  • Solution patch types. What they are, how they’re applied, how they’re used, benefits & drawbacks
  • BCP (Business Continuity Planning and Disaster Recovery) processes. What option/s should you be considering to ensure your business is fully covered in a disaster situation, how are they configured
  • Portals. What they are, how they’re set up, security permissions
  • Business rules, Business Process Flows, Workflows. What each one does/doesn’t do, benefits & drawbacks, how they’re set up & configured
  • Systems – On Premise vs Cloud. The advantages and/or drawbacks of each type, and the different BCP methods (see above) for each one
  • Data integration. OData vs Custom Service for continuous data
  • SLA’s and KPI’s. What they are, when each is used, how to set up & configure them
  • System upgrade paths and compatibility. How you go about upgrading legacy systems, and the necessary path/s that you have to take for a given version number
  • Customer Service through multiple channels. Which option/s would you select for a given scenario, how would you set it up/configure it
  • CDM/CDM/PowerBI/Azure Service Bus/PowerApps. What is each one, what are the benefits/drawbacks of them, how is each one used, & set up/configuration
  • Licensing Types. What license/s would you need for a given scenario
  • D365 Sales Insights. What it is, what benefit/s it brings, how is it used
  • Data security. How is security used for Dynamics 365 & PowerBI data, how is it set up/configured
  • Field properties. For a given scenario, how would you change field properties and/or parameters?
  • Data Migration. Different options available for this, benefits/drawbacks, resolving issues
  • Form security. What is it, what are the different types of security that’s able to be used, how is it set up
  • Solution management. What are the different types of solutions, how is each one used, what are the associated risks, which option would you use for a given scenario

Wow. That’s a LOT of stuff. Like…an incredible amount. Some of it touches on parts of the system that I’ve never used before (like PowerBI). Other parts are extremely familiar.

I can’t tell you if I’ve passed it or not…YET!. Results aren’t yet out, as it’s still in beta (and from what I’m hearing, it’s likely to be remaining in beta for several months still.

So, if you’re aiming to take it – I wish you the very best of luck, and let me know your experience!