Wednesday, December 30, 2009

Developing Your CRM/xRM Applications (Part - I)

There are THREE common methods to use CRM SDK in our extension projects. These are
  1. using CRM web reference, 
  2. using sdk assemblies files, and 
  3. using third-party tools. Each method has its own pros and cons. 

Using CRM web reference in extension project is very easy for implementation. All you need to do is just add web reference. But, if you have 300+ custom entities in your project, there will be some performance issues and memory leak problems occur in application development.

Using sdk assemblies files is good for application performance and stability. But, if you have many custom entities in your project, it will be a nightmare for all developers to do coding using dynamics entity approach.

The last method, using  third-party tools, will help you to a lot in your project implementation. They can provide easy way to implement dynamics entity approach  in your project. But, you have to spend a lot of money on license fees to use those third-party tools.

According to my experience, the second method is the best way for developing xRM applications. But you have to find out your own way to:
  1. generate entity wrapper class automatically
  2. convert wrapper class to dynamic entity, and
  3. implement library programs that support CRM SDK operations
How To Generate CRM Entity Wrapper Class Automatically

Today, I will show you a way to generate entity wrapper class using CRM Development Toolkit.

Software Requirements

1. VS .NET 2008 and .NET Framework 3.5 SP1
2. MS CRM 4.0 (either 32bit or 64bit)

Installation Steps

* Install VS 2008 and .NET Framework 3.5 SP1
* Install MS CRM 4.0 (either 32bit or 64bit)
* Install StyleCop V 4.3.2.1



Please do not forget to choose “MSBuild Integration Files” so that you can avoid following error message:



* Install CRM Explorer (Please refer to page 10 from "Customizing CRM by Using the Microsoft Dynamics CRM Developer Toolkit.pdf" for more detail)

Configuring CRM Solution Framework

1. The CRM Solution Framework is a suite of Visual Studio C# projects that are coupled with CRM Entity customizations and wrapped with extensible MSBuild–based developer builds and daily builds. The Framework contains several “pre-canned” projects for the typical tasks that are required of developers when undertaking most Enterprise-level CRM projects. Several of these projects have an inheritance model that affords simple and intuitive augmentation, which can significantly reduce the time required to “jump start” development of new projects.

2. Install CRM Solution Framework Template (Please refer to page 11 from “Customizing CRM by Using the Microsoft Dynamics CRM Developer Toolkit.pdf” for more detail)

setup.cmd [InstallDir] [Project Namespace] [Project Long Name] {Organization Name}




Configuring CRM Explorer

1.    The CRM Explorer complements the CRM Solution Framework, providing the project factories required to open and build the solution from within Visual Studio. The Explorer manifests as a window within Visual Studio 2008 and provides direct access to CRM for creating and editing business units, security roles, and most importantly, entities. The CRM Explorer is linked to the solution framework which enables it to intelligently place generated code into the relevant solution framework project.



2. Open VS 2008 and Configure Your CRM Explorer (Please refer to page 13 from “Customizing CRM by Using the Microsoft Dynamics CRM Developer Toolkit.pdf” for more detail)

Note: Default Port Number for CRM is 5555.



Generating Entity Wrapper Class



1. The EntityWrappers project supports a project factory that enables integration with CRM by means of examining the CRM metadata and generating code within the project to support the entities that exist. The core purpose of this project is to expose the CRM entities and their corresponding attributes as classes and properties respectively to enable code to be developed to interact with the entities.

2. For each CRM entity that the developer selects, two files will be created namely: [entityname].cs and [entityname].Attributes.cs (where [entityname] represents the name of the Entity within CRM). These files split a single class named after the entity through partial classing. The [entityname].Attributes.cs file contains all of the attributes present on the entity at the time of creation.

Note: A major reason for separating the attributes into a separate file is because of their volatility throughout the development phase. The [entityname].attributes.cs file should not be manually edited by the developer as it supports re-generation via the CRM Explorer.

3. Open CRM Solution Framework Solution from your installed directory. Right-click on entity you want to generate wrapper class from CRM Explorer. Then, click “Generate Wrapper Class”.



I will tell you how to convert entity wrapper class to dynamic entity, and how to implement library programs that support CRM SDK operations in my next posts. If you have questions about this post, either leave a comment or email me at thuta@thuta.info. Thanks.

