CRM Blog

CRM Activity Usage Report
by Danny Varghese 10.20.09

Comments    3 Comment(s)

My colleague Jeremy Hofmann has been busy at one of our clients providing them valuable solutions to meet their business needs.  Below is another great example of how Jeremy has harnessed the customizability of CRM!

 

Business Problem:

Do your clients need a way to monitor activity usage as a means to track user adoption?

 

Solution:

Below is a CRM report we created that looks at activities created or modified over six periods of time, starting with the current date.  It can help spot overall trends for individual users or business units.

 

Technical Notes:

This is just a standard SRS report.  While I’m not a huge fan of the courier font on reports it was the client standard at the time so feel free to change it.  Also it is currently grouped by branch, which is a custom field.  You would likely need to change it to another grouping level such as business unit, depending on your clients needs.

 

User Story or Screenshot:

Launch the report from the CRM reports area.  With pre-filtering, you can select specific users to monitor.

 

Look for the up/down arrows and then drill into specific business units.  Schedule follow up calls with the users’ managers to understand why usage has dropped, stayed at zero, or increased.  Solicit feedback on the application in order to improve specific functionality or determine unmet needs and re-engage Crowe to fill those needs.

 

Activity Usage

CRM Custom Browse Folder
by Danny Varghese 10.17.09

Comments    3 Comment(s)

My colleague Jeremy Hofmann has been busy at one of our clients providing them valuable solutions to meet their business needs.  Below is a great example of how Jeremy has harnessed the customizability of CRM!

 

Business Problem:

We’ve given the client a way to add a documents I_FRAME on a contact record, however there was no easy way for their users to browse the folders – they have to type in a path manually.

 

Solution:

Provide a way for them to browse to a folder.  SharePoint is not currently an option.

 

Technical Notes:

While IE provides a file browse dialog, there is simply no way to browse folders by themselves.  So you have to write your own ActiveX scripting and html output to provide the functionality.

 

User Story or Screenshot:

Now the user can click a browse button next to the path field on the contact form which will launch the dialog box below.  Here they can browse to the folder they want and click ok, which will populate the path field on the contact record and update the documents I_FRAME.

 

Notice it looks very much like Vista so it fits in nicely with their desktop look and feel.

 

Custom Browse

CRM Developer Ramp-Up Kit
by Danny Varghese 10.13.09

Comments    No Comments

Microsoft has a great article containing tools to help a CRM developer ramp up.  The article includes presentations and labs that will help complement a developer's .NET skills to help build on top of the CRM 4.0 platform.

 

The article contains links to the following:

  • Introduction to concepts for developing with Microsoft CRM 4.0
  • New relationship types
  • Web services, authentication methods for each installation, multi-tenancy and CRM online
  • Integrating custom pages into the user interface, SiteMap customization, IFRAME's, and JavaScript
  • Developing plug-ins which can help extend product functionality with custom code, triggered either before or after an event
  • Explanations of the new workflow features
  • Features of the SDK for working offline
  • New reporting features
  • Analytics & Business Intelligence
  • Explanations on how to write new API for making changes to the metadata
  • E-mail setup and new deployment features
  • Performance
  • Labs to help developers tune their skills

 

This link can be found here: http://msdn.microsoft.com/en-us/library/dd393296.aspx

CRM & Multi-Tenancy
by Danny Varghese 10.08.09

Comments    No Comments

How does Microsoft Dynamics CRM handle multi-tenancy?  What is multi-tenancy?  These are the questions I often get from clients and other developers just interested in the CRM architecture.

 

Multi-tenancy allows CRM to be deployed on a single server, but allows multiple organizations to be supported.  For example, say a company has two business units like Commercial and Retail.  If there is a need for that company to use CRM differently for each business unit, that's where multi-tenancy can play a key role.  We can create a tenant for each unit, and each business unit can have it's own configurations and customizations.  So how does the CRM architecture handle multi-tenancy?

 

There are two ways new tenants/organizations can be created.  One way is using the CRM Deployment manager tool.  When setting up CRM for the first time, there is a default organization (tenant) created.  The Deployment Manager creates a new URL each time a new organization/tenant is created.  For example, we can use this to create Commercial and Retail tenants. The url is usually in the format http://<server: port> /tenant/page.aspx.  The Deployment Manager also creates a new database named “<tenant>_MSCRM” on the specified SQL Server, and creates all CRM tables, filtered views, etc.  It then updates the MSCRM_CONFIG database (base CRM database) with the information for the newly created tenant/organization.

 

