Microsoft Dynamics CRM 2013 setup with SQL Server 2014 High Availability

When Dynamics CRM is setup with SQL Server 2013 High Availability a Listener is required to be used in the connection string.  However when doing a Organization import from for example your Test server CRM will not allow you use a Listener if you attempt to use a Listener Dynamics CRM with throw the following error.

InnerException:

System.Net.Sockets.SocketException (0x80004005): No such host is known

at System.Net.Dns.InternalGetHostByName(String hostName, Boolean includeIPv6)

at System.Net.Dns.GetHostAddresses(String hostNameOrAddress)

at Microsoft.Crm.Setup.Server.Utility.ManagedNetworkUtility.IsHostNameLocal(String hostName)

at Microsoft.Crm.Setup.Server.Utility.ManagedNetworkUtility.AreHostNamesSynonymous(String host1, String host2)

at Microsoft.Crm.Tools.Admin.GrantSrsAccessToConfigDBAction.GrantSrsServiceAccessToLocalConfigDB(Uri reportingUrl)

at Microsoft.Crm.Setup.Shared.CrmAction.ExecuteAction(CrmAction action, IDictionary parameters, Boolean undo)

Because Microsoft does not provide a way within its UI to update the connection string back to the physical server name the only option seems to be to manually update the Organization table in the MSCRM_Config database directly, which of course is unsupported by Microsoft.  This has been confirmed by Microsoft Support.

 

Below is the official response from Microsoft CRM Support

Thank you for your time over the case today.

As discussed earlier, I can confirm that the issue with importing organization is reproducible, in an environment where CRM is configured with SQL 2012 Always On. To fix this issue, we have to update the Connection String in MSCRM registry hive as well as the Organization table in the MSCRM_Config DB, to change the DataSource Name from Lister to the Primary Replica. Once these changes are done the Organization import works just fine and then they go back and revert the changes.

Following changes are done:

  • Change the Data Source from the SQL Server instance name to the availability group listener name.

The complete connection string should appear similar to the following example, where MSCRMAG is the availability group listener name for the availability group that includes the Microsoft Dynamics CRM configuration database:

Data Source MSCRMAG;Initial Catalog= MSCRM_CONFIG;Integrated Security=SSPI

  • Update query for MSCRM_Config DB

Update Organization

set ConnectionString = ‘Provider=SQLOLEDB;Data Source=AG_Listener_Name,Port_Number;Initial Catalog=OrganizationName_MSCRM;Integrated Security=SSPI;multisubnetfailover=true’ where DatabaseName = ‘OrganizationName_MSCRM’

I have discussed this with our senior resources at Microsoft, and we can confirm that this is a workaround for now and the same is supported. The deployment will continue to stay supported until and unless there are no other changes made to the database, then the ones mentioned above.

 

 

Executing a Dynamics CRM WorkFlow from a Plugin

As part of a StateFlow engine I writing for a Microsoft Dynamics CRM 2011 project I needed to be able to run a series of custom workflow activities.  I needed the workflow activities to be driven off a configuration entity that would hold rules like, how often to run, what status reason to set a matching record to and so on.  One part that was a bit less than obvious was how to get the GUID for the workflow I wanted to execute in a search by “workflow name”.  I’m sure there are several ways to do this but I was surprised when I found you could query it just like any other entity.  Just be sure that you add a condition of “type”, ConditionOperator.Equal, 1 otherwise CRM will grab the unpublished version of the workflow and throw a error “workflow must be in published state”.

Code Snippets

The following is a code sample that calls two methods: GetProcessId and ExecuteWorkFlow before we can do so we need to get the ID of the workflow which is stored in the PrimaryEntityId attribute of the workflow context.

// Create the context

IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();

_primaryEntity = context.PrimaryEntityId;

Guid processId = new Guid(GetProcessId(service, “workflow”, “name”, “StateFlow”).Id.ToString());

ExecuteWorkFlow(service, processId, _primaryEntity);

private void ExecuteWorkFlow(IOrganizationService service, Guid workFlowId, Guid entityId)

{

try

{

// Create an ExecuteWorkflow request.

ExecuteWorkflowRequest request = new ExecuteWorkflowRequest()

{

WorkflowId = workFlowId,

EntityId = entityId

};

// Execute the workflow.

ExecuteWorkflowResponse response =

(ExecuteWorkflowResponse)service.Execute(request);

}

catch (Exception ex)

{

throw new InvalidPluginExecutionException();

}

}

 

 

private Entity GetProcessId(IOrganizationService service, string EntityLogicalName, string SearchFieldName, object SearchValue)

//Internal method used to search for entity records

