Pages

Showing posts with label Microsoft Dynamics CRM 2013. Show all posts
Showing posts with label Microsoft Dynamics CRM 2013. Show all posts

Tuesday, November 18, 2014

CRM_URL Manipulation

There is a well known technique for opening an entity form from an SRS report. For example, you can create a hyperlink to the underlying CRM contact record using the following syntax:

=IIF(IsNothing(Parameters!CRM_URL.Value),Nothing,Parameters!CRM_URL.Value & "?ID={"&Fields!contactid.Value.ToString()&"}&LogicalName=contact")


However if you want to create a link to a CRM record without an underlying reference ID to pass then things can become a little more tricky. This is because while you require the server reference provided by the CRM_URL variable (shown in green below), you need to get rid of the "CRMReports/viewer/drillopen.aspx" section as that throws it off (shown in yellow).


This can be achieved by using the following function in the URL action:
=Mid(Parameters!CRM_URL.Value, 1, InStr(Parameters!CRM_URL.Value, "/CRMReports"))

Now you can rebuild the URL anyway you want. For example, you can construct a URL as follows:


And this will open up a new CRM record (with passed defaults etc.).


Monday, November 17, 2014

Convert Org Owned Entity to User Owned

A while back I discussed the pros and cons of user vs. organization owned entities. I concluded as follows:

The theory might all be well and good, but let's say you're presently in the predicament described above i.e. you're in production and have come across a requirement that means that you'll need to convert an entity from organization-owned to user-owned - what are the steps to achieve this? In the next post I'll attempt to address this with a step by step walk through.
Well it's about time I made good on that promise... So here goes -

Caution: This is not for the fainthearted. Especially in CRM Online installations where you can't really make a backup (as concluded in the above referenced post - when in doubt go with user-owned entities...).

Step 1 - Export all the data

You need to save all your data linked to the entity you wish to update. Assuming this is a CRM Online instance you can use the export to Excel option (in on-premise there are of course other options). This includes (but not necessarily limited to) the following:

  • Export Main  Entity




  • Export Notes - All columns
  • Export Activities - All columns
  • Export data from other 1:N relationships that you wish to recreate/relate

You need to resign your self to the fact that you will lose information stored in system attributes such as created/modified by/on.

Generally speaking, restoring N:1 relationships is not a problem because they'll be recreated with the re-import.

However with the 1:N relationship as in the case of notes and activities there is a level of effort involved so you'll need to make a judgment call of whether it is worth it. Same applies for N:N relationships (perhaps even more so since there is no way to re-import using native tools. Bottom line if there is a lot of dependent data this exercise is likely going to be too painful and you'll need to consider other options such as duplicating the entity and migrating the data over with all the relationships (tools such as Scribe can help here).



Step 2 - Create and Export Solution


Retains all customizations - views, forms etc.

  • Export a solution containing the entity you wish to modify and workflows on that entity 
  • Export a solution with everything but entity (including workflows, security roles)....
  • Make a copy of the exported zip
  • Unzip the solution, and open customizations.xml in a text editor
  • Replace the following section... 
<attribute PhysicalName="OrganizationId">
              <Type>lookup</Type>
              <Name>organizationid</Name>
              <LogicalName>organizationid</LogicalName>
              <RequiredLevel>none</RequiredLevel>
              <ImeMode>auto</ImeMode>
              <ValidForReadApi>1</ValidForReadApi>
              <IsCustomField>0</IsCustomField>
              <IsAuditEnabled>1</IsAuditEnabled>
              <IsSecured>0</IsSecured>
              <IntroducedVersion>1.0</IntroducedVersion>
              <IsCustomizable>1</IsCustomizable>
              <IsRenameable>1</IsRenameable>
              <CanModifySearchSettings>1</CanModifySearchSettings>
              <CanModifyRequirementLevelSettings>1</CanModifyRequirementLevelSettings>
              <CanModifyAdditionalSettings>1</CanModifyAdditionalSettings>
              <ReferencedEntityObjectTypeCode>1019</ReferencedEntityObjectTypeCode>
              <LookupTypes />
              <displaynames>
                <displayname description="Organization Id" languagecode="1033" />
              </displaynames>
              <Descriptions>
                <Description description="Unique identifier for the organization" languagecode="1033" />
              </Descriptions>
            </attribute>
              
  • With:
<attribute PhysicalName="OwnerId">
              <Type>owner</Type>
              <Name>ownerid</Name>
              <LogicalName>ownerid</LogicalName>
              <RequiredLevel>systemrequired</RequiredLevel>
              <DisplayMask>ValidForAdvancedFind|ValidForForm|ValidForGrid|RequiredForForm</DisplayMask>
              <ImeMode>auto</ImeMode>
              <ValidForReadApi>1</ValidForReadApi>
              <ValidForCreateApi>1</ValidForCreateApi>
              <IsCustomField>0</IsCustomField>
              <IsAuditEnabled>1</IsAuditEnabled>
              <IsSecured>0</IsSecured>
              <IntroducedVersion>1.0.0.0</IntroducedVersion>
              <IsCustomizable>1</IsCustomizable>
              <IsRenameable>1</IsRenameable>
              <CanModifySearchSettings>1</CanModifySearchSettings>
              <CanModifyRequirementLevelSettings>1</CanModifyRequirementLevelSettings>
              <CanModifyAdditionalSettings>1</CanModifyAdditionalSettings>
              <LookupStyle>single</LookupStyle>
              <LookupTypes>
                <LookupType id="00000000-0000-0000-0000-000000000000">8</LookupType>
                <LookupType id="00000000-0000-0000-0000-000000000000">9</LookupType>
              </LookupTypes>
              <displaynames>
                <displayname description="Owner" languagecode="1033" />
              </displaynames>
              <Descriptions>
                <Description description="Owner Id" languagecode="1033" />
              </Descriptions>
            </attribute>
            <attribute PhysicalName="OwnerIdName">
              <Type>nvarchar</Type>
              <Name>owneridname</Name>
              <LogicalName>owneridname</LogicalName>
              <RequiredLevel>systemrequired</RequiredLevel>
              <ImeMode>auto</ImeMode>
              <ValidForReadApi>1</ValidForReadApi>
              <IsCustomField>0</IsCustomField>
              <IsAuditEnabled>0</IsAuditEnabled>
              <IsLogical>1</IsLogical>
              <IsSecured>0</IsSecured>
              <IntroducedVersion>1.0.0.0</IntroducedVersion>
              <IsCustomizable>1</IsCustomizable>
              <IsRenameable>1</IsRenameable>
              <CanModifySearchSettings>1</CanModifySearchSettings>
              <CanModifyRequirementLevelSettings>1</CanModifyRequirementLevelSettings>
              <CanModifyAdditionalSettings>1</CanModifyAdditionalSettings>
              <Format>text</Format>
              <MaxLength>100</MaxLength>
              <Length>320</Length>
              <Descriptions>
                <Description description="Name of the owner" languagecode="1033" />
              </Descriptions>
            </attribute>
            <attribute PhysicalName="OwnerIdType">
              <Type>int</Type>
              <Name>owneridtype</Name>
              <LogicalName>owneridtype</LogicalName>
              <RequiredLevel>systemrequired</RequiredLevel>
              <DisplayMask>ObjectTypeCode</DisplayMask>
              <ImeMode>disabled</ImeMode>
              <ValidForReadApi>1</ValidForReadApi>
              <ValidForCreateApi>1</ValidForCreateApi>
              <IsCustomField>0</IsCustomField>
              <IsAuditEnabled>1</IsAuditEnabled>
              <IsSecured>0</IsSecured>
              <IntroducedVersion>1.0.0.0</IntroducedVersion>
              <IsCustomizable>1</IsCustomizable>
              <IsRenameable>1</IsRenameable>
              <CanModifySearchSettings>1</CanModifySearchSettings>
              <CanModifyRequirementLevelSettings>1</CanModifyRequirementLevelSettings>
              <CanModifyAdditionalSettings>1</CanModifyAdditionalSettings>
              <Format></Format>
              <MinValue>-2147483648</MinValue>
              <MaxValue>2147483647</MaxValue>
              <Descriptions>
                <Description description="Owner Id Type" languagecode="1033" />
              </Descriptions>
            </attribute>
            <attribute PhysicalName="OwnerIdYomiName">
              <Type>nvarchar</Type>
              <Name>owneridyominame</Name>
              <LogicalName>owneridyominame</LogicalName>
              <RequiredLevel>systemrequired</RequiredLevel>
              <ImeMode>auto</ImeMode>
              <ValidForReadApi>1</ValidForReadApi>
              <IsCustomField>0</IsCustomField>
              <IsAuditEnabled>0</IsAuditEnabled>
              <IsLogical>1</IsLogical>
              <IsSecured>0</IsSecured>
              <IntroducedVersion>1.0.0.0</IntroducedVersion>
              <IsCustomizable>1</IsCustomizable>
              <IsRenameable>1</IsRenameable>
              <CanModifySearchSettings>1</CanModifySearchSettings>
              <CanModifyRequirementLevelSettings>1</CanModifyRequirementLevelSettings>
              <CanModifyAdditionalSettings>1</CanModifyAdditionalSettings>
              <Format>text</Format>
              <MaxLength>100</MaxLength>
              <Length>320</Length>
              <YomiOf>OwnerIdName</YomiOf>
              <Descriptions>
                <Description description="Yomi name of the owner" languagecode="1033" />
              </Descriptions>
            </attribute>
            <attribute PhysicalName="OwningBusinessUnit">
              <Type>lookup</Type>
              <Name>owningbusinessunit</Name>
              <LogicalName>owningbusinessunit</LogicalName>
              <RequiredLevel>none</RequiredLevel>
              <ImeMode>auto</ImeMode>
              <ValidForReadApi>1</ValidForReadApi>
              <IsCustomField>0</IsCustomField>
              <IsAuditEnabled>0</IsAuditEnabled>
              <IsSecured>0</IsSecured>
              <IntroducedVersion>1.0.0.0</IntroducedVersion>
              <IsCustomizable>1</IsCustomizable>
              <IsRenameable>1</IsRenameable>
              <CanModifySearchSettings>1</CanModifySearchSettings>
              <CanModifyRequirementLevelSettings>1</CanModifyRequirementLevelSettings>
              <CanModifyAdditionalSettings>1</CanModifyAdditionalSettings>
              <ReferencedEntityObjectTypeCode>10</ReferencedEntityObjectTypeCode>
              <LookupStyle>single</LookupStyle>
              <LookupTypes />
              <displaynames>
                <displayname description="Owning Business Unit" languagecode="1033" />
              </displaynames>
              <Descriptions>
                <Description description="Unique identifier for the business unit that owns the record" languagecode="1033" />
              </Descriptions>
            </attribute>


  • Replace the following...
