Thursday, February 23, 2012

Display Full-Screen Dashboards with Auto-Refresh in CRM 2011

CRM dashboards are great visualizations of what’s going on in the business. Sometimes we would just want to have a huge plasma screen displaying specific dashboards and refreshing the data automatically and regularly. This post will show you how simple that is!

When you want to permanently display a dashboard in a screen, these are the usual requirements:
  • Strip down the dashboard to exclude ribbon, navigation menu, etc.
  • Automatically refresh the page every X minutes
The solution is to create an HTML web resource which will embed the stripped-down dashboard in a new HTML page with refreshes automatically. These are the steps to do so:


1. Identify the dashboard you want to display on a screen
Click on the arrow to the right of “Dashboards” on the sitemap, then right click on the dashboard you select and click “Copy a Link” (and allow access to clipboard)

image

When you paste the link, it will look something like this: Customer Service Performance Dashboard <https://avanade45.crm.dynamics.com/workplace/home_dashboards.aspx?dashboardId=%7b2e3d0841-fa6d-df11-986c-00155d2e3002%7d&dashboardType=1030&sitemappath=Workplace%7cMyWork%7cnav_dashboards>
You need to copy the URL (in blue for the example above).



2. Create your HTML Web Resource to host the dashboard
Create a new web resource in your solution as follows
image



3. Edit the HTML to embed your dashboard and auto-refresh
Click on the “Text Editor” button and then click on the “Source” tab to enter your HTML code. This is the HTML I used:

<HTML>
  <HEAD>
    <TITLE>Customer Service Performance Dashboard</TITLE>
    <META content="300" http-equiv="REFRESH">
      <META charset="utf-8">
  </HEAD>
  <FRAMESET contentEditable="true" frameSpacing="0" border="0" frameBorder="0" rows=""*>
    <FRAME noResize="" src="/workplace/home_dashboards.aspx?dashboardId=%7b2e3d0841-fa6d-df11-986c-00155d2e3002%7d&dashboardType=1030&sitemappath=Workplace%7cMyWork%7cnav_dashboards" name="top" scrolling="no">
  </FRAMESET>
</HTML>


The highlighted values are the refresh rate (in seconds) and the relative URL to your dashboard (taken from step 1). Note that the relative URL above works for CRM Online, but for OnPremise you might need to modify the path slightly.
The HTML above is basically an embedded frame to your dashboard with a META tag to refresh the content every 300 seconds (5 minutes). It should work on most (or all) browser versions supported by MSCRM.



4. Navigate to your dashboard and make it full-screen.
There is a URL link from the web resource which you can click to navigate to your dashboard:

image

Now to make it full screen you need to hit F11 in your keyboard, and voila! This is all you will see on the screen:

image

Note that there is a dropdown control to update the dashboard; however, if you update the dashboard here, each time your window refreshes it will revert back to the original dashboard. So you might need to follow these steps for each dashboard that you want to display on a screen and never change the dashboard from the dropdown menu. Now you can also bookmark these URLs so you can directly access your dashboard screen anytime. Note that the same authentication as to access CRM will be required to access these HTML pages.

Monday, February 13, 2012

Duplicate Detection in CRM 2011

The Duplicate Detection feature has improved considerably since CRM 4.0 but it is often not given much attention. I would like to highlight in this post what has improved in Duplicate Detection, how to use it and what is still missing (areas of improvement for future releases).

Synchronous MatchCode Generation
MatchCodes allow the CRM platform to detect duplicates in the create/update operations. In CRM 4.0 the MatchCode generation was implemented asynchronously with a recurring system job which would generate the MatchCodes. The implication of that process is that if you create a record and then create a new duplicate record within a few seconds, the platform would not detect the duplicate because the MatchCode was not yet generated. This blog post talks about how to work around this limitation by making use of the PersistInSyncOptionalParameter; however, when creating/updating a record through the UI, the parameter was not enabled by default so you would need to write code to force the MatchCode generation in a synchronous manner. In CRM 2011 the PersistInSyncOptionalParameter (or CalculateMatchCodeSynchronously) parameters no longer apply because MatchCode generation is always done synchronously. What this means is that regardless of how fast you are creating one record after the other (and theoretically how many threads you have), the CRM platform will always be able to detect immediately if you are creating a duplicate. The fact that you can rely on the Duplicate Detection Engine to capture all your duplicates without having to consider any time variable is a huge relief in my opinion.

