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!

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!

Power Automate & Lookup Fields

Recently I’ve been expanding my knowledge of Power Automate, and how it works. It really is a truly amazing tool, though there can be some quirks to things! There are so many connectors to use, though I haven’t really used that many of them to date.

Truthfully, most of my work in Power Automate is around CDS & Office 365. Occasionally I’ll dip into another system, but for the most part that keeps me busy enough. It’s not to say I don’t want to explore further, but finding the time can be quite difficult!

One of the great abilities that Power Automate has is to be able to update a record. With focusing on CDS entities for the moment, we would use the inbuilt action for this:

We’d run a query to get a specific record – this would give us the record ID (or GUID, depending on your preference). With this, we’d use the Update Record action & pass in the record GUID. After all, we need to know which record we’re going to update! So for example:

What we can then do is set values for the record. So we can pass in Dynamics Content, use Expressions, etc. These can be from records that are part of our Power Automate query chain, or from elsewhere.

For example, I can say that when a contact’s postcode changes (or zip code for USA), go away, look up the new city, and update it (Note: I haven’t shown the postcode lookup part below):

So this is all really brilliant. Different fields have different behaviours, of course, and we need to respect that. Otherwise the Power Automate flow won’t run, and will error. This is, of course, the digital equivalent of not trying to force a square brick into a round hole!

What we can also do is clear a field value. If for example we’re wanting to remove a value from a field, we can use the NULL expression on the field. When the Power Automate flow runs, it’ll clear whichever value the field is currently holding:

Now, one of the the field types available within CDS is the lookup field. I’m not going to go into what this is, as we should already know this!. We can, of course, set lookup fields values to populate the field, which works as expected.

However (& thanks for bearing with me so far), what happens if we want to clear a lookup field value?

Say for example that we have a task, that’s assigned out to someone. If they reject the task, we want to be able to remove them from the task record. We wouldn’t delete the task, as we still need it (& now would need to assign it to someone else). We need a way to do this.

I can hear what you’re thinking right now – mentioned above is the use of NULL, so we’d use this! Um…well, you’d think so. You can try that, but we’ve found that doesn’t always work. Additionally, that doesn’t actually seem to remove the underlying relationship that’s been put in place.

Update: Thanks to Lin Zaw Winn, who dropped me a line to let me know further information around this. The standard CDS connector (the first one that was available) allowed this to work, but the updated CDS connector (Current Environment) doesn’t allow it. Unfortunately the different connectors aren’t at parity, which is a pity!

So, there’s another way to clear lookup field values. This involves the Unrelate action that’s also available. The steps for this are as follows:

  1. Get the related record (lookup the record type, pass in the GUID for it)
  2. Use the Unrelate action to remove the connection

This will then remove the relationship, which actually results in clearing the lookup field value. In practise (for our scenario), this would look like:

Let’s take a bit of a further look at the options available here:

  • The Relationship field is the relationship between the two entities (eg here it’s Contact & Task). Thankfully you don’t need to manually type this – it’s easily selected from a dropdown list.
  • The URL field is the linked record itself

Note: It’s VERY important to have the Entity Name & URL values in the right order. I’d suggest looking up the connected record first (ie what the lookup field is pointing to), and using that as the Entity Name value. You’d then select the record where the lookup is saved on as the URL value.

What I’d usually suggest as best practise is to have a condition before this takes place. As mentioned earlier, removing the lookup would happen on a record update. This is because you wouldn’t be removing a field value if you’re creating the record!

But you’re not always going to want it removed. In the scenario that I’ve been dealing with, we’re only wanting to remove the volunteer if they’ve rejected the assigned task. So our Power Automate flow is set out like this:

  • When Task record is updated
    • Filtering on the field for ‘Task Accepted’, as we could have other things being updated on the Task record that we don’t want to trigger this particular process
  • Condition to check the ‘Task Accepted’ field value
    • When it’s something other than ‘Rejected’, cancel the flow
    • When it’s ‘Rejected’, run the Unrelate process set out above, and stop flow

You can obviously build out other functionality within it as you so desire.

So with this in mind, how do you think you could benefit from this? Drop a comment below – I’d love to hear!

My past year, & Alison Mulligan

This post is going to be somewhat different & out of the norm for the usual sort of topics that I talk about. It’s also going to be somewhat personal, and mention a special person who’s been an absolute rock for me.

So, where to start? Well, there’s been a lot that’s happened in my life over the last year or so. I touched on things briefly in my post at the end of last year. Several deaths in the family (father & grandmother), some sicknesses, etc. I’ve also started one job, decide it wasn’t right for me after almost a year, and then needed to look for another job. Thankfully I managed (even with all the craziness going on in the world currently), which I started in March 2020.

We’ve also expanded our own family (again), and been dealing with all of the usual things that come with children etc.

