Bulk Edit and Restriction of bulk edit in Microsoft Dynamics CRM

Hi all,

This post may be very old on bulk edit feautre in Microsoft Dynamics CRM but hope this gives some more information on bulk edit.

Bulk Edit in Microsoft Dynamics CRM:

Editing record is very easy in Microsoft Dynamics CRM.But what if we need to edit a field of all records with same value. So here, Instead of opening records one by one and editing it, we can also use Bulk edit feature which edits that field in one go for all records.

Limitations:

Not so good for large numbers of customer records where results ‘go onto the next page’ of the results grid – you can only select one page of results at a time so you would need to repeat the bulk edit steps.

By default the scripts are disabled for bulk edit forms.But we can enable on load and on change event scripts for bulk edit.

On save scripts will not be triggered while performing Bulk Edit

Restriction of Bulk Edit for particular records:

Because of its limitations thought of Exploring a bit more on bulk edit with a requirement  restricting bulk edit of different owner records.

Steps:

  1. Created a custom entity .Bulk edit previllege will not be available for users unless miscelleaneous previllege Bulk Edit is enabled.Capture
  2. Inorder to restrict bulk edit for particular records , create a enable rule(custom javascript rule) for this button and add a parameter “CRM Parameter” for this enable rule and the name of this parameter “selectedcontrolselecteditemreferences“.
  3. This will retrieve all the selected records by the user for bulk edit

Javascript code:

function run(selectedItems)
{
    
    var selectedItem = selectedItems[0];
    alert(“Id=” + selectedItem.Id + “\nName=” + selectedItem.Name + “\nTypeCode=” + selectedItem.TypeCode.toString() + “\nTypeName=” + selectedItem.TypeName);
}
Here
selectedItem.Id — Selected record Guid
selectedItem.Name — Selected record Name
selectedItem.TypeCode — Entity Type code 
selectedItem.TypeName — Entity schema Name
By using record details we can perform our required actions on bulk edit . We can hide/show edit button based on our requirement .
Javascript for hiding a ribbon button :
function hideRibbonButton()
{
if(selectedItem!=null)
{
return true; // Shows button
}
else
{
return false; // Hides button
}
}
Enabling javascripts on Bulk Edit:

By default the scripts are disabled for bulk edit forms.

To enable the script for Bulk edit forms check the below syntax

<event
active=[“0” “1” “true” “false”]application=[“0” “1” “true” “false”]attribute=”String”
BehaviorInBulkEditForm=”String”
eventType=[“DataEvent” “ControlEvent”]name=”String”></event

Export the entity as solution from CRM system by adding the required entity where bulk edit need to be enabled along with javascript. By default server side events gets enabled for bulk edit. But inorder to enable client side events, open the file  called Customizations.xml from downloaded solution and find  <formlibraries>.

Capture

Note: Microsoft Dynamics CRM provides multi forms and you can enable for single form or multiple forms.

Save and Import the solution, publish it. Now javascript gets enabled on the solution

Performing Bulk Create,Update,Delete by using C# ExecuteMultipleRequest:

Bulk Create:

 

/// <summary>
   /// Call this method for bulk Create
   /// </summary>
   /// <param name="service">Org Service</param>
   /// <param name="entities">Collection of entities to Create</param>
   public static void BulkCreate(IOrganizationService service, DataCollection<Entity> entities)
   {
       // Create an ExecuteMultipleRequest object.
       var multipleRequest = new ExecuteMultipleRequest()
       {
           // Assign settings that define execution behavior: continue on error, return responses.
           Settings = new ExecuteMultipleSettings()
           {
               ContinueOnError = false,
               ReturnResponses = true
           },
           // Create an empty organization request collection.
           Requests = new OrganizationRequestCollection()
       };
 
       // Add a CreateRequest for each entity to the request collection.
       foreach (var entity in entities)
       {
           CreateRequest createRequest = new CreateRequest { Target = entity };
           multipleRequest.Requests.Add(createRequest);
       }
 
       // Execute all the requests in the request collection using a single web method call.
       ExecuteMultipleResponse multipleResponse = (ExecuteMultipleResponse)service.Execute(multipleRequest);
 
   }

 