Different Way to Specify Whether to Run Duplicate Detection on Record Create/Update
Not much has changed here except perhaps the syntax. By default, when you execute a create or an update request against the CRM Web Service, the record will be created/updated without checking for duplicates. If you want to override this behaviour so that you force the platform to check for duplicates you would need to set the SuppressDuplicateDetection optional parameter to “false”. Not specifying this optional parameter has the same effect as if you would set it to “true” (bypasses duplicate detection):
CreateRequest req = new CreateRequest();
Account acc = new Account()
{
    Name = name,
};
req.Target = acc;
req.Parameters["SuppressDuplicateDetection"] = false;

try
{
    service.Execute(req);
}
catch (FaultException<OrganizationServiceFault> ex)
{
    if (ex.Detail.ErrorCode == -2147220685)
    {
        // duplicate detected: Handle it here
    }
    else
    {
        throw;
    }
}


Enhanced Duplicate Detection Processing (UR5+)
With the release of UR5, there have been some other improvements to Duplicate Detection:
  1. You can specify in a rule whether or not duplicate detection should consider two null (blank) values as identical
  2. You can select to detect duplicates only from active records, this can be useful to improve performance.
    What is Still Missing?
    In my opinion, the most fundamental feature that Duplicate Detection still lacks is the ability to package duplicate detection rules as part of a solution. It is quite painful to have to replicate the rules in all environments an having to do it directly in production can be scary, some rules are quite complex and error prone. I hope Microsoft has plans for improving their solution framework in the future to include “solutionizing” duplicate detection rules!

    Monday, February 6, 2012

    How to Prevent Broken Workflow References in CRM 2011

    You might have noticed a very annoying behaviour when you promote processes (workflows or dialogs) across environments and many references in the workflow definition get broken because of the differences in the environment.

    For example, assume you have a workflow that assigns an account to the Sales Team on certain conditions. Your assign step will look like this in your development environment:
    image

    Now you include your workflow in a solution and promote to a Test (or any other) environment. Even if the target environment contains the same team with the same name, your workflow will now contain a broken reference and cannot be activated. In fact, if you try to automatically activate the workflow on solution import you will get the following error:

    This workflow has errors and cannot be published. Please remove the errors and try again.

    The reason why the reference is broken is because workflow keeps track of referenced records by GUID, not by name. So unless you have a team with the same GUID in both environments then the reference will be broken. Your workflow step would look like this after import:
    image

    You can go ahead and fix the lookup and then activate the workflow, but here are some bad news of that manual approach:
    • Each time you import an update to the solution that contains the workflow you have to manually update the workflow again.
    • This can happen for teams, queues and many other records referenced in a workflow.
    • Trying to find the GUID in the workflow definition XAML is tedious and risky, there is no documented schema or process on how to do this.
    Ideally, I would like to see a way to add my “Sales Team” to the solution, so it will be automatically created in every environment and it will preserve its GUID across multiple environments. However, team records are unfortunately not solution aware. the workaround I have been using is to export the teams from the development environment and import to all the other environments (preserving the GUID). Once this is done, I can import the above workflow as many times as I need and the references will not be broken.

    To export the teams you need to go create a query that excludes all default teams:
    image

    After executing the query, click the Export Teams button. Make sure to select the option to make data available for re-importing:
    image


    Now here is the tricky part, you need to modify the Excel file to be able to import it to another environment. This is what you need to do:

    1. Save the file as CSV. Close and re-open the CSV file.
    2. Rename column A header to “Team”. If there is another column that already has a header called “Team” you should delete that other column and leave column A.
    3. Delete all other columns whose header starts by “(Do No Modify)”.
    4. If your Business Units don’t have the same name in all environments then you should also delete the “Business Unit” column. The teams will by default belong to the root Business Unit.
    5. Save.
    Now you just need to import the CSV file in each of your environments, this will create the teams with the same GUID as the source environment. You can re-use the same file for all environments, and you only need to this once per environment. During import you will need to map it to the “Team” entity, but all the fields should be automatically mapped. Now when you open back your “broken” workflow you will see that it is no longer broken! You can import the teams before or after you import the solution.

    One little nuisance I have found is that you cannot import the teams if your Sales Person role does not exist. This looks like a bug, but you should be fine unless you have deleted that role, in which case you’d need to bring it back, at least while you import the teams.

    Note that the broken references only occur when the workflow references entities which are not solution aware (teams, queues, etc.) but, it will not be a problem with solution aware entities (e.g. email templates) because you can include the record in the solution itself. Additionally in CRM 2011 there is a mechanism to prevent broken links to users and currencies, so even when you cannot include currencies and users in solutions, when importing a workflow that references these 2 records, the mapping will be done based on name instead of GUID so the references will resolve. For example if you have an “Assign” step that assigns an account to “Gonzalo Ruiz”, even if the user “Gonzalo Ruiz” exists in multiple environments with different GUID, it will still be automatically mapped. But all other entities are referenced by GUID.