Tag Archives: crm

CRM 2011 Duplicate Checking Enhancements in Rollup 5

Microsoft CRM’s duplicate checking feature has always had a ‘quirk’ that bugged me.  Good news though, rollup 5 introduces a solution.   I’m not seeing this enhancement getting much mention so thought I would explain the enhancement and why you need to make use of it.

I talk about the limitation in this older post.  In a nutshell pre-rollup 5 any duplicate detection rules you defined would match blank fields to blank fields.  For example if you defined a rule that matched on first name + email address and you had a record with a first name of “Adrian” that had a blank email address then any future “Adrian” records who also had a blank email address would be considered a potential duplicate:

Existing record:

image

New record being entered:

image

Potential duplicate detected:

image

What Rollup 5 gives us is nice little check box that addresses this issue:

image

If you’re making use of CRM’s duplicate detection features you will definitely want to revisit your rules and consider checking this option.   Do remember as you test this that anytime you re-publish your rules CRM has to rebuild its match codes, so the change is not immediate.  There is a system job you can see attached to the Duplicate rule, that might be the one to monitor.

Now, if Microsoft would just tidy up the Duplicate Detection window and make that a bit more user friendly (or give us the ability to customise it) we would have a really nice solution.

Smile

Advertisements

VirtualBox Network Configuration for Microsoft CRM 2011

I tend to live inside VirtualBox VM’s whenever I’m working on CRM presales or projects.  For the most part I work inside a single box solution where I have 1 VM running as Domain Controller, SQL Server and CRM Server.  I also tend to have the CRM Outlook Client installed, hooked up to a Hotmail account.  My host machine has 8GB RAM and 4 cores, I allocate the VM 4.3GB and 2 cores.  This generally works well. 

Every now again though I want to add a second VM to this environment, either to isolate a CRM Server component like the Asynchronous Service or to add a Windows client machine to the environment.  

Now things get tricky as we have to start understanding VirtualBox networking.   Well that doesn’t appeal to me, so instead here’s a cheat sheet you can follow to network your 2 VMs together and retain internet connectivity. 

Thanks to my Avanade colleague Safiulla MohamedAli for helping me out with this…


On your CRM server you need to have 2 network adaptors defined.   Adaptor 1 should be defined as per below:

image

(this gives us internet connectivity by piggy backing off of the host machine)

And Adaptor 2 should look like this:

image

(this adaptor connects the VM to an internal network called “intnet”)

If you already have 2 adaptors defined you can edit these whilst the VM is running via the Devices menu option.  Otherwise you will need to shutdown your VM and then set from the Oracle VM VirtualBox Manager:

image

Inside the VM we need to do a couple of things. 

  1. Open the Network and Sharing Centre
  2. Click change adaptor settings
  3. Right-click on the second adaptor and select Properties
  4. Set the IP addresses as per below:

image

What we are doing here is assigning the CRM Server a fixed IP address and telling it to use the locally installed DNS server.

Ok, good, we’re done with the CRM Server. 

Switch over to your second machine.  In my case, my second machine is a Windows XP SP3 VM (assigned 1GB RAM and 1 core).

Here again we need to have 2 adaptors.  The first should look like this:

image

(this gives us internet connectivity by piggy backing off of the host machine)

And the second adaptor should look like this:

image

(here we are connecting this VM to our “intnet” internal network, where the CRM Server is also connected).

Again, we need to go and tweak the adaptors…

  1. Open the Network and Sharing Centre
  2. Click change adaptor settings
  3. Right-click on the second adaptor and select Properties
  4. Set the IP addresses as per below:

image

What we are doing here is giving this machine a fixed IP address and then telling it to refer to the CRM Server for it’s default gateway and DNS server.

And we’re done.  We should now have both VMs sitting on the same network and both enabled for internet access.

There may well be other ways to do this and this might not be the best way.  But it works for me!  Hope this helps someone.

Smile

