DateTime fields, XrmToolBox, & Dynamics 365 behaviour

Recently we’ve been rapid producing & deploying solutions, due to the current pandemic. One of the apps that I’ve been working on required quite a few fields for data capture. Well, truthfully most apps require quite a few fields, but I thought that I’d talk about this one in particular, due to something that I discovered.

Now, we all know how to create fields in the Power Platform maker experience. It’s really quite simple – you select that you want to add a new field, put in the details/type of field, & save. Hey voila – you have yourself a nice new field! You can then go on to add it to forms, views, etc etc. We all know how it’s done:

What I’ve found myself doing recently though is not to create fields through the Maker interface (make.powerapps.com), especially when there are lots of fields to create. Instead, I’ve been using the XrmToolBox to do this. There’s a very helpful tool within it called Attribute Editor, which allows you to use an Excel spreadsheet. It takes this, and creates the relevant fields through the Dynamics 365 API.

One of the reasons for doing things this way was that it allows me to get on with other things whilst the fields are being created. Although it doesn’t happen in the blink of an eye (especially when there are a lot of fields to create), I can leave it whizzing along, and do something else. This, of course, makes me feel VERY productive!

Right – back to what I was saying. So I had a lot of fields to create, and many of them needed to be datetime fields. Actually, all I needed was the time component, but unfortunately Dynamics 365 DOESN’T allow you to just show the time. It’s either Date, or DateTime, but no option for JUST Time. A flaw, in my opinion, for what it’s worth….

So I created the Excel template, started the process, and went on to do something else. I of course made sure to specify that the field type should be ‘DateTime’.

Coming back to it when it had finished, I started to place fields on forms, and noticed something strange. All of the datetime fields that I had created through this were date ONLY. This was…puzzling! Going to check the fields themselves, they were set as Date ONLY, not DateTime!

I went back to check my upload spreadsheet, and it was set correctly there. I even tried uploading another field, but still the same issue was occurring.

Now, with the way that Dynamics 365/Power Platform works, once you’ve created a field & saved it, you can’t change the field type. When it’s created it’s saved down to the underlying database structure as the specified field type, and that’s it. No way to change it…or at least not through the front end!

With this in mind, I fired up another one of the XrmToolBox tools, namely Attribute Manager. What this handy tool does is, behind the scenes, allow you to change the field type. Well, it doesn’t ACTUALLY change it directly – it clones it, deletes the original, then clones it back. There are some caveats to it working properly (ie that the field isn’t used in a view somewhere, for instance), but it’s really helpful.

Note: It only works for custom created fields, not the default OOB fields!

Depending on the field type that you’re wanting to change it to, you can select different options. However for DateTime, there’s only one option. OK – I was going to see what happened.

Well, I ran the update, but nothing changed. It was still ‘Date’ only within the interface, which was really being incredibly annoying. It wasn’t as if I could just delete & recreate it (well, I could, of course). I had dozens & dozens of these to do, and quite frankly didn’t want to spend all of that time in doing this.

Thankfully (with the help of one of my colleagues, who’s an experienced & devoted developer – thanks Sid!), we found the solution.

See, I had been doing everything within the ‘new’ interface. This is the one that Microsoft keeps pushing everyone to, as they don’t want people to really be using the Classic Interface anymore. That’s all very well & good, but the ‘new’ interface isn’t on parity (for some things).

Reverting back to the Classic interface (note that the option below is only available when working within a solution!), we discovered some hidden behaviour

We located the entity that we needed, and the field itself, and opened it in Classic. With the screen that’s presented (I do miss this in some ways – I remember the days where I almost lived permanently in here!) we AMAZINGLY have the following option:

We can CHANGE THE TYPE!! Now, this is just with the field that we’ve selected. To be frank, I have no idea at this point about any other field types, and would need to explore that separately. But for the moment, my problem has been solved! (well, to the point that I have ‘time’ values available – I’d still like to see JUST time values being an option).

So with this in mind, I merrily waded through the dozens of fields in the Classic UI, changing them all as needed. It wasn’t just a few minutes of work, but it was definitely much less time that deleting & manually creating each one!