Reference:
CRM Development Toolkit
Customizing CRM by Using the Microsoft Dynamics CRM Developer Toolkit
Developing Your CRM xRM Applications (Part - I)

Tuesday, December 22, 2009

XRM Notebook has been listed as a Technical Blog in Microsoft Dynamics Community

Today, my technical blog, XRM Notebook, has been listed as a XRM Technical Blog  in Microsoft Dynamics Community. Thanks to Nick Hoban who gives me a chance to participate and contribute my knowledge in our Dynamics CRM Community.

Reference:
Community added another XRM blog to the CRM blogs
Microsoft Dynamics CRM Blogs

Thursday, December 10, 2009

Offline Client Error On Data Synchronization

Last week, my users complaint that they cannot see migrated data in some offline client laptops. I checked synchronization filter, CRM user data and both are working fine.

Finally, my colleague suggest me to do following steps:
  1. Go Online
  2. De-activate Local Data Group which has synchronization problem, and
  3. Go Offline
After synchronization process, You will not find no data at all. Then,
  1. Go Online
  2. Activate Local Data Group, and
  3. Go Offline again
You will get all data that were never synchronized before. It is something like restart process and I don't know how to explain this to user. The following are the list of screen shots for your reference:

1. Local Data Group (You can only see it after you go online)


















2. De-activate Data Group














3. Activate Data Group














4. Filter Data Group


CrmException: transactionCurrencyId needs to be supplied to format a transaction money field.



Sometime you may find above error when you tried to open a record in MS CRM. This happened because there is no data in transactioncurrencyid attribute defined in your record. (For my case, it is related to data migration issue.) This transactioncurrencyid field is related to money data type attribute.

Resolution: Query the default  transactioncurrencyid (guid) in your organization and update from SQL. Please backup your database before you start this process.

Sometime, it can also happened if you take out existing money attribute from your CRM entity. In this case, adding one money attribute to that entity will solve your problem. Weird Thing!!!

Thursday, December 3, 2009

MSSQL Synonym Generator

Sometime, we may need to reference tables and views across two or more databases. For example, in CRM extension development, we used to keep our extended store procedures and views in external database. Those stored procedures and views will pull out data from ORGNAME_MSCRM database.

In this case we have to refer objects from MSCRM database with four-part identifiers
[[[server.][database].][schema_name].]object_name
It will be very time consuming job and very difficult to maintain the code, if we are referencing those four-part identifiers in our stored procedures and views. Moreover, SQL Server will never check validity and existent of base objects at synonym create time. So, the best way is used the program to generate synonyms in external database.

Below is the screen shots of my SQL Synonyms Generator program. It will read stored procedures, views and functions from source database and automatically create synonym at another database. You can also filtered sys objects by user defined data types.



System Requirements:
  • VS .NET Framework 2.0
Download Link:
MSSQL Synonyms Generator (Application)
MSSQL Synonyms Generator (Source Code)

Reference:

Friday, November 27, 2009

MS CRM 4.0 CSS Stylesheet Template is released!

Microsoft released CRM Sdk v 4.0.11 on Nov 24, 2009. Here is a list of updated features at a glance:
The package includes a visual style guide you can use to make your customizations fit in smoothly, and a style sheet you can use as a basis for your work. There are also tools and helper code provided in this package. Look for regular updates to this SDK!

Download Link:
CRM Sdk v 4.0.11
MS CRM 4.0 CSS Stylesheet

XrmVisioER: CRM/xRM ER Diagram Generator Revised Version

Last week, my colleague said XrmVisioER diagram generator takes too long to retrieve entity information at log-in process. When he tried the program for first time, he even though it was not working :) I also noticed that its took around 3 mins+ to retrieve meta data information from remote server. This morning, I decided to review my program again and did necessary changes.

Here is the list of updated features:
  • Reduce processing time at application log-in process
  • Apply caching concepts on meta data retrieval process
  • Diagram pages will be shown as display name of an entity
  • Provide user friendly information on screen while generating diagrams






Configuration:
Connection: Cable 8 mbps
Server: Remote Hosted Server, Win 2003, 4GB RAM, VMWARE
Client: WinXP, 2GB RAM,  Core 2 Duo 1.8 GHz