Bulk Update:

/// <summary>
   /// Call this method for bulk update
   /// </summary>
   /// <param name="service">Org Service</param>
   /// <param name="entities">Collection of entities to Update</param>
   public static void BulkUpdate(IOrganizationService service, DataCollection<Entity> entities)
   {
       // Create an ExecuteMultipleRequest object.
       var multipleRequest = new ExecuteMultipleRequest()
       {
           // Assign settings that define execution behavior: continue on error, return responses.
           Settings = new ExecuteMultipleSettings()
           {
               ContinueOnError = false,
               ReturnResponses = true
           },
           // Create an empty organization request collection.
           Requests = new OrganizationRequestCollection()
       };
 
       // Add a UpdateRequest for each entity to the request collection.
       foreach (var entity in entities)
       {
           UpdateRequest updateRequest = new UpdateRequest { Target = entity };
           multipleRequest.Requests.Add(updateRequest);
       }
 
       // Execute all the requests in the request collection using a single web method call.
       ExecuteMultipleResponse multipleResponse = (ExecuteMultipleResponse)service.Execute(multipleRequest);
 
   }

 

Bulk Delete:

/// <summary>
   /// Call this method for bulk delete
   /// </summary>
   /// <param name="service">Org Service</param>
   /// <param name="entityReferences">Collection of EntityReferences to Delete</param>
   public static void BulkDelete(IOrganizationService service, DataCollection<EntityReference> entityReferences)
   {
       // Create an ExecuteMultipleRequest object.
       var multipleRequest = new ExecuteMultipleRequest()
       {
           // Assign settings that define execution behavior: continue on error, return responses.
           Settings = new ExecuteMultipleSettings()
           {
               ContinueOnError = false,
               ReturnResponses = true
           },
           // Create an empty organization request collection.
           Requests = new OrganizationRequestCollection()
       };
 
       // Add a DeleteRequest for each entity to the request collection.
       foreach (var entityRef in entityReferences)
       {
           DeleteRequest deleteRequest = new DeleteRequest { Target = entityRef };
           multipleRequest.Requests.Add(deleteRequest);
       }
 
       // Execute all the requests in the request collection using a single web method call.
       ExecuteMultipleResponse multipleResponse = (ExecuteMultipleResponse)service.Execute(multipleRequest);
   }

Hope this helps 🙂

 

Duplicate detection in Microsoft Dynamics CRM Using a generic Plugin

Hi all,

Lot of times I used to write different plugins for duplicate detection,but got a thought of writing a generic plugin by passing the the parameters to check duplicates from Un Secure Config in Parameters.

Read the parameters passed from Un Secure Configurations:

I used a generic List for reading the parameters

List<string> parameters=new List<string>();

public CheckDuplicate(string unSecureConfig)
{
foreach (var item in unSecureConfig.Split(‘|’))
{
parameters.Add(item);
}
}

Design Query Expression:

Generic Query Expression is designed in this way

private QueryExpression getQueryExpression(Entity entity, string entityLogicalName, List<string> parameters)
{
QueryExpression query = new QueryExpression();
query.EntityName = entityLogicalName;
query.ColumnSet = new ColumnSet(true);
FilterExpression ft = new FilterExpression();
ft.FilterOperator = LogicalOperator.And;
foreach (var item in parameters)
{
if(entity.Contains(item))
{
if((entity.Attributes[item].GetType().Equals(typeof(Microsoft.Xrm.Sdk.OptionSetValue))) && ((OptionSetValue)entity.Attributes[item]).Value!=null)
{
int attributeValue=((OptionSetValue)entity.Attributes[item]).Value;
ft.AddCondition(new ConditionExpression(item, ConditionOperator.Equal, attributeValue));
}
else if((entity.Attributes[item].GetType().Equals(typeof(Microsoft.Xrm.Sdk.EntityReference))) && ((EntityReference)entity.Attributes[item]).Id!=null)
{
Guid attributeValue = ((EntityReference)entity.Attributes[item]).Id;
ft.AddCondition(new ConditionExpression(item, ConditionOperator.Equal, attributeValue));
}
else if((entity.Attributes[item].GetType().Equals(typeof(Microsoft.Xrm.Sdk.Money))) && ((Money)entity.Attributes[item]).Value!=null)
{
decimal attributeValue = ((Money)entity.Attributes[item]).Value;
ft.AddCondition(new ConditionExpression(item, ConditionOperator.Equal, attributeValue));
}
else if(entity.Attributes[item].ToString()!=null)
{
string attributeValue = entity.Attributes[item].ToString();
ft.AddCondition(new ConditionExpression(item, ConditionOperator.Equal, attributeValue));
}
}
}
query.Criteria = ft;
return query;

}
}

 

