Knowledge found and lost while working with Microsoft Dynamics CRM
RSS icon Home icon
  • Understanding the CRM 3.0 SDK Rollup Messages

    Posted on December 12th, 2006 mitch Print Print No comments

    As you have probably seen, CRM has the ability to roll-up information from child Entities to the parent Entity.  Activities would be one such example: When you look at the Activities for an Account, you actually see Activities for both the main Account as well as all Activities for the Account's Contacts as well.  A pretty great feature, if you ask me.

    Anyway, the CRM SDK also has Roll-up messages that allow you to retrieve information in a similar manner.  The following list shows the target classes for the Rollup message:

    TargetRollupActivityPointerByAccount

    TargetRollupActivityPointerByContact

    TargetRollupActivityPointerByOpportunity

    TargetRollupAnnotationByAccount

    TargetRollupAnnotationByContact

    TargetRollupAnnotationByOpportunity

    TargetRollupContractByAccount

    TargetRollupContractByContact

    TargetRollupIncidentByAccount

    TargetRollupIncidentByContact

    TargetRollupInvoiceByAccount

    TargetRollupInvoiceByContact

    TargetRollupOpportunityByAccount

    TargetRollupOpportunityByContact

    TargetRollupQuoteByAccount

    TargetRollupQuoteByContact

    TargetRollupSalesOrderByAccount

    TargetRollupSalesOrderByContact

    TargetRollupDynamic

     

    I haven't worked through all of these messages, but I have tested the Activitypointer ( Activities ) and Annotation ( Notes ) messages, and they work exactly as you would expect.

    I did have one problem when I first started playing around this morning: I couldn't make it work.  No matter what I tried, I could not make the rollup message execute successfully.  Luckily, Jonathan Randall, one of the Microsoft Online Support resources, had posted a solution to my exact problem, to another person back in April of 2006.  His code is follows:

      RollupResponse related = null;
    
      try
      {
    	QueryExpression query = new QueryExpression();
    	query.EntityName = EntityName.activitypointer.ToString();
    	query.ColumnSet = new AllColumns(); 
    
    	TargetRollupActivityPointerByAccount activityRollup =
    		new TargetRollupActivityPointerByAccount();
    	activityRollup.AccountId = 
                       new Guid("69B242AE-0348-DB11-AAA0-00142A05B544");
    	activityRollup.Query = query; 
    
    	RollupRequest rollup = new RollupRequest();
    	rollup.ReturnDynamicEntities=false;
    	rollup.RollupType=RollupType.Related;
    	rollup.Target=activityRollup; 
    
    	related = (RollupResponse)service.Execute(rollup); 
    
    	if (related.BusinessEntityCollection.BusinessEntities.Length >0)
    	{
    		string txtResults = string.Empty;
    
    		foreach (activitypointer pointer in
    			related.BusinessEntityCollection.BusinessEntities)
    		{
    			txtResults += pointer.subject + " : " +
    				pointer.description + " : " +
    				pointer.activitytypecode.Value.ToString() +
    				" : " +
    				pointer.statecode.ToString() +
    				Environment.NewLine;
    		} 
    
    		MessageBox.Show(txtResults, "Activities");
    	}
      }
      catch (System.Web.Services.Protocols.SoapException err)
      {
    	MessageBox.Show(err.Detail.OuterXml.ToString(), "Error");
      }
    

    So what is the big deal?

    The problem I was having, was related to the formation of the Query field that is being passed to the Rollup message.  Let's take the TargetRollupActivityPointerByAccount for example.  This message has two fields: AccountId and Query. 

    It turns out that the Query field is a query on the Entity being rolled up, not on the parent Entity to which those records belong.  In other words, given the above message, I would specify my Query parameters for the ActivityPointer Entity, not the Account Entity.

    TargetRollupAnnotationByAccount works in a similar manner.  We specify Query parameters for the Annotation Entity, not the Account Entity.

    Once I understood that little fact, all of the other stuff made perfect sense.

    Note: In the example above, we specify no expression filters so the query will return All of the activities.

     

    Reference:

    CRM Developer Newsgroup Post

    Customization, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    1,887 views
  • Question of the day: Do you need to revert Accounts to Leads

    Posted on December 12th, 2006 mitch Print Print No comments

    One of my customers is an association whose membership is subscription based ( like most associations ).

    They have a business requirement to remove companies that have dropped their membership from the Accounts Entity and add them back to the Leads Entity ( with history, etc. ).

    I am curious if others in my audience have a similar requirement to revert an Account and/or Contact back to a Lead.  If you do, and you don't mind sharing, then I would like to know more about how and why your business ( or customer ) has such a requirement and how their process is implemented.

    Just drop me a quick email: mitch (at) infinite-x (dot) net.

    Thanks, Mitch

    Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    859 views
  • Does Santa pre-stage his deliveries?

    Posted on December 12th, 2006 mitch Print Print No comments

    Or does he stick everything into the sleigh when he leaves the North Pole?

    Just one of the questions that popped into my head yesterday.

    Meanderings
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    653 views
  • Introduction to the CRM SBE Configuration Wizard

    Posted on December 11th, 2006 mitch Print Print 2 comments

    Dynamics CRM 3.0 ships with a Configuration Wizard that allows you to configure most of the common customization points automatically.  It builds a configuration file that can either be saved for later Import or Imported live.

    Where to find it:

    Look in the following folder on your CRM Server:

    [installation drive]\Program Files\Microsoft CRM\Tools\

    The application file name is:

    Microsoft.Crm.Sbe.Configuration.Wizard.exe

    Launching the wizard will step you through a process that begins with the following dialog:

    You can select the Primary Industry of your company, which will provide answers to later questions.

    The following Industries are currently provided:

    Financial Services
       Banking
      Insurance
    Government
    Healthcare
      Health Plan Payer
      Healthcare Provider
    Life Sciences
      Pharmaceuticals
    Manufacturing
      Discrete Manufacturing
      Process Manufacturing
    Media and Entertainment
      Advertising
      Entertainment
    Nonprofit
    Professional Services
      Real Estate
      Management Services
      Engineering and Architecture
      Legal
    Retail
    Telecom
      Communication Service Providers
      Equipment Providers
      Network, Internet or Applications Service Providers
    Transportation and Logistics
    Utilities

     

    The subjects provided will be automatically populated based on your Industry choice.  As you can see, you can Add, Remove, and Edit existing items.

    When you define your Sales Operations information, you will allowed to set the display name format for the contact names within CRM as well as change the names of the Account and Contact Entities.

    If you utilize territories in your business, you will be allowed to enter those as well.

    You can also define your Top Competitors.

    Should you use the CRM Services module, you can change specific settings for that as well.

    And define your Service Sites.

    And Service Queues.

    Finally, you may either apply your changes immediately, or wait until a later time.  Should you choose Later, you will be allowed to specify a file name that will be used to store the settings ( in XML format ) that will be used by the Configuration Wizard to apply your changes.

    In order to start the Configuration Wizard and instruct it to use the XML configuration file you created earlier, you must execute the Configuration Wizard from the command line and specify the name of the configuration file, as is shown below:

    The config file will be read and a summary of your specific group of settings will be displayed.

    You will then be asked to enter the location for your CRM server.

    When you click next on the above dialog, the Configuration will begin the Import process, as shown below:

    As you can see, any configuration sections that didn't contain data were skipped. The other messages indicate if that part of the process Succeeded or Failed.

    Clicking Finish will close the Wizard.

     

    Related Items of Interest:

    The SBE Configuration Wizard is launched at the end of the CRM SBE installation, but you can cancel it and run it later.

    Even though the Wizard is titled "SBE", you may also run the Wizard on a CRM Professional installation ( all of the above screen shots are from my development system, which is CRM Professional ).

    The configuration file created by the Wizard is to only be used by the Wizard to implement your changes. It is not in a format that is compatible with the CRM Customizations Import process.

    I know of no method of adding information to the Wizard to add additional Industries, etc., so we're pretty much stuck with what Microsoft delivers.

    Customization, Dynamics CRM, Installation
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    2,407 views
  • Changing Navigation Titles for "Sub-" Entities

    Posted on December 10th, 2006 mitch Print Print No comments

    Ok, that is a horrible title but I really wasn't sure how to word it.  But anyway, a couple of weeks ago I was digging around inside CRM when I noticed something unexpected that has caused me more than a bit of concern and effort in the past.

    As you probably know by now, you can rename CRM entities to match your business processes and definitions.  That's one of the coolest features about Dynamics CRM.

    So let's say we take Account and change it to Customer, since that is how we refer to the people who buy our products and services.  That's all well and good since CRM now matches our business process.  But now I have a really irritating problem:  Take a look at the following picture that shows the navigation pane that is displayed when you open or edit a Customer:

    As you can see, Sub-Accounts is still the name for child accounts, instead of Sub-Customers.  This is where my discovery comes into play.

    Let's Customize the Customer Entity, by performing the following steps:

    1) Select Settings, Customization, Customize Entities.

    2) Edit the Customer Entity ( what was once the Account Entity ).

    3) Click the Messages link under Details.

    4) Scroll down until you find "Sub-Accounts" and double-click that entry and you should see the following dialog box:

    5) Change the Custom Display String from "Sub-Accounts" to "Sub-Customers".

    6) Click the Save and Close button to save your changes to the Message and again to save your changes to the Customer Entity.

    7) Click the Publish button to publish the Customer Entity customizations.

    8) Edit one of your Customers.  You should the following change to the navigation bar:

    So now the Entity and Sub-Entity messages match, and the perfectionist in me is satisfied enough to let myself relax and go back to watching the Dallas Cowboys play football. :)

    Customization, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (3 votes, average: 5.00 out of 5)
    Loading ... Loading ...
    972 views
  • The ultimate web site error message

    Posted on December 8th, 2006 mitch Print Print No comments

    I love people with an honest sense of humor.

    Misc
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    1,778 views
  • MSDNWiki is live

    Posted on December 8th, 2006 mitch Print Print No comments

    [via Brad Abrams]

    Microsoft has added a Community Content feature to the MSDN site that will allow users to add their own content:

     

     

    I think this is just amazing and one of the coolest things Microsoft has done in quite a while.

    Now if we can just talk them into extending that feature over to the CRM SDK section.  That would be really cool. ( and yes, I checked it out before I wrote this – it's not there. )

    Some cool links:

    The Statistics page: http://msdn2.microsoft.com/en-us/library/default.aspx
    RSS Feed: http://msdn2.microsoft.com/en-US/library/Community-Edits(d=rss).aspx
    For .NET Framework 2.0 reference: http://msdn2.microsoft.com/en-us/library/ms229335(VS.80).aspx
    For .NET Framework 3.0: http://msdn2.microsoft.com/en-us/library/aa388745.aspx

    Development, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    968 views
  • Recovering from a bad SiteMap customization

    Posted on December 8th, 2006 mitch Print Print No comments

    There are really not too many customization points with CRM and those are fairly well protected, so it takes a lot to make CRM mad.

    But, adding invalid information to the SiteMap and importing that site map will do it.

    The CRM SiteMap is treated a bit differently from other customizations in that SiteMap customizations are immediately published.  This means if you have SiteMap customization issues, you will have an unuseable system, like this:

    In case you didn't know, it's really hard to change CRM when you can't get past the opening page.  Luckily, there is a work around ( as documented in the CRM SDK readme ).

    If you open the following URL:

    http://[CRM_Server]/tools/systemcustomization/
    ImportCustomizations/importCustomizations.aspx

    The import customization page will be displayed. This will allow you to import a corrected SiteMap.  Just load the main CRM page again after you perform the import.

    Note: In some cases, you may need to clear the browser cache and/or perform an IISReset in order for the revision to take effect.

     

    And what where you doing to cause the above error?

    I was modifying navigation of the Marketing area to show the "Groups," using the following code:

     

    <?xml version="1.0" encoding="utf-8" ?>
          <Area Id="MA" ResourceId="Area_Marketing"
    		Icon="/_imgs/marketing_24x24.gif"
    		DescriptionResourceId="Marketing_Description"
    		ShowGroups="true">
            <Group Id="MA">
              <SubArea Id="nav_leads" Entity="lead" />
              <SubArea Id="nav_accts" Entity="account" />
              <SubArea Id="nav_conts" Entity="contact" />
              <SubArea Id="nav_lists" Entity="list" />
              <SubArea Id="nav_campaigns" Entity="campaign" 
                       Url="/MA/home_camps.aspx" />
              <SubArea Id="nav_products" Entity="product" />
              <SubArea Id="nav_saleslit" Entity="salesliterature" />
              <SubArea Id="nav_minicamps" ResourceId="Menu_Label_Mini_Campaigns"
    			DescriptionResourceId="Quick_Campaign_Description"
    			Icon="/_imgs/ico_18_minicamps.gif"
    			Url="/MA/home_minicamps.aspx">
                <Privilege Entity="activitypointer" Privilege="Read" />
              </SubArea>
            </Group>
            <Group Id="ExtensionsMA" ResourceId="Group_Extensions"
                        Title="Company Extensions">
              <SubArea Id="new_realtor" Entity="new_realtor" />
              <SubArea Id="new_lender" Entity="new_lender" />
              <SubArea Id="new_lendercontact" Entity="new_lendercontact" />
              <SubArea Id="new_realtorcontact" Entity="new_realtorcontact" />
              <SubArea Id="new_titlecompany" Entity="new_titlecompany" />
              <SubArea Id="new_titlecompanycontact" 
                        Entity="new_titlecompanycontact" />
              <SubArea Id="new_community" Entity="new_community" />
            </Group>
          </Area>

     

    I had added the ShowGroups parameter to the Marketing Area to get the "TreeView" effect you see in the Workplace area.  As the error message states, the "MA" Group does not have a Title and CRM needs a Title to display properly.  I corrected this problem by changing that line to:

     

    <Group Id="MA" Title="Marketing">
    

    This resulting in the following:

    Pretty cool, huh?

    Customization, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    1,007 views
  • Finding Shared CRM Accounts, Part 2

    Posted on December 6th, 2006 mitch Print Print No comments

    I just love the CRM community.  Ayaz Ahmad posted a comment on the previous article about finding Shared CRM Accounts and included a C# function written to perform a similar function to the SQL code in the other article. 

    Ayaz's version uses the CRM SDK to retrieve all of the accounts for a specified Team instead of performing a SQL query.  This will allow you to add it to an application without having to resort to performing direct SQL Queries. 

    This the example will place the Account Names into a ListView and is used like this:

    // This is the Guid from the Everyone Team on my development
    // system. You will need to substitute a real Guid from
    // your system to make this function correctly.
    Guid TeamID = new Guid("3146CAE5-B13E-DB11-ADAF-00142A05B544");
    ListSharedObjectByTeams(TeamID);
    

     

    and here is the function that does all of the work.

    void ListSharedObjectByTeams(Guid TeamId)
    {
        try
        {
    	CrmService service = new CrmService();
    	service.Credentials = System.Net.CredentialCache.DefaultCredentials;
    
    	// Create the ColumnSet indicating the fields to be retrieved
    	ColumnSet cols = new ColumnSet();
    
    	// Sets the ColumnSet's Properties
    	cols.Attributes = new string [] {"name", "accountid"};
    
    	// Create the QueryExpression Object
    	QueryExpression query = new QueryExpression();
    
    	// Set the QueryExpression Object's Properties
    	query.EntityName = EntityName.account.ToString();
    	query.ColumnSet = cols;
    
    	// Retrieve the Contacts
    	BusinessEntityCollection bus = service.RetrieveMultiple(query);
    	for (int i = 0; i<bus.BusinessEntities.Length; i++)
    	{
    		account acct = (account)bus.BusinessEntities[i];
    
    		TargetOwnedDynamic target = new TargetOwnedDynamic();
    		target.EntityId = acct.accountid.Value;
    		target.EntityName = EntityName.account.ToString();
    
    		// Get Shared Access Rights
    		RetrieveSharedPrincipalsAndAccessRequest access = new
    		RetrieveSharedPrincipalsAndAccessRequest();
    		access.Target = target;
    
    		RetrieveSharedPrincipalsAndAccessResponse accessResponse =
    		(RetrieveSharedPrincipalsAndAccessResponse)
                         service.Execute(access);
    		foreach (PrincipalAccess principalAccess in
    			accessResponse.PrincipalAccesses)
    		{
    		     switch (principalAccess.Principal.Type)
    		     {
    			case SecurityPrincipalType.Team:
    			    if (principalAccess.Principal.PrincipalId
                                         == TeamId)
    			    {
                                         // Add the Account Name to the ListView
    				listAvailable.Items.Add(acct.name);
    			    }
    			break;
    		    }
    		}
    	}
         }
         catch(Exception ex)
         {
    	throw(ex);
         }
    }

    Thanks for sharing Ayaz.

     

    By the way, Ayaz is a big part of the Microsoft CRM Pakistan User Group.

    MSCRMPUG (Microsoft CRM Pakistan User Group) is an INETA chartered user group, a Microsoft Dynamics Related Community, Culminis ALLIANCE and O'Reilly User Group Professional Association. This group is set up in mind of the growing numbers of Microsoft Dynamics CRM (pronounced as Customer Relationship Management) users in Pakistan. It provides members with the base for communicating with each other to share ideas and exchange contacts as well as helping each other in development work and to discuss technical issue regarding implementation, customization, Development and extending MSCRM in small and medium businesses. A group open to all users, administrators, developers and consultants working with Microsoft Dynamics CRM (Customer Relationship Management).

    Customization, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    1,698 views
  • CRM, ISVReadiness, and XML Parsing

    Posted on December 6th, 2006 mitch Print Print No comments

    Morning Everyone,

    This may be way to deep-geek for most of you, but I ran into something this morning that may be of interest to those of you who work with CRM's XML config files.

    I was extending the IsvConfigCustomizer code that ships as part of the ISVReadiness sample code from the CRM SDK to iterate through the Entities section of the ISV.Config file to pull the names of CRM Entities that have had ISV customizations added.

    The XML looks like this:

        <Entity name="campaignactivity" />
        <Entity name="campaignresponse" />
        <Entity name="incident" />
        <!-- Case -->
        <Entity name="quote" />
        <Entity name="salesorder" />
        <!-- Order -->

    Everything worked fine, until I hit that comment line containing the word Case.  Since it is a comment, it has no attributes. Since I am looking for an attribute called name, my code was failing.

    Luckily, the .NET XmlNode class has a corresponding XmlNodeType property that allows me to see if I have encountered a comment or not.  The following code ensures I have not encountered a comment before I add the Entity name to my array:

     

    XmlNode docRoot = GetConfigurationNode().SelectSingleNode("Entities");
    
    int iCount = docRoot.ChildNodes.Count;
    
    ArrayList sArray = new ArrayList();
    for(int i = 0; i < iCount; i++)
    {
    	if (docRoot.ChildNodes[i].NodeType != XmlNodeType.Comment)
    	{
    		XmlAttribute xAttrib = docRoot.ChildNodes[i].Attributes["name"];
    
    		if xAttrib!= null)
    		{
    			sArray.Add(xAttrib.InnerText);
    		}
    	}
    }
    
    Customization, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    1,160 views