Testing Scenario:
Drawing 1 entity: takes 1 min+
Drawing 3 entities: takes 1 min 28 sec
Drawing 280 entities: takes 15 mins+ (avg of 3.4 sec/entity)

Download Link:
XrmVisioER - CRM/xRM ER Diagram Generator (Application)
XrmVisioER - CRM/xRM ER Diagram Generator (Source Code)

Reference:
XrmVisioER - Metadata Diagram Generator
Power User Tips: The CRM 4.0 Metadata Cache

----------------------------------------------------
Updated on 16th Dec 2009:
  • Add re-size feature to entity diagram
  • Remove relationship attribute name from entity diagram
  • Add an option to draw all entities in one page

Sunday, November 22, 2009

xRM at Microsoft PDC09




Microsoft PDC09 conference was held in LA this week. They discussed about CRM 5.0 and xRM application development there. Below is the list of videos and presentation slides I found on PDC website.
  1. Developing xRM Application using Windows Azure 
  2. Managing the Solution Lifecycle for xRM Applications
  3. Building a .NET Business Application in 60 mins with xRM and Sharepoint
You can find out more information at Microsoft PDC09 Videos

CRM 5.0 At A Glance

Monday, November 16, 2009

SQL Server: Failed to pause full-text catalog for backup

Last week, my users complaint that they cannot perform regular backup on SQL Server using their backup software. I tried to investigate on backup process and found the error message stated below:



After searching through Google for a while, I found the source of problem which is related to SQL Server FullText Search Service. By right, this service must run under Local System account. But, their service is running under NT Authority/Network Service.

Reason: When SQL server is performing backup process, they tried to pause FullText Search service. If this service is not running under Local System account, there is no way they can pause this service and error message stated above will be appeared.

Caution: If you want to perform database restore process in MS CRM databases, you have to stop Microsoft CRM Asynchronous Service before you start your restore process.

Saturday, November 14, 2009

Local SMTP Virtual Server Configuration for CRM Outgoing Emails

If you want to use local SMTP virtual server for outgoing emails in CRM application, please review following document for installation and configuration guide-line.

This document consists of FOUR sections:
  1. Installing and configuration local SMTP service
  2. Configuration CRM email router
  3. Configuring outgoing email access for CRM users
  4. Testing outgoing email
Download Link

XRM Notebook has beed listed as a Member Blog in XRM Virtual User Group

Today, my technical blog, XRM Notebook, has been listed as a member blog in XRM Virtual User Group. Thanks to Julie Yack who gives me a chance to participate and contribute my knowledge in our XRM Community.

Wednesday, November 11, 2009

Trace Errors on CRM Workflows and Asynchronous Plug-ins

All Workflows and (async) plug-ins are running under CRM Asynchronous service. It is difficult to trace an error message when those workflows and asynchronous plug-ins are not working properly.

Here is the solution to trace errors:
  • Go to Advanced Find, choose System Job entity, and set the filter parameter as follow:

  • Click Edit Columns, and add TWO more columns called Error Code and Message.

  • Click Find to view result

Tuesday, November 10, 2009

CRM: SecLib::CheckPrivilege failed.

SecLib::CheckPrivilege failed. Returned hr = -2147220960,
User: 38327113-f014-dd11-8a77-0004e240fb2e,
PrivilegeId: ea8e9601-500e-4bd7-be73-022f3269e5b6

A CRM application may encounter privilege error in some sdk operations (i.e.; CURD). It will be a time consuming task for a developer to trace such kind of error if they don't know how to check it. They have to go through each and every entity to identify whether the defined user roles have correct privileges or not.

The first and easiest way is here.
  • Take PrivilegeId from above error message. (e.g.; ea8e9601-500e-4bd7-be73-022f3269e5b6)
  • Run following query to retrieve privilege name which was not set correctly in user role

  • Give correct privilege (e.g.; Read Access to dvm_girorejectreason entity) to required Role assigned to the specific user (e.g.; 38327113-f014-dd11-8a77-0004e240fb2e). If you do not know how to check the user in SQL server please let me know.

