Wednesday 29 June 2011

CRM 2011 Sitemap Editor without exporting & importing a Solution

Great new tool to edit the CRM 2011 Sitemap is available below. Benefit is allowing you to swiftly edit the sitemap without creating a solution to export it and import it back in. Instead the editor creates a connection to your CRM (whether its CRM Online or On-Premise). Also there is no need to publish anything. This will save you plenty of time.


It's easy to use interface allows you to easily add/remove areas, groups, subgroups.

Download:
http://sitemapeditor.codeplex.com/releases/view/69220#DownloadId=253692

Info:
http://mscrmtools.blogspot.com/2011/06/new-tool-sitemap-editor-for-microsoft.html

Sunday 19 June 2011

The data has invalid column headings, so you will not be able to re-import

When I was trying to export data I got the below message:


The data has invalid column headings, so you will not be able to re-import


After a little digging around I realised I had a duplicate column name. This would cause problems when re-importing the data, hence why the warning.


I had created a custom field called Status in addition to system field Status. When I removed one of the columns from the view and than try to export it I got no error message. 



How to edit the Sitemap in CRM 2011

Editing the sitemap is quite simple. This demo is going show you how to rename Sales




Go to Settings>Customization>Solutions


1. First create the Solution and go to Components, click Add Existing and than select Site map.



2. Export the solution and save it. The solution will save as a zip file.


3. Extract the zip file. You should now see 3 files in the folder. We need to edit customizations.xml file
Tip: Good software to modify the sitemap is XML Notepad 2007 or Notepad++


4. Search for the Area you wish to rename and add the following.
     
    <Titles>
        <Title ="Projects" LCID="1033"/>
    </Titles>
I am going to rename Sales to Projects. My code is going to look like this when i add the above:

<Area Id="SFA" ResourceId="Area_Sales" Icon="/_imgs/sales_24x24.gif" DescriptionResourceId="Sales_Description" >
        <Titles>
          <Title ="Projects" LCID="1033"/>
        </Titles>
        <Group Id="SFA">
          <SubArea Id="nav_leads" Entity="lead" DescriptionResourceId="Lead_SubArea_Description" GetStartedPanePath="Leads_Web_User_Visor.html" GetStartedPanePathAdmin="Leads_Web_Admin_Visor.html" GetStartedPanePathOutlook="Leads_Outlook_User_Visor.html" GetStartedPanePathAdminOutlook="Leads_Outlook_Admin_Visor.html" />
        </Group>
      </Area>


5. Save the changes, zip up the files and import it back into the CRM. Once imported and published. Refresh the browser to see your changes.


Sunday 12 June 2011

Retrieve using ODATA and JSON in CRM 2011

This is a quick simple way to use OData Query. In this example we are using the code on the Contact entity to get data from Account enity. We are going to use OData Query to get data onchange of a lookup. 


When a user changes the Parent Account lookup they would like the contact to have the same address information as the Account. Should they move the contact to another account their address changes as soon as the lookup has changed.

I have put a function 'retrieve' on the onchange event of parentcustomerid on the Contact Form.


Make sure you add Json2.js and JQuery -1.5.mins.js to the Entity


The files can be found in the sdk at this location:
sdk\samplecode\js\restendpoint\restjquerycontacteditor\restjquerycontacteditor\scripts


Change the code below accordingly to any form you wish by following the instructions in highlighted green. 


Enjoy 


*********************************************************************
function retrieve() {
//1.Get Guid from lookup on the form, change lookup name accordingly
var lookupObject = Xrm.Page.getAttribute("parentcustomerid");
if (lookupObject != null)
{
var lookUpObjectValue = lookupObject.getValue();
if ((lookUpObjectValue != null))
{
var lookupid = lookUpObjectValue[0].id;
}
}




var id = lookupid;
 //2.Change the second parameter to the Entity you want i.e. "ContactSet"
 retrieveRecord(id, "AccountSet", retrieveCompleted, null);
}




function retrieveCompleted(data, textStatus, XmlHttpRequest) {
 //Example of how to assign the data to CRM fields
//3. Assign the data to your CRM fields
var account = data;
Xrm.Page.getAttribute("address1_line1").setValue(account.Address1_Line1);
Xrm.Page.getAttribute("address1_line2").setValue(account.Address1_Line2);
Xrm.Page.getAttribute("address1_line3").setValue(account.Address1_Line3);
Xrm.Page.getAttribute("address1_city").setValue(account.Name);
Xrm.Page.getAttribute("address1_postalcode").setValue(account.Address1_PostalCode);
Xrm.Page.getAttribute("address1_stateorprovince").setValue(account.Address1_StateOrProvince);
Xrm.Page.getAttribute("address1_country").setValue(account.Address1_Country);
}


function retrieveRecord(id, odataSetName, successCallback, errorCallback) {
//You don't need to edit anything in this function at all! If this function
//works it will return the data to function retrieveCompleted(above)
var context = Xrm.Page.context;
var serverUrl = context.getServerUrl();
var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc";




 if (!id) {
  alert("record id is required.");
  return;
 }


 if (!odataSetName) {
  alert("odataSetName is required.");
  return;
 }


 //Asynchronous AJAX function to Retrieve a CRM record using OData
 $.ajax({
  type: "GET",
  contentType: "application/json; charset=utf-8",
  datatype: "json",
  url: serverUrl + ODATA_ENDPOINT + "/" + odataSetName + "(guid'" + id + "')",
  beforeSend: function (XMLHttpRequest) {
   //Specifying this header ensures that the results will be returned as JSON.          
   XMLHttpRequest.setRequestHeader("Accept", "application/json");
  },
  success: function (data, textStatus, XmlHttpRequest) {
   if (successCallback) {
    successCallback(data.d, textStatus, XmlHttpRequest);
 
   // Use this method for a selection that may return multiple entities
   //RetrieveMultipleEntities(data.d.results);
 
   //Example of what you might want in the RetrieveMultipleEntities function when you create it
   //var account = data.d.results[0];
   //var aname = eval('account.AccountNumber');
   //alert(aname);
 
   }
  },
  error: function (XmlHttpRequest, textStatus, errorThrown) {
   if (errorCallback)
    errorCallback(XmlHttpRequest, textStatus, errorThrown);
   else
    errorHandler(XmlHttpRequest, textStatus, errorThrown);
  }
 });
}