Monthly Archives: February 2011

reload grid

reload the grid in a javascript:

document.all[‘crmGrid’].Refresh();

how to get selected record

how to get the selected record when a grid button is pressed? Its kinda simple…

tasks = document.all[‘crmGrid’].InnerGrid.SelectedRecords;
if (tasks.length > 0){
  for (i=0; i < tasks.length; i++ ){
    var pId = a[i][0];
    var pType = a[i][1];
    alert(pId + ‘: ‘+pType);
  }
}

c# webservice

creating a webservice in c# is easy… really… just click around in the visual studio and voila a new webservice 🙂 ok its a bit spooky, but who cares…

consuming a webservice is kinda spooky too… i tried to attach a webservice on a remote server and in my program to call the service i dont have a app.config… ok thats not true, but i wanted to call the service witout changing it all the time… therefore:

BasicHttpBinding binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;

EndpointAddress remoteAddress = new EndpointAddress(<address>);

WebService1SoapClient ws= new WebService1SoapClient (binding, remoteAddress);

ws.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

isv config manager tool

the crm allows to improve its menus and toolbars. to do so, just edit the isv.config… but wait… first export the isv.config, unzip it, edit it (xml) and upload it… still sounds easy, but during developing i think it sucks… someone else too… so he created a tool: isv config manager

auto fill attribute of parent object

one of my requirement was to automaticly fill the fax number of the account to a new created contact. 

load the crmServiceFramework:

var url= “/server-path/crmServiceFramework.js”;
var xmlHttp=new ActiveXObject(“Microsoft.XMLHTTP”);
xmlHttp.open(“GET”,url,false);
xmlHttp.send();
eval(xmlHttp.responseText);

check, if the fax number is not set

if(crmForm.all.fax.DataValue == null){

get the parent entity and retrive the fax number

var customer = crmForm.all.parentcustomerid.DataValue;

attrArray = new Array(‘fax’);
resultArray = RetrieveRecord(‘account’, customer[0].id, attrArray);
accountFax = GetRetrivedValue(attrArray, resultArray, ‘fax’);
set the fax number, if it is set
if (accountFax!=null){
crmForm.all.fax.DataValue = accountFax;
}
}

This function additionally tries to fill the fax number to existing account, if the fax number is not set.

crm service framework

a lot of requirements to our crm require retriving data from the CRMService. in plugins / callouts its kinda easy… but in the frontend with jscript its really difficult… you need to create the soap xml and send it through the service… and of course you need to read the result xml… so i decided to write/search a framework for it… and actually i found one… link 

its almost the thing i was looking for, but changed a few things. following is my crm framework 🙂