For example, when setting up CRM for the first time, say a user sets up a default organization to be CroweHorwath on the local host, then the url would be: http://localhost:5555/CroweHorwath OR since this is the default organization, one can type http://localhost and it will default to the CroweHorwath tenant.  Then a user can use the Deployment Manager tool to create a new tenant for the Commercial business unit.  When the user is finished, the new url will be http://localhost:5555/Commercial, and a new database Commercial_MSCRM will be created to hold all configurations/data for the Commercial tenant.

 

One more thing, virtual directories are not created for every organization. CRM implements a virtual path provider that parses the URL to figure out which organization you are accessing and to perform the correct authentication.  CRM uses a web service and the user’s windows credentials to go against active directory and the appropriate organization to authenticate.

 

The second way tenants can be creates is programmatically using the CRMDeploymentService.asmx (http://<server>/MSCRMServices/2007/CrmDeploymentService.asmx).   One would have to use code to create a new CRM organization object, set the following fields: name, SQL server name, SQL server url, CRM currency information.    Next create a new instance of the CRM Deployment web service and use that to create a new Create response and request objects.

 

The above is a brief explanation of how multi-tenancy works in Microsoft Dynamics CRM.  I hope this will clarify many of the questions out there!

Filed under:
The Other Blue Screen of Death: the Blank Report Pre-Filter
by Shelley Lane 04.16.09

Comments    No Comments

Upon opening a report with a pre-filter, you expect to be presented with a query builder that will allow you to search for accounts, contacts or other CRM entity by location, owner, or any other field on the respective entity. Something that looks like this:

 

What do you do then, when instead you see this (and only this. Nothing's loading. It's "Done."): 

The pre-filter is blank and there doesn't seem to be an error anywhere. Attempting to "Edit the default filter..." results in the same empty, blue screen. In this case, the filter was loading correctly in the past, but now something is clearly wrong.

Let's go back to what the pre-filted should look like. It should allow users to filter Accounts by specific Account, Address 1, Category, or a custom attribute called Rating. After minutes of trying to connect the mental dots, I realized that I intentionally deleted one of the Rating attribute because it was no longer needed. Ah ha!

Turns out that, although CRM will not allow you to delete attributes that are on a published form, you are able to delete an attribute that is used on a report pre-filter. However, the fact that the attribute has been deleted keeps the pre-filter from being rendered.

To fix this, there are a couple of options.

If you know the name of the attribute the filter can't find, you can simply create a dummy attribute with that name, publish the entity with your attribute, edit the report's default filter and remove the dummy attribute from the report pre-filtered. Delete the dummy attribute from the entity and all it well again.

If you don't know the name of the attribute or would just like an excuse to dig around in the database, you can also edit the report filter's XML.

In your organization's CRM database, there is a table called ReportBase. Opening that table, you'll find all of the versions of the reports that are available or were available. To figure out which report you're working with, grab the GUID from the URL of the report pre-filter and query the ReportBase table for the record with that ReportId. That record will have a DefaultFilter field, which contains the pre-filter's XML. Once formatted correctly, it should look something like this:

 

To get the my report pre-filter to render, I can remove the element specifying the deleted attribute as a condition, in this case the line containing "new_rating." Once I've done that I can simply copy the XML back into the DefaultFilter field for that report and the pre-filter will render.

Although this fix is a little in-depth and should only be attempted by those very comfortable with the CRM database, it is a workaround if you're in a bind and do not want to have to re-create a report.

Filed under:
Example Of Deactivating An Entity
by Danny Varghese 03.06.09

Comments    2 Comment(s)

One of the least published example of CRM code is deactivating an entity, probably because it's not used as often as creating, updating or retrieving entities.  Below is an example I've used on several occasions to deactivate an entity:

 

public void DeactivateEntity(Guid entityId)

{

//variable initialization

            SetStateDynamicEntityRequest deactivateReq = new SetStateDynamicEntityRequest();   

 

            //deactivate the cloned assignment

            deactivateReq = new SetStateDynamicEntityRequest();

            deactivateReq.State = "Inactive";

            deactivateReq.Status = 2;

            deactivateReq.Entity = new Moniker();

            deactivateReq.Entity.Name = <entity name>

            deactivateReq.Entity.Id = entityId;

 

//execute the deactivation request

            service.Execute(deactivateReq);

}

Filed under:
Example of Dynamic Entity Update
by Danny Varghese 03.05.09

Comments    No Comments

I have seen numerous requests on other blogs about sample code to on how to update entities in CRM.  One way is to use the CRM web service to update business entities, however by doing so, you're only limited to out-of-the-box entities with system attributes.  To retrieve anything more "dynamic," you'll have to employ other methods.  Please remember that in order to update any record, you must have the proper permissions on that entity.

 

Below is a code example of how to update a record:

 

public void UpdateEntity(ICrmService service)

{

//variable initialization

            DynamicEntity entity = new DynamicEntity();                                                     //target entity to update

            TargetUpdateDynamic targetUpdate = new TargetUpdateDynamic();      //used to update entity

            UpdateRequest updateRequest = new UpdateRequest();                            //request to update entity

 

entity.Name = <entity name>

 

//add the properties you want to update on the entity

entity.Properties.Add(<property1>);

entity.Properties.Add(<property2>);

entity.Properties.Add(<property3>);

             

//set the target to update, and the request to update for

targetUpdate.Entity = entity;

updateRequest.Target = targetUpdate;

 

//execute the update request

service.Execute(updateRequest);

}

Filed under:
E-mail Field - Open In Outlook or E-mail Activity
by Danny Varghese 03.04.09

Comments    9 Comment(s)

Here's a simple JavaScript customization to enable an e-mail field, once filled in, have a user double-click it and open your default e-mail client with the address in the "To" field.

 

if(crmForm.FormType == 1 || crmForm.FormType == 2)

{

                crmForm.all.emailaddress1.ondblclick = function()

                {

                                var email = crmForm.all.emailaddress1.DataValue;

                                if ((email != null) && (email.length > 0))

                                {

                                     window.navigate("mailto:" + email);

                                }

                                                               

                }

}

 

Now if you want to make CRM open an e-mail activity instead of the default e-mail client, you can use the following code (when sending the email, CRM will use email address 1 regardless of what field was dobule clicked):

 

if(crmForm.FormType == 1 || crmForm.FormType == 2)

{

                crmForm.all.emailaddress1.ondblclick = function()

                {

                                var email = crmForm.all.emailaddress1.DataValue;

                                if ((email != null) && (email.length > 0))

                                {

                                     window.execScript(locAddActTo(4202))

                                }

                                                               

                }

}

Filed under:
Example of Dynamic Entity Create
by Danny Varghese 03.04.09

Comments    No Comments

There have been numerous requests on other blogs about sample code to on how to create entities in CRM.  One way is to use the CRM web service to create business entities, however by doing so, you're only limited to out-of-the-box entities with system attributes.  To retrieve anything more "dynamic," you'll have to employ other methods.  Please remember that in order to create any record, you must have the proper permissions on that entity.

 

Below is a code example of how to create a record using dynamic entities:

 

public void CreateEntity(ICrmService service)

{

//variable initialization

DynamicEntity entity = new DynamicEntity();                                                 //target entity to update

TargetCreateDynamic targetCreate = new TargetCreateDynamic();          //used to update entity

CreateRequest createRequest = new CreateRequest();                                //request to create entity

 

entity.Name = <entity name>

 

//add the properties                   

entity.Properties.Add(<property>);

Entity.Properties.Add(<property>);

 

//set the target to update, and the request to update for

targetCreate.Entity = entity;

createRequest.Target = targetCreate;

 

//execute the update request

service.Execute(createRequest);

}

 

Hope this helps, happy coding!

Filed under:
Debugging CRM Plug-ins, Stored Procedures & Custom Workflow Activities
by Danny Varghese 02.24.09

Comments    2 Comment(s)

Whether it's developing CRM plug-ins, custom workflow activities, or writing stored procedures against the CRM database, the most useful tool I've used is the Microsoft Visual Studio Debugger.  The debugger allows developers to step through the code for the above mentioned scenarios and has saved me hours! 

 

Microsoft has phenomenal documentation on how to setup remote debugging:

 

http://msdn.microsoft.com/en-us/library/bt727f1t.aspx

 

The biggest issues I've had trying to setup the debugger has always been with permissions.   I would recommend paying especially close attention to this section.  The next biggest issue I had was trying to attach the debugger to a running process: http://msdn.microsoft.com/en-us/library/c6wf8e4z.aspx

 

Once you've setup Visual Studio debugger, you can attach the following processes for the following CRM components:

 

  1. For plug-ins, attach the debugger to the w3wp.exe process.
  2. For custom workflow activities, attach the debugger to MSCRMAsyncService.exe
  3. For stored procedures, attach the debugger to sqlserver.exe

 

Once the debugger has been attached, you must set a breakpoint in the code (either the .NET or T-SQL code).  After the breakpoint is set, to test, do the following:

 

  1. For plug-ins, login to CRM and execute actions that will trigger the plug-in, such as create/update/assign a record.
  2. For custom workflow activities, login to CRM and perform actions that will trigger the workflow.  With this, being that it's an asynchronous service, you'll have to wait until that service runs, and then Visual Studio will let you step through the code.
  3. For the stored procedure, just execute the stored procedure in Visual Studio and it will go right to the breakpoint.

 

I hope this post will help CRM developers save time and effort.  I use the debugger every time I develop now to test and it's saved me tremendous amount of maintenance time and effort after the code has been deployed.  Happy debugging!

Filed under:
CRM 4.0 Plug-in Registration Tool Walkthrough
by Danny Varghese 02.21.09

Comments    8 Comment(s)

The CRM 4.0 Plug-in registration tool is Microsoft's tool to register any plug-in developed for CRM 4.0 and callouts that were developed for CRM 3.0, but need to be upgraded to 4.0.  In this article, I'd like to take a step by step walkthrough of the tool including any interesting facts or issues I've run into during this process.  Those will highlighted in the "NOTE" section.

 

To download the tool, please visit: http://code.msdn.microsoft.com/crmplugin for the latest version.  The tool also comes packaged when you download the CRM 4.0 SDK, which you can do from: http://www.microsoft.com/DOWNLOADS/details.aspx?familyid=82E632A7-FAF9-41E0-8EC1-A2662AAE9DFB&displaylang=en. 

 

Building The Plug-in Registration Tool

 

Either way, the download will contain Visual Studio project files that will need to be built.  Mitch Kett in his blog has outlined how to do this: http://www.crowehorwath.com/cs/blogs/crm/archive/2008/03/19/incorporating-custom-entities-into-a-plugin-revised.aspx. 

 

**NOTE:  The CRM SDK provides great information on what each service provides for the user:

 

The CRM Web service provides strongly typed access to all entities in Microsoft Dynamics CRM, including custom entities and attributes. This Web service also allows execution of all supported operations, including those with built-in business logic as well as specialized operations. It provides a valid Web Services Description Language (WSDL) that is dynamically generated on the server to include the latest customizations and provides a single endpoint for your code.

 

The Discovery Web service is a mechanism to find the correct CrmService endpoint for your organization or to obtain a CRM ticket for Internet-facing deployment (IFD) or for Microsoft Dynamics CRM Online.

 

The Metadata Web service provides methods to read and write the metadata for an organization. This includes the definitions for entities, attributes, and relationships.**

 

**NOTE:  If you don't place the assembly files mentioned in step (8) of Mitch's instructions, when you go to run the plug-in registration tool, you might get an error: "...Could Not Find Dependency…"**

 

Using The Plug-in Registration Tool

 

  1. You can launch the tool by either running the executable built from the project mentioned in the steps above, or if you've configured Visual Studio with a shortcut, you can launch it from that menu.

  1. Once the screen is loaded, click on Create New Connection.  Enter a simple label for the connection, the server in which CRM is installed on, port, domain and user name.

 

 

**NOTE:  There are security restrictions on the user that can register plug-ins.  According to the SDK, the user account registering the plug-ins must exist in the Deployment Administrators group or must be a System Administrator.  If the user is not part of at least one of those groups, you will get an error along the lines of "…Not have enough privilege to complete Create operation for an SDK entity…"**

 

**NOTE:  If you don't enter a username and password, it will use the windows default credentials you used to login.**

 

  1. Click on Connect.  Once connected, you will see a new screen with various menu options.  Let's dive deeper into each of these options.

 

 

  1. Register
    1. Register New Assembly - you can register a new assembly that contains the plug-in execution code.
    2. Register New Step - allows you to configure the event that triggers the execution of the code.  For example, this is where you can configure to fire a specific code after/before a record is created, updated, etc.  This is equivalent  to specifying a "PostUpdate," "PostCreate," in an xml configuration file for CRM 3.0 callouts.
    3. Register New Image - you can register an xml image of an entity.  This can be used to find out what the values of a record is before and/or after the record is created, updated, etc.  You can also specify which attributes of that record you want to pass into the execution context.
  1. Import/Export
    1. Export Solution Xml - allows a user to export an xml file that contains the assembly names, steps and/or images registered previously.  This allows for configuration of the plug-ins to be setup once and then migrated to other environments.
    2. Import Solution Xml - allows user to import the xml file mentioned above in (3bi).

 

NOTE:  According to a document walking through the registration tool published by Ajith Gande the "Import Export has some limitations and design assumptions

  • If a plug-in is impersonated on user MyDomain\crmUser and imported in an organization with different domain, it tries to map the user bases on the domain user name (crmuser)
  • Plug-in assembly DLL’s are not exported in the Xml. When Import is in progress, you need to copy the assemblies to the same location as the .xml file
  • Import overwrites the assemblies, plug-in, steps, images in the target organization if any other entity exists with same Guid, else it creates them
  • It is recommended to import assemblies, plug-in, and a step all at once to avoid a lot of overwrites. So delete any existing assemblies with same name on target org. But the tool supports updating or adding a step to the existing plug-in using the import."

This was referenced from:

http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=crmplugin&DownloadId=320**

  1. View
    1. Display By Assembly - this is the default view, showing all registered plug-ins by assembly name.
    2. Display By Entity - shows all registered plug-ins filtered by the entities they're registered for.
    3. Display By Message - organizes the plug-ins registered by messages or events such as Create, Update, etc.
  1. Unregister, Refresh & Search (all self-explanatory)

 

  1. Click on Register --> Register New Assembly  --> Complete the steps below and press Register Selected Plugins --> Click on Close

 

 

  1. Step 1- Allows you to browse to a location and select the assembly you want to upload.
  2. Step 2 - This is not shown on the screenshot, but you now have to click Load Assembly
  3. Step 3 - Select where the assembly should be stored for execution
    1. Database - Storing the files on the database allows users to update the assembly file through this wizard as many times as they want without having to perform an "iisreset," as you had to in CRM 3.0.  Advantage #2 is now the server\bin\assembly folder will not become cluttered if you have numerous  plug-ins.  Finally, this makes migration from different environments much easier because there are less files to move.

 **NOTE: If you want to debug the assembly files, you will need to place the symbols file (.pdb) in <crm installation directory>\Server\bin\assembly folder. **

  1. Disk - This option allows you to store the assembly file as you did in CRM 3.0 under the <crm installation directory>\Server\bin\assembly directory.  For debugging purposes, the symbols file (.pdb) must also be in this directory.  If you store files here, an "iisreset" will be needed anytime any changes are made to the assembly.
  2. GAC - (Global Assembly Cache), for more information on this, please see my other post: http://www.crowehorwath.com/cs/blogs/crm/archive/2008/03/05/gac-it-developing-portable-code-for-microsoft-crm.aspx
  1. Once you've registered your plug-in, click on Register --> fill in the steps outline below --> Register New Step

 

 

  1. Message - In CRM 3.0, you had to configure the callout.xml file to specify if the plug-in was to be triggered via and update, create, assign, etc.  Now you can configure this at this step.
  2. Primary Entity - The entity that will trigger the plug-in
  3. Secondary Entity - You should enter this only when the plug-in should be triggered for an event requiring two entities like the "SetRelated" message.
  4. Filtering Attributes - This allows you to filter which attributes of the entity will allow the triggering of the plug-in.  For example if on the account you want the plug-in to fire only when the name gets updated, but not the account type, then you in your filter you can remove the account type.  By default, all attributes are selected.
  5. Plugin - Select the assembly, and class you wish to associate to this step.
  6. Run In Users Context - By default it's set to calling user, which means the plug-in will be fired with the current users credentials.  This is to control security so a user w/o the proper permissions won't have a plug-in fire to create/update/etc.  any records.  You can specify other users to run the context in.  The list will pre-populate with all account names from the CRM installation.
  7. Execution order - Sometimes asynchronous operations on dependant on others asynchronous operations to complete.  The execution order allows you to specify when this plug-in is supposed to fire.
  8. Event Sate - Specifies if the plug-in should be fired before or after an event.  In  CRM 3.0, this is similar to configuring a "PostUpdate," "PostCreate," "PreUpdate," etc.
  9. Execution Mode - A new feature which allows the plug-in to execute asynchronously or synchronously.
  10. Step Deployment - If you want the plug-in to be deployed (not registered) on the server and/or offline (Outlook client).
  11. Triggering Pipeline - For example, if you have an account with activities and you re-assign that account.  If the plug-in was registered an activity, then it does not get fired because the activity is getting updated as part of another operation.  To trigger the plug-in in that case you have to set the pipeline to "Child Pipeline"

 

**NOTE:  According to the SDK, If you want your plug-in to run regardless of whether a Web service call or an (internal) platform call initiated the pipeline, register your plug-in in a child pipeline. However, do not use the IPluginExecutionContext.CreateCrmService or IPluginExecutionContext.CreateMetatdataService methods if you are writing code for a plug-in in that is used in a child pipeline. In a child pipeline, you must instantiate the CrmService or MetadataService manually.**

  1. Unsecure Configuration - if you don't want to hardcode any values and the plug-in needs certain configuration values (that may change based on deployment environments) you can specify the values here.  For example, the CRM server url.
  2. Secure Configuration - same concept as above, but you could place more secure configurations like user credentials.

 

  1. (Optional) Click on Register New Image.  I say this step is optional because you may not need this step at all times.  This is equivalent to the pre and post image entity xml's in CRM 3.0.  You can register an xml image of what the entity attributes were before and after an event.  For example, if you've registered a post-update event on an account and you want to check what the value of a field was before the update, you could register a pre-update image.  Furthermore, on this image, you can select which attributes you want the xml to contain.  This allows users to help performance (all be it, just a tiny bit) but cutting down unnecessary fields.

 

**NOTE: You can not register a pre-create image since there were no attributes for a specific record because it hasn't been created yet.  You will get an error if you try this.**

 

This concludes my in-depth look at the plug-in registration tool.  All the notes I've added have been experiences I've had registering plug-ins.  I hope this was informative and helps save you some time developing!  Happy coding!

Filed under:
Publishing Microsoft CRM 4.0 through ISA Server 2006
by Danny Varghese 02.21.09

Comments    No Comments

Here is a great article that illustrates how to publish Microsoft CRM 4.0 through ISA Server 2006: http://blogs.technet.com/isablog/archive/2008/07/23/publishing-microsoft-crm-4-0-through-isa-server-2006.aspx

 

The article is broken up into the following sections:

 

  1. Adjusting CRM Server For External Publishing
    1. General Considerations
    2. IFD Configuraiton
  1. Configuring ISA Server 2006 Web publishing rule
  2. Troubleshooting Tips

 

For those who need some information on Microsoft ISA Server: http://en.wikipedia.org/wiki/ISA_Server

Filed under:
Rules To Better Microsoft CRM & SSRS
by Danny Varghese 02.21.09

Comments    No Comments

Below are some very useful links on standards for Microsoft CRM and SQL Server Reporting Services:

 

http://www.ssw.com.au/ssw/Standards/Rules/RulestoBetterMicrosoftCRM.aspx

 

http://www.ssw.com.au/ssw/Standards/Rules/RulesToBetterSQLReportingServices.aspx

 

Enjoy!

Adding A Filtered Lookup In CRM
by Danny Varghese 02.03.09

Comments    2 Comment(s)

Another common question I see in blogs from users are is there a way to add filtered lookups?  That is only allow users to "lookup" certain records that related to that particular one.  Here's a real life example:

 

Say you have an account that has a 1:N parental relationship with entity A.  Now let's say there's another entity B that has N:1 referential relationships with both account, and entity A.  There is a way on entity B so that after you select, on the lookup, a record of the account you want to relate to it, to filter the second lookup of entity A to only those related to the account you just selected.  i.e.

 

Parental Relationship

Account --> Entity A

 

Referential Relationship

Entity B -- Account

Entity B -- Entity A

 

With simple JavaScript, when a user selects the lookup value for the account, the lookup for Entity A can be filtered to point to only those entity A's that are related to the account you just chose.  Here's the code to place on the form of Entity B:

 

crmForm.all.<lookup field for entity A>.additionalparams = 'search=' + encodeURIComponent(crmForm.all.<lookup field for account>.DataValue[0].name);

 

That's it!  Simple, yet effective.

Filed under:
Example of Dynamic Entity Retrieval
by Danny Varghese 01.31.09

Comments    1 Comment(s)

There have been numerous requests on other blogs about sample code to on how to retrieve entities in CRM.  One way is to use the CRM web service to retrieve business entities, however by doing so, you're only limited to out-of-the-box entities with system attributes.  To retrieve anything more "dynamic," you'll have to employ other methods.  Please remember that in order to retrieve any record, you must have the proper permissions on that entity.

 

Below is a code example of how to retrieve a record with an id using dynamic entity retrieve:

 

 

 public DynamicEntity RetrieveEntity()

{

            //variable initialization    

            TargetRetrieveDynamic target = new TargetRetrieveDynamic();        

            RetrieveRequest retrieveRequest = new RetrieveRequest();           

            RetrieveResponse retrieveResponse = null;                                      

DynamicEntity entity = null;                                     

 

            target.EntityName = <name of entity here>

            target.EntityId = <id of entity here>

 

            //initialize request parameters

            retrieveRequest.ColumnSet = new AllColumns();

            retrieveRequest.ReturnDynamicEntities = true;

            retrieveRequest.Target = target;

 

            //build the response object

            retrieveResponse = (RetrieveResponse)GetCrmService().Execute(retrieveRequest);

 

            //retrieve the service order item from the response

            entity = (DynamicEntity)retrieveResponse.BusinessEntity;

 

            return entity;

}

 

 

The above example is a simple one, but the example below retrieves all contacts that have an account id = some id, and also retrieve the records with only a certain attributes.  This is probably a more robust example encompassing many retrieval options:

 

private ArrayList RetrieveMultipleContacts(ICrmService crmService, Guid parentAccountId)

{

//variable initialization

ConditionExpression condition = new ConditionBLOCKED EXPRESSION;

FilterExpression filter = new FilterBLOCKED EXPRESSION;

QueryExpression query = new QueryBLOCKED EXPRESSION;

RetrieveMultipleRequest request = new RetrieveMultipleRequest();

ColumnSet cols = new ColumnSet();

RetrieveMultipleResponse response = null;

ArrayList contacts = new ArrayList();

 

//Set the condition for retrieval

condition.AttributeName = "parentcustomerid";

condition.Operator = ConditionOperator.Equal;

condition.Values = new string[] { parentAccountId.ToString() };

 

//Set the properties of the filter.

filter.FilterOperator = LogicalOperator.And;

filter.AddCondition(condition);

 

//Set the attributes needed to be returned.  NOTE: The CRM Sdk has an erroneous example

//of how to set the attributes for retrieval.

cols.Attributes.Add("address1_line1");

cols.Attributes.Add("address1_line2");

cols.Attributes.Add("address1_line3");

cols.Attributes.Add("address1_city");

cols.Attributes.Add("address1_stateorprovince");

cols.Attributes.Add("address1_postalcode");

cols.Attributes.Add("address1_country");

cols.Attributes.Add("telephone1");

cols.Attributes.Add("fax");

 

//Set the properties of the QueryExpression object.

query.EntityName = EntityName.contact.ToString();

query.ColumnSet = cols;

query.Criteria = filter;

 

//Set the query for the request and set the flag to return

//dynamic entities

request.Query = query;

 

//retrieve the contacts

response = (RetrieveMultipleResponse)crmService.Execute(request);

 

foreach (BusinessEntity cont in response.BusinessEntityCollection.BusinessEntities)

{

contacts.Add(cont);

}

 

return contacts;

}

 

I hope these examples help someone, happy coding!

Filed under:
More Posts Next page »