CRM 2013 has a handy new feature for displaying activities, notes, and posts in a single control. This is very easy to configure by just selecting the "Notes" control in the form designer.
You can subsequently also define the default view for this control in the properties. As an aside, it's also recommended to uncheck the "Display label on the form" check box as it will display better without this.
So far so good. Except for one small wrinkle - the "Activities" and "Posts" tabs for this control do not show...
I found a solution to this issue which is outlined in this blog post. Although it does appear to be an issue even for forms that have already been "upgraded". Case in point - the form that I was working with was a new form created in CRM 2013 for an existing entity and the issue still appeared.
Anyway, as described in that post, the issue is fixed by modifying FormPresentation node for the form in question from 0 to 1.
After importing and publishing, the 3 tabs for this control display as expected.
The intention of this blog is to focus on the business application of Microsoft CRM and its surrounding ecosystem. In doing so, whenever discussing a topic I will endeavor to avoid presenting dry facts but rather to relate it to the practical application and/or impact it might have on the business, the pros, cons, best practices etc. The correct way of thinking is paramount when confronting a business challenge and this is what I hope to bring to the table.
Monday, December 30, 2013
Friday, December 27, 2013
CRM Manipulation Library Date Calculation Issue
Speaking of the CRM Manipulation Library solution, I encountered an issue with the date calculation logic. Specifically with regards to the somewhat misleadingly named "Add Days" function. Misleading in that if you look at the function, you will notice that in addition to the capability of adding days, you can also use this to add years, months, weeks, hours and minutes to a given date.
This is an important clarification as adding a month to date is not always going to be the same as adding 30 days to a date. Similarly for years (as in the case of a leap year). And obviously being able to specify the more granular hour and minute parameters is also helpful. We probably could have worked around not having the week parameter but it does make life a little easier by not having to perform additional calculations.
Anyway, the issue that I encountered is that ironically if you do not specify a non-zero "Days To Add" value and just supply one of the other parameters, the calculation will not work. That is, if we were to specify parameters in the screenshot above (where we're trying to add years to the date) it would not work.
Luckily there is a simple workaround solution. Below is the same function call except we trick it by subtracting a day value and then cancel it out by passing in the equivalent days in the week parameter.
If you needed to use the week parameter, then you could similarly pass in 24 hours and cancel it out by passing -1 to the day parameter.
Anyway, the issue that I encountered is that ironically if you do not specify a non-zero "Days To Add" value and just supply one of the other parameters, the calculation will not work. That is, if we were to specify parameters in the screenshot above (where we're trying to add years to the date) it would not work.
Luckily there is a simple workaround solution. Below is the same function call except we trick it by subtracting a day value and then cancel it out by passing in the equivalent days in the week parameter.
If you needed to use the week parameter, then you could similarly pass in 24 hours and cancel it out by passing -1 to the day parameter.
Thursday, December 26, 2013
Workflow Plugin CRM Online Compatibility
There are a lot of useful free add-ons available for Dynamics CRM that can add some serious customization features. The issue in many cases is that these add-ons were only released for the on-premise version of CRM.
For example, take the very useful CRM Manipulation Library which contain some important calculation capabilities. I especially find the Date Utilities to come in handy as there is often a requirement to calculate an off-set of days or business days as part of workflow logic. But when you try import the solution into a CRM Online instance you will receive an error that looks something like the following:
The good news is that this can be made compatible with CRM Online by following these steps:
Once you have done so you should be able to import it into CRM Online. Applying this trick does not necessarily mean that the plugin will work as it might fail on something when trying to execute. However it also just may function without a problem which is indeed the case with the CRM Manipulation Library. So it's definitely worth a shot. If your plugin does not work after performing this tweak, you'll have to do some debugging at the code level.
For example, take the very useful CRM Manipulation Library which contain some important calculation capabilities. I especially find the Date Utilities to come in handy as there is often a requirement to calculate an off-set of days or business days as part of workflow logic. But when you try import the solution into a CRM Online instance you will receive an error that looks something like the following:
The good news is that this can be made compatible with CRM Online by following these steps:
- Unzip the solution into a folder
- Open the customizations.xml file
- Perform a search for the IsolationMode node
- Change IsolationMode value from 1 to 2
- Update the original zip file with the modified file
Once you have done so you should be able to import it into CRM Online. Applying this trick does not necessarily mean that the plugin will work as it might fail on something when trying to execute. However it also just may function without a problem which is indeed the case with the CRM Manipulation Library. So it's definitely worth a shot. If your plugin does not work after performing this tweak, you'll have to do some debugging at the code level.
Tuesday, December 24, 2013
CRM 2013 Form Design Guideline
This post is a work in progress and is far from being a definitive stance. Rather it is somewhat exploratory/tentative/philosophical based on experimentation using the CRM 2013 form designer. It may well be tweaked over time based on additional findings, user feedback etc.
In previous versions of CRM, the "default" design for forms was pretty straight forward. That is, when configuring a form, you could feel fairly "safe" in terms of selecting the "tab with one section and two columns" design option in terms of your starting point.
Sure on occasion when you knew you were adding lots of check box controls you might elect a 3 or 4 column section or conversely a 1-column section for a sub-grid. But the point is that you felt fairly certain you couldn't go too wrong in picking the "tab with one section and two columns" option in terms of how the form would render i.e. you were pretty certain that all fields would be easily visible and if the form was lengthy, you could easily add new tabs to simplify form navigation.
Maybe it's just me but I'm finding that I'm struggling a little bit more with the CRM 2013 forms. Suddenly we have a whole lot more form real estate to work with such that forms that used the previous "tab with one section and two columns" standard layout (2011, 4.0, 3.0, 1.2) , look rather sparse when viewing in CRM 2013. For example take a look at the upgraded contact form in 2013.
This is not helped by the fact that Microsoft has essentially eliminated the tab "jump" navigation option such that you have a lot of "scroll and hunt" in upgraded forms. As an aside, I personally don't know if eliminating the tab navigation is a long term decision - it seems to me that this could easily have been incorporated without compromising the look and feel of the 2013 form layout (e.g. by having a drop down where the general tab is showing or just having the tab names going from right to left at the top of the page). In contrast, they have indeed enabled a jump menu which enables navigating to different forms, so perhaps the long term design objective is to break up long forms into multiple mini-forms. Not quite sure at this point. But for now, I have to say that the lack of incorporating this tab navigation "bridge" to aid in navigation for forms upgraded from previous versions of CRM eludes me.
Anyway, the point of this post is essentially to be able to define a new "default" for CRM 2013 forms. There are definitely a lot more form design options - a simple comparison between the 2011 and 2013 forms illustrates this. We jump from having 2 tabs options to 6 tab options - this increases the form design options exponentially.
And while there are benefits to having more options there are also downsides to having so many choices. And correspondingly I've been finding that I've tended to vacillate a lot more than I did when working with previous versions of CRM. And so I've been looking for guidance as to how to go about thinking about form design in CRM 2013. But the most I've found is the following diagram which is Microsoft's take on form ergonomics.
And while this is helpful, it doesn't really address the overall issue described above. Therefore the objective of this exercise is to essentially take a stance on "default" form designs. That is, just as with previous versions of CRM, I'd like to have a fallback design that I can feel confident in taking based on the "you can't go too wrong" starting point premise. And when you reduce the requirement down, I think you come to the following basic guidelines:
We can also take a look at how Microsoft designed the core entity forms - account, contact, lead, opportunity - to hopefully draw some inspiration (as presumably they also took into account the above considerations).
When all is said and done, I will tentatively be employing the following "default" form design strategy:
That's pretty much it. This more or less throws out the "tab with one section and two columns" which was the staple of previous versions of CRM - it just looks way too sparse in CRM 2013. In fact, as a general guideline it throws out having any section with more than one column (all the examples shown above have tabs with multiple sections, not sections with multiple columns - a tad confusing). As if you do add additional columns to the sections shown above, then you're bound to run into issues with fields being cut off when the actual form renders.
When you boil it down, it means that I will be limiting myself to the 3 form options below when designing the initial CRM form (using the 3 points mentioned above as a general guideline to determine when to use each option).
... with perhaps a few exceptions here and there for very specific requirements. And then of course, forms can subsequently always be tweaked using one of the other myriad options based on user feedback.
As I mentioned at the outset - somewhat philosophical - but this guideline helps me take quick and clinical decisions in terms of form design that I can confidently feel will will function as a very good starting point.
In previous versions of CRM, the "default" design for forms was pretty straight forward. That is, when configuring a form, you could feel fairly "safe" in terms of selecting the "tab with one section and two columns" design option in terms of your starting point.
Maybe it's just me but I'm finding that I'm struggling a little bit more with the CRM 2013 forms. Suddenly we have a whole lot more form real estate to work with such that forms that used the previous "tab with one section and two columns" standard layout (2011, 4.0, 3.0, 1.2) , look rather sparse when viewing in CRM 2013. For example take a look at the upgraded contact form in 2013.
This is not helped by the fact that Microsoft has essentially eliminated the tab "jump" navigation option such that you have a lot of "scroll and hunt" in upgraded forms. As an aside, I personally don't know if eliminating the tab navigation is a long term decision - it seems to me that this could easily have been incorporated without compromising the look and feel of the 2013 form layout (e.g. by having a drop down where the general tab is showing or just having the tab names going from right to left at the top of the page). In contrast, they have indeed enabled a jump menu which enables navigating to different forms, so perhaps the long term design objective is to break up long forms into multiple mini-forms. Not quite sure at this point. But for now, I have to say that the lack of incorporating this tab navigation "bridge" to aid in navigation for forms upgraded from previous versions of CRM eludes me.
Anyway, the point of this post is essentially to be able to define a new "default" for CRM 2013 forms. There are definitely a lot more form design options - a simple comparison between the 2011 and 2013 forms illustrates this. We jump from having 2 tabs options to 6 tab options - this increases the form design options exponentially.
And while there are benefits to having more options there are also downsides to having so many choices. And correspondingly I've been finding that I've tended to vacillate a lot more than I did when working with previous versions of CRM. And so I've been looking for guidance as to how to go about thinking about form design in CRM 2013. But the most I've found is the following diagram which is Microsoft's take on form ergonomics.
And while this is helpful, it doesn't really address the overall issue described above. Therefore the objective of this exercise is to essentially take a stance on "default" form designs. That is, just as with previous versions of CRM, I'd like to have a fallback design that I can feel confident in taking based on the "you can't go too wrong" starting point premise. And when you reduce the requirement down, I think you come to the following basic guidelines:
- The form should not look too sparse with all the new form real estate i.e. take advantage of the new space that is available on the form such that the need for scrolling down is greatly reduced.
- Bring sub-grids that will be commonly accessed to the body of the form so that most of what the user will need will be right in front of them (I'll refer to these as "prominent" sub-grids).
- Consider the laptop/tablet experience where monitors are smaller - some things that fit nicely on your maximized form on your desktop monitor will be cut off on these somewhat smaller screen resolution sizes.
We can also take a look at how Microsoft designed the core entity forms - account, contact, lead, opportunity - to hopefully draw some inspiration (as presumably they also took into account the above considerations).
When all is said and done, I will tentatively be employing the following "default" form design strategy:
- Any form where notes/activities is something that is relevant/tracked - I'll follow the guideline that Microsoft has used which is the "3-Column Varied Width" for the first form tab with the notes/activities in the central column using the new activity, notes and post control. This doesn't leave a generous amount of space for the other "prominent" sub-grids which we'll place in the third column but we'll live with that.
- Any form that doesn't have notes/activities but has other prominent sub-grids - I'll be employing the "2-Column Varied Width" for the first form tab. The right column will be for the prominent sub-grids with a more generous allocation of space.
- Any other form sections that are just a listing of fields - I'll be employing the "3-Column Equal Width" tab option.
That's pretty much it. This more or less throws out the "tab with one section and two columns" which was the staple of previous versions of CRM - it just looks way too sparse in CRM 2013. In fact, as a general guideline it throws out having any section with more than one column (all the examples shown above have tabs with multiple sections, not sections with multiple columns - a tad confusing). As if you do add additional columns to the sections shown above, then you're bound to run into issues with fields being cut off when the actual form renders.
When you boil it down, it means that I will be limiting myself to the 3 form options below when designing the initial CRM form (using the 3 points mentioned above as a general guideline to determine when to use each option).
As I mentioned at the outset - somewhat philosophical - but this guideline helps me take quick and clinical decisions in terms of form design that I can confidently feel will will function as a very good starting point.
Monday, December 23, 2013
CRM 2013 Option Set Length
There are a few, let's say, particularities of the CRM 2013 UI experience. Some of them take getting a little getting used to such as the new way of navigating the system whereas others seem likely to be early release features that are destined to be "tweaked" in early product rollup releases... at least one would hope so!
A good example of this is the length of the drop down for option sets. Take for example, the following form:
As can be seen the drop down for the title is only showing two options at a time. Considering that there are at least 20 values in this option set, this experience is not likely to go down well with end users... and nor should it.
The way to get round this design issue is to add some spacers into the form as follows:
And after publishing, the form renders in a little bit more of a presentable fashion:
The downside is that when the option set is not in its drop down state there's a lot of unnecessary white space on the form.
A good example of this is the length of the drop down for option sets. Take for example, the following form:
As can be seen the drop down for the title is only showing two options at a time. Considering that there are at least 20 values in this option set, this experience is not likely to go down well with end users... and nor should it.
The way to get round this design issue is to add some spacers into the form as follows:
And after publishing, the form renders in a little bit more of a presentable fashion:
The downside is that when the option set is not in its drop down state there's a lot of unnecessary white space on the form.
So we have a workaround to this behavior but I find it to difficult to understand why it was designed in this way (maybe someone can enlighten me?). The way it worked in all previous versions seems much better and hopefully this will be rectified shortly (at which point we'll likely have to go through all those forms and remove the spacers which were added as a workaround - so hopefully sooner rather than later).
Thursday, December 19, 2013
Send email with PDF attachment
Frequently there is a need to send out an email from CRM containing a generated PDF attachment. the following approach can be used to allow an end user to manually initiate the process using the click of a button via the user interface.
But what if we wanted this to happen automatically rather than relying on the user to manually execute the action? From my experience this is by far a more common scenario. A good example might be auto-generating an invoice and then emailing it to a customer once an invoice has been approved. Another one might be to generate a quote and have it sent off once the quote has been approved. The natural solution that we can look to in such a scenario would be to leverage the CRM workflow capability.
The first step would be to design some kind of report that would be used as the template for generating the PDF document. Once this is in place we can leverage the technique outlined in my previous post for publishing the report externally and making it context sensitive which is a key requirement.
This allows us to design a workflow where we can construct a URL that will produce a report for the record in question. For example, we can design a workflow as follows:
Finally, you can also pass in the same URL and use the technique mentioned in this post to convert the report to a PDF and send as an attachment via email.
Note: Make sure that the service account under which the the asyncronous service is running has access to the SSRS report folder containing the externally published CRM report.
But what if we wanted this to happen automatically rather than relying on the user to manually execute the action? From my experience this is by far a more common scenario. A good example might be auto-generating an invoice and then emailing it to a customer once an invoice has been approved. Another one might be to generate a quote and have it sent off once the quote has been approved. The natural solution that we can look to in such a scenario would be to leverage the CRM workflow capability.
The first step would be to design some kind of report that would be used as the template for generating the PDF document. Once this is in place we can leverage the technique outlined in my previous post for publishing the report externally and making it context sensitive which is a key requirement.
This allows us to design a workflow where we can construct a URL that will produce a report for the record in question. For example, we can design a workflow as follows:
- Generate GUID for the record against which the workflow is running (using the workflow productivity tools)
- Create the URL passing in the GUID generated above as a dynamic parameter i.e. http://crm2011db01/ReportServer/Pages/ReportViewer.aspx?%2fCRMEZE2011TEST_MSCRM%2fUser+Summary&CRM_FilteredSystemUser=select [systemuser0].* from FilteredSystemUser as systemuser0 where (systemuser0.systemuserid = N'%7B{0}%7D')&rs:Command=Render [%7B and %7D are decodes for the { and }. And {0} is the parameter to be replaced by Param 1]
- Send email using the link generated above
Finally, you can also pass in the same URL and use the technique mentioned in this post to convert the report to a PDF and send as an attachment via email.
Note: Make sure that the service account under which the the asyncronous service is running has access to the SSRS report folder containing the externally published CRM report.
Wednesday, December 18, 2013
Publish External Reports - Dynamic Content
Time to complete what I started... So in my last post we walked through the steps to make an externally published report accessible to non-CRM users which would seem to be the objective of the whole publishing externally exercise as documented in the introduction to this topic.
However by following those steps we are limited to a fairly static report based on the report parameters of the originally published report. This is going to be of limited benefit. For example, consider the scenario where I want to include a link via an email to a non-CRM user that would allow them to view data from within CRM - for instance - we might want to send them a report on an opportunity whereby clicking on the link they are able to view the opportunity details. Well, unless we're able to pass in parameters to this published report we will be prevented from doing so i.e. it will lack the necessary context sensitivity.
In order to overcome this limitation we'll be manipulating the CRMFilteredEntity report parameter mentioned in my previous post. We'll continue using the example of the User Summary report for the sake of illustration.
The first thing to do is to navigate to the report using the Report Server navigation i.e.:
Now click on your externally published report (in our case "User Summary") and retrieve the execution URL i.e. http://crm2011/ReportServer/Pages/ReportViewer.aspx?%2fCRM_MSCRM%2fUser+Summary&rs:Command=Render and you should be presented with something that looks like this:
Now take the URL and carefully graft on the value from the CRMFilteredEntity parameter (provided in my previous post). That is, your URL should now include the CRM_FilteredSystemUser parameter and look something like the following:
http://crm2011/ReportServer/Pages/ReportViewer.aspx?%2fCRM_MSCRM%2fUser+Summary&CRM_FilteredSystemUser=select [systemuser0].* from FilteredSystemUser as "systemuser0" where ("systemuser0".systemuserid = N'{43AF6573-C97C-E011-9556-00155DA5304E}')&rs:Command=Render
And voila - your report will now render the User Summary report only returning the corresponding user specified by the report parameter.
Also test with a non-CRM user to ensure that this is working outside of CRM authentication.
This exercise proves that we can now manipulate the URL of this report to pass in parameters to the report. Essentially all you need to do is to update the query specified in the CRM_FilteredEntity parameter and this will filter the results of the report. Of course the same approach can be applied to any other report in the system. For example, if we were working with an account report we'd manipulate the query for the CRM_FilteredAccount parameter; if we were working an opportunity report we'd manipulate the query for the CRM_FilteredOpportunity parameter. And so on and so forth.
Now of course this result doesn't lend itself very well to specifying report parameters manually - your users would lynch you if you tried proposing this to them! But it does lend itself quite well to automated mechanisms such as via workflow whereby you can construct a URL using dynamic workflow fields resulting in a report URL in an email that a user just has to click on in order to see the relevant, context-sensitive, dynamic report content.
In the next post we'll take a look at performing those steps as well as seeing how this approach can also be leveraged to generate PDF documents that can be sent to external users or customers.
However by following those steps we are limited to a fairly static report based on the report parameters of the originally published report. This is going to be of limited benefit. For example, consider the scenario where I want to include a link via an email to a non-CRM user that would allow them to view data from within CRM - for instance - we might want to send them a report on an opportunity whereby clicking on the link they are able to view the opportunity details. Well, unless we're able to pass in parameters to this published report we will be prevented from doing so i.e. it will lack the necessary context sensitivity.
In order to overcome this limitation we'll be manipulating the CRMFilteredEntity report parameter mentioned in my previous post. We'll continue using the example of the User Summary report for the sake of illustration.
The first thing to do is to navigate to the report using the Report Server navigation i.e.:
Now click on your externally published report (in our case "User Summary") and retrieve the execution URL i.e. http://crm2011/ReportServer/Pages/ReportViewer.aspx?%2fCRM_MSCRM%2fUser+Summary&rs:Command=Render and you should be presented with something that looks like this:
Now take the URL and carefully graft on the value from the CRMFilteredEntity parameter (provided in my previous post). That is, your URL should now include the CRM_FilteredSystemUser parameter and look something like the following:
http://crm2011/ReportServer/Pages/ReportViewer.aspx?%2fCRM_MSCRM%2fUser+Summary&CRM_FilteredSystemUser=select [systemuser0].* from FilteredSystemUser as "systemuser0" where ("systemuser0".systemuserid = N'{43AF6573-C97C-E011-9556-00155DA5304E}')&rs:Command=Render
And voila - your report will now render the User Summary report only returning the corresponding user specified by the report parameter.
Also test with a non-CRM user to ensure that this is working outside of CRM authentication.
This exercise proves that we can now manipulate the URL of this report to pass in parameters to the report. Essentially all you need to do is to update the query specified in the CRM_FilteredEntity parameter and this will filter the results of the report. Of course the same approach can be applied to any other report in the system. For example, if we were working with an account report we'd manipulate the query for the CRM_FilteredAccount parameter; if we were working an opportunity report we'd manipulate the query for the CRM_FilteredOpportunity parameter. And so on and so forth.
Now of course this result doesn't lend itself very well to specifying report parameters manually - your users would lynch you if you tried proposing this to them! But it does lend itself quite well to automated mechanisms such as via workflow whereby you can construct a URL using dynamic workflow fields resulting in a report URL in an email that a user just has to click on in order to see the relevant, context-sensitive, dynamic report content.
In the next post we'll take a look at performing those steps as well as seeing how this approach can also be leveraged to generate PDF documents that can be sent to external users or customers.
Tuesday, December 17, 2013
CRM 2013 Report Error: "An error has occurred. Try this action again..."
We were getting an odd error when running a CRM report in an environment that had been upgraded from CRM 2011 Online to CRM 2013 Online.
In short, we were getting the following rather unhelpful generic error message:
This error only occurred with a few of the records but ran fine for other records. In order to troubleshoot, I removed all the front end components of the report so that essentially the report would just have a blank rendering. And even after doing this, the report still gave up the error above.
So this seemed to point to the fact that there was some issue with the data set...
As it happened this data set had a link-entity join clause and I discovered that when you added in the linked record such that the join would succeed the report would run fine. And in cases where the join did not bring back results the report error would occur - this being our particular case.
So this explained why it occurred only for certain records whereas not for other records in the system. However it does not explain why this error occurs in the first place. At the most I would expect the report to not render results when a join does not bring back results. After all in many cases it is perfectly valid to have a join that does not succeed. Even if there was an error caused by the lack of the join, I would expect to see this error manifesting itself in the returned report as is the case for example when running a report where the sub-report it is calling does not exist.
All in all, while I'm glad I discovered the issue, this does seem very much like a bug in the platform to me.
In short, we were getting the following rather unhelpful generic error message:
This error only occurred with a few of the records but ran fine for other records. In order to troubleshoot, I removed all the front end components of the report so that essentially the report would just have a blank rendering. And even after doing this, the report still gave up the error above.
So this seemed to point to the fact that there was some issue with the data set...
As it happened this data set had a link-entity join clause and I discovered that when you added in the linked record such that the join would succeed the report would run fine. And in cases where the join did not bring back results the report error would occur - this being our particular case.
So this explained why it occurred only for certain records whereas not for other records in the system. However it does not explain why this error occurs in the first place. At the most I would expect the report to not render results when a join does not bring back results. After all in many cases it is perfectly valid to have a join that does not succeed. Even if there was an error caused by the lack of the join, I would expect to see this error manifesting itself in the returned report as is the case for example when running a report where the sub-report it is calling does not exist.
All in all, while I'm glad I discovered the issue, this does seem very much like a bug in the platform to me.
Subscribe to:
Posts (Atom)