<OwnershipTypeMask>UserOwned</OwnershipTypeMask>
  • With:
<OwnershipTypeMask>UserOwned</OwnershipTypeMask>

  • Replace the following section (be sure to update "your_entity" with the name of your entity)...
<EntityRelationship Name="organization_your_entity">
      <EntityRelationshipType>OneToMany</EntityRelationshipType>
      <IsCustomizable>1</IsCustomizable>
      <IntroducedVersion>1.0</IntroducedVersion>
      <ReferencingEntityName>your_entity</ReferencingEntityName>
      <ReferencedEntityName>Organization</ReferencedEntityName>
      <CascadeAssign>NoCascade</CascadeAssign>
      <CascadeDelete>NoCascade</CascadeDelete>
      <CascadeReparent>NoCascade</CascadeReparent>
      <CascadeShare>NoCascade</CascadeShare>
      <CascadeUnshare>NoCascade</CascadeUnshare>
      <ReferencingAttributeName>OrganizationId</ReferencingAttributeName>
      <RelationshipDescription>
        <Descriptions>
          <Description description="Unique identifier for the organization" languagecode="1033" />
        </Descriptions>
      </RelationshipDescription>
      <field name="organizationid" requiredlevel="none" imemode="auto">
        <IsCustomizable>1</IsCustomizable>
        <IsRenameable>1</IsRenameable>
        <CanModifySearchSettings>1</CanModifySearchSettings>
        <CanModifyRequirementLevelSettings>1</CanModifyRequirementLevelSettings>
        <IsSecured>0</IsSecured>
        <IsAuditEnabled>1</IsAuditEnabled>
        <displaynames>
          <displayname description="Organization Id" languagecode="1033" />
        </displaynames>
      </field>
    </EntityRelationship>

  • With:
    <EntityRelationship Name="owner_your_entity">
      <EntityRelationshipType>OneToMany</EntityRelationshipType>
      <IsCustomizable>1</IsCustomizable>
      <IntroducedVersion>1.0.0.0</IntroducedVersion>
      <ReferencingEntityName>your_entity</ReferencingEntityName>
      <ReferencedEntityName>Owner</ReferencedEntityName>
      <CascadeAssign>NoCascade</CascadeAssign>
      <CascadeDelete>NoCascade</CascadeDelete>
      <CascadeReparent>NoCascade</CascadeReparent>
      <CascadeShare>NoCascade</CascadeShare>
      <CascadeUnshare>NoCascade</CascadeUnshare>
      <ReferencingAttributeName>OwnerId</ReferencingAttributeName>
      <RelationshipDescription>
        <Descriptions>
          <Description description="Owner Id" languagecode="1033" />
        </Descriptions>
      </RelationshipDescription>
      <field name="ownerid" requiredlevel="systemrequired" imemode="auto" lookupstyle="single" lookupbrowse="0" lookuptypes="8, 9">
        <IsCustomizable>1</IsCustomizable>
        <IsRenameable>1</IsRenameable>
        <CanModifySearchSettings>1</CanModifySearchSettings>
        <CanModifyRequirementLevelSettings>1</CanModifyRequirementLevelSettings>
        <IsSecured>0</IsSecured>
        <DisplayMask>ValidForAdvancedFind|ValidForForm|ValidForGrid|RequiredForForm</DisplayMask>
        <IsAuditEnabled>1</IsAuditEnabled>
        <displaynames>
          <displayname description="Owner" languagecode="1033" />
        </displaynames>
      </field>
    </EntityRelationship>
    <EntityRelationship Name="team_your_entity">
      <EntityRelationshipType>OneToMany</EntityRelationshipType>
      <IsCustomizable>1</IsCustomizable>
      <IntroducedVersion>1.0.0.0</IntroducedVersion>
      <ReferencingEntityName>your_entity</ReferencingEntityName>
      <ReferencedEntityName>Team</ReferencedEntityName>
      <CascadeAssign>NoCascade</CascadeAssign>
      <CascadeDelete>NoCascade</CascadeDelete>
      <CascadeReparent>NoCascade</CascadeReparent>
      <CascadeShare>NoCascade</CascadeShare>
      <CascadeUnshare>NoCascade</CascadeUnshare>
      <ReferencingAttributeName>OwningTeam</ReferencingAttributeName>
      <RelationshipDescription>
        <Descriptions>
          <Description description="Unique identifier for the team that owns the record." languagecode="1033" />
        </Descriptions>
      </RelationshipDescription>
      <field name="owningteam" requiredlevel="none" imemode="auto" lookupstyle="single" lookupbrowse="0">
        <IsCustomizable>1</IsCustomizable>
        <IsRenameable>1</IsRenameable>
        <CanModifySearchSettings>1</CanModifySearchSettings>
        <CanModifyRequirementLevelSettings>1</CanModifyRequirementLevelSettings>
        <IsSecured>0</IsSecured>
        <IsAuditEnabled>0</IsAuditEnabled>
        <displaynames>
          <displayname description="Owning Team" languagecode="1033" />
        </displaynames>
      </field>
    </EntityRelationship>
    <EntityRelationship Name="user_your_entity">
      <EntityRelationshipType>OneToMany</EntityRelationshipType>
      <IsCustomizable>1</IsCustomizable>
      <IntroducedVersion>1.0.0.0</IntroducedVersion>
      <ReferencingEntityName>your_entity</ReferencingEntityName>
      <ReferencedEntityName>SystemUser</ReferencedEntityName>
      <CascadeAssign>NoCascade</CascadeAssign>
      <CascadeDelete>NoCascade</CascadeDelete>
      <CascadeReparent>NoCascade</CascadeReparent>
      <CascadeShare>NoCascade</CascadeShare>
      <CascadeUnshare>NoCascade</CascadeUnshare>
      <ReferencingAttributeName>OwningUser</ReferencingAttributeName>
      <RelationshipDescription>
        <Descriptions>
          <Description description="Unique identifier for the user that owns the record." languagecode="1033" />
        </Descriptions>
      </RelationshipDescription>
      <field name="owninguser" requiredlevel="none" imemode="auto" lookupstyle="single" lookupbrowse="0">
        <IsCustomizable>1</IsCustomizable>
        <IsRenameable>1</IsRenameable>
        <CanModifySearchSettings>1</CanModifySearchSettings>
        <CanModifyRequirementLevelSettings>1</CanModifyRequirementLevelSettings>
        <IsSecured>0</IsSecured>
        <IsAuditEnabled>0</IsAuditEnabled>
        <displaynames>
          <displayname description="Owning User" languagecode="1033" />
        </displaynames>
      </field>
    </EntityRelationship>
  • Finally, update your entity name so it can exist side by side (temporarily) with the entity you will be replace. For example, find and replace all your_entity with your_entity2.
  • Similarly, replace the entity description with a replacement value so you'll be able to distinguish from the front end.
      <Name LocalizedName="Your Entity2" OriginalName="Your Entity2">snt_Your Entity2</Name>
      <ObjectTypeCode>10016</ObjectTypeCode>
      <EntityInfo>
        <entity Name="your_entity2">
          <LocalizedNames>
            <LocalizedName description="Your Entity2" languagecode="1033" />
          </LocalizedNames>
          <LocalizedCollectionNames>
            <LocalizedCollectionName description="Your Entity 2" languagecode="1033" />

  • Save Customization.xml and copy back into exported zip