Caution: If you cannot find the PrivilegId in error message, please check whether specified use has a role assigned to it. Most likely thing is there is no user role assign to that user.

Sunday, November 8, 2009

XRM Auto-Number Plugin (Online)

One of the most frequently asked features in xRM development is Auto-number @ Running Number generation process. Microsoft supports auto number generation for a few predefined entities like Contracts, Case, Invoice, Order etc.

Since I have been working in donation and clinical system projects, I found that most of our users request such feature in receipt number generation, reference number generation and document number generation processes. It is a quite common feature that they request.

There are a few ready-made CRM plug-ins out there. But most of them are only focus for numeric data type running numbers and cannot support for padding and/or auto number reset features. So, I decided to do it on my own way.

Let's take a look on the features of my Auto-number Plug-in:
  • This plug-in is supported only for server deployment and create message of any custom entity. 
  • Offline client does not need to register this plug-in since the number will auto populate when they sync back their offline data to CRM server.
  • Data type of running number attribute in custom entity can be either string (nvarchar) or integer data type. The rest is not supported.
  • You can specify auto reset number and padding format of running number in configuration setup.  Please check the screens below.
  • Prefix and Suffix values can be either fixed values or datetime ori ented values. Plugin will automatically parsed the value into date time format if  you provide datetime format in curly brackets:, for example {MM}-{yy} will be parsed into ’11-09’


Download Link:
Feel free to use this application.
Either leave comment or email me if you want to know further information.

Saturday, November 7, 2009

Configuration for Offline Client Plugins

If you received an error "Unable to load plug-in assembly." when triggering the plug-in under offline client mode, please configure the following steps:

  • Open Plug-in Registration Tool
  • Copy Public Key Token value under Assembly Information Section



  • Open registry in offline client computer
  • Create sub key folder with Public Key Token value under HKCU\Software\Microsoft\MSCRM Client\AllowList folder (E.g. 43820d73570614d5 here in current scenario)


Make sure you configure your plug-in executing context as “Calling User”. Please take note that Offline client application can be run under single user who is register to that computer.



For faster and easier installation, copy following quoted lines into a text file and change file extension to .reg file. You need to replace yellow color text with relevant values. Double click and install registry values on Offline client laptops. You can also put multiple public key tokens in one registry file.
 
Windows Registry Editor Version 5.00

;(Plugin) YourPluginNamespace.PluginClassName
[HKEY_CURRENT_USER\Software\Microsoft\MSCRMClient\AllowList\PublicKeyToken]

;(Plugin) YourPluginNamespace.PluginClassName
[HKEY_CURRENT_USER\Software\Microsoft\MSCRMClient\AllowList\PublicKeyToken]

Download Link:
Sample File

Wednesday, November 4, 2009

XRM Capitalize Attribute Plugin (Online/Offline)

Our users want to capitalize some of the attribute values from CRM entities when they save the data. The most frequently asked attributes that they want to capitalize are fullname, first name, last name, account name, and address information, etc.

You may think that it is easy to change string format through java script functions. But, if you have some external applications and CRM extension included in your project, it will be very hard to control the consistent of your application code. So, I planned to write a generic plug-in which is easy to configure and provide a variety of  capitalized functions through central configuration setup. (The idea of configuration setup implementation comes from  a33ik. Please refer my post for more detail)












String Capitalize Effects:
  • All Caps. Example; THUTA HLAING
  • Small Caps: Example; thuta hlaing
  • Word Cap: Example; Thuta Hlaing
  • First Char Cap: Example; Thuta hlaing

Download Link:
Feel free to use this application.
Either leave comment or email me if you want to know further information.

Sunday, November 1, 2009

How to retrieve entity and its related attributes in CRM Form










I was working with MS CRM plug-ins for half a year already. When we worked on reusable plug-ins, we needed a setup entity to store some configuration setting that is required in plug-in execution. Most of the time, we need to store THREE configuration values: entity, their related attributes and plug-in related settings.
Luckily, I found out a good article on Internet which was written by a33ik. After playing around with his program for a while, I realize that this is the idea that I am looking for. I want to apply this idea in my reusable plug-ins. Thanks  to a33ik for sharing his idea.