Now, why am I mentioning all of this, and specifically, why am I mentioning it now? Well, there’s one specific reason for me doing so, and that’s to mention Alison Mulligan. Otherwise there wouldn’t really be any point in this post at all, in my opinion…

Now, for those who don’t know Alison, let me try to summarise her as best as I can in a few words.

Created by LittleArtistRo at ScottishSummit ’20

Well, to start off with Alison works in the recruitment industry. Woah…hold on. Yes, she’s a recruiter. But she’s the FIRST recruiter that I’ve come across in over a decade who has what I would consider to be proper (& correct) principles. Now I’ve dealt with many recruiters & recruitment companies over my professional career. Some are better, some are worse, and some are truly dreadful (no, I’m NOT going to mention who they are).

However, Alison absolutely & totally bucks the trend. This isn’t just my opinion, it’s the opinion of everyone who I’ve met who’s ever known Alison. See, Alison doesn’t just want to fill roles with people. Her purpose (which she’s said time & time again, in private as well as public), is to find the right role for someone. That doesn’t stop at roles that she has to offer though. For her, it’s not about the money side of things; it’s about the person being happy & fulfilled in the role that’s right for THEM. To this end, she’ll connect someone who’s looking for a job with OTHER recruiters, or people within the industry who are looking to fill a role, even if she doesn’t make anything off of it.

I started The Oops Factor series last year. I had been bouncing ideas & concepts off several people, Alison being one of them. She was highly supportive of the project, and told me that I had to have her on as one of my first guests (which of course I did!)

When I was looking for my next role at the end of 2019/beginning of 2020, she was there at the end of a phone (and occasionally in person, when possible), whenever I needed to talk. She updated me constantly on the state of the market, & opportunities that she had, as well as those that she was aware of that OTHERS had. She was there as an absolute rock, without asking for anything specific in return. When I needed a laptop to present at PowerPlatform UG London in November 2019, and I didn’t have one available, she told me to come along to her office. When I got there, she handed me one of the office ones, told me to set it up as I needed, and to use it for as long as I needed to. How many people do you know who’d do that?

When I landed a new role (which incidentally wasn’t through her), she called me up immediately to congratulate me, and spent time on the phone asking about it, how I was feeling, etc. She truly cared about what I had been going through, and was happy & celebrating with me the success in finding something.

Now that was my own personal experience, but I know that it’s not unique to me. I’m aware of others who she’s helped in the same way, and who she’s continuing to help in these critical times. I constantly recommend Alison as the first point of contact to anyone who’s going to be looking for a new role – she’s that amazing.

Things don’t stop there though. Oh no. See, Alison is also active within the (technical) community. She comes along to the User Group sessions, knows the technology, & participates. She doesn’t even just confine herself to ones that are local to her – she goes to others that aren’t as near. As a result, people know her, and get to see that she’s not just pretending in order to get clients. She loves the technology that we all love, and can hold her own (usually) in conversations!

So for most people, that would usually be enough. They’re participating, getting known within the community, etc. Alison doesn’t just do that. She also gets involved in organising & hosting.

Let me give an example of this, to provide some some context. There was a SUPER special community Lego hackathon earlier this year.

The location for it had issues at the last moment, and it was going to be cancelled. Alison heard about this, told the organisers to leave it with her for a few hours, and she’d call them back.

Within that time, she organised to host it in her office building (remember – this is at the last minute, and not an easy thing to do!). She helped get things ready, participated throughout the day, helped pack things up, and finally joined everyone for the ‘after-event’ drinks. It’s not the first time that she’s done this, and highly unlikely to be the last.

Most people who are involved in recruitment tend to be looked at cautiously (at best) by the community. Honestly, we’re tired of them turning up, trying to get people’s details, and/or entice them away from current jobs without really considering what’s best for them. It’s happened time & time again, and we don’t like it. In fact, there was an offer last year from a recruitment firm to host a community event, and it was turned down due to this.

Alison doesn’t fall into this; she’s trusted (and absolutely adored, if you want the truth) by the community. Events without her there aren’t the same , though we understand of course that it’s not always possible to commit the time/travel to attending (we all have times that this happens).

Some years ago, a community organisation that I was helping out with told me that in every community, there are one or two people without whom things wouldn’t function at all. They may not be prominent, may not be paid much (or even at all), but they’re the crucial cog & lynchpin. If they weren’t around, things would fall apart.

In my opinion, Alison is one of these crucial cogs & lynchpins. I really don’t know how the different London technical communities would manage without her input, advice & help. I consider myself blessed to know her, count her as a friend, and to chat about motorbikes whenever we’re able to!

If you don’t yet know Alison, I humbly suggest that you try to come along to one of these events (which are virtual at the moment, making it somewhat easier), and get to know her. Her Twitter is https://twitter.com/AMulligan365, and she’s on LinkedIn at https://www.linkedin.com/in/amulligan365/.

You’ll appreciate her sense of humour, her experience in life, and the joy that she also has with seeing how the technology works to make everything better.