Step 3 - Import Customization

  • Import modified zip file to recreate entity
  • Import other solution file created
  • Verify forms, views etc.
  • Verify entity is user-owne
Note: If you get an invalid reference error when importing you'll need to remove the reference (could be a sub-grid or jscript web resource reference) and you'll need to manually add back after the import.

Step 4 - Import Data

Use the data import wizard to re-import the data to your new duplicated entity.


Step 5 - Post Steps

Once you're satisfied with the state of affairs of your new entity you can apply the post steps which includes:

  • Delete old entity - This can get quite hairy. Deleting an entity requires removing all kinds of dependencies. Make sure you export entities, workflows, security roles etc. and keep careful manual track of any thing that needs to be manually reset

  • Update forms - you may need to update the forms with removed references that caused import customization errors. 
  • Update security roles
  • Update workflow

Sunday, May 25, 2014

Import Organization Failed: Subquery returned more than 1 value

While trying to import a CRM 2011 organization to CRM 2013 I encountered the following error:


Viewing the log detail unfortunately file did not shed much more light on this.

The only thing I had to go on was the SQL error itself. This indicated that somewhere the system was trying to execute a nested SQL statement that looked something like the following:

select field1 from table1 where field2 = (select field3 from table2)

And that the results from table2 returned more than a single row which is not allowed as the nested relationship is using the "=" rather than "in" operator.

