Tuesday, March 17, 2009

Microsoft Dynamics CRM 4.0 Rollup 3

Download Dynamics CRM 4.0 Rollup 3 here: http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=05453fa4-9551-4a88-9852-634a9ad0e140

this rollup was released last week for CRM 4.0. And I would personally highly recommend it. Countless issues have been addressed up until this point. I've found that numerous behavior which I had even believed was by design has been corrected, simplifying plug-in development and customisations.

Friday, March 6, 2009

Dubugging Javascript in CRM Forms is Easy

Its easy to debug custom JavaScript in CRM forms. Save your JS code in the appropriate event and follow the instruction below. Debugging can be performed in IE or Visual Studio.

Scripting Debugging in Internet Explorer

entering the word "debugger" anywhere in your JS code will prompt IE to break at that point and load the script debugger.

Internet Explorer 8's New Developer Toolbar

If you've ever played around with Firefox's add-ons "Firebug", "Web Developer" and so on, you'd notice that there are capabilities that would take your CRM development to another level. It would be fantastic to have the ability to break down the DOM, CSS and test changes on the spot . Unfortunately Firefox is not compatible with Microsoft Dynamics CRM.

The latest release of Internet Explorer (IE8 RC1) contains the most useful tool as far as CRM development is concerned. The new Developer Toolbar holds a set of tools primarily targeted for developers in order to break down the DOM and list all elements of a web page.

Read more about the IE8 Developer Tools here.

How often have you tried to change the colour, font, visibility... of a control on the page? After a arduous task of finding the right tag, you then get to the job of making changes on your event code, save, publish, did not work right, try again...

The IE8 Developer Toolbar removes the hassle by displaying all page tags on a tree hierarchy and allowing live modifications to the page. The one shortfall that I've noted is that there is no facility to search a large page for a specific tag. Let's hope this is addressed in the next version.

Sunday, February 8, 2009

Reference External Javascript File in CRM Form Events Asynchronously

A few months ago I posted a method of importing external javascript files into CRM forms. See 'Reference External Javascript File in CRM Form Events'.

Some of you may have noticed an issue with this method when including multiple exeternal files. This is due to the fact that the process runs asynchronously while the rest of the code continues to execute.

A friend of mine Sam Manins managed to come up with a full work around for this. Thanks to Sam, the function below can be pasted into your OnLoad event for a more reliable method to import Javascript files into your CRM forms.

The idea is to invoke the command to add your external file, then wait for confirmation that the file was imported. Only then should we allow the code to continue. See comments within the code.

//Paste this function somewhere into your form "OnLoad" event
function includeExternalJSFiles(sec)
{
var errFound = 0;
// load the Ascentium js file into a Script element - do not do this on recursive calls to this function
if (sec == 1)
{
//Include the CRM js file
var Ascentium_Script = document.createElement("script");
Ascentium_Script.language = "javascript";
Ascentium_Script.src = "MyJSFunctions1.js"
document.getElementsByTagName("head")[0].appendChild(Ascentium_Script);
//Include another js file
var Ascentium_Script = document.createElement("script");
Ascentium_Script.language = "javascript";
Ascentium_Script.src = "MyJSFunctions2.js"
document.getElementsByTagName("head")[0].appendChild(Ascentium_Script);
//Add any more JS files you need
}
try
{
//Each file needs to have a simple function(with a unique name) that does nothing that can be called.
//th
en you can call this finction to see if the file has been imported yet.
MyJSFunction1_STUB();//this function is contained in the external JS file
MyJSFunction2_STUB();//this function is contained in the external JS file
}
catch(err)
{
//error found(probably could not find the function
errFound = 1;
}
if (sec < 5 && errFound == 1)
{
sec++;
setTimeout("includeExternalJSFiles(" + sec + ")", 100); //waits 0.1 second before trying the stubs again.
}
else
{
if (errFound == 1)
//Did not work after 5 attempts (0.5 seconds)
//Try a longer time period or output an error message for the user
//alert("Did not work: " + sec);
else
//All functions were found (all files imported)
//No need to do anything. Just exit functions and continue code
//alert("Success after " + sec + " attempts. ");
}
}

Remember to have a unique stub function to run in each external file. the function needs no do anything. Just needs to be there(See sample below).

//this function would be found in the file MyJSFunction1.js
function MyJSFunction1_STUB()
{
//stub function (does nothing)
var a;
}

Finally you need to call the function to import your Javascript files:

includeExternalJSFiles(0);

The above example makes the call to add the files to the page header, then continues to try to run a functions in each file every 0.1 seconds until successful or until 5 failed attempts. Different systems under different workloads may perform the job at different speeds. Feel free to modify the code to suit your needs.

And improvement on this function could be to also pass in the name of each Javascript file in an array, making it more generic.

A big thank you goes to Sam Manins for the solution.

Tuesday, January 27, 2009

Dynamics CRM Usergroup Sydney Returns!

The Sydney CRM usergroup was reopened last night(Microsoft building, North Ryde). Organised by Catherine Eibner and Guy Riddle, the event will be held every 4th Tuesday of every month.

This has been a long anticipated step forward for the Sydney CRM users and consultants and a great place to meet people in your field of business.

This month's discussions were over the newly release CRM Accelerators (presented by Guy), with detailed discussions on Notifications, eService and Events Management. The remaining Accelerators will be discussed next month.

Visit www.mscrm.com.au for more information and upcoming meeting event dates.

Tuesday, January 20, 2009

No need to retrieve entity in order to update attribute values

Scenario:
We have an existing account with a known GUID and would like to update their phone number.
Solution:

Common sense and traditional logic would often suggest to first open the specific account record, make modifications to all specific attributes, followed by update and close the entity:
ColumnSet cols = new ColumnSet();
cols.AddColumn("telephone1");
account myAccount = new account();
myAccount = oService.Retrieve(EntityName.account.ToString(), myAccountID, cols) as myAccount;
myAccount.telephone1 = "02 1234 1234";
oService.Update(myAccount);
The above code, though it works, contains a number of entirely unnecessary steps. For a far more efficient code block, see the following with an identical outcome:
account myAccount = new account();
myAccount.accountid = myAccountID;
myAccount.telephone1 = "02 1234 1234";
oService.Update(myAccount);
Note that there is no need to retrieve the targeted record before making modifications. As long as we set the entity ID to an existing GUID, the CRM SDK will take care of the rest. The stored value in the "telephone1" attribute will be replaced with the new value for the specified account GUID "myAccountID".

Monday, December 29, 2008

Action Cancelled: MSCRMKeyGenerator - 18949

When openning the CRM shortcut you promptly receive the message "Action Cancelled"

Error log details:
Source:   MSCRMKeyGenerator
Event ID: 18949

Current active key (KeyType : CrmWRPCTokenKey) is expired. This can indicate that a key is not being regenerated properly. Current Active Key : CrmKey(Id:c2e0c738-dc7a-dd11-b61e-00188b3466e9, ScaleGroupId:00000000-0000-0000-0000-000000000000, KeyType:CrmWRPCTokenKey, Expired:True.....
I recently came across this error a few times. On all occasions I had no luck in sorting it out the usual way:

Start services.msc and ensure that Microsoft CRM Asynchronous Processing Service is started.

If like in my case, you find that this service was already running, then save yourself hours of scratching and simply restart the SQL Server housing the CRM database. 

I'm yet to find the specific reason behind this error.