Use this Query Expression to retrieve duplicate records present in the system

Complete Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xrm.Sdk;
using System.Runtime.Serialization;
using System.ServiceModel;
using Microsoft.Xrm.Sdk.Query;

namespace duplicateDetection
{
public class CheckDuplicate:IPlugin
{
List<string> parameters = new List<string>();
public CheckDuplicate(string unSecureConfig)
{
foreach (var item in unSecureConfig.Split(‘|’))
{
parameters.Add(item);
}
}
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
if(context.InputParameters.Contains(“Target”) && context.InputParameters[“Target”] is Entity)
{
Entity entity = (Entity)context.InputParameters[“Target”];
string entityLogicalName = entity.LogicalName;
QueryExpression query = getQueryExpression(entity, entityLogicalName, parameters);
EntityCollection duplicates = service.RetrieveMultiple(query);
if(duplicates.Entities.Count>0)
{
throw new InvalidPluginExecutionException(“This record cannot be created since there are duplicates available in the system”);
}
}
}

private QueryExpression getQueryExpression(Entity entity, string entityLogicalName, List<string> parameters)
{
QueryExpression query = new QueryExpression();
query.EntityName = entityLogicalName;
query.ColumnSet = new ColumnSet(true);
FilterExpression ft = new FilterExpression();
ft.FilterOperator = LogicalOperator.And;
foreach (var item in parameters)
{
if(entity.Contains(item))
{
if((entity.Attributes[item].GetType().Equals(typeof(Microsoft.Xrm.Sdk.OptionSetValue))) && ((OptionSetValue)entity.Attributes[item]).Value!=null)
{
int attributeValue=((OptionSetValue)entity.Attributes[item]).Value;
ft.AddCondition(new ConditionExpression(item, ConditionOperator.Equal, attributeValue));
}
else if((entity.Attributes[item].GetType().Equals(typeof(Microsoft.Xrm.Sdk.EntityReference))) && ((EntityReference)entity.Attributes[item]).Id!=null)
{
Guid attributeValue = ((EntityReference)entity.Attributes[item]).Id;
ft.AddCondition(new ConditionExpression(item, ConditionOperator.Equal, attributeValue));
}
else if((entity.Attributes[item].GetType().Equals(typeof(Microsoft.Xrm.Sdk.Money))) && ((Money)entity.Attributes[item]).Value!=null)
{
decimal attributeValue = ((Money)entity.Attributes[item]).Value;
ft.AddCondition(new ConditionExpression(item, ConditionOperator.Equal, attributeValue));
}
else if(entity.Attributes[item].ToString()!=null)
{
string attributeValue = entity.Attributes[item].ToString();
ft.AddCondition(new ConditionExpression(item, ConditionOperator.Equal, attributeValue));
}
}
}
query.Criteria = ft;
return query;

}
}
}

Register the plugin in Pre-Operation of create and pass the parameters from Un secure configuration

Hope this helps 🙂

 

Hide Sub Grid ‘+’ button in Microsoft Dynamics CRM

Hi Folks,

We generally get these scenario lot of times in our requirement as hiding “+” button in Sub Grid.

We can achieve this in two ways .

Using un supported way in javascript and hiding the element :

http://”/webresources/new_Jquery.js”