Armed with this information, I decided to run a SQL trace while recreating the import error. And then performed a bit of a needle-in-haystack search for something that might fit the above - using correlating times from the SQL Trace and CRM trace file (although in retrospect I think I could have searched the SQL trace for a statement like 'update organization set set state=...' as this is what happens directly after the failed error).

Lo and behold, I came across the query below which matched the kind of query pattern I was looking for. The suspect had been identified...


Running the essence of the above query in SQL it came back with the following - looks like a smoking gun to me!


In the interest of moving forward as quickly as possible, I decided to run a query that eliminate this particular error by ensuring a singleton output.

update Role set RoleTemplateId = null
where RoleId != 'BDD45E0B-7482-DC11-AB36-005056BC02DA'
and RoleTemplateId='A4BE89FF-7C35-4D69-9900-999C3F603E6F'

Re-running the import again subsequently succeeded... and yet another successful CRM 2013 upgrade under the belt.

Tuesday, March 18, 2014

Run Report button missing on Forms

We noticed that certain forms in a CRM 2013 upgraded installation were missing the embedded "Run Report" option in the command bar. It appears in some forms but not in others... with no apparent rhyme or reason. For example, below is a screenshot of the upgraded opportunity form:



Anyone see the Run Report option? Neither do I... and the reason cannot be attributed to there not being any context sensitive reports for opportunities. There indeed are!