As usual, I changed a little bit on his original idea since my scenario did not need to create all related attributes in child table setup. Moreover, I was worry on performance of CRM when we query through Parent - Child tables to retrieve setup information, and when we run plug-in to extract all related attributes and create unnecessary records.
Another thing is about consistency. If user changed customization of attributes (for example; display name) on CRM, setup table may not be updated automatically.So, lesser information storgae will help us reducing consistency issues. I also add one javascript function to auto populate attribute information and update when user saved the configuration record. For your convenience, here is my javscript code sample:

entityOnChange = function ()
{
crmForm.all.psx_entityname.DataValue = document.getElementById('psx_schemaname').options[document.getElementById('psx_schemaname').selectedIndex].innerText;

var schemaName = document.getElementById('psx_schemaname').options[document.getElementById('psx_schemaname').selectedIndex].getAttribute('schemaName');

var request = "" +
"<soap:envelope xmlns:soap="\"http://schemas.xmlsoap.org/soap/envelope/\"" xmlns:xsd="\"http://www.w3.org/2001/XMLSchema\"" xmlns:xsi="\"http://www.w3.org/2001/XMLSchema-instance\"">" +
GenerateAuthenticationHeader() +
" <soap:body>" +  
"     <execute xmlns="\"http://schemas.microsoft.com/crm/2007/WebServices\"">" +
"         <request xsi:type="RetrieveEntityRequest">" +
"             <metadataid>00000000-0000-0000-0000-000000000000</metadataid>" +
"             <entityitems>IncludeAttributes</entityitems>" +
"             <logicalname>" + schemaName + "</logicalname>" +
"             <retrieveasifpublished>true</retrieveasifpublished>" +
"         </request>" +
"     </execute>" +
" </soap:body>" + 
"</soap:envelope>";

var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2007/MetadataService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Execute");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", request.length);
xmlHttpRequest.send(request);

var result = xmlHttpRequest.responseXML;
var schemaNames = result.selectNodes("//EntityMetadata/Attributes/Attribute");
ConvertAttributeToPicklist('psx_attributename', schemaNames);
}

attribOnChange = function ()
{
crmForm.all.psx_displayname.DataValue = document.getElementById('psx_attributename').options[document.getElementById('psx_attributename').selectedIndex].innerText;
}

function ConvertEntityToPicklist(fieldName, dataItems)
{
var defaultValue = crmForm.all[fieldName].DataValue;
var table = crmForm.all[fieldName + "_d"]; 
var select = "<select class="ms-crm-SelectBox" defaultselected="" id="" + fieldName + "" name="" + fieldName + "" onchange="javascript:entityOnChange();" req="0" tabindex="1170">      <option ).text="" +="" ;="" logicalname="" value="" + dataItems[i].selectSingleNode(">            select += "schemaName='"+ dataItems[i].selectSingleNode('LogicalName').text+"'";                        if (dataItems[i].selectSingleNode('LogicalName').text == defaultValue)             {                select += " SELECTED";                defaultValueFound = true;            }                        select += ">" + dataItems[i].selectSingleNode('DisplayName/LocLabels/LocLabel/Label').text + "</option>        <option selected="selected" value="" + defaultValue + "">" + defaultValue + "</option> </select>";

table.innerHTML = select; 
entityOnChange();
}

function ConvertAttributeToPicklist(fieldName, dataItems)
{
var defaultValue = crmForm.ObjectId != null ? crmForm.all[fieldName].DataValue: null;
var table = crmForm.all[fieldName + "_d"]; 

var select = "<select class="ms-crm-SelectBox" defaultselected="" id="" + fieldName + "" name="" + fieldName + "" onchange="javascript:attribOnChange();" req="0" tabindex="1170">       <option ).text="" +="" ;="" logicalname="" value="" + dataItems[i].selectSingleNode(">            select += "schemaName='"+ dataItems[i].selectSingleNode('LogicalName').text+"'";                        if (dataItems[i].selectSingleNode('LogicalName').text == defaultValue)             {                select += " SELECTED";                defaultValueFound = true;            }            select += ">" + dataItems[i].selectSingleNode('DisplayName/LocLabels/LocLabel/Label').text + "</option>        <option selected="selected" value="" + defaultValue + "">" + defaultValue + "</option> </select>";

table.innerHTML = select; 
attribOnChange();
}

