Friday, June 11, 2010

Views in MS CRM 4.0

There are two types of views that are centrally administered: 

1.Public View: Views that all users can see, including the default public view ( The default view users see when they are in a list. ) , and any new views you create from the Customize Entities area.

2.System-Defined Views . Views that are provided for all entities, and cannot be deleted or shared: Quick Find Views , Advanced Find Views, Associated Views , and lookup Views.

Quick Find Views:Views used to display results of searches done using the Search for records box.

Advanced Find Views:Views used to display results of searches created with Advanced Find.

Associated View:Views that are displayed in the forms of other entities. The associated view is different from the views that are visible for the entity in its own area of the user interface. For example, in an account record, under Details, you can click Contacts to view and open a contact form. That is the Contacts associated view. There can be only one associated view of each entity. 

Lookup Views:The views used when a user clicks a lookup field.

Web Services in MS CRM 4.0

Web Services

There are three types of Web Services use iin MS CRM 4.0 which are as following:

1. CRM Web Service:This is the "main" Web service. It handles the manipulation of an organization's transactional data.There are Six methods which are used for performing the operation on CRM Database i.e. Create,Update,Delete,Retrieve,Retrieve Multiple & Fetch.

2.CRM Discovery web Service:You can use this service to "discover" information about tenants (organizations) on a server (deployment). In some modes it will also issue security tickets.

3. Metadata Web Service:This service handles the manipulation of an organization's metadata (schema).It is used to perform read/write operation on CRM database for entities and their realtionship.

Using Web services is the standard way to connect to Microsoft Dynamics CRM and manipulate the data and schema of the system. Many assumptions you might have made with Microsoft Dynamics CRM 3.0, which is single tenant, must be reconsidered. Our Web service is a SOAP service, which we feel is a great fit for a complex business system such as Microsoft Dynamics CRM. 

Thursday, June 10, 2010

Removing Duplicate Records from CRM

After a recent migration, we had a number of duplicate account records in CRM. We were loading hundreds of thousands of records for performance testing, and then we wanted to continue to use the same database for integration development, so we wanted to clean up the data and get rid of duplicates to minimize errors with the integration. You can use the built-in Duplicate Detection to identify duplicate records, but this doesn't help you get rid of them - you would still have to manually merge or delete the records that the Duplicate Detection identifies.

One of the challenges is that, while it's relatively easy to locate duplicates, you don't want to delete all of them - you want to keep one of the potential duplicates. After doing some searching and testing, here's what I came up with. It's a very simple (and entirely unsupported) SQL query to identify the duplicate accounts.


UPDATE Account
SET deletionstatecode = 2
WHERE accountid IN
( SELECT a.accountid
FROM Account a, Account b
WHERE a.accountid != b.accountid
AND a.accountnumber = b.accountnumber
AND a.statecode = b.statecode
AND a.accountid < b.accountid )

Here's how this works: The inner SELECT identifies accounts where the accountnumber and statecodes match, and, by using two aliases for the account table, it compares the ID of the accounts to each other. The UPDATE statement sets the deletionstatecode to a value of '2' which is a hard delete. The next time the deletion procedure runs on the database, it will clean out all the account records that have deletionstatecode set to 2.

Pre and Post Images!!!!!

When the plugin action is a Create then you can only have a Post Image because Pre Image does not exist.

When the plugin action is a Delete then you can only have a Pre Image because the Post Image does not exist.

If you try to use a Pre Image on Create or a Post Image on Delete the plugin will fail before it even reaches your code.

In all the rest you should be able to have both the Pre and Post Images available

Showing and hiding fields based on another field

This is not a new topic, but it does creep up in the forums from time to time. I thought it may be easier to write a blog entry on the topic.

So here is the scenario, you have a picklist (or any other field) and you want to show and hide other fields based on this. Let's say your picklist field is called "mypicklist" and you have two other fields, one is a text field called "mytextfield" and one is a lookup called "mylookup". The values in the picklist are "Show Text Field", with a value of 1 and "Show Lookup Field" with a value of 2. You want to show/hide the fields accordingly.

Firstly you need to write the following code in the mypicklist onChange event:

if (crmForm.all.mypicklist.DataValue == 1) //show text field
{
//hide the lookup
crmForm.all.mylookup.style.display = 'none';
crmForm.all.mylookup_c.style.display = 'none'; //note the _c
crmForm.all.mylookup_d.style.display = 'none'; //note the _d, only required for lookups

//show the text field
crmForm.all.mytextfield.style.display = 'inline';
crmForm.all.mytextfield_c.style.display = 'inline'; //note the _c
}
else if (crmForm.all.mypicklist.DataValue == 2) //show loookup
{
//hide the lookup
crmForm.all.mylookup.style.display = 'inline';
crmForm.all.mylookup_c.style.display = 'inline'; //note the _c
crmForm.all.mylookup_d.style.display = 'inline'; //note the _d, only required for lookups

//show the text field
crmForm.all.mytextfield.style.display = 'none';
crmForm.all.mytextfield_c.style.display = 'none'; //note the _c
}
else // hide all
{
//hide the lookup crmForm.all.mylookup.style.display = 'none';
crmForm.all.mylookup_c.style.display = 'none'; //note the _c
crmForm.all.mylookup_d.style.display = 'none'; //note the _d, only required for lookups

//show the text field
crmForm.all.mytextfield.style.display = 'none';
crmForm.all.mytextfield_c.style.display = 'none'; //note the _c
}

As you can see, each field has two (three for lookups) sections that has to be hidden, the first section is identified by the field schema name and represents the textbox area. The second, represented by the fieldname following by an "_c" represents the label area. Lookups also has an additional area, replresented by the fieldname followed by an "_d" which represents the lookup button. Each of these sections needs to be shown/hidden individually.

The second part is ensuring these are hidden/shown after they are saved, so the exact same code above needs to be placed in the form load event too. It may also make your life easier to create a global function in the onload event and then call this function from both within the onload event and the picklist onchange event. Something like:

ShowHideField = function()
{
//all the above code goes in here
}

// then call the above in both the onload and the relevent onchange event
ShowHideField();

The above goes for most field types and you can also show or hide fields based on whether they contain data or not with the following:

if (crmForm.all.mypicklist.DataValue != null) //show text field
{
...
}

Copying a Microsoft CRM Workflow

Copying a Workflow seems like a time-consuming manual process of re-creating a workflow by re-entering it into CRM. But there is a very simple option.

As you probably know, you can create a workflow as a normal workflow, or as a workflow template. When you create a workflow template, you can easily use the template as a starting point to creating more workflows. What you may not have known is that your existing workflow can be saved as a template - then you can use the template to make copies.

Here's the process:

(1) Open the workflow that you want to copy.

(2) Unpublish the workflow (careful: if the workflow is in production, you may want to make sure that all open instances of the workflow have completed running and that the workflow will not be needed for the next few steps - best to do this between the hours of 1:00 am and 3:00 am )

(3) Convert the workflow to a template. This is accomplished by opening the unpublished workflow, and selecting "Workflow Template" for the field titled "Publish As"

(4) Publish the template: Before you can use the template, you have to publish it. You publish a template in the same manner that you publish a normal workflow (i.e. click the "Publish" button).

(5) Create a new workflow. Use the template you just created to create this new workflow. If you wanted to keep your old workflow running while you develop a new one, then go ahead and publish this new one immediately - and then create another new workflow that you will use to make your changes.

Copyright ©2010 Kumar's Blog

CRM 4 Auto-Numbering – A plugin approach




CRM 4 has lots of excellent customization options, one of which is the auto-numbering of entities:

The Settings – Administration section allows you to setup some options for auto-numbering your entities, you can choose the prefix, and the suffix length:









This feature is pretty powerful, but how would approach this problem if you needed your entities to have a more complex numbering scheme? So I would start with a plugin that implements the IPlugin interface:



public class AutoNumber : IPlugin

Then we need to implement the Execute method such as:

public void Execute(IPluginExecutionContext context)
{
   if (context.InputParameters.Properties.Contains("Target"))
   {
     DynamicEntity entity = (DynamicEntity)context.InputParameters.Properties["Target"];

         if (entity != null)
      {
            if (!entity.Properties.Contains("AttributeName"))
          {
                 entity.Properties.Add(new StringProperty("AttributeName", GetAutoNumber()));
         } 
      }
   }
}


Explanation:- The above code will check to make sure the input properties contains the ‘Target’ parameter, this will be the entity that is affected by the plugin. From here we can cast it to a DynamicEntity which will make it easier to work with. Once we have an instance of DynamicEntity the whole task of updating and attributes becomes trivial, the above code just creates a new property and calls some method that will generate the complex AutoNumber.


Once the plugin has been developed, the next important step is to register the plugin. The best tool for the job is probably the CRM Plugin Registration Tool:


NOTE:-

For above Plug-in we will choose the following options:

Message: Create (since we are doing an auto number, it makes sense to only run the plugin at the create stage)

Primary Entity: Your choice

Post Stage: we want to run it after the entity has been created, otherwise the built in CRM auto numbering will overwrite our value.

Synchronous: lets fire the event synchronously, no reason not to, the end user will be presented with a consistent interface this way.

Step Deployment: your choice

Triggering Pipeline: Parent