Sunday, November 23, 2008

AT&T Wireless self destructs...

It's actually an old story by now but I just recently heard of it from my new staff manager and it is a very interesting story of just how bad a CRM implementation can get. It concerns Siebel and my analysis of the story is that the reson for the crash was mostly due to bad management and a lock on both timeframe and functionallity, something I believe is impossible if you want to achieve any kind of quality. This case being the perfect example.

Please read it and leave a comment here if you want to discuss it!
http://www.cio.com/article/32228/Project_Management_AT_T_Wireless_Self_Destructs

Gustaf Westerlund
Microsoft Dynamics CRM Architect

Logica
www.logica.com

Wednesday, November 19, 2008

Automatic restart of Async Service

When developing new workflow activities for CRM 4.0 you need to release the filelocks on the dll to be able to copy the new dll to the assembly directory. This can of course be done manually by restarting the service in the service manager but can be scripted into the prebuild events aswell, so that it is more automatic. Add the following two lines to the Pre-build events of your workflow activity project to make it restart the MSCRMAsyncService:

net stop "MSCRMAsyncService"
net start "MSCRMAsyncService"

Please note that you might inflict any ongoing workflows by doing this so take care if it is a live production server.

Gustaf Westerlund
Microsoft Dynamics CRM Architect

Logica
www.logica.com

Friday, November 14, 2008

Quick create

As many of you know, in CRM 3 there is a special view of an entity form called quickcreate. This is used when you press "New" in a lookup window. For instance, on an account you can press: select primary contact, when the search dialog shows you can instead of selecting an existing contact press the new button and a "slimline" version of the contact form show with just the must-have and should-have fields available.

In CRM 4 this feature is not used any more and the complete form will always be shown in this case, however, the functionality hasn't been removed. I tried to find some kind of reference to it in the SDK but couldn't so I had a look in the original CRM code in CRM 3 and found how to do it.

To open a form as quick create, find the object type code (1 = account etc) and go to the URL:
http://[server:port]/[organisation]/_forms/QuickCreateReturn/quickcreate.aspx?crmFormSubmitObjectType=[objecttypecode].

For example, for account on the local machine when CRM is installed on port 5555 and the company is named "company":
http://localhost:5555/company/_forms/QuickCreateReturn/quickcreate.aspx?crmFormSubmitObjectType=1

Since I couldn't find any official reference to this in the SDK it is very possibly unsupported to do this but it works for now. Any hotfixes or similar might, but are not very likely to change this functionality, new versions of CRM like v.next are more likely to change/remove this functionality.

Gustaf Westerlund
Microsoft Dynamics CRM Architect

Logica
www.logica.com

Tuesday, November 11, 2008

Putting all javascript code in external files

Dynamics CRM is great. It has some really nice functions like being able to add javascripts to different event in the form to handle special needs of the GUI.

However, it is only fine as long as these scripts arn't that many and not too complex. When they start getting more and more complex, bigger and their numbers start increasing it soon becomes an impossible tast of maintaining them all and there is no built in function to handle javascript includes without special code. It also takes a long time developing more complex code in the javascript form window in CRM and then running the preview or publishing it each time before testing.

There is light in the tunnel however, by using the technique specified bellow, you can both
get global javascript files, save and refresh only to see you changes, and keeping all scripts for one entity in one file (and not one for onLoad, one for onSave and one for each onChange that is needed).

A lot of credit for this has to go to Michael Höhne at Stunnware since he added a posting on his blog on how to manage javascript includes in runtime.

So, first of all we have to put some standard code in the onLoad. This should only be done once and it shouldn't really be changed until you need to publish it for release (switching of the caching).

var LoadFile = function(url, cache)
{
var httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
httpRequest.open("GET", url, false);
if (!cache)

{
httpRequest.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
}

httpRequest.send(null);
return httpRequest.responseText;
}

eval(LoadFile("/isv/mycrmext/javascripts/MyGlobal.js", false));
eval(LoadFile("/isv/mycrmext/javascripts/Account_onload.js", false));

This code simply loads and executes the two files MyGlobal.js and Account_onload.js located in the directory C:\Program Files\Microsoft Dynamics CRM\CRMWeb\ISV\myCRMEXT\JavaScripts
and can be found at the url: :port/isv/mycrmext/javascripts/">http://:port/isv/mycrmext/javascripts/.

So, copy-paste it into the onload event form in the account form editor in CRM. Activate the event, save and publish.

Then you can create the two .js-files at the specified directory. Start with just some test code like:
alert("This is the MyGlobal.js-file");
or something similar.

The next step is to try to avoid using the onsave and onchange events. This is quite easy when you know how but it is sort of in the gray area of supported customizations so be aware of this.

In the file Account_onload.js add the following code:
var MyOnSave = function()
{
alert("onSave");
}

var MyOnChange = function()
{
alert("onChange");
}


alert("onload)

crmForm.attachEvent("onsave", MyOnSave);
crmForm.all.name("onchange", MyOnChange);

This attaches a simple function to the onsave event of the form and another to the onchange event of the attribute "name".

The functional defintions/declarations can be put into any of the includefiles.

Now, just save the file, and open an account to see the magic! (It should show a dialog when loading with the text "onload", when the accountname is changed, it should show "onchange" and when saved, it should show "onsave".

Please note that I would advise you to put the javascript files in the same "host" from a IE perspective since you will get less problems with cross domain scripting and similar IE related security issues. This doesn't however mean that you cannot put the js-files anywhere on the internet where the clients can access it.

Gustaf Westerlund
Microsoft Dynamics CRM Architect

Logica
www.logica.com

Wednesday, November 05, 2008

How to get the URL to the reportserver programmatically

I was searching the net the other day to try to find a way to programmatically get the reporting server url from CRM. I thought that there must be some way to find it using the standard CRM webservice and I really looked throught the SDK and all the blogs I could find to see if anyone knew.



Finally I gave up and tried to find some other way to get it and I remembered that it is set in the registry so I wrote some code to get it from there and here it is in all it's simple glory:



RegistryKey regkey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\MSCRM");
string reportserver = regkey.GetValue("SQLRSServerURL").ToString();




And it worked but only just since it uses the server name and my VPN connection to the customers environment didn't bother with sending it to me why I have to manually add it to the hosts file.



The host file can be found at the path: C:\WINDOWS\system32\drivers\etc\hosts



and I added the row:

192.168.0.100 CRMTESTSRV



Now my button which point to my aspx that redirects to a the report in pdf-format works just fine and is independant of the CRM server it is installed on.



The solution isn't supported as far as I know since you never know if they might change the registry value in the future (not very likely in an update but might happen in an upgrade). If anyone has any supported way of getting this URL, please comment this post.



This could also be done using javascripts but I find it easier to manage server side code and it doesn't add that much overhead considering the report has to be generated independantly of if I use aspx or javascript to open the report.



Gustaf Westerlund
Microsoft Dynamics CRM Architect

Logica
www.logica.com