var request = "" +
"<soap:envelope xmlns:soap="\"http://schemas.xmlsoap.org/soap/envelope/\"" xmlns:xsd="\"http://www.w3.org/2001/XMLSchema\"" xmlns:xsi="\"http://www.w3.org/2001/XMLSchema-instance\"">" +
GenerateAuthenticationHeader() +
"  <soap:body>" +  
"    <execute xmlns="\"http://schemas.microsoft.com/crm/2007/WebServices\"">" +
"      <request xsi:type="\"RetrieveAllEntitiesRequest\"">" +
"        <retrieveasifpublished>true</retrieveasifpublished>" +
"        <metadataitems>EntitiesOnly</metadataitems>" +
"      </request>" +
"    </execute>" +
"  </soap:body>" + 
"</soap:envelope>";

var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2007/MetadataService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Execute");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", request.length);
xmlHttpRequest.send(request);

var result = xmlHttpRequest.responseXML;
var schemaNames = result.selectNodes("//CrmMetadata/CrmMetadata");

ConvertEntityToPicklist('psx_schemaname', schemaNames);  
crmForm.all.psx_entityname.ForceSubmit = true;

document.getElementById('psx_entityname').style.visibility = 'hidden';
document.getElementById('psx_entityname_d').style.visibility = 'hidden';
document.getElementById('psx_entityname_c').style.visibility = 'hidden';
crmForm.all.psx_displayname.ForceSubmit = true;
document.getElementById('psx_displayname').style.visibility = 'hidden';
document.getElementById('psx_displayname_d').style.visibility = 'hidden';
document.getElementById('psx_displayname_c').style.visibility = 'hidden';
 
if (crmForm.ObjectId != null)
{    
document.getElementById('psx_schemaname_d').disabled = true;
document.getElementById('psx_attributename_d').disabled = true;
} 

Download: 
Customization File

Feel free to use this application.
Either leave comment or email me if you want to know further information.

Reference:
Field Security Level With Own Hands

Friday, October 30, 2009

Adding tooltips to attributes on CRM Form






I had been looking for the best method to implement tooltips feature in CRM Form log ago. I found a lot of solutions on internet but they never satisfied my requirements. Some are using of complicated java script functions, some are using their own created wizards and some are using web service to retrieve descriptions of attribute to display as tooltip on form.

Today, I found an easy way to do that. The original idea comes from Marcello Tonarelli. But, I changed a little bit on his original code.

//Original Script
crmForm.all.birthdate_c.title = "Please choose date of birth"; 
crmForm.all.birthdate_d.title = "Please choose date of birth";

Reference:
Marcello Tonarelli

How to add syntax highlight in your blog post

This following links will help you to explain how to add syntax highlight in your blog post.

Reference:
SyntaxHighlighter
How to add syntax highlight to blogger

Thursday, October 29, 2009

Collapsible Sections on CRM Forms




Very nice and impressive feature.
Thanks Marco Amoedo.You really save my life :-)


function getElementsByCondition(condition, container) {
    container = container || document;
    var all = container.all || container.getElementsByTagName('*');
    var arr = [];
    for (var k = 0; k < all.length; k++) {
        var elm = all[k];
        if (condition(elm, k))
            arr[arr.length] = elm;
    }
    return arr;
}

function attachCollapsableToSections() {
    var sections = getElementsByCondition(function (elm) { if (elm.className.indexOf("ms-crm-Form-Section") != -1) return true; }, null);

    for (var i = 0; i < sections.length; i++) {

        sections[i].innerHTML = 'Expanded, click to collapse' + sections[i].innerHTML;
        sections[i].childNodes[0].attachEvent('onclick', toggleVisibility);
    }

}

function toggleVisibility(e) {
    var sectionContainer = e.srcElement.parentNode.parentNode.parentNode;
    var elements = getElementsByCondition(function (elm) { if (elm.vAlign == "top") return true; }, sectionContainer);

    for (var i = 0; i < elements.length; i++) {
        if (elements[i].style.display == "none") {
            elements[i].style.display = "";            
            e.srcElement.src = e.srcElement.src.replace("navdown", "navup");
        }
        else {
            elements[i].style.display = "none";            
            e.srcElement.src = e.srcElement.src.replace("navup", "navdown"); 
        }
    }
}