Yet... it does appear in the command menu for the grid view. Go figure.

I found this post which pointed me in the direction of the resolution. It references two options for resolution. One by directly modifying the export XML for the entity. And the second by using the Ribbon Workbench tool.

The first solution is the way to go. Quicker and easier and does the job. That is, you just need to add the following command definition to the RibbonDiffXml of the entity.

<CommandDefinition Id="Mscrm.ReportMenu.Form">
    <EnableRules>
      <EnableRule Id="Mscrm.FormStateNotNew" />
    </EnableRules>
    <DisplayRules>
      <DisplayRule Id="Mscrm.ReadReport" />
    </DisplayRules>
    <Actions />
</CommandDefinition>

After importing and publishing, the reports have returned to their rightful place (ok I know the report icon is still missing but that is a battle for another day).



Friday, February 7, 2014

CRM 2013: Compelling Reasons to Upgrade

There are many posts that describe and illustrate the new features that CRM 2013 has introduced. Here are a few choice samples:




Having now spent quite a bit of time working and getting familiar with the new platform, my intention is to try and determine what might be considered features that provide compelling reasons to upgrade assuming that you are on the previous version of the product. That assumption includes the fact that you've spent some time and effort configuring CRM to suit your needs. So while there may be some features that make it easier to achieve certain configuration options that were implemented previously - that in my opinion would not provide a compelling reason to upgrade as there generally is not going to be a burning need to rework the option that has already been implemented and working as desired.

Let's also stipulate that I'm not advocating against upgrading. Rather upgrading is a strategic decision that needs to be weighed with other competing priorities and budgets. And therefore this is more of a question of whether this should be prioritized now or perhaps down the line. And let's make no mistake about it - Microsoft will be spending their time and effort improving the new platform rather than CRM 2011, so if you're planning on performing any major process improvements then you'd be well served to bite the upgrade bullet so you can leverage new capabilities. This post is not for you if you fall into that category. If however you are somewhere in between and looking for features that just may take you to the next level - then this might help put things in perspective.

In my opinion too many posts out there just hype features of the product without providing critical analysis of the real world advantage they're likely to bring. In my list below, I am endeavoring to analyze the features on their practicality and real world application.


POTENTIALLY COMPELLING

  • Business Process Flow - This is a net new feature, easy to configure/implement and can have a fairly significant impact to the ease of use. Especially for mobile devices such as tablets.
  • Exchange Server Side Sync - Although the CRM Outlook Client has made tremendous progress over the years, it still remains the Achilles heel of the product - in my opinion. Mainly because of the decentralized nature of the configuration and troubleshooting headaches when there is a syncing issue. There were 3rd party solutions that allowed this to happen at the server level. And now Microsoft has finally added this functionality to the core product. If you are experiencing issues with contact synchronization then this could well provide the single compelling reason to upgrade.
  • Mobile Optimization - The design of the product has been optimized to all mobile devices. Even more impressive - they have produce apps for the iPad, iPhone, Surface, and Android. If you think that mobile enabling your workforce will increase adoption and overall usage, then this is indeed a compelling reason for upgrading.


FACILITATIVE

  • Business Logic - There is nothing new about this feature that could not be achieved with form jscript. In fact, you will still need jscript for more involved scenarios. But it does give less techie users the ability to configure simple dynamic behavior on the form and therefore become more self sufficient.
  • Quick View Forms - This is definitely a nice new feature that makes it easy to display information from other related entities on the current form. But if you had that requirement previously, there were ways and means to achieve it.
  • Real Time Workflows - I'd say this is a very nice new feature that could replace a lot of jscript and plugin requirements. But again this does not enable a capability that could not be achieved in CRM 2011.
  • Access Teams - This is a nice new feature that is most likely to be used in scenarios of collaborative selling. The functionality was achievable with the standard team model in previous versions but is a lot more flexible and "on the fly" in the latest version.
  • Actions - This extends the programming capability of the product essentially providing the ability to abstract business logic even further. I can see this feature as potentially very useful to minimize the amount of custom code logic making it easier to modify without having to update plugins etc. But again this does not enable a capability that could not be achieved in CRM 2011. 


