CRM 2011 – Make data available for re-import: File Corruption in CRM Online

If you are getting an error when exporting records that you want to re-import, I found a solution here: http://social.microsoft.com/Forums/en-US/crmdevelopment/thread/723b2490-d7be-4225-a179-1bdb2a50114d#cf3c3f56-894c-493f-a2c6-a9065ecaac6c

All you have to do is right-click on the file and go to Properties, click on Unblock and then the file will open as expected.

Advertisements

Unequal/disproportionate axes on Charts in CRM 2011

A problem I’ve encountered recently with charts is that if there are multiple measure points on the axes it can cause the data to look disproportionate. An example is shown here below:

image

The left-hand side is showing a max value of 2,400,000 and the right is showing a max value of 24,000,000, which causes the disparity.

To solve this all you need to do is export the chart and remove some XML:

Under <presentationdescription> and under the <series> node you will see the following for one of the series:

image

Remove YAxisType=”Secondary” and then Save and re-import the chart. This should fix the problem and cause the Chart to display as follows:

image

CRM 2011 Activity Posts via Workflow

I was playing around with Activity Feeds today and I noticed that when you create a Post via workflow, the post will not be public for everyone to see. The user that wants to see posts for that record will have to either follow the record manually, or you can create a follow via workflow. This is very powerful because you will be able to create the post and create a follow for someone specific E.g. if a case is created, an automatic post and follow can be created for the user’s manager.

image

This allows for managers to only see posts that are relevant to their teams.

Hope it helps.

Phone Number Formatting in CRM 2011

Formatting Phone Numbers using JavaScript can often become a requirement for some customers. I found a great solution in the Wiley Administration Bible (link below. I highly recommend this book!) on how to format phone numbers. I’ve had to change it though for South African customers.

http://www.amazon.com/gp/product/0470568143/ref=pd_lpo_k2_dp_sr_1?pf_rd_p=486539851&pf_rd_s=lpo-top-stripe-1&pf_rd_t=201&pf_rd_i=0470416912&pf_rd_m=ATVPDKIKX0DER&pf_rd_r=1A64WCZS9KAF0G7E3XW1 

The best way to ensure that the phone number will display correctly is to first strip out all the unwanted characters and spaces, and then use the clean version and apply formatting. Also note that you would only want the formatting to apply for records where the Country is set to “South Africa”. I’ve included this in the code. In order that this will work as expected “most” of the time, it is a good idea to also set the Country to “South Africa” when the record is created, as this will ensure that the correct formatting will apply for most records.

Here is the code:

function formatPhone(context) {
    var BusinessPhone = context.getEventSource();
    var BusinessPhoneValue = BusinessPhone.getValue();
    var Country = Xrm.Page.data.entity.attributes.get("address1_country").getValue();
    var newPhone;

    var strCleanPhone = BusinessPhoneValue.replace(/[^0-9]/g, ""); //clean field

    if(Country === "South Africa"){

    switch (strCleanPhone.length) {
        case "0833211139".length:
            newPhone = "+27" + " (" + strCleanPhone.substring(1, 3) + ") " + " " + strCleanPhone.substring(3, 6) + " " + strCleanPhone.substring(6);
            break;
        case "27833211139".length:
            newPhone = "+" + strCleanPhone.substring(0, 2) + " (" + strCleanPhone.substring(2, 4) + ") " + strCleanPhone.substring(4, 7) + " " + strCleanPhone.substring(7);
            break;
        case "833211139".length:
            newPhone = "+27" + " (" + strCleanPhone.substring(0, 2) + ") " + strCleanPhone.substring(2, 5) + " " + strCleanPhone.substring(5);
            break;
    }
     BusinessPhone.setValue(newPhone);
   }

}

So to get this code running, all you will need to do is make the library available on the form, run the function on the onchange for each field you want the formatting to apply for, and then make sure the Pass execution context as first parameter box is checked. Also note that I have hard-coded the Country field, so you might need to change this on your side.

 

image

 

I’ll have a look at adding something soon so that it ignores phone numbers that have an extension. I will hopefully have that up soon.

 

Hope it helps.

Option Sets / Custom Entities in CRM 2011

I had a scenario this week where I had to decide on either using 2 custom entities and filtered lookup, or to use 2 Option Sets and then use JavaScript to filter them. Removing Options based on the value of another option is easy to do using getSelectedOption().value (or text) and then using the removeOption(value) method.

Here is what the Option Sets look like originally:

Option1

image

 

Option2

image

 

The code should look something like this if I want to remove three on Option2 if one is selected on Option1:

function hideOptionValues()
{
    var Option1 = Xrm.Page.getAttribute(“new_option1”);
    Option1 = Option1.getSelectedOption().value;
    var Option2 = Xrm.Page.getControl(“new_option2”);

    //If option1 = 1 then remove option 3 on option2

    if (Option1 == 100000000)
    {
        Option2.removeOption(100000002);
    }
}

 

The result will look like this:

image

 

So that’s easy enough. The issue is now if I want to select another option on Option1 and want all the options on Option2 to be available again. Unfortunately, there is no easy showOption method available. Once the option is removed, it’s not as easy to add back. I found a solution here which does work:

http://social.microsoft.com/Forums/en/crm/thread/d8189d2c-fb95-41c0-8a9c-49b6824b8459

The result of using this solution will look like this to add back the option:

function hideOptionValues()
{
    var Option1 = Xrm.Page.getAttribute(“new_option1”);
        Option1 = Option1.getSelectedOption().value;
    var Option2 = Xrm.Page.getControl(“new_option2”);  //Be sure to use getControl

    //If option1 = 1 then remove option 3 on option2

    if (Option1 == 100000000) {
        Option2.removeOption(100000002);
    }
   else if (Option1 != 100000000)
    {
        var InitialField = Xrm.Page.data.entity.attributes.get(“new_option2”);
        var controls = InitialField.controls.get();

        var optn = new Option();
        optn.text = “Three”;
        optn.value = 100000002;
        controls[0].addOption(optn, 1);
    }

}

It then does add back the Option successfully and not in the right order I might add.

image

 

So this is a working solution for adding back options. The real question comes down to whether you should use this solution over 2 custom entities and filtered lookup. My answer would be to look at what the customer needs it for. If the Options will always stay the same then use the Option Sets and JavaScript solution, but if they want to build on or change the Options available in the future then you should definitely use 2 custom entities and filtered lookup.

 

Hope it helps.

CRM 2011–Escalation Workflow – Manipulation Library

So I’ve found another use for the Manipulation Library. Escalation workflows are normally quite easily achieved in CRM 2011, but I encountered a scenario recently where it was necessary to look at either developing a plugin or at creating a custom entity to manage escalations, but I was able to find a quicker and simpler solution using the Manipulation Library.

The problem arose because service technicians are allowed to move out the Follow-up Date on their own cases if they have spoken to the customer. The problem with a normal escalation workflow is then that the Workflow will wait until 24 hours after the Follow-up date, but it has no way of knowing in that Workflow that the Follow-up date has changed and that it should cancel itself. This is because Workflow cannot store an old value. So instead of creating a plugin or looking at some other complex solution, I simply added a whole number field to the form. Every time that the follow-up date changes, it now increments the whole number field by 1 and then I use the manipulation library to run a simple calculation (“FieldValue” + 0), which means that it is just storing the value which can then be used at a later stage to compare against the current state of the form. The Workflow then looks like this:

image

So when it comes time for the workflow to run, it will compare itself with the current state of the form, and if the stored value does not equal the latest value then the workflow knows that it is not the most current escalation and it cancels itself.

Summary:

1. Create Whole Number field
2. Update the field to increment by 1 every time the Follow-up date changes.
3. Use the Manipulation Library to run a basic calculation (“FieldValue” + 0).
4. Timeout the process until the desired escalation date.
5. Check to see if the workflow is the most current by comparing the stored value against the current value.
6. If the current value does not equal the stored value, cancel the workflow. If it does equal the value then escalate the workflow.

Hope it helps.

Workflows – CRM 2011 Manipulation Library

If you haven’t played with the Workflow Manipulation library, you really should. There is so much you can do with it. Download it here: http://manipulationlibrary.codeplex.com/releases/view/52128

Here’s a good example of what you can use it for:

A client had a requirement recently where they needed to, based on the severity of a Case, calculate time differently. For example, if something was done after-hours, they would double the amount of time billed to the customer. This would also then be multiplied by a rate determined per severity e.g. Severity 1 = Actual time X 1.7. The real issue then comes in with Contract Lines for the Customer. The allotments for the Contract Line needs to be adjusted with the calculated time spent, not the actual time spent.

So as you can see, the basic functionality of calculations in CRM would not be able to cater for this requirement, and JavaScript would not be the most reliable option either (although it could work). Using the Manipulation Library you can take a Service Activity (which is what the customer uses to manage work done) and then multiply the Scheduled Duration by the relevant amounts and update the Actual Duration field. Here’s a snippet from the Workflow:

image

The workflow takes the Scheduled Duration, multiplies it by the After Hours Rate, then multiplies that by the Severity value, and then finally updates the Actual Duration field. This means that when you resolve the Case, it will bring through the new Actual Duration you’ve populated and update the Contract Line correctly.

CRM 2011 JavaScript–setting a Date and Time

I had an interesting idea today on playing with the DateTime fields in CRM. It is quite frustrating that the time always defaults to 12:00 AM… who will ever schedule something to be due then? Anyway, so I looked at defaulting the due date field to today’s date (onload) and then adjusting it based on the duration set for the Activity (onchange). I found the onload code on another blog that was very helpful and then I came up with the onchange code myself. Here’s the code:

_______________________________________________________________

Onload:

function setDate(date) {
var isCreateForm = Xrm.Page.ui.getFormType() == 1;
var dateField = Xrm.Page.getAttribute(date); //pass this as a parameter when adding the function
if (isCreateForm) { // Check that this is a new Record
dateField.setValue(new Date()); // Set the Date field to Today
}
}

So that’s easy enough. Now for the trickier bit. I want to take the Duration field and add it to the date to move out the Due Date by however long it’s expected to take.

_______________________________________________________________

Onchange:

var dateField = Xrm.Page.getAttribute("scheduledend");
var duration = Xrm.Page.data.entity.attributes.get("actualdurationminutes").getValue();
var today = new Date();
var minutesToday = today.getTime();
duration = duration * 60000; //to get the millisecond value
var newDate = today.setTime(minutesToday + duration);
dateField.setValue(newDate);
}

Hope it helps.

Blog at WordPress.com.

Up ↑