//Example of utilization
attachCollapsableToSections();
Reference: El del CRM

Wednesday, October 28, 2009

Custom Warning Message on CRM Form





Very nice and impressive notification method.

addNotification = function(message) {

    var notificationHTML = '<DIV class="Notification"><TABLE cellSpacing="0" cellPadding="0"><TBODY><TR><TD vAlign="top"><IMG class="ms-crm-Lookup-Item" alt="" src="/_imgs/error/notif_icn_crit16.png" /></TD><TD><SPAN>' + message + '</SPAN></TD></TR></TBODY></TABLE></DIV>';

    var notificationsArea = document.getElementById('Notifications');
    if (notificationsArea == null) return;

    notificationsArea.innerHTML += notificationHTML;
    notificationsArea.style.display = 'block';
}

//Example of utilizations
addNotification('Some warning message that you want to show to the user ');

Reference:
El del CRM
Dynamics CRM Tools

Sunday, October 25, 2009

XrmVisioER: Metadata Diagram Generator

Since CRM entities are composed of TWO SQL tables (i.e; extension and extension based), it is very time consuming for developers to draw an ER diagrams for each entity. If we used ER Diagram generators in the market, the diagrams they generated become very complex and it will not be easy to understand by users when they try read it.

That's why, Microsoft came out with a very useful Metadata diagram generator (CRM ER Diagram Generator) which we can find under CRM SDK samples. But, I still feel that the program is quite difficult to use for beginners since it is written in console application mode and can be run only from server (if you do not know how to change server URL in program).

This weekend, I re-modal the whole program to provide following functions for CRM developers:
  • Allow program to run from anywhere (no need to reside in server)
  • Ask users to choose which entities they want to generate diagram and where to save them
  • Allow each ER diagram to save in separate pages within one MS Visio file
  • Allow users to customize exclusion entities and relationships when they generate diagram


System Requirements:
  • .NET Framework 2.0
  • Microsoft Visio

Feel free to use this application.
Either leave comment or email me if you want to know further information.
---------------
Revised version can be found here.

Saturday, October 24, 2009

XRM Virtual User Group Membership Drive Contest Award

Yesterday, I won TOP 5 Membership Drive Contest Award at XRM Virtual User Group. I received an XRM SDK license plus a 5 user XRM Extensions license complete with a full year of maintenance from Shan McArthur at ADXSTUDIO.

I would like to say thanks to Shan McArthur, xRM Virtual User Group and my colleagues at PulseSync for their support and giving me a great chance to explore more on MS xRM development platform.

Hello Thuta,

Congratulations, you are one of the top-5 winners of the XRM Virtual User Group membership drive. This prize includes on year’s subscription for a single developer for ADXSTUDIO XRM SDK plus a 5-user license of ADXSTUDIO XRM Extensions. This includes one year of maintenance for both products. Thank you so much for making this membership drive successful!

Product download link
Product demonstration videos

If you have any questions about the product or you license rights, please feel free to contact me or post on the community forums at http://community.adxstudio.com/forums/xrm

Thanks,

Shan McArthur – VP, Technology (Microsoft Dynamics CRM MVP)

Thursday, October 22, 2009

FileHelpers Library 2.0

Very useful tool to extract and create flat files based on strong type record structure
The FileHelpers are a free and easy to use .NET library to import/export data from fixed length or delimited records in files, strings or streams.

You can strong type your flat file (fixed or delimited) simply describing a class that maps to each record and later read/write your file as an strong typed .NET array. The Library also has support for import/export data from differents storages like Excel, Access, SqlServer, etc.
Reference:
FileHelpers Library 2.0

Reporting Services Scripter (RSScripter)

Very useful tools to deploy reports across reporting servers
Reporting Services Scripter is a .NET Windows Forms application that enables scripting and transfer of all Microsoft SQL Server Reporting Services catalog items to aid in transferring them from one server to another. It can also be used to easily move items on mass from one Reporting Services folder to another on the same server.

