Wednesday, April 16, 2008
Helpful CRM links for developers
The Microsoft CRM Dev center @ MSDN:
http://msdn2.microsoft.com/en-us/dynamics/crm/default.aspx
Tons of great info here, especially in the forums.
Microsoft Dynamics CustomerSource
http://www.microsoft.com/dynamics/customersource.mspx
This is the place for technical support (assuming you have an active subscription).
Microsoft Dynamics CRM Team Blog
http://blogs.msdn.com/crm/
Posts on new features and functionality from the CRM developers themselves. There are also guest bloggers offering up their expertise.
Sonoma Partners
http://www.sonomapartners.com/
These guys literally wrote the bookon CRM customization.
The MscrmGuy’s blog
http://blogs.msdn.com/jstraumann/
This blog has a lot of good info. If you search it for HOL (hands on lab) there are several good tutorials that cover the basics of CRM customization.
SSW’s Rules to better Microsoft CRM
http://www.ssw.com.au/ssw/Standards/Rules/RulestoBetterMicrosoftCRM.aspx
SSW is an Australian consulting service. Their Rules are always helpful, and there are other technologies in the series (such as Reporting Services).
Stunnware
http://www.stunnware.com/
This site has been very helpful. The Javascript library (found in the blog section) is especially useful.
Ronald Lemmen’s blog
http://ronaldlemmen.blogspot.com/
Ronald is a CRM consultant who really knows his stuff. His blog is full of valuable information and he also posts frequently on the Microsoft forums.
Friday, April 11, 2008
Using JavaScript to access the CRM offline database
Here is an example:
var accountGuid;
accountGuid = document.getElementById("your fieldname here");
if (IsOnline())
{
// write code for online version here.
}
else
{
var iCount = 0;
var connection = new ActiveXObject("ADODB.Connection");
var connectionString = "Provider=SQLOLEDB;Server=.\\CRM;Database=MSCRM_MSDE;Integrated Security=sspi";
connection.Open(connectionString);
var query = "SELECT count(*) FROM AccountBase WHERE AccountID='" + accountGuid.value + "'";
var rs = new ActiveXObject("ADODB.Recordset");
rs.Open(query, connection, /*adOpenKeyset*/1, /*adLockPessimistic*/2);
rs.moveFirst();
while (!rs.eof) {
iCount = rs.Fields(0).Value;
rs.moveNext();
}
connection.Close();
if (iCount > 0 ) {
//do something useful here
}
else {
//do something else here
}
}
Restoring the CRM database
Doh!
Thursday, April 10, 2008
Remote Desktop console session
Tuesday, April 8, 2008
Troubleshooting errors when going offline in CRM
You can track down the problem by performing a platform trace on the PC that is receiving the error. Microsoft provides info on how to accomplish this here.
After enabling tracing, you can review the log file for the cause of the error. The log can be quite lengthy, so search for words such as “Error” or “Exception”. Often the cause is someone such as myself, has attempted to customize the system in an un-supported manner (one example can be seen here).
Monday, April 7, 2008
Enabling Activities on Custom Entities after they have been created.
I was able to take the procedure outlined by Aaron and modify it to enable Activities instead of Notes. Note – this is completely un-supported by Microsoft. The technique has not caused any problems on my test system, but results may vary. Use at your own risk!
The first step is to create a stored procedure using the following script.
Second, paste the name of your custom entity (where is says “placeEntityNameHere”) in the SQL script below, and execute it. This should create all of the needed system relationships between the custom entity and the Activity entities (Email, Task, etc.).
-- Define the Entity to Update
DECLARE @entityname varchar(64);
SET @entityname = 'placeEntityNameHere';
-- Define a GUID for the relationship
-- This is defined here and passed in so that we can access the relationship later
-- and apply special options if needed
DECLARE @TEMP_RelationshipId uniqueidentifier;
-- Add the ActivityPointer Relationship
SET @TEMP_RelationshipId = NEWID();
EXEC dbo.AddCrmRelationship @entityname, 'ActivityPointer', '_ActivityPointers', @TEMP_RelationshipId;
-- Add the Appointment Relationship
SET @TEMP_RelationshipId = NEWID();
EXEC dbo.AddCrmRelationship @entityname, 'Appointment', '_Appointments', @TEMP_RelationshipId;
-- Add the Email Relationship
SET @TEMP_RelationshipId = NEWID();
EXEC dbo.AddCrmRelationship @entityname, 'Email', '_Emails', @TEMP_RelationshipId;
-- Add the Fax Relationship
SET @TEMP_RelationshipId = NEWID();
EXEC dbo.AddCrmRelationship @entityname, 'Fax', '_Faxes', @TEMP_RelationshipId;
-- Add the Letter Relationship
SET @TEMP_RelationshipId = NEWID();
EXEC dbo.AddCrmRelationship @entityname, 'Letter', '_Letters', @TEMP_RelationshipId;
-- Add the PhoneCall Relationship
SET @TEMP_RelationshipId = NEWID();
EXEC dbo.AddCrmRelationship @entityname, 'PhoneCall', '_PhoneCalls', @TEMP_RelationshipId;
-- Add the ServiceAppointment Relationship
SET @TEMP_RelationshipId = NEWID();
EXEC dbo.AddCrmRelationship @entityname, 'ServiceAppointment', '_ServiceAppointments', @TEMP_RelationshipId;
-- Add the Task Relationship
SET @TEMP_RelationshipId = NEWID();
EXEC dbo.AddCrmRelationship @entityname, 'Task', '_Tasks', @TEMP_RelationshipId;
go
The final step is to add and delete a new custom entity (or use the app provided at Aaron’s post to handle the update). This step causes CRM to re-process all of its relationships, and forces our manual updates to take affect.
Aaron’s example for Notes also required exporting the entity’s customizations and modifying the XML. This is not required for Activities because no changes are made the entity’s form.
Friday, April 4, 2008
Increasing the length of a CRM 3.0 custom entity nvarchar field
A. Create a new field with the new length, transfer all existing data to the new field, and hide the existing field from users.
B. Back up all data, delete the entity, create a new one, and import all of the archived data.
C. Hack the system by going around CRM’s user interface and modifying the field length.
Option C would give us what we were really looking for (and it sounded like the most fun), so I decided to give it a try.
Here are the steps that were attempted (Warning this is un-supported by Microsoft, and is listed here for educational purposes only! It could seriously harm your CRM installation.):
1. Export the entity’s customizations as an XML file.
2. Open the file in your favorite editor and search for the field’s name.
3. Assuming you only work in one language, there are two values that will need to be modified. They are Length and maxlength. Change maxlength to the new value and Length to two times the new value.
<attribute PhysicalName="Ffs_fieldtomodify">
<Type>nvarchar</Type>
<Length>150</Length>
<ValidForCreateApi>1</ValidForCreateApi>
<ValidForUpdateApi>1</ValidForUpdateApi>
<ValidForReadApi>1</ValidForReadApi>
<IsCustomField>1</IsCustomField>
<DisplayMask>PrimaryNameValidForAdvancedFindValidForFormValidForGrid</DisplayMask>
<Description>The name of the custom entity.</Description>
</attribute>
<field name="ffs_fieldtomodify" requiredlevel="required" maxlength="75" format="text">
<displaynames>
<displayname description="Field To Modify" languagecode="1033" />
</displaynames>
</field>
4. Save the XML, import it into CRM, and publish customizations. (At this point, CRM will show the new length but the SQL tables have not been updated. So, if you try to save a value that is too long you will get a SQL exception message. To solve this, continue on.)
5. Modify the field’s length in the
6. To get the field length to display correctly in the CRM metadata browser, update the Attribute table in the
select * from attribute where [name] = 'ffs_fieldtomodify'
After all of these steps, everything appeared to be working perfectly. Until, I tried to take my CRM client offline. It gave the error message, “The XML passed to the platform is not well-formed XML”. A CRM client trace revealed this:
>Crm Exception Message: Updating Ffs_temp.ffs_fieldtomodify.Length but it's not valid for update. Original value:150. New value:250., ErrorCode: -2147220991
After thinking about this for awhile, I decided to cancel plan C and go back to plan B. It was an interesting challenge; but in the end it was safer and easier to just delete and re-create the entity. However, if you do not use the CRM offline client, you MIGHT be able modify the field lengths without any problems.