Working with Display Rules in CRM 2011–Ribbon Customisation

In this post I provide a quick guide on how to apply Display Rules to your custom ribbon buttons in Microsoft CRM 2011.

Firstly, here’s a quick run through on how to apply a Display Rule.

I have added a custom button to the Campaign form’s ribbon, as per below:

image

To add a display rule to limit when the button should appear I need to do 2 things:

1. Define the Display Rule

2. Assign the Display Rule to the button

To define the Display Rule we need to add the following to our customization.xml file:

image

This can be read as: 

“I want to define a new display rule called "GT.campaign.Form.Star.FormStateNotCreate.DisplayRule".  The rule is the button should only show if the form is not the Create form”.

And then to assign this rule to our button we simply reference the above ID in the Command Definition of our button:

image

Here’s a few more common Display Rule examples:

Display only on Create form:

            <DisplayRule Id="GT.campaign.Form.Star.FormStateCreate.DisplayRule">
              <FormStateRule State="Create" />
            </DisplayRule>

Display only on Update or Create form:

            <DisplayRule Id="GT.campaign.Form.Star.FormStateCreateOrUpdate.DisplayRule">
              <OrRule>
                <Or>
                  <FormStateRule State="Existing"/>
                </Or>
                <Or>
                  <FormStateRule State="Create"/>
                </Or>       
              </OrRule>
            </DisplayRule>

Do NOT display when Offline:

            <DisplayRule Id="GT.campaign.Form.Star.IsOffLine.DisplayRule">
            <CrmOfflineAccessStateRule
               Default="true"
               State="Online"  />
            </DisplayRule> 

Call Centre Optimised CRM–An Example Solution

CRM in the Call Centre is a different beast from regular CRM with factors such as telephony integration and click minimisation playing a big influence.  In this post I will present an example approach to optimising the Call Centre Agent experience in a Customer Service environment.  Every customer scenario is different so this is not meant to be an all encompassing solution, rather its just an example of how we can streamline the user experience with Microsoft CRM 2011.

In this scenario the CTI is going to always pop the Phone Call form.  If the CTI can match the caller the Phone Call will be pre-populated with the CRM Contact.  Otherwise a dummy “Unknown Caller” Contact will be populated.  The Phone Call will be created by custom code and then launched to the user as a saved record.  

Here’s my phone call screen, as the Call Centre Agent would receive when the CTI has successfully matched to a Contact:

image

And when not matched:

image

When the caller has been matched to an existing Contact in CRM their Case History is displayed on the form (with the help of an HTML web resource):

image

The Call Centre Agent greets the caller and determines their identity and the reason for their call.  Here’s what can happen:

Use Case 1:

If the caller has been correctly matched by the CTI and they are calling in regards to an existing Case the Agent will click the Existing Case button on the Ribbon:

image

This pops a Case lookup window displaying the Cases related to the Caller:

image

The Agent selects the relevant Case, and the lookup window closes, as does the Phone Call form and then the Case form pops for the user:

image 

Also note the Caller’s phone number and email address are populated directly onto the Case record for ease of access.

The user can then progress the Case with the Customer (add Notes, check the status of open activities, resolve the Case, etc.).

Behind the scenes the Phone Call has been linked to the Case (so that it appears under the Case’s History) and it has been auto-completed.   

This scenario has been completed in 2 clicks.  That’s pretty good!

Use Case 2:

If the caller was not matched by the CTI and they are legitimately a first time caller who is not yet in CRM the Agent will click the New Case button on the Ribbon:

image

Immediately the Phone Call form closes and a Case form is popped:

image

Now if we cater for anonymous callers then this Case can be progressed just like any other case.  It is already attached to our “Unknown Caller” Contact.

Otherwise, you will notice the Case form has a Quick Create New Contact section on the form (a customisation I have blogged about previously).  The Agent can easily populate this section…

image

… and the Contact will be created and the Case re-associated accordingly:

image

Again, behind the scenes the Phone Call has been linked to the Case and has been auto-completed.

This solution also supports the following use cases:

– The caller is not auto-matched by the CTI as they have called from a different number.  The Agent can simply use the Contact lookup field on the Phone Call form to locate their Contact record.   The process flow then continues as if they were matched by the CTI.

– The caller is matched by the CTI but they are calling in regards to a new issue.  This scenario starts of like Use Case 1 but the user would click the New Case button, and then the scenario follows Use Case 2.

What I like about the solution is:

  • Simplicity for the user – the Phone Call pops, they click either the New Case button or the Existing Case button
  • Processing speed – this solution has the minimal number of clicks possible and does not require the use of the Contact form at any stage
  • Consistent process for emails – this same design could be applied to the Email form for handling inbound customer service emails
  • Automatic activity history – every inbound call results in a (saved) Phone Call activity without any risk of the user not creating/saving the record.  And the Phone Calls are auto-completed for the user.
  • Distinct Cases for each unique Service Request – we are not creating a Case for every call, only when the Agent identifies the call relates to a new issue.
    Hopefully this gives you an idea of what Microsoft CRM is capable of.  Out of the box Microsoft CRM like any CRM system can be a little clunky but the power of Microsoft CRM is its rich (and upgrade friendly!) extensibility.  Don’t be scared of this sort of customisation, Microsoft have designed Microsoft CRM expecting us to configure this types of solutions, and it is more configuration then it is customisation.  After all, I was able to build this out and I’ve never compiled a piece of code in my life.
    If you are not seeing the sort of rich user experience I have described here in your CRM system, well, it’s probably time you found yourself a decent CRM vendor. Smile
      This example solution is available for download here
      To deploy, import the Solution and publish.  Then edit the Configuration entity definition so that it appears in the Settings area (this is meant to appear but didn’t for me when I tested this), create a Contact called “Unknown Caller” and create a Configuration record like the below:

    image

     

    The “Value” you need is the GUID of the Active Contacts view which you can get by opening that view to customise it and then selecting Copy Link from the Actions menu.

     

    Technical Notes

    For those that are curious here’s how I’ve achieved the above.  It’s all real apart from the Case History view which I didn’t bother to build out.

    Phone Call Java Script

    • Change the lookup view of the Sender field to search against Contacts rather than Accounts by default
    • Custom “Existing Case” lookup field added
    • The 2 ribbon buttons were added
    • The “Existing Case” button pops the lookup view of the “Existing Case” lookup field (by firing it’s Click event)
    • Once the “Existing Case” field is populated it is replicated into the “Regarding” field.  Then the SaveAsCompleted function behind the Mark Complete ribbon button is fired.  Then the Case form is launched for the Case GUID specified in the “Existing Case” field.
    • The “New Case” button calls the CRM REST service and creates a new Case record for the Contact specified in the Sender field.  It then populates this Case GUID into the “Regarding” field, fires the SaveAsCompleted function and then launches the Case form.

    Case Java Script

    • Change the lookup view of the Customer field to search against Contacts rather than Accounts by default
    • Hide the Quick Create section unless the Customer field is blank or “Unknown Contact”
    • Once all Quick Create fields are populated the CRM REST service is called to create the new Contact and then that new Contact is populated into the Customer field and the Quick Create section is then hidden
    • Whenever the Customer field changes the CRM REST service is called to retrieve the Contact’s Email Address and Phone Number and these are then populated onto the CRM form

    I have provided sample code for these components in my previous posts. 

    Working With REST Results in CRM 2011

    A short post today.   When using Microsoft CRM 2011’s REST oData End Point to create a new record or to retrieve an existing record the result is provided to you in 2 different ways.  This can catch you out.

    Retrieving Records

    When querying for existing records the result provided by the oData query is an array of CRM records.  You can access that by referring to data.d.results[0] as illustrated below:

    success: function (data, textStatus, XmlHttpRequest) {
    	var Contact = data.d.results[0];
    	if (Contact.Telephone1 != null) {
    		Xrm.Page.data.entity.attributes.get("new_phonenumber2").setValue(Contact.Telephone1);
    		alert("phone set");
    	}
    

    I’m placing the first CRM object in that array into a variable called Contact.  In the above example my query (which I haven’t included) was performing a top1 selection so I am only expecting one record and therefore only interested in the first record (array value 0). 

    I then retrieve the Contact’s phone number by referring to Contact.Telephone1 where Contact is my object variable and Telephone1 is one of it’s attributes.  To know the attribute name and the correct case to use make sure you test your REST query in IE or using the oData Query Designer.

    Creating Records

    When creating a new record you will be returned the object that was created.  This will be just a single CRM object rather than an array of objects.  You can access that by referring to data.[“d”] as illustrated below:

    success: function (data, textStatus, XmlHttpRequest) {
    	var NewCRMRecordCreated = data["d"];
    	alert(NewCRMRecordCreated.IncidentId);
    

    Hope this helps.  Smile

    Adding a new Button Group to the CRM Ribbon

    Here’s a quick run through on how to add a new Group of buttons to the ribbon in Microsoft CRM 2011.

    Here’s the end result that will be achieved:

    image

    In this scenario we are customising the Phone Call entity’s Form ribbon.  In particular the Main Tab of that ribbon (the tab that carries the name of the Entity).

    To implement this change we need to customise the Phone Call entity.  At present CRM does not provide a UI for Ribbon customisations but the customisation XML does support these changes.  So we need the Phone Call entity’s customization xml.   Create a Solution, add the Phone Call entity, export the solution, unzip and then open the customization.xml file in Visual Studio.

    Collapse the EntityInfo and FormXml nodes and you should see the RibbonDiffXml node, this is where we specify changes to the Ribbon.  Replace the CustomActions line with the following XML:

    <CustomActions> 
      <CustomAction Id="Mscrm.Form.phonecall.CustomGroup.CustomAction" 
                    Location="Mscrm.Form.phonecall.MainTab.Groups._children" 
                    Sequence="110"> 
        <CommandUIDefinition> 
          <Group Id="Mscrm.Form.phonecall.CustomGroup.Group" 
                  Command="Mscrm.Form.phonecall.CustomGroup.Command" 
                  Title="Gareths Group" 
                  Sequence="51" 
                  Template="Mscrm.Templates.Flexible2"> 
            <Controls Id="Mscrm.Form.phonecall.CustomGroup.Controls"> 
              <Button Id="Mscrm.Form.phonecall.CustomGroup.Button.A" 
                      Command="Mscrm.Form.phonecall.CustomGroup.Button.A.Command" 
                      Sequence="10" 
                      LabelText="Button 1" 
                      ToolTipTitle="TipTitle" 
                      ToolTipDescription="TipDescription" 
                      TemplateAlias="o1" 
                      Image16by16="/_imgs/ribbon/newchart16.png"  
                      Image32by32="/_imgs/ribbon/newchart32.png"  /> 
              <Button Id="Mscrm.Form.phonecall.CustomGroup.Button.B" 
                      Command="Mscrm.Form.phonecall.CustomGroup.Button.B.Command" 
                      Sequence="20" 
                      LabelText="Button 2" 
                      ToolTipTitle="TipTitle" 
                      ToolTipDescription="TipDescription" 
                      TemplateAlias="o1" 
                      Image16by16="/_imgs/ribbon/CustomEntity_16.png"  
                      Image32by32="/_imgs/ribbon/CustomEntity_32.png"   /> 
            </Controls> 
          </Group> 
        </CommandUIDefinition> 
      </CustomAction> 
      <CustomAction Id="Mscrm.Form.phonecall.CustomGroup.MaxSize.CustomAction" 
                    Location="Mscrm.Form.phonecall.MainTab.Scaling._children" 
                    Sequence="120"> 
        <CommandUIDefinition> 
          <MaxSize  Id="Mscrm.Form.phonecall.CustomGroup.MaxSize" 
                    GroupId="Mscrm.Form.phonecall.CustomGroup.Group" 
                    Sequence="21" 
                    Size="LargeLarge" /> 
        </CommandUIDefinition> 
      </CustomAction> 
      <CustomAction Id="Mscrm.Form.phonecall.CustomGroup.Popup.CustomAction" 
                    Location="Mscrm.Form.phonecall.MainTab.Scaling._children" 
                    Sequence="140"> 
        <CommandUIDefinition> 
          <Scale    Id="Mscrm.Form.phonecall.CustomGroup.Popup.1" 
                    GroupId="Mscrm.Form.phonecall.CustomGroup.Group" 
                    Sequence="85" 
                    Size="Popup" /> 
        </CommandUIDefinition> 
      </CustomAction> 
    </CustomActions>
    

    We are adding 3 Custom Actions here: 

    • The first Custom Action adds the new Group and the 2 Buttons inside that Group.
    • The second Custom Action adds the MaxSize definition for the Group to the Scaling definition of the Ribbon.  This tells CRM how to display the buttons when the screen size does not require any collapsing of the buttons.
    • The third Custom Action adds the Scale definition for the Group to the Scaling definition of the Ribbon. This tells CRM how to display the buttons when the screen size is insufficient.

    To adjust my sample code for your scenario do the following:

    Do a Find and Replace on “phonecall”, replacing with the name of your entity.

    Change the Location value on line 3 to the relevant Group ID of your entity’s Ribbon definition.  I’ll explain.  In my scenario I wanted to add a Button Group to the Phone Call form’s Main tab so I went and found the Phone Call ribbon definition in the SDK here:

      \sdk\samplecode\cs\client\ribbon\exportribbonxml\exportedribbonxml\phonecallribbon.xml

    [UPDATE: 14 Dec 2011 – The latest SDK did not include the ribbon definition XML files forcing you to build and run an app from source code provided in order to generate them for your self. I provide instructions on this process here]

    And looked for my Tab in that file, finding it here (see the yellow highlight below):

    image

    I wanted to add a new Group under the Groups section of the Ribbon so the Location value in our customization file needs to be that Groups Id (highlighted in green above) – appended with ._children.  i.e.:

    image

    That’s all you need to change at this stage.  We’ll come back and personalise other settings in a sec, let’s just try and get the button group to appear first.

    Ok, now we need to add some commands to our customization file.  Replace the CommandDefinitions line with the following XML:

    <CommandDefinitions> 
      <CommandDefinition Id="Mscrm.Form.phonecall.CustomGroup.Button.A.Command"> 
        <EnableRules /> 
        <DisplayRules /> 
        <Actions> 
          <Url Address="http://www.google.com" /> 
        </Actions> 
      </CommandDefinition> 
      <CommandDefinition Id="Mscrm.Form.phonecall.CustomGroup.Button.B.Command"> 
        <EnableRules /> 
        <DisplayRules /> 
        <Actions> 
          <Url Address="http://www.google.com" /> 
        </Actions> 
      </CommandDefinition> 
      <CommandDefinition Id="Mscrm.Form.phonecall.CustomGroup.Command"> 
        <EnableRules> 
          <EnableRule Id="Mscrm.ConvertActivity" /> 
        </EnableRules> 
        <DisplayRules> 
          <DisplayRule Id="Mscrm.ConvertActivity" /> 
        </DisplayRules> 
        <Actions /> 
      </CommandDefinition> 
    </CommandDefinitions>
    

    Here again we have 3 bits, 3 Command Definition’s:

    • The first Command Definition defines what should happen when the first button is clicked.  I just have a hardcoded URL being launched. 
    • The second Command Definition defines the 2nd button’s action.
    • And the third Command Definition defines when the Group of buttons should be enabled and visible.  You can alternatively set these rules per button.  You’ll see I am referring to a rule called “Mscrm.ConvertActivity”.   I got this from the phonecallribbon.xml.  This is the rule used for the Convert to Case button.  I find it’s handy to just steal the rule of another button who’s behaviour you want to mimic.

    To adjust my sample code for your scenario do the following:

    Change the URL being launched by each button or replace s jscript function call like the below:

    image

    And find a Display Rule and Enable Rule in your entity’s ribbon.xml that you can use.  You can’t just use my “Mscrm.ConvertActivity” rule as it may not exist on your entity.

    Ok, that should be enough to get our buttons to appear.  To deploy, zip back up the customization.xml file along with it’s other solution files and then import that solution zip file back into CRM and Publish.  Pop your form and you should now see the new Button group and it’s 2 buttons:

    image 

    To adjust the appearance you can now go back and tweak some of the XML attributes (after which you would re-zip, import and publish).

    To change where the Group appears on the Ribbon change the Sequence value under the Group node:

    image

    Refer back to the entity’s ribbon.xml to see what sequence each existing Group has to figure out what value you need to slot your in between:

    image

    Change the Button Group label and the label of the individual buttons here:

    image

    Change the Button icon here:

    image

    You have 2 approaches for setting the button icons.  You can browse the entity’s ribbon.xml (or any entity’s ribbon.xml for that matter, or even applicationribbon.xml) and steal the path and filename of a button you want to use.   Or, you can upload your own button icons as web resources and then reference the web resource, which is done in this manner:

    Image16by16="$webresource:new_star16x16"  
    Image32by32="$webresource:new_star32x32"
    

    That should be enough to get you going.  Hope this helps someone.

    Smile

    Gareth.

    Editing Ribbon Buttons in CRM 2011

    In my previous posts I provide an introduction to working with the Ribbon in CRM 2011 where I demonstrate how to add and remove buttons.   In this post I will explain how to edit existing buttons.

    Let’s start by framing an example.  On the Phone Call form we have Ribbon buttons for both “Convert to Case” and “Convert to Opportunity”:

    image

    You’ll note the poor Convert to Case button got the short straw and is presented as a small button, whilst the Convert to Opportunity button appears in full and with a text label.    But what if we are implementing CRM for Customer Service?  In that scenario we are unlikely to care about Opportunities and would likely prefer these buttons switched around.   Here’s how we do that…

    As described in my previous posts customising the ribbon involves a bit of initial research and then some manual editing of an exported customization XML file.   For the research component what we need to do is have a look at the ribbon definition for the Phone Call form.  We find that in the SDK here:

    \sdk\samplecode\cs\client\ribbon\exportribbonxml\exportedribbonxml\phonecallribbon.xml

    [UPDATE: 14 Dec 2011 – The latest SDK did not include the ribbon definition XML files forcing you to build and run an app from source code provided in order to generate them for your self. I provide instructions on this process here]

    Open that file in Visual Studio and locate the XML that represents these buttons we want to change.  In this case we want to find the form ribbon’s Main tab:

    image

    Always make sure you are looking at the right Tab as similarly named button may appear on the SubGrid tab and HomepageGrid tabs as well.

    The lesson for first timers I want to reiterate here is DO NOT change this XML file.  It will have no effect.   This file is essentially documentation of the out-of-the-box CRM ribbons it is no way used by CRM to render the ribbons.   To change the ribbon we need to make entries into an exported customization.xml file that contains the definition of the Entity involved.

    So jump back to CRM, create a Solution called PhoneCall and add the Phone Call entity into that Solution.  Export that Solution, unzip the file and then open customization.xml file in Visual Studio.  Collapse the EntityInfo and FormXml nodes and you should see the RibbonDiffXml node, this is where we specify changes to the Ribbon:

    image

    Replace the CustomActions line with the following XML:

    <CustomActions> 
      <CustomAction Id="GT.switch.button.sequence1" 
                    Location="Mscrm.Form.phonecall.MainTab.Convert.Controls._children" 
                    Sequence="1"> 
        <CommandUIDefinition> 
          <Button Id="Mscrm.Form.phonecall.Convert.Opportunity"  
                  Command="Mscrm.Form.ConvertToOpportunity"  
                  Sequence="21"  
                  Alt="$Resources:MenuItem_ToolTip_ConvertToOpportunity"  
                  LabelText="$Resources:MenuItem_Label_ConvertToOpportunity"  
                  Image16by16="/_imgs/ribbon/ConvertOpportunity_16.png"  
                  Image32by32="/_imgs/ribbon/ConvertOpportunity_32.png"  
                  ToolTipTitle="$Resources:Mscrm_Form_Other_MainTab_Actions_Convert_Opportunity_ToolTipTitle"  
                  ToolTipDescription="$Resources:Mscrm_Form_Other_MainTab_Actions_Convert_Opportunity_ToolTipDescription"  
                  TemplateAlias="o2"  
                  /> 
        </CommandUIDefinition> 
      </CustomAction> 
      <CustomAction Id="GT.switch.button.sequence2" 
                    Location="Mscrm.Form.phonecall.MainTab.Convert.Controls._children" 
                    Sequence="2"> 
        <CommandUIDefinition>           
          <Button Id="Mscrm.Form.phonecall.Convert.Case"  
                  Command="Mscrm.Form.ConvertToCase"  
                  Sequence="9"  
                  Alt="$Resources:MenuItem_ToolTip_ConvertToCase"  
                  LabelText="$Resources:MenuItem_Label_ConvertToCase"  
                  Image16by16="/_imgs/ribbon/ConvertCase_16.png"  
                  Image32by32="/_imgs/ribbon/ConvertCase_32.png"  
                  ToolTipTitle="$Resources:Mscrm_Form_Other_MainTab_Actions_Convert_Case_ToolTipTitle"  
                  ToolTipDescription="$Resources:Mscrm_Form_Other_MainTab_Actions_Convert_Case_ToolTipDescription"  
                  TemplateAlias="o1"  
                  /> 
        </CommandUIDefinition> 
      </CustomAction> 
    </CustomActions>
    

    Here’s a breakdown of the XML…

    This first bit:

    image

    Reads as:  “I want to perform a Custom Action, lets call my action GT.switch.button.sequence1.  I want to change one of the child nodes in the ribbon definition under the node that has the Id: “Mscrm.Form.phonecall.MainTab.Convert.Controls”.

    Then we have:

    image

    Here we are defining a button.   Now what I did here was I copy and pasted the definition of the Convert to Opportunity button from phonecallribbon.xml into this customization.xml file.  I then changed the properties that I wanted changed.  Specifically I changed the Sequence so that this button would be rendered after the Convert to Case button (which has Sequence 20) and I changed the TemplateAlias to o2 so that this button will be rendered as a little button.   I think this is important as this button group has been defined as 1 big + 2 small button group and I don’t want to defy that.   Those are the only 2 items I have changed.  Because the Id I have specified for this button matches an existing button CRM knows to merge my definition with its existing definition and overwrite it’s definition with mine, rather than creating a new button.

    In my XML snippet in addition to the above I have a second Custom Action containing a second button definition where I specify the overrides I want to the Convert to Case button.   Each button definition needs to sit under it’s own Custom Action header, hence this structure.

    That’s it.  To deploy we simply zip back up the customization.xml file along with it’s other solution files and then import that solution zip file back into CRM and Publish.  

    Here’s the end result:

    image

    You can follow this same approach to change buttons icons, button labels, etc.

    Note: to retain both buttons as large buttons simply set TemplateAlias="o1" on each:

    image