Depending on the scripting options chosen, Reporting Services Scripter can also transfer all catalog item properties such as Descriptions, History options, Execution options (including report specific and shared schedules), Subscriptions (normal and data driven) and server side report parameters.
Reference:
Reporting Services Scripter
Download Link

Wednesday, October 21, 2009

Get all child business units by level based on specified BU id

To retrieve all child business units by level based on specified business unit id:

ALTER FUNCTION [dbo].[f_GetAllBusinessUnitByID]
(    
    @BUID VARCHAR(MAX)
)
RETURNS TABLE 
AS
RETURN 
(
    WITH BUTree(ParentBusinessUnitId, BusinessUnitId, Name, Level)
    AS
    (
        -- Anchor member definition
        SELECT P.ParentBusinessUnitId, P.BusinessUnitId, 

               P.Name, 0 AS Level
        FROM BusinessUnit AS P
        WHERE P.BusinessUnitId = @BUID

        UNION ALL

        -- Recursive member definition
        SELECT P.ParentBusinessUnitId, P.BusinessUnitId, 

               P.Name, Level + 1
        FROM BusinessUnit AS P
        INNER JOIN BUTree AS B
            ON P.ParentBusinessUnitId = B.BusinessUnitId
    )

    -- Query All Child Node
    SELECT C.ParentBusinessUnitId, C.BusinessUnitId, 

           C.Name, C.Level
    FROM  BUTree C
    WHERE C.BusinessUnitId NOT IN 

          (SELECT ParentBusinessUnitId 
           FROM   BUTree
           WHERE  ParentBusinessUnitId IS NOT NULL)
)

Sunday, October 18, 2009

SQL performance WITH (NOLOCK)

A few months ago, we started UAT for our application development and found out that some statistical SRS reports were running very slow. After debugging and done performance tuning steps, we noticed that those reports were running very slow when a lot of concurrent users accessing the same tables and/or views that the reports were referencing.

After surfing through Google, we found out a hint called NOLOCK.
SELECT au_lname FROM authors WITH (NOLOCK)
NOLOCK does not issue shared locks and do not honor exclusive locks. When this option is in effect, it is possible to read an uncommitted transaction or a set of pages that are rolled back in the middle of a read. Dirty reads are possible. Only applies to the SELECT statement.
We changed most of the SELECT statements with NOLOCK and performance of statistical reports became very must faster. Query execution time which took around 45 minutes previously became around 6 minutes plus.

But there were some pros and cons of using NOLOCK in SELECT query. Below is the comment made by Lumbago on SQL Team forum.
NOLOCK will cause your selects to read dirty data and I have prevoiusly said that I belive this is perfectly acceptable in over 80% of the queries I have worked with over the years, and I still belive this is true. It will reduce locking in your database and increase performance of your queries.

HOWEVER, it is absolutely essential that you know how it works and you need to think well through where to use it and not. It could cause severe inconsistencies in your database if not used properly and you should never use it in any insert/update operations. The general advice is that if you're not 100% sure it's ok to read the dirty data, then don't use NOLOCK.

Reference:
Lumbago
MSDN: Locking Hints
SQL Server NOLOCK / ROWLOCK Directives To Improve Performance

Friday, October 16, 2009

What is xRM?

You do not have the Flash plugin installed to view the file correctly. You may download the plugin from here: http://www.macromedia.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash

There are a couple of different definitions for XRM. One is that the “x” stands for extended, as in extended relationship management. The other definition is that the “x” is a variable, and means “anything” relationship management, such as partner relationship management, constituent relationship management, employee relationship management, etc.

Both of these definitions are referring to building any application on top of the Microsoft Dynamics CRM platform. Building an XRM application can take the form of customizing the existing customer relationship management applications that are included in Microsoft Dynamics CRM, or by designing completely new line-of-business applications that are not based on the sales, service, or marketing capabilities included in Microsoft Dynamics CRM.

The common thread to all the definitions of XRM and methods of extending it is that your application will use the Microsoft Dynamics CRM as a platform, leveraging the capabilities of the platform to deliver business value to your users.

Reference:
An Introduction to XRM for a .Net Developer
credit goes to original uploader@YouTube

hug a developer today

You do not have the Flash plugin installed to view the file correctly. You may download the plugin from here: http://www.macromedia.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash

credit goes to original uploader