$( document ).ready(function() {
if (parent.document.getElementById(“subgridname_contextualButtonsContainer”) != null ) {

parent.document.getElementById(“subgridname_contextualButtonsContainer”).style.display=’none’;}

});

Here subgrid name need to be replaced by your subgrid name

Ribbon Work Bench 2016 :

if you didn’t download Ribbon Work Bench you can download it from here Click Here .

Capture

Note : Hiding the + button does not mean users cannot create new records, allowing or forbidding users to create new records should  be configured in their security roles.

 

Hope this helps 🙂

Use Of OData in Javascript in Microsoft Dynamics CRM

Hi Friends,

This will be oldest post you will find in google regarding odata usage in Microsoft Dynamics CRM , but i feel this will give lots of information regarding Odata. Although Microsoft has introduced WEB API in javascript in its latest update, till we can write our queries using OData .

XMLHttpRequest object :

Server requests from browser are made through XMLHttpRequest Object . JavaScript requests use XMLHttpRequest use two functions

  • Send Request – to send request to browser
  • Call Back – to get response browser .

XMLHttpRequest  object has capabilites to send requests to browser and call back (response) requests from browser .

Often we use jquery functions to write these queries , but Microsoft has recommended to user not to use Jquery methods for Querying data . (Here Jquery.Ajax is referred as $.Ajax which uses XMLHttpRequest available in the browser for querying the data from server )

PUT,DELETE,MERGE  requests are noted as POST request .

RETRIEVE request are stated as GET request.

To support versions of Windows Internet Explorer prior to Internet Explorer 7, use the following function to get the XMLHttpRequest object.

//Retrieves XMLHttpRequest object
function GetRequestObject()
{
if (window.XMLHttpRequest)
{
return new window.XMLHttpRequest;
} else
{
try {
return new ActiveXObject(“MSXML2.XMLHTTP.3.0”);
} catch (ex) {
return null;
}
}
}

 

Access the server URL :

The first thing to do when you start to use the ODATA endpoint with JavaScript is establish the URL to the organization root URL

var serverUrl = Xrm.Page.context.getClientUrl();

Create OData Query :

It can be created manually or using CRM rest builder tool

Sample :

var userRolesQuery = “/RoleSet?$top=1&$filter=RoleId eq guid'” + RoleId + “‘&$select=Name”;

Example : Retrieve Security Roles of Logged in User in Microsoft Dynamics CRM

//Main method to retrive all user roles

function getAllUserRoles()
{
var Roles = Xrm.Page.context.getUserRoles();
for (var i = 0; i < Roles.length; i++)
{
var RoleId = Roles[i];
//Query designed by using Odata
var userRolesQuery = “/RoleSet?$top=1&$filter=RoleId eq guid'” + RoleId + “‘&$select=Name”;
var role = null;
role = GetRolesRequest(userRolesQuery);
var RoleName = role[0].Name;

alert(“Role ID=” + RoleId + ” Role Name=” + RoleName);
}
}

NOTE : Xrm.Page.context.getUserRoles() returns an array of GUIDs of roles  that the User currently has

// OData Request :