// Finalizes the SOAP and sends it.
function SubmitSOAP(xmlSoapBody, soapActionHeader){
 var xmlReq = “” +
 “<?xml version=’1.0′ encoding=’utf-8′?>” +
 ”  <soap:Envelope xmlns:soap=’http://schemas.xmlsoap.org/soap/envelope/’ xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’ xmlns:xsd=’http://www.w3.org/2001/XMLSchema’>” +
  GenerateAuthenticationHeader() +
 ”   <soap:Body>” +
   xmlSoapBody +
 ”   </soap:Body>” +
 “</soap:Envelope>”;

 //alert(xmlReq);
 
 var httpObj = new ActiveXObject(“Msxml2.XMLHTTP”);
 httpObj.open(‘POST’, ‘/mscrmservices/2007/crmservice.asmx’, false);
 httpObj.setRequestHeader(‘SOAPAction’, soapActionHeader);
 httpObj.setRequestHeader(‘Content-Type’, ‘text/xml; charset=utf-8’);
 httpObj.setRequestHeader(‘Content-Length’, xmlReq.length); httpObj.send(xmlReq);
 var resultXml = httpObj.responseXML;
 
  //alert(resultXml.xml);
 
 var errorCount = resultXml.selectNodes(‘//error’).length;
 if (errorCount != 0) {
  var msg = resultXml.selectSingleNode(‘//description’).nodeTypedValue;
  alert(“The following error was encountered: ” + msg);
  return null;
 } else {
  return resultXml;
 }
}

// Get CRM Entity. Only in attrArray given Attributes will be get.
// Example: Returns lastname, firstname and telephone2 of current object
//   attrArray = new Array(‘lastname’, ‘firstname’, ‘telephone2’)
//   var objectId = crmForm.ObjectId;
//   resultArray = RetrieveRecord(‘contact’, objectId, attrArray );
function RetrieveRecord(entityName, entityId, attrArray ){
 var xmlSoapBody = “” +
 ” <Retrieve xmlns=’http://schemas.microsoft.com/crm/2007/WebServices’>” +
 ”   <entityName>” + entityName + “</entityName>” +
 ”   <id>” + entityId + “</id>” +
 ”   <columnSet xmlns:q1=’http://schemas.microsoft.com/crm/2006/Query’ xsi:type=’q1:ColumnSet’>” +
 ”     <q1:Attributes>”;
 for (index in attrArray) {
  xmlSoapBody += ” <q1:Attribute>” + attrArray[index] + “</q1:Attribute>”;
 }
 xmlSoapBody += “” +
 ”     </q1:Attributes>” +
 ”   </columnSet>” +
 ” </Retrieve>”;

 var resultXml = SubmitSOAP(xmlSoapBody, ‘http://schemas.microsoft.com/crm/2007/WebServices/Retrieve’);
 if (resultXml != null) {
  var resultArray = new Array();
  for (index in attrArray) {
   if (resultXml.selectSingleNode(“//q1:” + attrArray[index]) != null) {
    resultArray[index] = resultXml.selectSingleNode(“//q1:” + attrArray[index]).nodeTypedValue;
   } else {
    resultArray[index] = null;
   }
  } return resultArray;
 } else {
  return null;
 }
}

// Update CRM Entity. Given Arrays are the key value pairs to update.
// Example: Updating the Phone number of a contact
//  UpdateRecord(‘contact’, ‘contactid’, objectId, new Array(‘telephone2’), new Array(‘555 1234′));
function UpdateRecord(entityName, entityIdName, entityId, keyArray, valueArray ){
 var xmlSoapBody = “” +
 ” <Update xmlns=’http://schemas.microsoft.com/crm/2007/WebServices’>” +
 ”   <entity xsi:type='”+entityName+”‘>”+
 ”     <“+entityIdName+”>”+entityId+”</”+entityIdName+”>”;
 for (index in keyArray) {
  xmlSoapBody += ” <“+keyArray[index]+”>” + valueArray[index] + “</”+keyArray[index]+”>”;
 }
 xmlSoapBody += “”+
 ”   </entity>”+
 ” </Update>”;
 var resultXml = SubmitSOAP(xmlSoapBody, ‘http://schemas.microsoft.com/crm/2007/WebServices/Update’);
 
 // reload window
 window.location.reload();
}

// Changes the Status of a CRM Entity.
// Example: Open Phonecall
//   SetStateCode(‘phonecall’, objectId, ‘Open’, ‘1’);
function SetStateCode(entityName, entityId, state, status) {
 var xmlSoapBody = “” +
    ” <Execute xmlns=’http://schemas.microsoft.com/crm/2007/WebServices’>” +
 ”   <Request xsi:type=’SetStateDynamicEntityRequest’>” +
    ”     <Entity>” +
 ”       <Id xmlns=’http://schemas.microsoft.com/crm/2006/CoreTypes’>” + entityId + “</Id>” +
    ”       <Name xmlns=’http://schemas.microsoft.com/crm/2006/CoreTypes’>” + entityName + “</Name>”+
 ”     </Entity>” +
    ”     <State>” + state + “</State>” +
    ”     <Status>” + status + “</Status>” +
    ”   </Request>+” +
 ” </Execute>”;
 
 var resultXml = SubmitSOAP(xmlSoapBody, ‘http://schemas.microsoft.com/crm/2007/WebServices/Execute’);
 
 // reload window
 window.location.reload();
}

// Returns the value of given key.
function GetRetrivedValue(attrArray, resultArray, val){
 for(index in attrArray) {
  if(attrArray[index] == val){
   return (resultArray[index]);
  }
 }
 return null;
}

Ok its still not final, i want to add an debug functionality, the commented out alerts are not really usable 😛

Save the framework in a file (crmServiceFramework.js) and store it on the server. The following script can be used, to include the script:

var url= “/<server-path>/crmServiceFramework.js”;
var xmlHttp=new ActiveXObject(“Microsoft.XMLHTTP”);
xmlHttp.open(“GET”,url,false);
xmlHttp.send();
eval(xmlHttp.responseText);

Retriving data Example:

attrArray = new Array(‘lastname’, ‘firstname’, ‘telephone2’)
var objectId = crmForm.ObjectId;
resultArray = RetrieveRecord(‘contact’, objectId, attrArray );

The attrArray is needed to define which attributes should be get. There is no way, to get all attribute, without filling this list.

With the following function, the value lastname will be returned

lastname = GetRetrivedValue(attrArray, resultArray, ‘lastname’)

Updateing entities is as simple as getting them:

UpdateRecord(‘contact’, ‘contactid’, objectId, new Array(‘telephone2’), new Array(‘555 1234’));

the two arrays are simple key-value pairs. a key array and a value array.

Changing the status is a bit different. closed entities cant be changed anymore. therfore:

SetStateCode(‘phonecall’, objectId, ‘Open’, ‘1’);

 

crm including .js-files

To include a external file to the CRM in onload, onchange or onsave use the followind sourcecode

var url= “/server-path/filename“;
var xmlHttp=new ActiveXObject(“Microsoft.XMLHTTP”);
xmlHttp.open(“GET”,url,false);
xmlHttp.send();
eval(xmlHttp.responseText);

why a blog again?

ok im not really the blogger… i actually hate writing stuff in blogs… and i really tryed… hat an old wp installation, wrote an own blog, but never really wrote something.

So… why a blog again? Its simple… i am currently the Microsoft CRM 4.0 developer, supporter, owner and everything else about it, and actually always asking google for the same stuff… dont find my own code on the servers… so why not just write notes… somewhere… and thats the reason of a blog again 🙂 we will see, if i can do it… 😛