Pages

Thursday, August 25, 2011

Copying Lookup Values

Very recently a poster in the CRM Development forum asked why she could not copy the value from a Contact Lookup field into the “To” field of a Phone Call entity.  On the surface, her code was very simple and would largely be expected to work.  What ended up working was basically creating a new value for the PartyList that recreated values from the Contact Lookup.

Why was this necessary?  I don’t really know, and haven’t looked any deeper into CRM 2011 yet, but what I know from CRM 4 is that certain expressions of the DataValue for a Lookup field can contain extra, undocumented data elements.  I suspect that CRM 2011 has expanded the use and perhaps number of these undocumented data elements, and their presence from one Lookup field prevents the direct assignment of the value to another Lookup field.

Perhaps this is limited to Single-to-PartyList copies, but perhaps not.  Either way, I’ve whipped up a handy function that can help easily copy or append values into Lookups when those values are taken from other Lookups.  Also, it allows you to provide a delegate function to which it will pass each entity reference and expect a boolean indication as to whether or not the value should be accepted for inclusion in the target attribute.

function CopyLookupValue(sourceAttribute, targetAttribute, boolAppendSource, funcDelegate)
{
var sourceValue = sourceAttribute.getValue();
var newValue = [];

if (typeof boolAppendSource != "undefined" && boolAppendSource)
{
sourceValue = targetAttribute.getValue().concat(sourceValue);
}

foreach(var valueIndex in sourceValue)
{
var copyValue = true;

if (typeof funcDelegate == "Function")
{
copyValue = funcDelegate(sourceValue[valueIndex]);
}

if (copyValue)
{
newValue.push({
id: sourceValue[valueIndex].id,
name: sourceValue[valueIndex].name,
entityType: sourceValue[valueIndex].entityType});
}
}

targetAttribute.setValue(newValue);
}

Using the thread that initiated this code as an example, here is how the above code would be used to copy the value of a Contact field on a parent form window to a To field on the child form window:

var remoteAttribute = window.parent.opener.Xrm.Page.data.entity.attributes.get("bc_contact");

CopyLookupValue(remoteAttribute, Xrm.Page.getAttribute("to"));

Monday, August 22, 2011

Changing Product Unit Groups

I ran into a situation where a large list of Products had been imported into CRM 2011, but the Unit Groups for many of them needed to be changed after the fact.  As many have discovered, even though the form customization options for the Product entity professes that the field is not flagged as “read only”, the field is in fact “read only” when Products are opened.

The workaround is fairly simple, but comes with some caveats:  export the records to an Excel spreadsheet with the option “Make this available for re-importing by including required column headings” selected.  You must export both the Unit Group field and the Default Unit field.  In spreadsheet form, you can alter the Unit Group and the Default Unit.  Now, here’s the caveats:

  1. The Default Unit must be uniquely named.  Multiple Units with identical names (in any Unit Group) will cause the import to fail, because it does not look for the Unit in a specific Unit Group.  The failure is because CRM cannot properly resolve the Unit, due to name duplication.
  2. Beware of any Price List Items configured to use the old Units configured for this Product.  I don’t know what CRM will do to you if you try to use the Product in a Quote/Order/Invoice after you change its Unit Group in this way.

When you import the changed data, you should notice that the modifications to the Unit Group (and Default Unit) values have been properly changed.

[Update:  Astute reader, Jevgenij, notes that the following Microsoft KB will also allow you to work around the problem using the Bulk Edit feature: http://support.microsoft.com/kb/949941  This is particularly useful for CRM administrators.  The process above, however, will work for anyone with access Product catalog maintenance.]