function GetRolesRequest(query)
{
var serverUrl = Xrm.Page.context.getClientUrl();

var oDataEndpointUrl = serverUrl + “/XRMServices/2011/OrganizationData.svc/”;
oDataEndpointUrl += query;

var service = GetRequestObject();

if (service != null) {
service.open(“GET”, oDataEndpointUrl, false);
service.setRequestHeader(“X-Requested-With”, “XMLHttpRequest”);
service.setRequestHeader(“Accept”, “application/json, text/javascript, */*”);
service.send(null);

var retrieved = JSON.parse(service.responseText).d;

var results = new Array();
for (var i = 0; i < retrieved.results.length; i++) {
results.push(retrieved.results[i]);
}

return results;
}
return null;
}

 

Retrieve XMLHttpRequest  object :

//Retrieves XMLHttpRequest object
function GetRequestObject()
{
if (window.XMLHttpRequest)
{
return new window.XMLHttpRequest;
} else
{
try {
return new ActiveXObject(“MSXML2.XMLHTTP.3.0”);
} catch (ex) {
return null;
}
}
}

Hope this helps 🙂

On Premise Installation of Microsoft Dynamics CRM 2015/2016 Server

Hi folks,

We all get lots of information for setting up Micrsoft Dynamics CRM 2015/2016 server in on premises.In this post, i will explain clearly about setting up Microsoft Dynamics CRM 2015/2016 server on premises.

Active Directory setup on Windows Server 2012 :

  1. Open the Server Manager from the task bar.
  2. From the Server Manager Dashboard, select Add roles and features.

    This will launch the Roles and Features Wizard allowing for modifications to be performed on the Windows Server 2012 instance.

  3. Select Role-based or features-based installation from the Installation Type screen and click Next.
  4. The current server is selected by default. Click Next to proceed to the Server Roles tab.

     

  5. From the Server Roles page place a check mark in the check box next to Active Directory Domain Services. A notice will appear explaining additional roles services or features are also required to install domain services, click Add Features.
  6. Review and select optional features to install during the AD DS installation by placing a check in the box next to any desired features, and then click Next.Capture 
  7. Review the information on the AD DS tab and click Next.

     

  8. On the Confirm installation selections screen, review the installation and then click Install.

Configure Active Directory:

Once the AD DS role is installed the server will need to be configured for your domain.

  1. If you have not done so already, Open the Server Manager from the task bar.
  2. Open the Notifications Pane by selecting the Notifications icon from the top of the Server Manager. From the notification regarding configuring AD DS, click Promote this server to a domain controller.Capture.PNG
  3. From the Deployment Configuration tab select Add a new forest from the radial options menu. Insert your root domain name into the Root domain name(EX:CONTOSO.com) field, and then click Next.
  4. The system checks to ensure all necessary prerequisites are installed on the system prior to moving forward. If the system passes these checks, proceed by clicking Install.

Install SQL SERVER on Windows Server 2012 :

If you haven’t already downloaded SQL Server 2012 Express, you can get it from Microsoft here.

Step 1.
To begin, launch the install program and choose the top option to install a new stand-alone installation.

Capture.PNG

Step 2.
Read and accept the license agreement and click next. At this point you can choose the features that you want to install. You can also change the install folder if you do not want to install to the default location.

Click Next to continue.

Capture

Step 3.
Now you can configure the SQL instance. If this is the first instance of SQL Server on your computer, you probably want to change this setting to Default instance.  If you already have another instance of SQL Server, you will want to use Named Instance and give it a name.

Click Next to continue.

Capture

Step 4.
The next step is server configuration. From here you can change the Windows services associated with this instance of SQL Server. You can keep the defaults here unless you want to specify different user accounts for the services. You can also change the default collation settings if you are not in the United States.

Click Next to continue.

Capture.PNG

Step 5.
Now we come to the Database Engine configuration. On the Server Configuration tab you can select whether SQL Server will only authenticate using Windows accounts or you can choose Mixed Mode which will allow Windows accounts and SQL accounts

Capture

Step 6.
On the Data Directories tab you can change the locations of various files that SQL will use. Depending on your server configuration and the load that will be put on SQL, you may want to put the database and log folders on separate drives. For most people, you can leave the default values.

Click Next to continue.

Capture

Step 7.
The next step configures Reporting Services. Set this to Install Only if you don’t need reporting services or may need them in the future.  You can always go back and configure it later.

Click Next to continue.

Capture

Step 8.
On the Error Reporting step, you can choose whether or not you would like to send error reports to Microsoft to help them improve future releases of SQL server.

Click Next to continue.

Capture

At this point, SQL server will install on your computer.  This could take a while to complete depending on the computer you are using.

Capture

Once the installation has completed, you will receive a screen showing the details of what was completed and if there were any problems.

Capture

If everything completed successfully, you can close the window and begin using your new copy of SQL Server 2012 .

Make Sure these services are running fine, if not open services.msc and start the services.

Capture

Install Microsoft Dynamics CRM 2015 :

If you haven’t already downloaded  Dynamics CRM 2015 Server you can get it from Microsoft here.

Launch the installation wizard :

Capture

Step 2:

Capture

Make sure these updates will not create any hindrances in the system and Click next.

Capture

Microsoft provides 90 days free trial for on premises installation . you can get the key  here for trial version Evaluation Key .

Install Required Components:-

If Setup detects that components are missing, the Install Required Components page appears.

Note :- If you are prompted to restart the computer, do so, and then start Setup again

Capture.PNG

Capture

Either accept the default location or enter a different file installation location, and click on Next.

Capture

Select all roles to install

Capture

Specify Deployment Options page, select the name of the computer that is running SQL Server to use the deployment box, type or select the instance of Microsoft SQL Server that will be used to store the Dynamics CRM database (MSCRM_CONFIG)

Capture

Click on Browse to display your Active Directory structure. Select the location where you want the Microsoft Dynamics CRM organizational unit to be installed, click on OK, and click on Next. Microsoft Dynamics CRM security groups are  created in this organizational unit.

Capture

Specify Service accounts :

Capture

 

On the Select a Web Site page, click Create a new Web site or click Select a Web Site and select a website from the list. By default, Setup will use the default website.

When you select the Create a new Web site option, Setup creates a new website for Microsoft Dynamics CRM. You can specify the following option:

Port Number: Type the TCP port number that Microsoft Dynamics CRM clients will use to connect to the Microsoft Dynamics CRM Server 2015. The default port number is 5555. Click on Next

Capture

Specify the Organization Settings:-

On “Specify the Organization Settings” page, specify the following information.

1.   In the Display Name box, type the name of your organization.

2.   In the Unique Database Name box, you can keep the name that is automatically generated or you can type a unique name that must be limited to 30 characters. Spaces and extended characters are not allowed.

3.   Under ISO currency code, click Browse, select the ISO currency code that you will use as the base currency for the organization in the list, and then click OK.

You can change the currency’s symbol, name, or precision.

4.   In the SQL collation list, keep the default selection or select a different database collation that the organization database will use to sort and compare data characters.

Important:-

After Setup is complete, you cannot change the database collation, base ISO currency code, or the organization unique name. However, you can change the base currency name and base currency symbol.

Capture

On the Specify Reporting Services Server page, type the Report Server URL. Make sure that you use theReport Server URL, not the Report Manager URL.

To verify that you are using the correct URL, in a browser, type the Report Server URL as the address.

Capture

This page is a summary of all requirements and recommendations for a successful installation. Errors must be resolved before installation can continue. If no errors or only warnings appear, you can continue with the installation. To do this, click on Next

Capture

Capture

Click on install

Capture

Installation take awhile to complete and setup the Reporting extensions .

Here is an excellent video tutorial for Setting up Dynamics CRM 2015  Video

Hope this helps  🙂

 

 

Assign owner of a record in Microsoft Dynamics CRM using C#

Hi all,

There are few  scenarios in Microsoft Dynamics CRM where we come across to assign the owner of a record pro-grammatically using C# to achieve the business requirement.

Recently i came across a scenario from my client where i need to assign the owner of a Manufacturer(User/Team level entity) based on the channel(Lookup) in Microsoft Dynamics CRM.

In order to achieve this , Microsoft has provided us with AssignRequest class in Microsoft Dynamics CRM.

Assign Request Class :

AssignRequest assign = new AssignRequest
    {
        Assignee = new EntityReference("systemuser",
            new Guid("userguid")),
        Target = new EntityReference("TargetEntity",
            "TargetentityrecordGuid")
    };


// Execute the Request
service.Execute(assign);

Sample Code :

AssignRequest assign = new AssignRequest
    {
        Assignee = new EntityReference("systemuser",
            new Guid("9245fe4a-d402-451c-b9ed-9c1a04247482")),
        Target = new EntityReference("new_manfacturer",
           new Guid("8245fe4a-d402-451c-b9ed-9c1a04247482"))
    };


// Execute the Request
service.Execute(assign);

Hope this helps 🙂