INTERESTING

  • User Interface/Navigation - The new version is pretty nice but in some ways can be more challenging to navigate. There are merits to the new user interface but also to the previous user interface. The flat user interface is nice but does not come without a cost (e.g. the benefits of alt+tabbing vs. having to re-navigate to where you were previously). I suspect there will still be a few improvements to come to help optimize this particular experience. And make no mistake about it - upgrading will require you to optimize your form layout to leverage and benefit from the new form layout. If you do not allocate budget for that effort, you are in fact likely to be negatively impacted by the new user experience.
  • Command Bar - Microsoft thought it had it all figured out when they introduced the ribbon interface. Only to apparently discover that it was also too overwhelming for the average user and have now scaled it back to the simpler command bar. I do think that they are moving in the right direction with this design change but I hardly think this will make a meaningful difference to those who have gotten familiar with the ribbon interface.
  • Dashboards - This feature has been slightly enhanced such that a different default dashboard can be configured for each area (sales, marketing, service, etc.) and per role.


NICE TO HAVE
  • Auto-Save - Honestly? BFD.
  • Social Pane - Ditto. Maybe I'm old school but this is a feature that I have rarely seen employed. There's already activities and notes and at some point the lines gray between what should be what. And this doesn't really help. Perhaps for larger companies.
  • Quick Create Forms - If I'm not mistaken this is kind of a re-introduced feature from CRM 3.0 and earlier. Not revolutionary and unlikely to improve the user experience in any significant way. 
  • Images - All entities now support associating images to them. Most likely usage is for contacts (although still doesn't sync with the Outlook contact image). Nice if you need it.

Thursday, January 23, 2014

Error running a report via Outlook Client

Update from Microsoft (3/25/14):

          The issue appears to be fixed:
I received confirmation that the team has processed a change with the NLB system used by CRM Online. As a result, this incident with receiving script errors when running reports from your CRM Online organization should now be resolved.

Update from Microsoft (2/20/14):

After working with my team further, we were able to reproduce this problem internally (not using CRM Online). The problem is specific to a setting on the load balancers used by CRM Online. As such, it appears that this will affect Office365 based organizations (which to be honest makes more sense now). The setting on the load balancers was something recently applied in the move to CRM 2013, however our internal teams are getting approval to undo that change which should resolve this problem. They gave me an approximate 2 week timeframe to get proper approval and undo that change. We’re currently about 1 week through that, so we should be close to having this problem fully resolved.

Update from Microsoft (1/31/14):

The core problem is still being investigated, however a “workaround” was discovered that ties in with the new ‘Process Isolation’ feature of the CRM Client for Outlook. There is a registry key that can be applied on client systems to disable the feature. Testing on our side so far looks promising as the script errors on reports have ceased after disabling the feature. This is by no means a solution to the problem and our teams are still actively investigating. If you wish to test this, I’ve included the registry key below to implement on a client. If you confirm it also works from your side, we can discuss pros/cons of this workaround and if it’s feasible for your organizations.
Key Path: HKEY_CURRENT_USER\Software\Microsoft\MSCRMClientKey (DWORD): UseWebFormProcessIsolationValue: 0
-----------------------------------------------------------------------------------------------------------

In one of our CRM 2013 online instances we are receiving errors whenever trying to run a report from the Outlook client. The error looks something like in the examples below (errors occur one after the other).




This does not happen when running reports via a browser so clearly some kind of platform issue. It is somewhat sporadic too and seems to be related to browser cache. So it might go away and then come back at a later point in time. For example, one solution I tried was to delete/recreate the report as I figured that it was perhaps due to some upgrade issue from 2011. This solved the issue for a while but then it returned.

And this was confirmed by Microsoft who are currently troubleshooting the issue. The following is the current guidance provided by Microsoft:

Per our phone conversation, this issue with running reports in the CRM Client for Outlook against a CRM Online 2013 organization on our CTP authentication platform is currently a known issue that has recently been brought to our attention. We are actively investigating this problem and I’ll keep you posted as I know more. Currently, we believe this may be a server side setting – but the investigation has not yet yielded the exact cause of the problem. Unfortunately there is no workaround for the web client other than using the CRM Web Client (i.e. Internet Explorer).


Monday, January 6, 2014

CRM Online vs. CRM On Premise

The CRM Online platform has really come along way over the years coming closer and closer to its on premise counterpart. There is however one aspect which poses significantly more challenges than the on premise version. Specifically this is the limitation that the CRM online data cannot be accessed directly via SQL.

This limitation typically impacts the following two fairly common-place requirements:

1. Reporting

For CRM Online you are forced to use FetchXML to retrieve data rather than SQL. And while most report requirements can be satisfied using this technology it requires a little more effort than standard SQL reporting. Frankly, it is far easier to construct a query in SQL than FetchXML and the comparative difficulty between the constructs only increases with increasing complexity of the query required (or you can break the report down differently to avoid more complex query requirements when using FetchXML - "tricks" you wouldn't normally need to consider when using straight SQL). And of course for a complex reporting requirement, FetchXML may not be flexible enough to extract the data in the way that is required making it necessary to perhaps "flatten" the data using plugins or using a tool such as Scribe Replication Services before reporting against. This as compared to on premise reporting where you can use techniques such as dynamic SQL where the sky is really the limit.

2. Bulk Updates

In the on premise version of CRM, you have the ability to easily make bulk updates to your data. Though running direct SQL updates is officially "frowned" upon by Microsoft, this is done as a form of CYA. Allow me to explain - the integrity of the CRM database is maintained via the web services business layer. The minute someone is allowed to "tamper" with the underlying data directly all havoc can break loose. There simply is no way to protect against someone who is intent on corrupting the database. Not that anyone will do that intentionally of course but someone who is insufficiently knowledgeable in SQL and/or the CRM database may unwittingly introduce "problems" by trying their hand at SQL. And Microsoft of course cannot control who would be performing such updates so therefore they issue a blanket statement saying that the direct updates to the CRM database is unsupported (I once had the rather amusing case with Microsoft support where the resolution required running a script that they provided with a cautionary note that direct SQL updates are not supported - in the same email!).

However if you are sufficiently knowledgeable and take the necessary cautionary measures - it is difficult to argue against performing direct SQL updates with a straight face. The first reason is due to the relative ease that such updates can be constructed and run. And the second and often more valid reason is due to the speed in which it will be applied. If you need to run an update in a table with millions of rows - the difference will be between a few minutes and potentially a few days via web service.



Please don't get me wrong - I am not at all down on the CRM Online option. In fact, I think it is actually a pretty amazing platform and has some significant upsides from the on premise version - especially for smaller companies where the playing field is levelled in that they also have access to an enterprise level strategic software solution at a very affordable price and without the necessity of having their infrastructure and/or IT department. The barrier to entry was significantly lowered when CRM first offered its online solution. However, when evaluating the merits of going on premise vs. online for a given company's requirements - I would definitely factor in the above against the stated long term requirements of the undertaking.

Thursday, January 2, 2014

CRM 2013 Insufficient Form Permissions

We had some users who encountered a strange error in their upgraded CRM 2013 environment. We saw this happen on the account and contact form whereby the users were presented with an "insufficient permissions" error when they attempted to open the form.



The resolution proved elusive because the issue itself was very inconsistent. A little hard to explain or understand but the following example illustrates the type of behavior that was being experienced:


  1. User experiences permission issue
  2. Assign system administration role to user
  3. User able to open forms
  4. Remove system administration role from user
  5. User still able to open forms
  6. Later on user again experiences permission issue
So without changing anything the problem mysteriously goes away. Only to resurface at a later point in time (usually after logging out/in but not even that was consistent). So somehow this issue seemed to "cache".


This was despite the fact the user roles assigned did indeed have the necessary read permissions for these entities. And the users could in fact see the views for these entities but were blocked with the message above when trying to open any record.

The first thing to track down was to ensure that the users had permissions to the forms in question. After all, we had created a custom form to replace the built in version as part of the 2013 upgrade merge effort. But this also passed the test with the form being accessible to everyone (and enabled as fallback even though this was irrelevant since this was the only active Main form for the entity).


So this issue had to somehow be permissions related. After a bit of trial and error the issue seemed to hinge around the following "Process Configuration" read permission. This permission existed in CRM 2011 but for some reason (bug?) CRM 2013 is now requiring it to open these forms.





Monday, December 30, 2013

CRM 2013 Notes Control only showing notes

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.



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:

  1. 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.
  2. 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).
  3. 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).



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