In a previous post I wrote about some of the differences and limitations around custom reporting in Microsoft Dynamics CRM, specifically of using FetchXML vs. the SQL Filtered Views. Because CRM Online is limited to the use of FetchXML, I have seen many of our online customers run into issues with activity reporting. There are out of the box reports available but do not allow flexibility when it comes to customizing them to fit the specific customer’s needs. Because of this limitation when one of my customers had the requirement to be able to run a report out of CRM that returned all activities that were “Set Regarding” an Account or their related Opportunities and/or Contacts it required a deeper dive into the capabilities of activity reporting using FetchXML. As I was developing this report I wasn’t able to find a lot of comparisons so I thought I would share what I did.

Through a few different iterations we were able to develop a custom activity report, using FetchXML that allows them to run an activity summary for selected Account or that returns activities that are set regarding either an account or that related accounts contacts or opportunities (@Accountid) and also filters based on these other parameters:

Parameter

Field

@Accountid

Regardingobjectid

@EventDateFrom

Scheduledend

@EventDateTo

Scheduledend

@ActivityType

Activitytypecode

@Status

Statecode

 

By using the link-type='outer' I was able to return the data I needed including custom columns from the phonecall and appointment entity. Note: performance should be considered when utilizing the outer link-type, for this particular customer they were okay with the fact that performance of the report may be impacted because their business need for this information is so high, they also put heavy restriction on who can run the report and the time of day that the report is run.

The query I used is:

<fetch version="1.0" output-format="xml-platform" mapping="logical"
       distinct="false">
  <entity name="activitypointer">
    <attribute name="subject" />
    <attribute name="ownerid" />
    <attribute name="regardingobjectid" />
    <attribute name="activitytypecode" />
    <attribute name="statecode" />
    <attribute name="scheduledstart" />
    <attribute name="scheduledend" />
    <attribute name="activityid" />
    <attribute name="description" />
    <attribute name="createdon" />
    <attribute name="createdby" />
    <attribute name="actualstart" />
    <attribute name="actualend" />
    <order attribute="modifiedon" descending="false" />
    <filter type="and">
      <condition attribute="regardingobjectid" operator="not-null" />
      <condition attribute="isregularactivity" operator="eq" value="1" />
      <condition attribute="statecode" operator="in" value="@Status" />
      <condition attribute="activitytypecode" operator="in" 
                 value="@ActivityType" />
      <filter type="and">
        <condition attribute="scheduledend" operator="on-or-after"
                   value="@EventDateFrom"/>
        <condition attribute="scheduledend" operator="on-or-before"
                   value="@EventDateTo"/>
      </filter>
    </filter>
    <link-entity name="opportunity" from="opportunityid" to="regardingobjectid"
                 alias="opp" link-type="outer">
      <attribute name="opportunityid" />
      <attribute name="customerid" />
      <link-entity name="account" from="accountid" to="customerid"
                   alias="opportunityaccount" link-type="outer" >
        <attribute name="accountid" />
        <attribute name="territoryid" />
        <filter type="and">
          <condition attribute="accountid" operator="in" value="@account" />
        </filter>
      </link-entity>
      <filter type="and">
        <condition attribute="accountid" operator="in" value="@account" />
      </filter>
    </link-entity>
    <link-entity name="contact" from="contactid" to="regardingobjectid"
                 alias="cont" link-type="outer">
      <attribute name="contactid" />
      <attribute name="parentcustomerid" />
      <link-entity name="account" from="accountid" to="parentcustomerid"
                   alias="contactaccount" link-type="outer" >
        <attribute name="accountid" />
        <attribute name="territoryid" />
        <filter type="and">
          <condition attribute="accountid" operator="in" value="@account" />
        </filter>
      </link-entity>
      <filter type="and">
        <condition attribute="accountid" operator="in" value="@account" />
      </filter>
    </link-entity>
    <link-entity name="account" from="accountid" to="regardingobjectid"
                 alias="acct" link-type="outer">
      <attribute name="accountid" />
      <attribute name="territoryid" />
      <attribute name="name" />
      <filter type="and">
        <condition attribute="accountid" operator="in" value="@account" />
      </filter>
    </link-entity>
    <link-entity name="appointment" from="activityid" to="activityid"
                 alias="appt" link-type="outer">
      <attribute name="activityid" />
      <attribute name="new_appointmenttype" />
      <attribute name="ownerid" />
      <filter type="and">
        <condition attribute="regardingobjectid" operator="not-null" />
        <filter type="and">
          <condition attribute="scheduledend" operator="on-or-after"
                     value="@EventDateFrom"/>
          <condition attribute="scheduledend" operator="on-or-before"
                     value="@EventDateTo"/>
        </filter>
      </filter>
    </link-entity>
    <link-entity name="phonecall" from="activityid" to="activityid"
                 alias="phone" link-type="outer">
      <attribute name="activityid" />
      <attribute name="new_phonetype" />
      <attribute name="ownerid" />
      <filter type="and">
        <condition attribute="regardingobjectid" operator="not-null" />
        <filter type="and">
          <condition attribute="scheduledend" operator="on-or-after"
                     value="@EventDateFrom"/>
          <condition attribute="scheduledend" operator="on-or-before"
                     value="@EventDateTo"/>
        </filter>
      </filter>
    </link-entity>
  </entity>
</fetch>
I was then able to use a table in SQL Server data tools (A.K.A. BIDS) report builder to group and format the data in the way the customer had requested.

 

 

Hope this was helpful! For additional information on FetchXML performance, specifically using the isquickfindfields function see my fellow PFE Sean McNellis’s blog post here: Take advantage of better query performance.

If you are interested, our PFE team is ready to help you with this, we can assist with query examples and various other engagements to help you improve your CRM reports and performance. In addition, we have many other services we offer such as reporting workshops, developer training, admin workshops, and code reviews.  If you would like to have another Microsoft PFE or I visit your company and assist with the ideas presented on our blog, contact your Microsoft Premier Technical Account Manager (TAM) for booking information.  For more information about becoming a Microsoft Premier Customer email PremSale@microsoft.com.

Thanks!

Sarah Champ

Microsoft Premier Field Engineer