So, really quite helpful. The only other thoughts that I had around things were that it would be nice if the various tools within the XrmToolBox could do this as well. However, the fact that they don’t seem able to actually seems to be a limitation of the API. Having gone to check the different field types & how they’re set programmatically (https://docs.microsoft.com/en-us/powerapps/maker/common-data-service/types-of-fields), I’ve noticed the following:

There really doesn’t seem to be any way to specify the different sub-type, which is a shame!

Have you ever had a similar situation with fields? Drop a comment below- I’d love to hear about it.

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!

Introductory Training for Dynamics 365/Power Platform

This post really goes back to basics, but it’s one of basic fundamentals for any successful project. In order to lay a proper foundation base, and to ensure success for a project, users need to actually know how to use the system! When going into greenfield (new) implementations, or expanding brownfield (existing) implementations, users need to know how the system works. For new implementations, it’s highly likely that many users, if not all, will never have actually used Dynamics 365 before! Going into a completely new system, with no understanding of how it works, can be extremely daunting. If not handled in the right way, and the right skills imparted, it can be a major blocker to the project itself.

Incidentally Microsoft Learn has closed the gap slightly on this. The different learning paths & courses can be really helpful to gain understanding of the system, and the basic components. I’ve done quite a few of these (the gamification angle helps with that!), and am generally quite impressed!

So with all of that in mind, I thought I’d share something. Over the last few years, I’ve noted the D365 Academy Belt Program (https://www.d365ug.com/participate/academy/blackbelt). It’s something that I’ve toyed with doing, but never got round to it.

I’ve recently had the opportunity to look over the actual material that’s used for the different belt courses. Not only have I looked over it, I’ve actually gone through all of the different belt training as well, to see how it actually is. Even with my knowledge & experience of the system, I’ve still learned/improved my knowledge in several things. I think it’s a really good structured learning system, and furthermore, actually shows clients how to become system ‘power users’!

I’ve listed below the different belts, and what’s included in each one

White Belt

  • Creating a trial – how to sign up & set one up
  • Overview of users – what they are
  • Office 365 vs Dynamics 365. The differenced in how they work when it comes to users
  • User maintenance – setting up users & teams, and handling licenses
  • System settings – how to set organisation-wide defaults
  • The basics of workflow – what a workflow is, and what it does
  • Form configuration – what is a form, modifying fields properties to display accordingly
  • Creating new fields – different field types & options
  • View configuration – creating, adding columns & filter criteria to display the data

Blue Belt

  • Security concepts – overview of how security works in Dynamics 365
  • Business Units – what they actually are, and how they help with things
  • Security Role Concepts – how they’re used, and the power that they bring to the security model
  • Security Role Applications – how to set them up, and showing practical uses with examples
  • Hierarchy Security Concepts – what exactly is a security hierarchy, and why it can be helpful
  • Hierarchy Security Application – how to set this up, and use within the system
  • Ownership Teams – why this can be helpful when using records
  • Access Teams – how are these different from the other teams, and how they can be used
  • Auditing – how Dynamics 365 has an in-built audit trail for records, and the benefits of it

Purple Belt

  • Advanced Form Configuration -sub grids, charts, navigation links & iframes
  • Creating Custom Entities – building on the knowledge of the system so far to implement these
  • Calculated & Roll Up Fields – what these are, the differences, & where to use them best.
  • Field Level Security – ways to restrict specific data fields on entities to a specific team of users
  • Charts, Dashboards & Reports – how to set these up, and the different ways in which they help
  • Document Generation – how to automatically create Word & Excel documents from templates
  • Business Rules – ‘no code’ approach to making fields required, hiding them, setting values
  • Business Process Flows – guiding users to enter data in a specific way, with making it easier
  • Branding – making your site reflect your company colours & logo
  • Site Map Editor – placing just those entities that users access to create a clean interface

Brown Belt

  • Duplicate Detection Overview – what it is, and how it works
  • Duplicate Detection Configuration – how to set up rules to enable it to work in the right way
  • Data Imports – how to configure & set them up to then import data into the system
  • Data Mapping – the key item in data imports. Getting this right is imperative
  • Bulk Deletion – carrying it out, and what to be careful of
  • Cascading Relationships – how these can be so powerful, & where to use them best
  • Data Integration – best practise thinking in how to approach integration

Black Belt

  • Workflows – what are they, understanding how they work
  • Realtime & Background – the differences between these two, and how you should use each one
  • Power Automate – how it differs from traditional workflow, & how to start configuring one
  • Document Storage – the different options available, including cost considerations.
  • Extending with 3rd Party Tools – using tools available in the XrmToolBox, and how this can help
  • Power Apps Introduction – what these are, and scenarios for them
  • Model/Canvas Apps – the differences between the two, and considerations for each

I’ve been working with Dynamics 365 for a decade now, yet there were still things that I felt I learned from the course. I feel that it’s possible to learn from everything, even from what we’d consider to be a ‘simple’ source.

So what are the next steps for people looking to learn? Well, Microsoft Learn (https://docs.microsoft.com/en-gb/learn/) of course would be a great place. Carrying on from there, you could look to start taking some of the available exams. There are plenty of these available, ranging from basic fundamentals all the way up to solution architect.

I hope that this has been useful to you – if you’ve come across other great introductory training resources, please let me know!

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.

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!

Farewell to the Outlook Add-In

From the first time that I used Microsoft Dynamics CRM (all the way back in the day), I remember the Outlook add-in. Or rather, I should say that I remember the PAIN that the Outlook add-in was!

You remember what I’m talking about, I hope. Here’s a screenshot of the ‘fabled’ toolbar:

The installation of this was a nightmare, to be honest. From the pre-requisites that it needed to install (and download – even if the machine already had them installed), to just hanging there, it wasn’t ever something that I looked forward to putting on machines.

It was a memory hog, slowed performance, and occasionally crashed Outlook, seemingly just because it felt like it! In addition, trying to carry out a mass roll-out of it (through SCCM, or Group Policy, or even other methods) never seemed to work properly at all.

In one of my roles we had to install this for dozens of users. Randomly, even on brand new machines (with nothing else installed), it would fail to install or initialise. Long hours were spent poring through logs, trying to work out error messages, and frantically get it working. Users were VERY used to seeing the following error happen:

In short, it’s been around for a VERY long time, as the following diagram shows (I’m loving how they compress 12 years into just a short space):

In late 2017, Microsoft announced that they were going to deprecate the Outlook add-in. There were several other options around, such as proper server-side sync, and the Dynamics 365 app for users. These were supposed to be being used instead.

The response from clients was crazy – so crazy in fact, that Microsoft did something that it very rarely does. They reversed the decision to deprecate it, and instead confirmed that it would still be sticking around. They realised that the other options weren’t at parity with the Outlook add-in for desktop, and didn’t want to deprive users of the essential functionality that they were needing.

In 2018, I was at Summit EMEA in Dublin. One of the more interesting conversations that I had with one of the senior Microsoft people was around the Outlook add-in. They told me that from the moment that Microsoft had announced that it was deprecated, every client had asked them about it. Even to non-technical people (eg sales, etc). It was due to this, in part, that they decided to un-deprecate it!

Moving on several years, the landscape has now matured. A lot of users are using Outlook through browsers, rather than the desktop version. They natively plug-into Dynamics 365 through the web as well. The Dynamics 365 App for Outlook has gotten better, along with the way that it works:

Users, on the whole, seem to have generally adopted the latest technology, and have therefore moved on from relying on the Outlook add-in for desktop. There’s also the new Unified Interface, which the Outlook add-in doesn’t support (and which will be being rolled out to all users on Dynamics 365 during 2020!).

Microsoft has therefore announced that as of March 2020 (which has just passed), the Outlook add-in has now been deprecated (once again). Support, security & other critical updates will be continue to be provided until October 1st 202, but customers will need to transition to the Dynamics 365 App for Outlook by then.

Very nicely, they’ve provided a playbook (which can be found at https://aka.ms/OutlookCOMPlaybook). This details the upgrade path, and has some good information in it for customers who will need to upgrade from it.

So if you’re still on the old version, take a look now, and work out the best way for you & your organisation to upgrade. It’ll give you newer & better functionality, work easier, and above all, shouldn’t crash your machine!

Let me know in the comments if you have any questions around this, and I’ll do my best to help you out.

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).