{

EntityLogicalName = EntityLogicalName.ToLower();

SearchFieldName = SearchFieldName.ToLower();

QueryExpression query = new QueryExpression(EntityLogicalName);

query.ColumnSet = new ColumnSet(true);

query.Criteria.AddCondition(new ConditionExpression(SearchFieldName, ConditionOperator.Equal, SearchValue));

query.Criteria.AddCondition(new ConditionExpression(“type”, ConditionOperator.Equal, 1));

try

{

EntityCollection response = service.RetrieveMultiple(query);

if (response != null && response.Entities.Count > 0)

return response.Entities[0];

else { return null; }

}

catch (Exception ex)

{

//Do error hadling

throw ex;

}

}

CRM 4.0 Master Schema Management and Customization Change Control

 Recently I found a CRM 4.0 Schema comparison tool that I find makes life much easier when I’m playing the role of Schema Master.  Managing schema changes is in my opinion a arduous and very manual process.  It is  not advisable to use TFS for schema file comparisons and definitely not for merging, this is because TFS does line by line comparison not XML tag comparisons.  The Customization Comparison Utility lets you compare the customization files between two Microsoft Dynamics CRM systems and the Configuration Data Utility lets you transfer custom configuration data from one Microsoft Dynamics CRM system to another.   You can download the solution file here

The process I recommend for the proper management and change control practices   essential for the ongoing life cycle of a Microsoft CRM Dynamics Organization Database Schema.  The diagram below represents the three typical scenarios that the Schema Master may encounter on a frequent basis.  The three scenarios are Jr. Developer or Third Party Developer interactions, Senior Developer Interactions and Multi-Developer Entity Edits.  Using the Customization Comparison Utility along with this process will ensure the integrity of your CRM schema and save you from a lot of pain.

  

Master Schema Scenarios

Scenario 1

Under scenario 1 a junior developer or a third-party or outside vendor may need to promote changes to the CRM Master Schema.  In this circumstance the Schema Master would likely be responsible for heavy validation of the schema changes.

1.       The schema items impacted are exported from the developers environment .

2.       The schema items impacted are documented in a standard SharePoint change-log.

3.       The schema export file is checked in to the weekly schema build folder.

4.       The Schema Master reviews the change-log and the may make manual or automated adjustments to the Master Schema.

Scenario 2

Under scenario 2 a senior developer may need to promote changes to the CRM Master Schema in this circumstance would likely be responsible for validation of the schema changes.

1.       The schema items impacted are exported from the developers environment .

2.       The schema items impacted are documented in a standard SharePoint change-log.

3.       The schema export file is checked in to the weekly schema build folder.

4.       The Schema Master reviews the  change-log and the may make manual or automated adjustments to the Master Schema.

Scenario 3

Under scenario 3 multiple developers may need to promote changes to the CRM Master Schema impacting the same entity.  In this circumstance the developers would likely be responsible for creating and validating a single schema export file.

1.       The schema items impacted are exported from the developers environment .

2.       The schema items impacted are documented in a standard SharePoint change-log.

3.       The schema export file is checked in to the weekly schema build folder.

4.       The Schema Master notifies the developers of potential conflicts or collisions.

5.       The developers create a single schema export file and check it in to TFS.

6.       The Schema Master reviews the change-log and the may make manual or automated adjustments to the Master Schema.

The TFS Role

TFS is used as a repository for the incremental schema edits that are proposed as candidates to the Schema-Master.  It’s critical that developers only submit specific entity schema segments rather than the full CRM schema, this is because TFS analyzes code line by line rather than in the XML  tag format the CRM schema model uses.  Also because the environment that the CRM schema is exported from can alter the format and order of the XML.  For these reasons it will be incumbent upon the Schema-Master to understand where the schema segments are coming from and to identify the risks associated with the submitting party.

The SharePoint Role

A standard SharePoint form should be used to capture the schema changes being submitted by each developer.  The SharePoint form should capture at minimum:

               

o    ID Number

o    Entity, Workflow or Role Name

o    Attribute

o    Deployment Comments

o    Impact Analysis Comments

The ID Number shoul

 

d always be references within the TFS check-in comments   and included in the release and deploy notes sent to the Deployment team for each build.

 

 

 

 

 
 
 
 
 
 
 

How to Programmatically Create a Microsoft Word Document from Dynamics CRM

Recently I had a need to create a Microsoft Word document and dynamically populate it from data in CRM.  Microsoft Word can be invoked from JavaScript using the ActiveXObject .  This first example shows a very basic application of the concept.  Create a blank document , add a report title then add some body  text.  In my application I call the JavaScript from a toolbar button added with the ISV.config file.  For more information on adding buttons that call javaScript see Calling JavaScript from Microsoft CRM  Toolbar Buttons

// Start a new instance of Microsoft Word

var MsWord = new ActiveXObject(“Word.Application”);

// Create a new document

MsWord.Documents.Add();

//Carriage Return

MsWord.Selection.TypeParagraph();

//Report Name

MsWord.Selection.TypeText(crmForm.all.new_name.value);

//Carriage Return
MsWord.Selection.TypeParagraph();
//Carriage Return
MsWord.Selection.TypeParagraph();

//Memo field from CRM containing paragraphs of text

MsWord.Selection.TypeText(crmForm.all.new_body.value);

//Show Microsoft Word

MsWord.Visible = true;

 

To create a new document using a Microsoft Word Template do this:

msWord.Documents.Add(“http://myserver:5555/documentTemplate.dotx&#8221;);

To add text to a specific Microsoft Word form field first create a Word template and add a field to it using the developer toolbar then use this code:
msWord.ActiveDocument.FormFields(“Text1”).Result = crmForm.all.new_name.value;

Obviously you can take this much further, in my application I use a AJAX call to a web service to get related CRM records.  I also lock all the fields so their content can’t be modified by the user.  What the user can do is add content to the document which may include HTML content.  The need to generate a report but then add custom content was the genesis for this feature.

Here’s a article about creating fields in Microsoft Word.  Click Here

Show hide form elements in Microsoft Dynamics CRM 4.0 based on user role.

  

Because Microsoft Dynamics CRM 4.0 only allows a single form for each entity it is often necessary to show or hide certain form elements like buttons, iFrames and tabs based on the role of the currently logged in user.

Calling the CrmService of Microsoft Dynamics CRM 4.0 allow us to determine who the currently logged in user is and what roles they have been assigned.  I have attempted to keep this example straightforward the only code that has nothing to do with getting the current user and their role are the the two line turning off a tab in the event the user doesn’t have the role of “Manager”.

    crmForm.all.tab2Tab.style.visibility = “hidden”;

    crmForm.all.tab2Tab.style.position = “absolute”;

Everything else is specific to calling the CrmService getting the current user and finding their user roles in the XML DOM that the CrmService returns.

//Based on the role of the user logged in, hide the named tab on the entity form 

if 

(currentUserHasRole(‘Manager’)) {else 

crmForm.all.tab2Tab.style.visibility = 

crmForm.all.tab2Tab.style.position = 

{“hidden”;“absolute”;function 

UserHasRole(roleName) {}function 

xmlhttp.open( 

xmlhttp.setRequestHeader( 

xmlhttp.setRequestHeader( 

soapXml += GenerateAuthenticationHeader(); 

soapXml += soapBody; 

soapXml += 

xmlhttp.send(soapXml); 

xmlDoc = 

xmlDoc.async = 

xmlDoc.loadXML(xmlhttp.responseXML.xml); 

getUserId() {try {var xmlhttp = new ActiveXObject(“Msxml2.XMLHTTP”);“POST”, “../../mscrmservices/2007/crmservice.asmx”, false);“Content-Type”, “text/xml; charset=utf-8”);“SOAPAction”, http://schemas.microsoft.com/crm/2007/WebServices/Execute&#8221;);var soapBody = “<soap:Body>” + “<Execute xmlns=’http://schemas.microsoft.com/crm/2007/WebServices’>&#8221; + “<Request xsi:type=’WhoAmIRequest’ />” + “</Execute></soap:Body>”;var soapXml = “<soap:Envelope “ + “xmlns:soap=’http://schemas.xmlsoap.org/soap/envelope/&#8217; “ + “xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance&#8217; “ + “xmlns:xsd=’http://www.w3.org/2001/XMLSchema’>&#8221;;“</soap:Envelope>”;new ActiveXObject(“Microsoft.XMLDOM”);false;var userid = xmlDoc.getElementsByTagName(“UserId”)[0].childNodes[0].nodeValue;return userid;catch (e) {return null;function 

command.SetParameter( 

getUserRoles(userId) {try {var command = new RemoteCommand(“UserManager”, “GetUserRoles”);“userIds”, “<guid>” + userId + “</guid>”);var oResult = command.Execute();if (oResult.Success) {return oResult.ReturnValue;catch (e) {return null;function 

result = getUserRoles(userId); 

oXml.resolveExternals = 

oXml.async = 

oXml.loadXML(result); 

roleNode = oXml.selectSingleNode( 

hasRole = 

userHasRole(userId, roleName) {var hasRole = false;if (result != null) {var oXml = new ActiveXObject(“Microsoft.XMLDOM”);false;false;“/roles/role[name='” + roleName + “‘]”);if (roleNode != null) {if (roleNode.selectSingleNode(“roleid[@checked=’true’]”) != null) {true;return hasRole;function 

userId = getUserId(); 

currentUserHasRole(roleName) {return userHasRole(userId, roleName); 

For more information see….

WhoAmI Message (CrmService)

CrmService Messages

Attaching Javascript code to a CRM Toolbar Button

Attaching Javascript code to a tool bar button can be very ugly.  Generally the code needs to be included within the CRM, ISV Config  XML file.  It’s pretty easy to add a button via the ISV Config.  Click Here for more information on adding custom buttons to a Microsoft Dynamics CRM Entity form, toolbar.

The red highlighted Javascript tag below shows you where you would typically place your JavaScript or JavaScript function call but this isn’t the best place for the JavaScript.  I have seen huge JavaScript routines embedded in to the tag whci makes debugging and readability a painful exercise.  Even if you call a JavaScript function and leave the tag nice and cleas as shown here that Javascript function has to be maintained outside of the CRM Model.

<Entities>
        <Entity name=”new_customentity”>
          <ToolBar ValidForCreate=”0″ ValidForUpdate=”1″>
            <ToolBarSpacer></ToolBarSpacer>
            <Button Icon=”/_imgs/ico_18_debug.gif” JavaScript=”
DuplicateRecord (10016);”>
              <Titles>
                <Title LCID=”1033″ Text=”Duplicate Record” />
              </Titles>
              <ToolTips>
                <ToolTip LCID=”1033″ Text=”Copies a record based on this open record.” />
              </ToolTips>
            </Button>
            <ToolBarSpacer />
          </ToolBar>
        </Entity>
      </Entities>
 

The solution is pretty simple.

If we change the structure of our JavaScript function a bit we can simply place it in a Entity’s form OnLoad Event.  The key syntax is simply  MyFunction = function() .

Here is a working example of a function I wrote which calls a web service to copy the  current open record and create a new one based on it,

The CRM Form OnLoad Event JavaScript

DuplicateRecord = function() {

    try {
        var oXmlHTTP = new ActiveXObject(“Msxml2.XMLHTTP”);
       oXmlHTTP.Open(“POST”, “/somepath/ DuplicateRecord Service.asmx/ DuplicateRecord?mso-spacerun: yes”>      + crmForm.ObjectId, false);
        oXmlHTTP.setRequestHeader(“Content-Type”, “application/x-www-form-urlencoded”)
        oXmlHTTP.Send(‘jobId=’ + crmForm.ObjectId);
        var newId = oXmlHTTP.responseXML.selectSingleNode(“string”).text;
   }
    catch (e) {
        debugger;
        return null;
    }
}

 

The ISV Config  XML Tag

<Button Icon=”” Url=”” PassParams=”1″ WinParams=”” WinMode=”0″ JavaScript=” DuplicateRecord ();”>
              <Titles>
                <Title LCID=”1033″ Text=” Duplicate This Record ” />
              </Titles>
              <ToolTips>
                <ToolTip LCID=”1033″ Text=”Copy Record” />
              </ToolTips>
            </Button>
 

Conclusion

I like this approach because now all our JavaScript is still maintained within the CRM Entity’s and for a number of good reasons that’s where a Microsoft Dynamics CRM  application should store the JavaScript.  Because its with the entity it will get exported with your model and other customizations.

Working With CRM 4.0 Data Types and Form Controls

Boolean

Specifies a field  that displays one check box or two radio buttons. The Boolean field type is one display option for bit type attributes. The other option is list. The list option uses the Picklist field type.

Note   Changing the formatting options of a bit attribute is done on the form, not in the attribute definition like other attributes. Changing the formatting option from a check box or two radio buttons to a list will change the way that you access the values in the form, potentially breaking your code.

The following properties are available:

Boolean properties Type Description
{Field}.DataValue Boolean or Null Get/set property. The original value is left unchanged if the new value cannot be parsed.
{Field}.DefaultValue Boolean Get property. Returns the default value for the field.

 

Example

The following code example shows how to set a field of type Boolean.

crmForm.all.SOME_BOOLEAN_FIELD_ID.DataValue = true;
 
crmForm.all.SOME_BOOLEAN_FIELD_ID.DataValue = false; 

 

Customer

A Customer field represents a type of Lookup where either an account or contact is a valid type of record.

The following properties are available:

Customer or Regarding properties Type Description
{Field}.DataValue   Specifies an array of lookup objects. For the Customer field this array always has a length of one. DataValue is Null when no value is selected. Set DataValue to Null to make the lookup field blank.

 

Example

The following code example shows how to use a Customer field type.

var customer = new Array();
customer = null;

// This gets the lookup for the attribute customerid on the Opportunity form.
customer = crmForm.all.customerid.DataValue;

// If there is data in the field, show it in a series of alerts.
if (customer[0] != null)
{
   // The name of the customer.
   alert(customer[0].name);

   // The GUID of the customer.
   alert(customer [0].id);

   // The entity type name of the customer.
   alert(customer[0].typename);
}

 

DateTime

A DateTime field can be formatted to show both the date and time, or the date only. The following properties are available:

DateTime properties Type Description
{Field}.DataValue Date or Null Get/set property.The original value is left unchanged if the new value cannot be parsed.
{Field}.TimeVisible Boolean Get property.This property specifies if the time is to be shown.

 

Example

The following code example shows how to use a field of type DateTime.

var oDate;
var oToday;

oDate =  crmForm.all.scheduledend.DataValue;
if (oDate == null) {
    oDate = new Date();
}

oToday = new Date();
oDate = oToday;
oDate = oDate.setHours(17,0,0);

if (oDate.TimeVisible)
{
   alert("The time is visible.");
}
else
{
   alert("Only the date is visible; the time is hidden.");
}

crmForm.all.scheduledend.DataValue = oDate;

 

Duration

Duration fields are presented as a picklist giving the user a selection of time options from 1 minute to 3 days. But the actual value of a duration field is an integer. If a user types an integer into the field or your code sets the value of the integer representing minutes, the field will convert that value into a more user-friendly unit of measurement. For example, 420 will be displayed as 7 hours.

The following properties are available:

Duration properties Type Description
{Field}.DataValue integer or Null Get/set property.The duration can be set to Null. The original value is left unchanged if the new value cannot be parsed.

 

Example

The following code example shows how to use a field of type Duration.

var iMinutes = 60; crmForm.all.SOME_DURATION_FIELD_ID.DataValue = iMinutes;
 
 
 

E-mail Body

This field type appears in the E-mail activity form. The following properties are available:

E-mail body field methods Type Description
{Field}.DataValue String Used to get the HTML stream for the e-mail body.

Remarks

The HTML stream that defines the DataValue for an e-mail body field is read-only. The DataValue is not available to be read in the OnLoad event.

Example

The following code example shows how to use a field of type E-mail body.

var oField = crmForm.all.SOME_EMAILBODY_FIELD_ID;

alert(The field's HTML is: " + oField.DataValue);

 

 

Float

The following properties are available:

Float properties Type Description
{Field}.DataValue float or Null Get/set property. The original value is left unchanged if the new value cannot be parsed.
{Field}.Min Integer Get property. Returns the minimum allowed value.
{Field}.Max Integer Get property. Returns the maximum allowed value.
{Field}.Precision Integer Get property. Returns the number of digits allowed. This is a value between 0 and 5.

 

Example

The following code example shows how to use a field of type Float.

var oField = crmForm.all.SOME_FLOAT_FIELD_ID;

var iValue = 1976.1102;

// Set the precision of the value.
var oNumber = new Number(iValue);
iValue = oNumber.toPrecision(oField.Precision);

if (iValue < oField.Min)
{
   iValue = oField.Min;
}
else if (iResponse > oField.Max)
{
   iValue = oField.Max;
}

oField.DataValue = iValue;

 

Integer

The following properties are available:

Integer properties Type Description
{Field}.DataValue Integer or Null Get/set property. The original value is left unchanged if the new value cannot be parsed.
{Field}.Min Integer Get property. The minimum allowed value.
{Field}.Max Integer Get property. The maximum allowed value.

 

Example

The following code example shows how to use a field of type Integer.

var oField = crmForm.all.SOME_INTEGER_FIELD_ID;

var iValue = 1000;

if (iValue < oField.Min)
{
   iValue = oField.Min;
}
else if (iValue > oField.Max)
{
   iValue = oField.Max;
}

oField.DataValue = iValue;
 
 

Lookup

A Lookup field type represents the relationship attribute on the related entity. The valid type for the lookup is established in the relationship. Although Lookup is frequently used as a generic term, there are different types of lookups and technically Lookup is the most restrictive kind of field type. Unlike Customer or Regarding, only one entity type is valid in a lookup. Unlike PartyList, only one reference is stored in the field. A lookup field is defined by using the following attributes:

Attribute Type Description
id String The GUID of the item. Required for set.
type Integer Deprecated. The object type code.
typename String The entity name of the item. Required for set.
name String The name of the item to be displayed. Required for set.
data   Any other data. Optional for set.

The following properties are available:

Lookup properties Type Description
{Field}.DataValue An array of lookup objects Get/set property.For lookups this must be an array with the length of one. DataValue is Null when no value is selected. Set DataValue to Null to make the lookup field blank.

Example

The following code example shows how to read values from a field of type Lookup.

var lookupItem = new Array;

// This gets the lookup for the attribute primarycontactid on the Account form.
lookupItem = crmForm.all.primarycontactid.DataValue;

// If there is data in the field, show it in a series of alerts.
if (lookupItem[0] != null)
{
   // The text value of the lookup.
   alert(lookupItem[0].name);

   // The GUID of the lookup.
   alert(lookupItem[0].id);

   // The entity type name.
   alert(lookupItem[0].typename);

}

Example

The following code example shows how to set values in a field of type Lookup. This example shows how to set the parent account lookup field on the account form.

//Create an array to set as the DataValue for the lookup control.
var lookupData = new Array();
//Create an Object add to the array.
   var lookupItem= new Object();
//Set the id, typename, and name properties to the object.
   lookupItem.id = '{1AAC1363-01A1-DB11-8432-0003FF9CE217}';
   lookupItem.typename = 'account';
   lookupItem.name = 'A Bike Store';
// Add the object to the array.
   lookupData[0] = lookupItem;
// Set the value of the lookup field to the value of the array.
   crmForm.all.parentaccountid.DataValue = lookupData;

Memo

Memo represents a multiline text box using the ntext attribute type. The following properties are available:

Memo properties Type Description
{Field}.DataValue A reference to a string object Get/set property.
{Field}.MaxLength Integer Get property.The maximum length of the string.

 

Example

This field is used in the same manner as a String Type.

 
 

Owner

A Owner field represents a Lookup where the linked record can be any record type that can be presented in the field.

The following properties are available:

Regarding properties Type Description
{Field}.DataValue   For the regarding field type this is an array with a length of one. DataValue is Null when no value is selected. Set DataValue to Null to make the lookup field blank.

Example

The following code example shows how to use a field of type Owner.

var lookupItem = new Array;
lookupItem = null;

// This gets the lookup for the attribute regardingobjectid on the Task form.
lookupItem = crmForm.all.ownerid.DataValue;

// If there is data in the field, show it in a series of alerts.
if (lookupItem[0] != null)
{
   // The text value of the lookup.
   alert(lookupItem[0].name);

   // The GUID of the lookup.
   alert(lookupItem[0].id);

   // The entity type name.
   alert(lookupItem[0].typename);
}

PartyList

A type of Lookup that allows for multiple references to records of multiple types of entities to be set in a single field. A PartyList is typically found on e-mail activities to represent the To, Bcc and cc fields. A PartyList is defined by using the following attributes:

Attribute Type Description
id String The GUID of the item. Required for set.
type Integer Deprecated. The object type code.
typename String The entity name of the item. Required for set.
name String The name of the item to be displayed. Required for set.
data   Any other data. Optional for set.

 

The following properties are available:

PartyList properties Type Description
{Field}.DataValue An array of lookup objects Get/set property.For PartyLists this must be an array with the length of at least one. DataValue is Null when no value is selected. Set DataValue to Null to make the lookup field blank.
 
 

Picklist

A picklist contains several options. Each option has the following attributes:

Attribute Description
DataValue The index value of the selected option.
Text The text of the picklist option.

The following properties and methods are available:

Picklist properties and methods Type Description
{Field}.DataValue string Get/set propertyGet returns a string representation of the value of the selected option. You can use the method parseInt() to safely convert this to an integer value.

Set changes the selection to the value specified.

{Field}.SelectedText string Get propertyReturns the string value of the selected option.
{Field}.GetSelectedOption option Picklist optionReturns a Picklist option.
{Field}.Options array of picklist options Get/set propertyGet returns an array of Picklist option objects.

Set defines a new set of options, specified by an array of Picklist option objects.

{Field}.AddOption(Text, DataValue) option Used to add an option to the end of the current control’s collection.Text – a string value to be displayed in the option.

DataValue – an integer value that represents the index of the option.

Text and DataValue cannot be Null.

Data is used for storing arbitrary data on the picklist object.

To define valid options, you must modify the Attribute definition by using the Customization tools or the metadata APIs. You should not create new picklist options programmatically in form event code. Manipulating the Options array is the most common solution to ensure valid picklist data.

{Field}.DeleteOption(value) integer Used to delete the option specified by value from the control’s option collection. Does nothing if the option does not exist.
{Field}.DefaultValue integer Get/set property.Get returns the default value for the picklist.

Set specifies the default value for the picklist.

Remarks

All the valid picklist options are defined in the Microsoft Dynamics CRM Metadata. When a record is saved with an invalid picklist option selected the field will be set to the default value and the invalid data will be lost.

There are two supported methods for retrieving the current selection for a picklist field as shown here.

The following returns the text value of the selected picklist item.

crmForm.all.(picklistitem).SelectedText

The following returns the index of the selected picklist item.

crmForm.all.(picklistitem).DataValue

Example

The following code example shows how to use a field of type Picklist. Note that when you add an option to a Picklist, the option must already exist in the set of possible options.

var oField = crmForm.all.SOME_PICKLIST_FIELD_ID;

// Capture the fourth option
var oOption = oField.Options[4];

// Show how many options are available
alert("Original length :"+ oField.Options.length);

// Set the field to the first option by value
oField.DataValue = 1;

// Show the text for the first option
alert(oField.SelectedText);

// Remove the fourth option
oField.DeleteOption(4);

// show the new length
alert("New length :"+ oField.Options.length);

// Restore the fourth option
oField.AddOption(oOption.Text, oOption.DataValue);

// Show the restored length
alert("Restored length :"+ oField.Options.length); 
 

Regarding

A Regarding field represents a Lookup where the linked record can be any record type that can be presented in the field.

The following properties are available:

Regarding properties Type Description
{Field}.DataValue   For the regarding field type this is an array with a length of one. DataValue is Null when no value is selected. Set DataValue to Null to make the lookup field blank.

 

Example

The following code example shows how to use a field of type Regarding.

var lookupItem = new Array;
lookupItem = null;

// This gets the lookup for the attribute regardingobjectid on the Task form.
lookupItem = crmForm.all.regardingobjectid.DataValue;

// If there is data in the field, show it in a series of alerts.
if (lookupItem[0] != null)
{
   // The text value of the lookup.
   alert(lookupItem[0].name);

   // The GUID of the lookup.
   alert(lookupItem[0].id);

   // The entity type name.
   alert(lookupItem[0].typename);
} 

StringThe following properties are available:

String properties Type Description
{Field}.DataValue A reference to a string object Get/set property.
{Field}.MaxLength Integer Get property.The maximum length of the string.


Example

The following code example shows how to use a field of type String.

var oField = crmForm.all.SOME_STRING_FIELD_ID;

var sValue = "String that might be too long.";

if (sValue.length > oField.MaxLength)
{
   sValue = sValue.substr(0, oField.MaxLength); 
}

oField.DataValue = sValue;

CRM 4.0, SQL Server 2005, Column and Row Limitaions

Speaking with Microsoft I was told there is a limitation of either 8060 bytes per row or 1024 columns per table and that there is also a limit of 400 bittype/picklist combination.

I,m not sure I belive them so I will do some further research. I’m aware that these limitations existed with SQL Server 2000 but with 2005, 2008 they should not imo.

Microsoft CRM 4.0 SSRS 2008 Integration

The following document contains a proposed  Microsoft CRM 4.0 SSRS 2008 Integration architecture I worked with Microsoft to create along with a number of roadblock solutions for various errors encountered while attempting to integrate SSRS with Microsoft CRM 4.0.  To simplify the integration concepts I have limited the server configuration to 2 servers.

Overview of Microsoft CRM 4.0 integrated with SSRS 2008

crm_ssrs20081

Setup CRM Data Connector for SSRS 2008 Scaled Out Deployment

The CRM Data Connector acts as a IFD authentication service for SSRS.  The setup wizard is straight forward but there are two potential snags

The first snag is that the Data Connector setup can’t automatically handle a Scaled Out deployment which you almost certainly will be using.  To work around this you must run the Data Connector from the command prompt and specify the install-config.xml file and path.  The Data Connector install-config.xml file tells the setup program where the instances of SSRS are located.  Were you to run the setup program without specifying the install-config.xml file you would get the following error:

Error message in the Environmental Diagnostic wizard when you try to install the Microsoft Dynamics CRM Connector for SQL Server Reporting Services: “Unable to validate SQL Server Reporting Services Report Server installation”


Here are the instruction for modifying the install-config.xml and running setup from the command line.

1.     Copy all the files in the SrsDataConnector folder on the installation CD to a folder on drive C. For example, copy the files to the following folder:

C:\SrsDataConnector

Note The SrsDataConnector folder is located in the following folder on the installation CD:

drive:\Server\i386

The drive placeholder represents the CD drive.

2.     Locate the folder in which you copied the installation files. Right-click the Install-config.xml file, and then open the file in Notepad.

3.     Add the following information to the Install-config.xml file:

The reportserverurl tags

The URL for the server that is running SQL Server 2005 Reporting Services

For example, if the server that is running Reporting Services has a named instance of Titan, the reportserverurl tags resemble the following example.

<reportserverurl>http://servername/Reportserver$Titan</reportserverurl&gt;

If the server that is running SQL Server 2005 Reporting Services has a named instance, modify the instancename tags.

For example, if the server that is running Reporting Services has a named instance of Titan, the instancename tags resemble the following example.

<instancename>Titan</instancename>

After you complete steps 3 and 4, click Save on the File menu, and then close the Install-config.xml file.

Open a Command Prompt window, and then locate the folder in which you copied the installation files in step 1.

At the command prompt, type the following command, and then press ENTER:

C:\SrsDataConnector> SetupSrsDataConnector /CONFIG path of the folder that contains the Install-config.xml file\install-config.xml

The second item to note is that it’s important to choose the “Update installation files”, when the setup wizard first runs.  In my experience the process will fail if you don’t choose this option.

For further information visit Microsoft

http://support.microsoft.com/kb/947060


Map SSRS2008 Web Service URL to work with a named instance

When you install Microsoft Dynamics CRM 4.0 together with Microsoft SQL Server 2008 and SQL Server 2008 Reporting Services all on the same server, you may receive the following error message:

“The specified path is not a metabase path.” Platform Error: System.Exception: Action Microsoft.Crm.Setup.Server.RSConfigAction failed. —> System.ArgumentException: The specified path is not a metabase path.

This issue occurs when the path of Reporting Services does not exist on the server.

To work around this issue, create a Web site that runs on the same port and the same URL that the Reporting Services server is using. In SQL Server 2008 Reporting Services, IIS is not used for accessing reports. However, if Microsoft Dynamics CRM 4.0 is installed on the same server, Microsoft Dynamics CRM 4.0 must find a Web site that has the same URL to bypass the error. To verify the URL of Reporting Services, follow these steps:

1.     Click Start, click All Programs, click Microsoft SQL Server 2008, click Configuration Tools, and then click Reporting Services Configuration Manager.

2.     Click connect to connect to your report server instance.

3.     Click the Web service URL, and see what the report server Web service URL is. For example, the URL may be http://SQLServername:8181/ReportServer.

In Windows Server 2008, follow these steps:

1.     Click Start, click Run, and then type inetmgr.

2.     Expand the server name, right-click Sites, and then click Add Website.

3.     Enter a name for the site, and then select a physical path.

4.     Enter the port number of the report server Web service. For example, enter 8181.

5.     Click OK.

In Windows Server 2003, follow these steps:

1.     Click Start, click Run, and then type inetmgr.

2.     Expand the server name, right-click Web Sites, click New, and then click Web Site.

3.     Enter a description for the site, and then click Next.

4.     Enter the port number of the report server Web service. For example, enter 8181, and then click Next.

5.     Enter a path for the Web site, and then click Next.

6.     On the Permissions page, click Next.

7.     Click Finish.

Configure Microsoft Dynamics CRM with Deployment manager

1.     Configure the Microsoft Dynamics CRM Application to point to the new SQL Server and SQL Server Reporting Services. To do this, follow these steps:

2.     On the computer that is running Microsoft Dynamics CRM Server, click Start, point to All Programs, point to Microsoft Dynamics CRM, and then click Deployment Manager.

3.     Click Organizations.

4.     Right-click the organization that you moved to the new computer that is running SQL Server, and then click Disable.

5.     Right-click the organization that you disabled, and then click Edit Organization.

6.     Type the new name of the SQL Server and the new URL for the SQL Server Reporting Services server.
Note This step publishes the reports that are in Microsoft Dynamics CRM to the new computer that is running SQL Server Reporting Services server that you specify.

7.     Click Next two times, and then click Apply.

Right-click the organization that you disabled in step 4c, click Enable, and then click Yes.

Use embedded data-sources

Microsoft CRM 4.0 does not support shared data-sources which is basically the default for SSRS2008.  Be sure to change any shared data-sources to embedded data-sources as follows:

1.     Open the report in Report Designer.

2.     On the Data tab, click the lookup button to the right of the Dataset list.

3.     Click the lookup button to the right of the Data Source list.

4.     Click to clear the Use shared data source reference check box.

5.     Click Edit to the right of the Connection box.

6.     In the Server name box, type the server name. Then, select the authentication method and the correct database name.

7.     Click OK two times.

8.     On the File menu, click Save as.

9.     Save the report on the Microsoft Dynamics CRM server, and then add the report.

Rollup 2 is required if you are using stored procedures in your reports

When you attempt to run a report from CRM 4.0 you likely will receive the following error:

“Query execution failed for data set dsNorthwind”.

There are two possible solutions for this.  Either apply the hotfix found in the link below or apply Rollup 2 for Microsoft CRM 4.0.  Since Rollup 2 for Microsoft CRM 4.0 includes the aforementioned hotfix I recommend this approach.  Also to get the hotfix files separate from Rollup 2 you will have to contact Microsoft.

http://support.microsoft.com/kb/956852