Use Social Media to connect with Customer Effective Find Customer Effective on Facebook Find Customer Effective on Linked In Find Customer Effective on Twitter View Customer Effective on YouTube

 
Subscribe in a reader

Add to Google Reader or Homepage

Enter your email address:

Delivered by FeedBurner

Customer Effective

January 18, 2012

Microsoft Dynamics CRM 2011 Standalone Sandbox Using VirtualBox Part 2

Back to Part 1... Microsoft Dynamics CRM 2011 Standalone on VirtualBox Part 1

2: Add the ASP.NET role service:

Image17

Install CRM 2011

Great! We are ready to finish and fulfill our goal.  From the host machine unmount the SQL Server 2008 R2 and mount the Microsoft Dynamics CRM Server 2011.  When you mount Microsoft Dynamics CRM Server 2011 from the host machine go to CRMDEMO2011 and run the splash.exe from the ‘D:’ drive.

1: Select: Install Microsoft Dynamics CRM Server

2: Toggle: Get update for Microsoft Dynamics (recommended)

3: Specify the SQL Server, in this guide we are saying it is CRMDEMO2011, the local machine:

Image18

4: Specify the Organizational Unit, the Active Directory root we prompted the server to:

Image19

5: Specify what CRM services will run as, use the CRM2011NET\CRMDEMOADMIN account:

Image20

6: Specify the database name:

Image21

7: Get Excited!  Here’s your first glimpse of the URL for your new CRM environment:

Image22

8: Blast off! Click install and wait with your http://crmdemo2011 url in the clipboard to paste that sucker into IE.  But wait…make sure you allow the Microsoft Dynamices CRM Reporting Extensions Setup to run.

Login to http://crmdemo2011 with the CRMDEMOADMIN user and gloat with pride:

Image23

All-in-all, this installation should only take 3 hours or less once you have all the components downloaded and in place.  The first time can take up to 6-8 hours because you have to download all the ISOs and get familiar with VirtualBox.  But, once you make a copy of the CRMDEMO2011.VDI at a point that you consider a starting point then you can start from there to cut out more time.  Which by the way…now is a good time to back up that CRMDEMO2011.VDI file.  Looking forward, another idea from here is using the VM created to install the SharePoint and Outlook components. 

Good Luck…

Back to Part 1... Microsoft Dynamics CRM 2011 Standalone on VirtualBox Part 1

Microsoft Dynamics CRM 2011 Standalone Sandbox Using VirtualBox Part 1

One of the best approaches to learn CRM is to have a sandbox.  A lot of recommendations out there suggest having your IT administrator provide you with a CRM sandbox to play in.  That is fine and is surely a good idea, but personally creating a sandbox will certainly give you the satisfaction of getting your hands dirty and will give you a little respect with your colleagues.  So here we are going to look at getting a basic MS CRM 2011 up and running with Oracle’s VirtualBox.

So why VirtualBox?

  1. It is free
  2. Microsoft Dynamics CRM 2011 requires a 64-bit operating system to install
  3. Microsoft does not provide a desktop virtual platform that supports 64-bit guest OS.  Microsoft's 64-bit virtual platform, Hyper-V, only runs on Windows server.  Even the 64-bit version of Windows Virtual PC will not support 64-bit guest operating systems.
  4. VirtualBox can mount and run Hyper-V images, including the Microsoft provided demo VPC. (PartnerSource or Customersource login required).

So unless you have access to a server with Windows 2008 installed, VirtualBox is your best option for setting up a standalon virtual sandbox on your PC.  Note that when Windows 8 is released, Microsoft will support Hyper-V on the desktop, so our recommendation may change at that time.

The steps included in this post should be applicable to setting up a standalone sandbox in "virtually" any other virtualization platform. 

Performing the steps in order is very important to keep things easy.  Here are the brief steps we are going to perform:

This guide will enable us to create a brand new CRM environment within less than 3 hours, but there are a few prerequisites that you will want to have downloaded:

  • Windows Server 2008 - Standard or Enterprise
  • CRM 2011 Server Edition
  • SQL Server 2008 R2 (x86, x64, ia64) - Standard or Enterprise
  • Product Key for CRM 2011 Sever.  *IMPORTANT: A valid key is a must to finish the install.

Other tools needed:

  • ISO mounting tool, this guide is using MagicDisc.  Use your own ISO mounting tool if you have one more familiar to you
  • VirtualBox, which can be found at www.virtualbox.org

I am only going point out the installation steps necessary to get a very basic CRM 2011 environment up and running.  This means that if a step is not mentioned I used the default.   If you are interested in adding features please do so, as the scope here is just the bare bones.     

 

Create a VirtualBox Instance

*IMPORTANT: Hardware virtualization must be enabled in the BIOS.  This is an easy toggle and will not cause any issues to your system, but you will receive an error about VT-x/AMD-V and will not be able to boot Windows Server 2008 until this change is made.  The setting lingo varies from Bios to Bios but a common word in all will be ‘virtualization’, so look for that.

Create a new VM host; in this case CRMDEMO2011 is the name.  The defaults are fine for this example, but you may want to bump up the RAM if you are going to do some presenting or adding SharePoint, Outlook or Visual Studio.  I also strongly recommend that you bump up the disk space to a minimum of 40gigs if you are going to use SharePoint, Outlook or VisualStudio.  In any case, make sure you set the version of Windows to 8 (64 bit) or 2008 (64 bit).  Both work, but the ‘8’ version automatically sets the RAM higher which is probably better.

1: Create VM Host

  Image1

2: Mount Windows Server 2008 R2 ISO

We are going to use our mounting software from our host machine and mount the Windows Server 2008 R2 there.  Make note of the drive that the mount is using, in this case ‘I:’.

  Image2

3: Attach Drive with ISO to VM

The Windows Server 2008 R2 ISO is mapped on drive ‘I:’ from your host machine.  Attach the ISO by going to Settings -> Storage -> IDE Controller -> select Empty or create a new controller and map it to Host Drive ‘I:’ or the drive you used for the Windows Server 2008 R2 ISO.  When the VM starts the drive will be ‘D:’. 

Summary:  On host mount Windows Server 2008 R2 ISO on drive ‘I:’, on VM (CRMDEMO2011) the drive will be ‘D:’.

  Image3

4: Start VM

Starting the VM with the Windows Server 2008 ISO attached to the ‘I:’ will start the install with ease because it is now a part of the boot sequence.

Image4

 

Install Windows Server 2008 R2 Standard 64-bit

Installing a new Windows Server 2008 R2 is pretty straight forward.  Go through all the defaults.  You will want to add your product key here if you have one.  You may want to allow all the updates to happen if you have a nice network connection.  Once that is all done, it is not a bad idea to back up your CRMDEMO2011.VDI file.  That way you have a nice blank server ready to go for future use.

Two things for VirtualBox:

1:  After you are done with the server install, go ahead and install the guest additions, so you can get a nice full screen:

  Image5

2:  A very important VirtualBox command:  [RIGHT CTRL] +Delete = CTRL+ALT+DELETE for the VM…probably the only one you really need to know.  This will drive you nuts if you don’t know it…you will hate VitualBox if you don’t remember!

 

Promote Windows Server 2008 to Active Directory Domain Controller

This step is in my opinion the most daunting.  For many years I have be conditioned that installing a domain server is a one and done deal.  That two domain server on the same network is really bad.  Yes, having two or more domain controllers can be bad, but here we are going to set it up so we do not compromise our host network.  Unless you really know what you are doing, DO NOT mess around with the AD settings or the VM network settings, especially while on your corporate network without the guidance from your local neighborhood IT guru.  CRM requires a domain, and since we are going for a standalone installation, we have to promote the CRM server itself to the domain controller role.  Additionally, promoting the server before we install SQL helps avoid additional configuration steps as a result of the server’s name and user accounts changing.

Promoting a domain controller is done from the commandline by running:

c:\>dcpromo

Seven tweaks are necessary:

1: Toggle: Create a new domain in a new forest

  Image6

2: Name our network: CRM2011NET.local

  Image7

3: Change forest function level to: Windows Server 2008 R2

  Image8

You may get:

  Image9

Selecting “Yes, the computer will use an IP…” is fine and keeps you from having to look at network settings.

You may also get:

  Image10

Select ‘Yes’

 

Put in a password and you are done creating an Active Directory Domain Server…Congratulations!  You will have to reboot after dcpromo has done its thing.  The Domain we created is CRM2011NET, we will want to log back into the server using that domain. 

4: Rename computer back to original name

Making the server a domain controller renames the computer to something weird, rename computer back to CRMDEMO2011 and reboot. 

5: Create domain users

Create a few domain users is done from the commandline by running:

c:\>dsac

Create at least these users:

1: CRM2011NET\CRMDEMOADMIN

2: CRM2011NET\CRMSQLADMIN

3: CRM2011NET\Sal.Salesman

4: CRM2011NET\Mark.Marketing

 

Put the users in the ‘Users’ CN:

  Image11

Make the password the same for all users and make it so it never expires to make things easier:

  Image12

6: Make CRMDEMOADMIN and CRMSQLADMIN the administrators of CRMDEMO2011

7: Logout/Login

*IMPORTANT: Logout out as CRM2011NET/Administrator and log back in as CRM2011NET/CRMDEMOADMIN.  Installing SQL and CRM as the domain administrator will cause strange installation errors.

 

Install SQL Server 2008 R2

1: Login to CRMDEMO2011 as CRM2011NET\CRMDEMOADMIN.

2: From the host machine unmount the Windows Server 2008 R2 and mount the SQL Server 2008 R2.  When you mount SQL Server R2 from the host machine go to CRMDEMO2011 and run the SETUP.EXE from the ‘D:’ drive.

3: Install a new instance of SQL with a minimum of the following components selected:

  Image13

4: Set the service accounts to the CRMSQLADMIN user:

  Image14

5: Add CRMSQLADMIN as an administrator:

  Image15

 

Install IIS and ASP.NET

Installing IIS is accomplished by adding the Web server role to the server using the server management console. In addition to the IIS role we’ll need ASP.NET, which must be selected separately. Once these two things are selected, the installer will install them both simultaneously.  Starting the Server Manager can be started from the commandline:

C:\>ServerManager

1: Select Web Server (IIS) by selecting Roles -> Add Roles:

  Image16

Continue... Microsoft Dynamics CRM 2011 Standalone on VirtualBox Part 2

 

 

 

January 17, 2012

Sabert Corporation uses Scribe to integrate SAP ERP and Microsoft Dynamics CRM

Customer Effective customer, Sabert Corporation, is using the Scribe Data Integration Platform to connect its SAP ERP system and Microsoft CRM. Sabert is a leader in the food packing industry  and has been increasing sales productivity dramatically over the last three years with Microsoft CRM and is now seeing increased efficiency in its reporting as a result of the integration. 

Every day, Sabert pushes all of the customer data from SAP to CRM using Scribe. Sabert’s 70 field sales representatives report that they are saving hours a night per person on clerical tasks now that they can get the information they need — such as order status reports — from CRM through Outlook on their laptops.

Mike Freeman, Director of Information Technology at Sabert knew they needed a partner like Customer Effective to make their CRM project a success; "When we were evaluating CRM solution providers for sales force automation, Microsoft CRM had what we needed: a native Outlook interface, which our field sales already used on their laptops, and the ability to work offline. We knew there would be heavy integration requirements, and we didn’t want to add staff, so we turned to a trusted partner and integration platform."

Read the entire news article on Sabert's success on our Customer Effective News page

Rely on Microsoft Dynamics CRM to Satisfy Increasing Regulator Compliance Burdens and Investor Due Diligence Requests

As a result of the severe market volatility of 2011, the recent downgrade of the US debt rating, the massive shortfall and bankruptcy of MF Global, and the deepening of the Eurozone debt crisis, today’s Institutional investors are much more risk averse. Investors are clamoring for far greater transparency from their money managers, and thus are conducting more rigorous due diligence on a firm’s portfolio holdings, investment selection and allocation processes, and internal operational controls. Besides dealing with more demanding investors, Asset Managers must also be more prepared to withstand and overcome more regulatory oversight and scrutiny as a result of the landmark reform legislation of Dodd-Frank. In both cases, Asset Managers need to have in place sophisticated integrated systems and tools that can demonstrate compliance, promote transparency, and earn the confidence of investors and regulators. To provide timely, accurate, and increasingly on-demand reporting, many Asset Management firms are turning to a centralized CRM hub, such as Microsoft Dynamics CRM 2011, which can integrate with other core portfolio management systems, performance reporting engines, trading platforms, and investor portals.

With its advanced data recordkeeping, management, and business intelligence reporting capabilities, CRM 2011 enables Asset Management firms to quickly and accurately respond to the influx of inquiries from prospects, clients, partners, institutional consultants, and regulators. These Asset Managers are better equipped to reply to mounting requests for data collection and analysis because their client and portfolio data is more organized and easily searchable in one centralized location within CRM. Since Microsoft CRM 2011 offers a consolidated, comprehensive 360 degree view of client information, employees can easily filter, locate, sort, aggregate and report on data in real-time to promptly collaborate and correctly respond to all of the incoming audit, compliance, and investor due diligence requests. Additionally, Asset Management personnel can access and leverage CRM 2011 directly within their Outlook to refer to interaction history with key relationships and stakeholders, monitor capital raising pipelines, automate new fund launch marketing campaigns, track lead and referral sources, and streamline client on-boarding processes. The ensuing combination of increased employee productivity and more informed strategic business decision-making results in enhanced service levels to the firm’s client base. Therefore, the ever-increasing demanding clientele will be more satisfied with their overall investing experience with the firm, and thus be less likely to move their money down the block to a competitor. Furthermore, the firm is more agile and better positioned to adapt promptly to the more stringent regulatory environment to remain in compliance.

On the other hand, Investment Managers lacking a single core CRM system, and instead using siloed legacy applications and spreadsheets will inevitably severely lose assets and market share. Moreover, their widespread operational inefficiencies could potentially place the firm at a higher risk of being out of compliance and ultimately shut down.

Customer Effective is ready to partner with your firm to establish and successfully execute an industry-tailored CRM deployment, which can either be hosted in the cloud or installed on premise. To learn more about the operational simplicity and flexibility of Customer Effective: FinServ for Capital Markets and how we can accelerate your CRM ROI, lower your total cost of ownership, and grow your business, please visit www.customereffective.com.

January 16, 2012

Manually Setting Up Activity Feeds on Forms in Microsoft Dynamics CRM 2011

Microsoft Dynamics 2011 Activity Feeds provide real time notifications and quick sharing of information via quick, short updates. The solution is available on the Dynamics Marketplace here. If you are an online user, and you do not use multiple forms on the entities you want to highlight, simply download, import and publish the solution. You would then go to configure your post entities (step 1 below) and then you are good to go.

If you are using Microsoft Dynamics CRM and you have multiple forms configured for an entity on which you wish to display the Activity Feed wall, you will need to download, import and publish the solution, and then you will need to follow the steps below to ensure the activity feeds are visible on the forms you want to display the wall.

1. Once you have imported and published the Activity Feed Solution, you need to enable yourimage selected entities and enable wall posting. Settings > System > Activity Feeds Configuration. Note that this form uses a text field for entering the entity name (not the more common lookup) and you will need to be careful to use the logical name. Also check the “Enable walls” box. You will need to go then to the entity you enabled and publish it individually.

2. Open an entity form for the entity you want to enable for activity feeds. In this example, we are using accounts. Open the Form Editor.

    • Insert > Tab > One Column
    • Open the Tab to edit the Tab Properties > Display
      • Name= tab_recordwall
      • Label = Record Wall
      • Uncheck “Expand this tab by default”
    • Tab Properties > Events
      • Form Libraries, add msdyn_/ActivityFeeds.Form.js
      • In event handlers, Add
        • Library: msdyn_/ActivityFeeds.Form.js
        • Function: ActivityFeeds.Form.CustomizationUtils.updateRecordWallRenderingState
        • Check “Enabled.
        • Check “Pass execution context as first parameter.

image

3. Save your changes to the tab and return to the form editor. Select the section inside of the Record Wall Tab. Set to ‘One Column’.

4. Back in the Form Editor, click Insert > Web Resource

  • General Tab
    • Web resource = msdyn_/RecordWall.htm
    • Name = RecordWall
    • Visible by Defualt = checked
    • Pass record object…= checked
  • Formatting Tab
    • One column
    • 15 rows (this is flexible, but 15 is standard the standard look).
    • Display border = yes
    • Scrolling = as necessary

5. Save, publish and go!

January 13, 2012

XRM 2011 - Microsoft Dynamics CRM 2011 Style Buttons

Adding a button to a Form is a great way to add additional functionality right where the user is already focused. Today we are looking at a few different approaches to adding a button. First, we’re looking at handling the upgrade for those of you who have already used the 4.0 button inside of 2011 or if you had a 4.0 environment and are upgrading. If you have a clean 2011 environment, then feel free to skip down to the “From Scratch” section.

 

There is already some code floating around to create a 4.0 style button inside of CRM 2011. The button we’re creating will instead create a CRM 2011 style button (i.e. “Example Button”).

image

 

The CRM 2011 button starts gray and then when the user hovers over it, the button will look like:

image

 

Creating our Web Resource

First,name your Web Resource whatever you’d like. In my case, I’m planning to re-use it in various ways, so I’m throwing it in our JS root directory.

image

 

   1: // CRM 2011 Style Button 
   2: // Creates a button from a form field 
   3: // Paul Way - 1/3/2012
   4: function ConvertToButton(fldName, btnLabel, btnWidth, evt){ 
   5:    var btn = '<button id="btn_' + fldName + '" ' + 
   6:                     ' style="width:' + btnWidth + '" ' + 
   7:                     ' class="ms-crm-Button" ' + 
   8:                     ' onmouseover="Mscrm.ButtonUtils.hoverOn(this);" ' + 
   9:                     ' onmouseout="Mscrm.ButtonUtils.hoverOff(this);" ' + 
  10:                  '>' + btnLabel + '</button>'; 
  11:  
  12:    var ctrl = Xrm.Page.ui.controls.get(fldName)._control;
  13:  
  14:    // Add the new button 
  15:    ctrl.get_element().innerHTML += btn;
  16:  
  17:    // Hide the textbox 
  18:    ctrl.get_element().firstChild.style.display = 'none';
  19:  
  20:    // Hide the label (optional) 
  21:    Xrm.Page.ui.controls.get('pager').setLabel('');
  22:  
  23:    // Add Event to the newly created button 
  24:    ctrl.get_element().childNodes[1].attachEvent('onclick', evt);
  25:  
  26: }

 

Modifying our Form

To use this new function, you’ll first need to add the newly created web resource to the form. You’ll also want to have a separate JS web resource to call the ConvertToButton function. In my case, I already have a web resource for contact specific JavaScript. If I didn’t, I would need to create a new web resource and then place my contact specific code there. Here’s an example screenshot:

image

 

By having two web resources for this, you’ll have only one version of your ConvertToButton function throughout your CRM 2011 environment. Let’s say down the road you’ll need to update the function to change the label to “Button”, then you only need to modify one file. In CRM 4.0, you probably had a lot of duplicate code. With CRM 2011, your browser can cache the JavaScript for better performance and it is easier to maintain when organized appropriately.

In our other web resource, the one we setup with the OnLoad, we need the following code.

   1: function contactsOnLoad(){ 
   2:    convertToButton('pager', 'Example Button', '150px', function(){alert("test")}); 
   3: }

 

Why is this so different then the 4.0 code?

If you’ve used the CRM 4.0 code, you’ll notice the code here is a lot shorter. It’s actually pretty different as well.

  • For one, instead of modifying the input element we are actually creating a button HTML element. This just means that we can now use about any kind of field instead of just pure textboxes. Not a huge deal, but opens up the email address 3 and other attributes.
  • Both are really unsupported but the other uses the deprecated crmForm.all.
  • Finally, the button style was meant for 4.0 whereas now we have the 2011 look-n-feel.

 

From Scratch

So far we’ve mainly focused on if you already were using the 4.0 code and were upgrading. But what if you don’t have the existing code structure? I’d argue against creating a new attribute just to have a button. When adding a new attribute, you are also adding the attribute to the underlying SQL tables and views. Using an existing field isn’t really a great option either because there is always the chance you will need the field or it will overlap with an application from the MS marketplace.

Instead, I’d recommend creating a button place holder web resource and then embedding the web resource on the page. The web resource is just a JPG image like this:

image

 

We then place the image wherever we want on the form. Make sure to set the formatting to one column and one row.

image

image

 

Finally, we need a little bit of code added to the /js/formButton.js web resource:

   1: // CRM 2011 Style Button 
   2: // Creates a button from a form field 
   3: // Paul Way - 1/3/2012
   4:  
   5: function convertWebResourceToButton(fldName, btnLabel, btnWidth, leftMargin, evt){ 
   6:    var btn = '<button id="btn_' + fldName + '" ' + 
   7:                        ' style="margin-left:' + leftMargin + ';width:' + btnWidth + ';" ' + 
   8:                        ' class="ms-crm-Button" ' + 
   9:                        ' onmouseover="Mscrm.ButtonUtils.hoverOn(this);" ' + 
  10:                        ' onmouseout="Mscrm.ButtonUtils.hoverOff(this);" ' + 
  11:                      '>' + btnLabel + '</button>'; 
  12:    
  13:    var ctrl = Xrm.Page.ui.controls.get(fldName)._control.get_element().childNodes[1];
  14:  
  15:    // Replace image with buttom 
  16:    ctrl.innerHTML = btn; 
  17:    
  18:    // Add Event to the newly created button 
  19:    ctrl.firstChild.attachEvent('onclick', evt);
  20:  
  21: }

And as for our OnLoad function, we’ll need to use this instead:

   1: function contactsOnLoad(){ 
   2:    convertWebResourceToButton('WebResource_btnProfInfo', 'Another Approach', '150px', '119px', function(){alert("test2")}); 
   3: }

Notice that this will require an additional parameter for the left margin.

image

 

Summary

As you can see, there are several different approaches to adding a button onto the CRM form for 2011. With 2011, I’d opt for using the button place holder image method. No matter which approach you take, the end goal is enhancing the user’s experience. I hope you enjoy!

January 12, 2012

Track In Microsoft Dynamics CRM Or Set Regarding?

In working with users over time, we have routinely advocated the use of Set Regarding for tracking emails or appointments (or Set Parent when it comes to contacts).  Sometimes I’ll do such a good job of communicating my point that I’ll get the question of “Well why should we use Track In CRM at all?”.  It’s a fair question.

image

When it comes to adding records in CRM the difference between using Set Regarding and Track In CRM is significant.  Set Regarding allows users to file the email or appointment or task against a CRM record such as an account, an opportunity or even a custom CRM entity directly. In our case, we use CRM to track our projects in addition to our accounts or opportunities.

In this sample email, I’m going to use Set Regarding to track it directly against a project:

image

I won’t go through all the details here, but this is the start.  Now if I had just hit Track In CRM, it would be associated only to the recipients of the email as well as the senders, be they users or contacts. (These activities would also rollup to their parent records as well by default). CRM would attempt to resolve against the user or contact email addresses.  With that said, there would be no context for the email against an opportunity or account or project.  That is why Set Regarding is so nice: it does the job of Track In CRM and then some.

With that said, there is a good reason to use Track In CRM. Lets take a look at what happens with a received email before and after Track In CRM is clicked:

image  image

 

For a received email, clicking Track in CRM exposes the Convert To, Add Connection, or View in CRM.  The main point I want to focus on is the Convert To option.  As the screen shot indicates, users can convert that email to either an Opportunity, Case, or Lead. In the following example, I would convert this email to an Opportunity:

image

This allows you to quickly create the record, without a lot of clicks.  I’ve used this in the past when I received a support request from a customer as well as new business inquiries.

I’ve consciously noted that the above was a received email, and wanted to point out that sent emails have their own options of Insert Template, Insert (KB) Article, or Attach Sales Literature.

 

image

 

So in summary, Track In CRM is especially useful for creating new records in conjunction with the Convert To feature.  As a best practice use the Set Regarding, but keep this option in mind.

CRM 2011 - iFrames & Saving

After spending time on several of the CRM forums, I noticed a few people having trouble with iFrames and saving data inside of the iFrame. While a forum post is a little difficult to write a full response, I wanted to share some insight on capturing the form save event to then trigger a save event inside of your iFrame.

From a business case, this is a fantastic way to tie multiple systems together. If all you are doing is syncing data, then look first at a plugin or scribe. However, if you are looking for the user to interact with multiple systems simultaneously, then an iFrame is a wonderful way to integrated with an existing system. A good example might be where CRM is only storing the summary information and the iFrame contains the details. The user may update the details which should save both the CRM record and the details of the web site.

 

Prerequisites

First, let’s assume you have an iFrame inside an entity.

Secondly, we need to uncheck the “Restrict cross-frame scripting” check box on the iFrame properties.

image

Lastly, it’s a good idea to make sure our iFrame is using HTTPS to prevent mixed mode security warnings.

 

Talking Directly

If you try to talk directly to the iFrame via something like:

Xrm.Page.ui.controls.get('IFRAME_opp').getObject().contentWindow.document

Unless you are On-Premise, you may encounter the “Access is Denied” warning. This will show itself when dealing with URLs on a different domain (or subdomain). Cross domain scripting is a security feature within the browser. Now an easy fix is to disable the browser settings, but this isn’t a good solution.

 

Messaging

Instead of talking directly, we need send a messages to our iFrame. To send a message, we’d do something like:

Xrm.Page.ui.controls.get('IFRAME_opp').getObject().contentWindow.postMessage('test', "*")

To receive the message on the iFrame, you need to listen for the message event. Let’s take a look at the JavaScript on our example iFrame page:

   1: function receiveMessage(e) {
   2:   
   3:    if (e.origin == 'https://way.crm.dynamics.com'){
   4:  
   5:       if (e.data == 'test'){
   6:          document.getElementById('msgBox').innerHTML = 'testing...<br />' + e.origin + '<br />' + e.data; 
   7:       }
   8:  
   9:       if (e.data == 'save'){
  10:          saveForm();
  11:       }
  12:    }
  13:  
  14: }
  15:  
  16: saveForm = function() {
  17:    document.getElementById('msgBox').innerHTML = 'saving...';
  18: }
  19:  
  20: window.attachEvent("onmessage", receiveMessage);

 

It is very important to check the origin and the message if you are dealing with publicly facing sites.

If the idea of messaging is new to you, here are some additional resources:

 

The OnSave

To initiate the message from the CRM 2011 form, you need to register an OnSave event from within the “Form Properties”.

image

 

How about .NET Pages?

If your iFrame is an ASPX page, all of this still applies. The only difference is that you want to have an ASP.Net button on your page to call the server side code. Instead of the saveForm event, simply call the click event of the button.

When dealing with server side saves though, you can either post a message back to say “I’m done” which will then complete the CRM save or you can put a set timeout in the onSave on the CRM side.

 

Conclusion

Hopefully you have seen how easy it is to integrate with another web site while inside of CRM 2011. If you have had problems with iFrames in the past, I really encourage you to use iFrames for your integration needs as they can really enhance your users experience and can allow for improved data across systems. I hope you enjoy!

January 04, 2012

Auto-Creating Contacts and Duplicate Detection in Microsoft Dynamics CRM 2011

As we have mentioned in previous posts, one of the new features in CRM 2011 for Outlook is the ability to automatically create new contact records if you track an e-mail with an address that does not exist in CRM.

This feature is turned on by default, and is located toward the bottom of the “E-mail” tab of user settings in CRM for Outlook.

image

As you plan your roll-out of Microsoft Dynamics CRM, you should be aware of the default options and how they may interact with other application features.

One example that I’ve seen with this new feature, is that when you track an e-mail and the system creates a new contact, if duplicate detection is enabled, and the contact being created matches another contact in the system, the duplicate detection process will prevent the contact from being created, and also prevent the e-mail from being tracked.

If you find that periodically you are getting errors when tracking e-mails, I recommend testing with the automatic contact creation feature disabled.

Entity Relationship Diagrams in Microsoft Dynamics CRM 2011

Visual representation of entity relationships and metadata can be very useful in a CRM project. Thankfully, Microsoft has provided pre-built Entity Relationship Diagrams (ERD) for the eleven of the most important out of the box entities in CRM2011. They are available here in Visio format.

You can also create ERDs for custom entities. The generator is buried deep inside of the SDK (…\sdk\samplecode\cs\metadata\diagram ). You will need Visual Studio and Visio 2010 to run the document generator.

1. First, open the above file path and open the file MetadataDiagram.csproj in Visual Studio.
2. Next, from the toolbar, click the Build Solution icon.meta1
3. You could run the program now. However, it will map all of the entities, their attributes and their relationship to each other. This will take a very long time, but more importantly, it's complexity may render it useless to most people. What I have found useful it to map one entity at a time, or at the most two or three.
4. In order to draw one or more specific entities, click the debug tab, then enter the logical name in the Command line argument box. You can enter as many entities as you would like to map here. For instance, if you would like to map accounts, then simply enter "account". If you would like to map an custom entity then enter "new_entityname". If you would like to map the relationships between you custom entity and accounts, then enter "account new_entityname". Remember, that will map your new entity, accounts, and the relationships between them. If you want a map for accounts and another map for your custom entity, you will need to run the program twice.
5. To run the program, hit the Start Debugging button in the toolbar.
6. This will bring up a command prompt. It will ask for a CRM server and a port. It is very simply orgname.domainname.net (no https:, etc.) Then you enter your username and password just as you would if you were logging into CRM as a user.CP1
7. The program will run (usually a few minutes) and create a Visio document in the path: (..sdk\samplecode\cs\metadata\diagram\bin\Debug ). The name of the file will be simply "account.vsd". It is important to note that if you use the program to create another account diagram, and there is already a file called "account.vsd" in the Debug file, the command prompt will issue an error and the document will not be created. It is a good best practice to move your finished files from the Debug folder as you finish them.


A sample of the output is below. This is for the entity 'sharepointsite' in ootb CRM.

sp1

January 03, 2012

Microsoft Dynamics CRM 2011 – Pre-Populated Emails (Alternative Approach)

Recently, we came across the need for a single-click email feature on the ribbon of a custom entity.  The idea was to be able to share CRM data as quickly and easily as possible.  Another interesting caveat was the client wanted to have the email come directly from Outlook.

For those of you old enough to have used the internet before the iPad, you may recall that fancy-dancy “mailto” feature.  (Granted I’m only 29 but my Omron body age says I’m 50 Surprised smile).

Back to the point at hand though, CRM already has a few built in email features.  Our situation calls for something a little different.

 

What’s Installed By Default

CRM already has the feature of sending a link to the CRM entity you’re working with.

image

 

CRM also has a really nice Email Template feature.

image

 

Which can automatically mail-merge information pertaining to the entity to eliminate any of that “automated” feel.

image

What We Need

Our situation is somewhat unique, but really we want both features combined.  We want to open a new message like the link feature: inside outlook and with one click.  However, we need more than just the link.  We want to have a brief summary of the call report with a  link to it. 

Here’s an example email of what we’d like to send:

image

 

Adding the Button

The first thing we need to do is add the button to the ribbon like so:

image

If you are unfamiliar with the ribbon, Microsoft offers some really nice walkthroughs.  I’d start with http://msdn.microsoft.com/en-us/library/gg334341.aspx.

For our situation, the XML that matters is our Action

<Actions>
   <JavaScriptFunction Library="$webresource:cei_example.js"
                       FunctionName="emailContact" />
</Actions>

 

Adding our JavaScript

At this point, the button should be on the form.  From here, we need to add the JavaScript to open our populated email message.

To do this, add to the Form OnLoad events the following function:

emailContact = function() {
   if (Xrm.Page.data.entity.getId() != null) {
      var sRptID = Xrm.Page.data.entity.getId().replace('{', '').replace('}', '');
      var sLink =  "
http://paul.customereffective.com/userdefined/edit.aspx?id=" + sRptID + "&etc=10011";

      var sSubject = 'Contact - ' + Xrm.Page.getAttribute("firstname").getValue() + ' ' + Xrm.Page.getAttribute("lastname").getValue();
      var sCustomer = '';
      if (Xrm.Page.getAttribute("parentcustomerid").getValue().length > 0){
         sCustomer = Xrm.Page.getAttribute("parentcustomerid").getValue()[0].name;
      }
      var sBody = '---\n\nCustomer:\t' + sCustomer + '\n\n' + sLink + '\n\n---';
        
      var sMailTo = 'mailto:?subject=' + escape(sSubject) +
         '&body=' + escape(sBody);

      parent.location=sMailTo;

   } else {  
      alert('You must save the contact before emailing.');
   }
}

 

 

Note: If you change the name of the function, make sure it matches the name inside your Ribbon XML.

 

What about Window.Open

If you use Window.Open to trigger the email (or OpenStdWin), the user will get a blank IE page inside of Outlook. By using the parent.location for your mailto, you’ll have a consistent user experience across IE and Outlook.

 

Seeing the Final Results

Now whenever a user wants to share a call report, they can easily hit the “Email Call Report” button.  Add any of the fields you want. 

image

For our needs I ended up with the following; however, this technique can add whatever field you’d like.

image

 

Well this isn’t a tool in the toolbox I’d use daily, it can be valuable when the situation calls for it.  I hope you enjoy!

December 30, 2011

Best Practices for Activity Reporting In Microsoft Dynamics CRM 2011

So you want to report on your activities in CRM—and that is a great idea.  Activities such as appointments, phone calls, tasks, and e-mails are core CRM functionality and a great indicator of how your users are interacting with your customers, and how actively your users are adopting CRM.

For basic activity reporting, such as activity lists or viewing a count of activities by type by user, consider using the out of the box views and charts. 

For example, if I want to see the number of activities by type and priority, I can just go to the Activity view in CRM and select the “Activities by Type and Priority” chart.

image

If you are not familiar with creating charts in CRM 2011, check out Kevin Wessels’ Introduction to charts in CRM 2011.

I recommend using the views and charts whenever possible, because it is fast, it is dynamic, and it can easily be added to your CRM 2011 dashboard.

However, if you find you want a report that requires more advanced formatting or that can be published to additional formats, such as Word or PDF documents, another option is to create a SQL Server Reporting Services (SSRS) report.

The point of this post is not to introduce you to SSRS.  If you don’t have experience creating SSRS reporting, I recommend checking out resources like the report development section of the CRM 2011 SDK.

The point of this post is to discuss the unique challenges of working with activity data in reports.  To understand how to work with activities in SQL queries, you need to first understand how activity data is stored.

Activitypointer – The “Anchor”

In the Microsoft CRM SQL databases, activity records are stored in an anchor entity view called filteredactivitypointer.  This view contains the fields that are common to all activity types.  This includes fields such as activityid, scheduled start, scheduled end, actual end, actualduration, subject, and description (the “body”).  This entity also includes a field called Activitytypecode.  This indicates what type of activity the record is.

 Activityparty – The people

Any people, leads, or accounts linked to an activity will be stored in the filteredactivityparty view.  This is a related entity that enables you to add multiple recipients/attendees/customers to activities.  When you create an appointment, for example, and have 3 required attendees, 2 optional attendees, a regarding company, an owner, and a organizer, a total of 8 activity party records are created.  Activity party includes fields like partyid (the GUID of the record related to the actity), partyobjecttypecode (the entity type code of the related record), and activity id.  The filteredactivityparty view also includes some of the fields from the filteredactivitypointer view, such as scheduledstart, scheduledend.

One important thing to understand about activities and activity parties is that some activity parties are stored in both filteredactivitypointer and filteredactivityparty.  The ownerid and the regarding objectid are fields in filteredactivitypointer, but they also are stored as activity parties related to the activity.

This is important to understand, because many people over-complicate their activity reports and views because they misunderstand this—if you want to see any activities where you are the owner, the regarding object, or a recipient/attendee, don’t do something like this:

select distinct a .activityid from filteredactivitypointer a inner join filteredactivityparty p on a.activityid = p.activityid where a.ownerid = @user or a.regardingobjectid = @user or p.partyid = @user

instead, do this:

select distinct activityid from filteredactivityparty where partyid = @user.

Since all people or accounts related to an activity are stored in the filteredactivityparty view, you can limit your query person filter to the activityparty entity, and make your query more efficient.  This is why the default “My Activity” views in CRM filter the activity list by the related activity parties, and they get not only the records owned by the selected user, but also the records where that user is an attendee or recipient or regarding object.

image

The specific activity type views

As we discussed earlier, the fields that are common to all activity types are stored in the FilteredActivityPointer Anchor entity view.  These fields are also available from the specific entity type views, such as FilteredEmail, Filtered PhoneCall, Filtered Task, Filtered Appointment (and the poor lonely FilteredFax entity view).

These views also contain the fields that are unique to a specific activity type, such as custom fields you might have added to the appointment entity, and status reasons that are unique to the activity type (for example, there is a “sent” status on e-mails, but not appointments).

Planning your report

So as you begin to design your report, there are a couple of questions you should ask:

1.  What records do I want to return?  Is this a report covering all activity types, just one type of activity? Should this show all activity statuses, just open/scheduled, just closed, or both?

2.  How should this data be filtered?  Do I want to see it for a single user, a group of users, a set date range, or a date range selectable by user?

3.  How will this data be consumed?  Is somebody going to look at it on the screen, in a dashboard, export to a spreadsheet, or print out a PDF?

Common Mistakes

1.  Over complicating the query.  If you just want to have a count of activities by person, there is no reason to join activity party to activity pointer and union together the filteredemail, filteredtask, filteredphonecall, and filteredappointment views.  Overcomplicated queries are the main reason why activity reports are frequently slow or time out.

2.  Misunderstanding how dates in activities work.  There are  a number of date fields in filteredactivitypointer—scheduledstart, scheduledend, actualstart, and actualend.  No one of these date fields are consistently populated on all activity types.  For example, tracked emails will typically just have an actualend date, and not a scheduledend or scheduledstart, and only closed appointments have an actualend date.  This is one of the main reasons why dates in activity reports and views do not work as expected.

To account for this, I recommend using a case in your SQL query to accommodate various date fields being null.  For example:

(case when actualend is not null then actualend

when actualend is null and scheduledend is not null then scheduledend

else scheduledstart

end) as date

This approach puts priority on the actual close date, so if the activity is closed, it will count that as the date of the activity, but if not, will use one of the scheduled dates. 

It is also very important to understand what your audience expects to see as the date of an activity—if they expect the date of an activity to be what it was scheduled as on their calendar, but they close the activity two weeks after the appointment, if you select actualend as the date of the activity in the report, the results won’t match their expectation.

3.  Misunderstanding how dates in SSRS report parameters in CRM work

Consider this common scenario—the user wants to enter a start date and an end date and show all activities that fall between @start and @end.  So, at first glance, you assume that the report query should say something like this:

“where date between @start and @end”

Not so fast.  You first need to understand that when you populate a date parameter in an SSRS report in CRM, it assumes the time of day when you are running the report.  So, for example, if you run the report at 3:30 PM on January 5, 2011 and say start date is January 2 and end date is January 4, you are really saying between January 2 at 3:30 PM and January 4 at 3:30 PM.  Any activities earlier in the day on the second and the end of the day on the fourth will not be returned.

The right way to do it is to adjust your parameter values so the start date is the beginning of the day and your end date is the end of the day.  For example:

“Where date BETWEEN DATEADD(dd, DATEDIFF(dd, 0, @start), 0) AND DATEADD(minute, 1438, DATEADD(dd, DATEDIFF(dd, 0, @end), 0)))”

In this example I am using dateadd to set the @start parameter to the beginning of the day specified, and using dateadd to add 1,438 minutes to the start time of the @end parameter.  All activities between these dates will be returned.

4.  Lacking a clear focus

Once you start building your report, it can sometimes grow beyond the original scope and purpose of the report.  Users will want to add additional fields and be able to group or sort by different fields to use the report to answer different questions.  This is fine, but be careful that in doing that you don’t over-complicate the report.

The best reports serve a specific purpose and are consumed in a specific way.  Reports that are exported to PDF should not have more fields than will fit in one page width.  If you keep adding fields to the report, your query will run more slowly, and you may exceed the number of rows that will fit on one page.

Formatting of reports is driven by the way the report will be used.  Column layouts that look good in PDF don’t often look good when exported to Excel, and Excel optimized layouts may not look good when exported to Word.  If you try to make the report exportable in all formats, you frequently will wind up with a report that doesn’t look very good in any format

Also, many times the users want the report to handle every niche scenario, so, for example, if there is a custom field that just exists on appointment records, they will want to include it in an activity report.  This small change can make a big difference in report execution performance, as it means having to join or union in the filteredappointment view in your query.  If you have additional custom fields on other specific entities, that makes it even slower.

Best practice is to limit your fields in the report to just the minimum necessary for the main use case for the report, and if there are any entity specific fields needed for other scenarios, you may want to build additional reports that just focus on those activity types.

Best Practices

  1. Whenever possible use views and charts for activity reports
  2. Whenever possible, report from the filtered views
  3. Whenever possible, use the FilteredActivityPointer entity view for activity reports rather than unioning the specific entity views.
  4. Build report people filters from the FilteredActivityParty entity view
  5. Create your report with a clear focus, not an open-ended “all things to all people” activity report

December 29, 2011

Identifying Synchronized Microsoft Dynamics CRM items in Outlook

If you use Microsoft Dynamics CRM for Outlook, you may know that Microsoft uses the following icon to display records that are synced from a users outlook client to CRM.

image

Sometimes a user can do something which causes the icon to disappear.  Some examples that would cause this situation include removing the CRM Outlook client, or reconfiguring the users client to point to an upgraded CRM 4 to 2011 Organizations, or editing fields on the record in Outlook that are not synched to CRM. When that icon disappears there is no real way to tell between a personal contact or other synced item to CRM. As a result a user might have hundreds of contacts and not know if they manually created them,  or if it was synchronized with CRM.

Well I learned today there is a way. Using the following steps will quickly allow you to see items that are  synchronized with CRM.

1.) Go to your views in Outlook. In our example we are going to make this change to the contact view.

2.) Click on Add Columns button and then Click on New Column button

clip_image005

3.) Enter the following new column information below.

Name: crmLinkState      Type: select Number

clip_image006

4.) Then add the column to your view

clip_image007

5.) Then look at your outlook view. (2 – Means currently synced with your org, 0 – means previously synced and blank means never synced)

image

Hope it helps you too!

December 28, 2011

XRM 2011 - JavaScript 101 in Microsoft Dynamics CRM 2011

When it comes to CRM 2011, knowing JavaScript opens up a whole new world for what you are able to do. Whether it’s a functional piece like address verification or a cosmetic change like shading the form, it’s all possible through JavaScript. I’ve been to several CRM events and when it comes to JavaScript, it’s always light on the details. So I’ve decided to put together a small series of learning JavaScript for CRM 2011. If right now JavaScript sounds a little frightening, realize that pretty soon it will be just another tool in your arsenal.

Where oh where do we begin? Smile

First of all, there is more to JavaScript then just JavaScript. With CRM 4, we used crmForm.all.?. With CRM 2011, we use Xrm.Page.?. Those are JavaScript objects or libraries built to make your life easier. When it comes to JavaScript as a whole though, there is jQuery, Dojo, Sencha, Prototype and countless other libraries out there. We are only going to focus on CRM 2011 and basic JavaScript.

In today’s lesson, we’re going to look at the value of an Option Set and toggle a section based on the value. When the Relationship Type is set to Customer, we’re going to show the “Policy Info” section. When the Relationship Type is set to Prospect, we’re going to hide the “Policy Info” section. The purpose for this is to only show to the user what is important for the contact. In the case of a Prospect, they don’t have a policy with us, so it doesn’t provide any value to our users.

image

Getting Prepared

To start, we need to three different schema names: the field, the tab and the section. One way to get the schema names is to click the “Customize” tab and select “Form”.

image

Once the Form Editor opens up, select the field you want to use (in our case we’re using a custom field). Once you’ve clicked the field, click on the “Change Properties” button on the ribbon at the top of the screen.

image

A new window should pop-up. Click on the Details tab, to see the “Name”. This is the schema name.

To find the schema name for the tab, click just to the right of the text. A light blue border should now be on the tab. At this point, it’s selected so let’s click the “Change Properties” button again.

Tip: To move around a section, use your arrows

clip_image008

clip_image010

For tabs and sections, the Display tab contains the schema name we need.

Note: If you have a GUID for the name, feel free to rename it to something recognizable. Typically, I prefix tabs with “tab” and sections with “section”.

Next, get the name of the section we are hiding.

Now we should have our schema names

  • Relationship Type – customertypecode
  • General Tab – general
  • Section – sectionPolicy

 

Ode to the Code

Getting a Field

To do this, you’ll want to call:

Xrm.Page.getAttribute(“CRM_Field_SchemaName”)

So for our example, I’m going to use the “Relationship Type” attribute called customertypecode. To get this attribute, we’re going to call:

Xrm.Page.getAttribute(“customertypecode”)

Getting the Fields Value

Now that we have the field, let’s get the value:

Xrm.Page.getAttribute(“customertypecode”).getValue()

Our Logic (Pseudo code)

When writing code, I like to talk my way through it and pseudo code and comments are two easy ways to do this. A comment in JavaScript can be done with the double slash “//”.

// function togglePolicyInfo(){

// if policy info equals Customer

// show section

// else

// hide section

// }

 

Showing the Real Code

Our psuedo code is just the plan of what we want to do.  Here’s the code, you’ll actually need.

function togglePolicyInfo(){
   if (Xrm.Page.getAttribute('customertypecode').getValue() == 100000000){
      // Customer - show policy information
      Xrm.Page.ui.tabs.get("general").sections.get("sectionPolicy").setVisible(true);
     
   } else {
      // hide policy information
      Xrm.Page.ui.tabs.get("general").sections.get("sectionPolicy").setVisible(false);
   }
}

 

Adding the Code

We need to add the code to a Web Resource and then to two events: OnLoad of the Form and OnChange of the Field.

image

image

 

Summary

Now whenever I choose the relationship type Customer, I can see the applicable sections.  Although this was a bit on the light side, hopefully this can get you started.

image

Here are some additional resources:

 

Hope you enjoy!

Creating Cross-Tab Data Inputs in Microsoft Dynamics CRM 2011

I recently was asked if there was a way to put inputs that are of similar manor on a form in a cross-tab grid format. Similar to this:

 

Col 1

Col 2

Col 3

Row 1

     

Row 2

     

Let’s see how this can be done. Start by creating your attributes. For simplicity sake I created 6 attributes:

  • row1col1
  • row1col2
  • row1col3
  • row2col1
  • row2col2
  • row2col3

From there I added them to a section of my form. Making sure the new section is formatted for 4 columns. I then add the attributes to the section but leave the first column empty. Also make sure to turn the labels off for each attribute. Here is what the form looks like in the designer.

clip_image002

clip_image004

From there you will need to add jquery to your webresouces and add it to the form properties. If you do not have jquery you can download it at www.jquery.com. It is a very powerful javascript library that makes working with the DOM much cleaner and more precise. Once you have jquery you will need to create an onload function to be called. Here is what the code would look like:

Form_OnLoad = function () {

               $("#jm1_row1col1_d").prev('td').html("<br><span style='font-weight:bold; float:right;'>Row #1</span>");

               $("#jm1_row2col1_d").prev('td').html("<span style='font-weight:bold; float:right;'>Row #2</span>");

               $("#jm1_row1col1_d").prepend("Column #1").css("color","#333").css("text-align","center").css("font-weight","bold");

               $("#jm1_row1col2_d").prepend("Column #2").css("color","#333").css("text-align","center").css("font-weight","bold");

               $("#jm1_row1col3_d").prepend("Column #3").css("color","#333").css("text-align","center").css("font-weight","bold");

               $("#jm1_row1col1_d").parent().css("height","40px");

};

What you will notice here is that I use the jquery selector function to select the label and textbox td’s that CRM uses to layout the form. At first I select the empty td cell using the prev() function in jquery to put in some html text. Notice I put a <br> tag before the text for row 1. This is used to move the first row header down a little to accommodate the height difference when we put in a column header. For row 2 I do not add the <br> tag as it will line up fine. After that I get each row 1 textbox and prepend text with some css styles. This text will be the headers for your columns. After I add all the header text I will set the height of the <tr> for row 1 to 40px to allow for the textbox to show properly. Here is what the resulting form looks like after the onload function fires.

clip_image006

December 23, 2011

Dynamically Generating URLs for Cached Web Resources for Microsoft Dynamics CRM

CRM 2011 supports several methods for accessing web resources.  These includes using the $webresource: directive when referencing web resources from the site map or ribbon, a relative URL, or an absolute URL.  While this allows a web resource to be accessed in virtually any situation, if a scenario arises in which an absolute URL must be used, the benefit and speed of retrieving the cached web resource is lost.  The reason for this has to do with the caching mechanism used by CRM for web resources.  Take the following URL that could be generated by CRM when using the $webresource: directive or when a web resource is included on a CRM form as an example.

https://yourorgname.crm.dynamics.com/%7B634594655730000000%7D/WebResources/cei_/test.htm

Notice the magic number that is highlighted in the example URL.  CRM automatically inserts this token into the URL and the CRM 2011 SDK indicates that this magic number is a GUID value that ensures the latest cached version of the requested web resource is used.  If you use a tool like Fiddler to examine the response returned by the GET request for the web resource, you will notice that it has caching headers that set it to be cached for one year.  If the magic GUID value is removed from the URL so that the URL would resemble an absolute URL to the web resource, the response returned by the GET request for the web resource, depending upon your version of CRM, will be a non cached version or a version that is cached for a short amount time such as 24 hours.

This caching functionality provided by CRM is great, but what if you need to dynamically generate the URL for a large web resource?  It would be preferable to access the cached version, but in order to do that you need the magic GUID value.  Fortunately, the magic GUID value is not magic at all, and not actually a GUID.  The caching token inserted into the URL for the web resource by CRM is merely a timestamp that represents the modified time of the last web resource to be modified.  The timestamp is represented as ticks in UTC time as generated by the .NET Framework. 

Now in order to get the URL for a web resource, it is merely necessary to generate this timestamp.  The example function below shows exactly how to generate the timestamp for the caching token using a quick call to the REST service in CRM and a simple conversion from the JavaScript Date object to the timestamp value.

   1: function getWebResourceUrl(webResourceName) {
   2:  
   3:     var dotNetMillisecondsAt_1970_01_01 = 62135596800000,
   4:         ticksPerMillisecond = 10000,
   5:         lastWebResourceModifiedOn = null,
   6:         webResourceCachingToken = null,
   7:         webResourceUrl = "/WebResources/" + webResourceName;
   8:     
   9:     // Retrieve the modified date of the last web resource to be modified
  10:     $.ajax({
  11:         async: false,
  12:         beforeSend: function (xhr, settings) {
  13:             xhr.setRequestHeader("Accept", "application/json");
  14:         },
  15:         contentType: "application/json; charset=utf-8",
  16:         datatype: "json",
  17:         global: false,
  18:         success: function (data, textStatus, xhr) {
  19:         
  20:             // Extract the modified date from the results
  21:             lastWebResourceModifiedOn = +(/\/Date\((\d*)\)\//.exec(data.d.results[0].ModifiedOn)[1]);
  22:             
  23:             // Convert the JavaScript Date value to the caching token value
  24:             webResourceCachingToken = (lastWebResourceModifiedOn + dotNetMillisecondsAt_1970_01_01) * ticksPerMillisecond;
  25:         },
  26:         type: "GET",
  27:         url: Xrm.Page.context.prependOrgName("/XRMServices/2011/OrganizationData.svc/WebResourceSet()?$select=ModifiedOn&$orderby=ModifiedOn%20desc&$top=1")
  28:     });
  29:     
  30:     // If we have a caching token value then prepend it to the current URL.
  31:     if (webResourceCachingToken !== null) {
  32:         webResourceUrl = "/%7B" + webResourceCachingToken + "%7D" + webResourceUrl;
  33:     }
  34:     
  35:     // Return the URL to the web resource prepended with the organization name if necessary
  36:     return Xrm.Page.context.getServerUrl().replace(/\/$/,"") + Xrm.Page.context.prependOrgName(webResourceUrl);    
  37: }

Notice the function takes the name of a web resource, e.g. cei_/mypage.htm, and prepends it with the caching token, organization name if necessary, and the server URL.  Now this function can be used to dynamically generate the URL for a web resource and still retrieve the cached web resource.  Of course, there could be some improvements made,  such as wrapping the call to retrieve the caching token in a closure so that it is only retrieved the first time a URL is generated, but I will leave that up to you.

**Note, that generating a URL in this manner is not supported by Microsoft and the caching mechanism used by CRM for web resources could be changed in the future.

December 22, 2011

CRM 2011 for Outlook Sync Errors

We have seen users experiencing some rather annoying Sync issues with CRM 2011 Outlook Contacts. When attempting to Sync in Outlook, users were receiving several error messages on Contact records that said “You cannot link this item to Microsoft Dynamics CRM. Synchronization for this record or activity type has been turned off”. Contacts would appear to sync and show a CRM icon that would quickly change back to an Outlook icon and the contacts would not show a link back to a Parent CRM Account.

Note: Prior to UR 5, there was an issue where inactivating or removing the default My Outlook Contacts filter broke all other Contact filters. This issue has been resolved with UR 5.

We found that the users experiencing the sync issues had a program called “Microsoft Office Interop Assembly 2007” installed on their machines that was interrupting the CRM MAPI calls. We un-installed this program using Add/Remove Programs in the Control Panel. After un-installing the Interop Assembly 2007, we used the following steps:

1) Deactivate all Outlook filters

a. Open Outlook and go to File – CRM – Synchronize – Outlook Filters

clip_image002

b. Select all filters and click the icon that looks like a stop sign to Inactivate all filters. Click Ok when complete.

clip_image004

2) Clean up the Outlook Contacts synced from CRM

a. Once the filters are dactivated, go to File – CRM – Synchronize and click Synchronize

clip_image006

b. Browse to Contacts. Locate and delete duplicate contacts or leftover CRM contacts that did not get removed with the sync. Do not delete personal contacts that are not found in CRM.

3) Delete and recreate the user’s profile in the CRM configuration wizard.

a. Go to All Programs – Microsoft Dynamics CRM 2011 – Configuration Wizard. Note the Server URL. Highlight the existing CRM profile and click Delete.

b. Click Add to recreate the profile.

clip_image008

c. Enter the server name copied from step A. when prompted, enter the user’s login credentials and select Ok. Once authenticated, select the Organization. Click OK when complete.

clip_image009

When complete, user can log back into Outlook and recreate the custom filters without Sync errors.

December 21, 2011

Syntax when using CTE’s in an SSRS Report Dataset for Microsoft Dynamics CRM

CTE’s (Common Table Equivalent) are very useful when writing complex SQL queries.  I recently used one in a dataset in a report.  This was a secondary dataset that I was appending to an existing report which was already in CRM and worked correctly.  Designing and testing the reports in Visual Studio worked as well.  Only after uploading and running the report from within Microsoft CRM did I get an error naming the dataset as the culprit.

I suspected the CTE to be culprit as the dataset query was working fine.  Thanks to a bright and esteemed colleague of mine, the answer was provided to me.  A semicolon ( ; ) must be inserted before your WITH expression.

Incorrect
WITH RepIDs as (Select * FROM SystemUser …)

Correct
;WITH RepIDS as (Select * FROM SystemUser …)

I updated my dataset, saved the report to Microsoft CRM, and ran the report successfully.

December 16, 2011

Setting Lookup Field Values on Microsoft Dynamics CRM Forms with Silverlight

Recently, I have found myself developing a lot of Silverlight customizations for CRM 2011. If you happen to find yourself in the realm of Silverlight and CRM you will more than likely have the need to interact with the CRM form in context. The tool that Silverlight provides for interacting with the hosting web page is the HTML Bridge. The types and methods exposed by the HTML Bridge allow access to the hosting pages DOM and JavaScript objects. By utilizing the types and methods of the HTML Bridge it is possible to access the Xrm JavaScript object of the CRM SDK to set field values so let’s take a look at how the HTML Bridge can be leverages to do so.

There are a couple of different methods that can be used when accessing the Xrm object of CRM. One is to create an object model around the Xrm object that mirrors the Xrm object in JavaScript and the other is to use a dynamic object in Silverlight. I am going to use a dynamic object in this instance as it requires much less code, however, the downside is that there is not any compile-time type checking and errors may not be discovered until runtime.

   1: // Get a reference to the Xrm object
   2: dynamic Xrm = HtmlPage.Window.GetProperty("Xrm");
   3:  
   4: // Set a string field value
   5: Xrm.Page.getAttribute("cei_stringfield").setValue("Hello World!");
   6:  
   7: // Set a floating point field value
   8: Xrm.Page.getAttribute("cei_floatfield").setValue(3.14159);

Notice in the previous example I simply use the HtmlPage.Window object to get a reference to the Xrm property on the hosting page. Also, notice that the local Xrm object is declared as a dynamic variable. Declaring the local Xrm object as a dynamic object allows the object to bypass static type checking. At this point, it is simply a matter of using the Xrm object just as if it were being used from JavaScript. In line 5 of the previous code snippet I have done just that. A reference to the cei_stringfield attribute is obtained and the value is set to a “Hello World!”. In line 8, the same approach is used to set a numeric field.

After seeing how the previous snippet of code works, you may think, as I did, that setting a lookup field’s value could be done using the same technique with an anonymous array object that mimics a lookup fields value as the argument to the setValue function. However, calling the setValue function for a lookup field will not work from within Silverlight due to the way the HTML Bridge marshals managed objects to JavaScript. Fortunately, there is another method that can be used, although it is not quite as elegant. The following snippet shows how a lookup field can be set from within Silverlight.

   1: private void SilverlightSetLookupValue(string fieldName, Guid? id, string entityLogicalName, string name)
   2: {
   3:     // Define eval statements for setting lookup to a value and null
   4:     string setLookupJscript = @"Xrm.Page.getAttribute(""{0}"").setValue([ {{ id: ""{1:B}"", typename: ""{2}"", name: ""{3}"" }}])";
   5:     string setLookupToNullJscript = @"Xrm.Page.getAttribute(""{0}"").setValue(null)";
   6:     string evalStatement = null;
   7:  
   8:     // Set the statement to be evaluated based upon the value of the id argument
   9:     if (id.GetValueOrDefault().Equals(Guid.Empty))
  10:     {
  11:         // Setting the lookup to null
  12:         evalStatement = string.Format(setLookupToNullJscript, fieldName);
  13:     }
  14:     else
  15:     {
  16:         // Setting the lookup to a value
  17:         evalStatement = string.Format(setLookupJscript, fieldName, id, entityLogicalName, name);
  18:     }
  19:  
  20:     // Set the lookup
  21:     HtmlPage.Window.Eval(evalStatement);
  22: }

That’s right, I broke out the big dog, the EVIL EVAL function. As I said previously, it is not the most elegant solution, however, sometimes the heavy hitters like the eval function need to be dusted off and it works beautifully. As you can see, the method in the snippet builds the JavaScript necessary to set a lookup field dynamically as a string and then evaluates the string on the hosting page using the HtmlPage.Window.Eval method within Silverlight.

December 15, 2011

Redeploying Scribe Server ODBC Connections for Microsoft CRM Integrations

The following is a quick way to redeploy Scribe ODBC data connections from one scribe server to another. This is particularly helpful when you want to move scribe and/or DTS from a test/development deployment to a production deployment.

1.) You need to click on start run and type “regedit” on the server from which you want to copy the ODBC connections.

Note: If you are not confortable working in the registry key ask for assistance. You can cause bad problems if you do not understand what you are doing.

2.) Find the ODBC Key for your type of installation. There are two location depending on OS verion 32 Bit. or 64 Bit.

32 bit server location
HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI

64 bit server location
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ODBC\ODBC.INI

image

3.) Export the registry key to a *.reg file.

image

4.) Logon to the server that you want to restore/copy the ODBC settings to and run regedit.

5.) Please backup this servers registry key prior to importing the exported registry keys from the other server. This way you can restore the original if something happens (Repeat step 2-3)

6.) Double click on the exported *.reg file from the server you are moving the ODBC settings from and it will import them.

December 13, 2011

Importing Records Created Since the Last Run Date of a Scribe DTS for Microsoft CRM

When using Scribe, you frequently want your integration process to identify only the records that have changed since the last time the integration job ran, so you only do an incremental insert or update. There are several ways to do this, including message queues or application publishers. One of the simplest ways to do it is by using the GetLastRunDate function in Scribe. This function gets the last time a job has run from the executionlog table of the scribeinternal database, and you can use that variable as a filter in your source query, either from one of the Scribe adapters or from a SQL query.

Here is how you would filter a SQL query by last run date of the job in Scribe Insight:

1. Get the file path for the scribe dts. Easiest way to do this is navigate to the collaborations folder and shift + right click and select “copy as path.”

2. Create a calculated variable called LastRunDateTime.

3. Set the formula for the calculated variable to be

GETLASTRUNDATE( "C:\Program Files (x86)\Scribe\Collaborations\CustomerTest.dts" ) (replace the file path with the one copied in step 1).

4. Call that in your query as follows:

SELECT TASKID, FLOWID, STEPID, STARTTIME, ENDTIME, STATUS, LOCKBY, LOCKTIME, USERID, USERKEY, USERKEY2, PRIORITY, DEADLINEFLAG, DEADLINE,
AVAILABLEDATE, FILE_NO, FOLDER_NO, DESCRIPTION, DRAWER, PACKAGETYPE, FROM_USERID, DATE_INITIATED, LOCKPERIOD, FROM_FLOWSTEP, DOCTYPE,
RPTFLAG, FORMTEMPDIN
FROM dbo.IR_TASK_DATA (nolock)
where ENDTIME >= :LastRunDateTime AND File_NO <> ' ' and File_NO is not null
ORDER BY ENDTIME

Considerations and shortcomings of this approach

  • If you lose your scribeinternal database, your process will fall apart—this approach depends on the executionlog tables. Backup, backup, backup.
  • The last run date approach can be problematic with related records, for example when accounts and contacts are created. If you have an account load running off of last run date and you have a contact load running based on last run date, you risk data loads failing if the account and contacts are created after the account load has run but the contact load has not run. In this case your contact will fail because the parent customer doesn’t exist. I recommend combining these into one step—getting all contact and parent account information in one query where the modified on the contact is greater than last run date or the modified on the account is greater than last run date—that way you won’t have any dependency/timing issues causing records to fail to load.
  • The last run date approach can be problematic if rows fail. Since it is only getting records that have changed since the last time the job ran, if during a load a row fails for some reason, next time the job runs it will not retry that row. I recommend adding a “retry bit” to the source data table, and if for some reason a row fails, you can update the source for retry. Then, in your DTS, have your source query include records that were modified after the last run date OR records where retry = 1/yes. This is one way to eliminate the timing issues in the previous point—if a row fails because a dependency is not present, flag the row for retry and by the time the job runs again, the dependency will probably be there.
  • Make sure that if you are reading from a MSCRM database using the lastrundate approach, you are reading from the filtered views, not the base views or tables. Keep in mind that the modified date field will be 4+ hours later in the base tables and views so if you are reading from the base tables and views your last run date logic will not work dependably.

 

del.icio.us Tags: ,

December 12, 2011

Jscript Pop-up in Microsoft Dynamics CRM - Internet Explorer vs. Outlook

Occasionally when developing custom solutions in CRM, there will be a need to open a new window from Jscript. Typically the window.open function is used to accomplish this, but this is not always ideal in CRM.

Consider developing a custom solution in CRM where you need to open another CRM record in a new window. In the web interface of CRM the window.open function works fine, but what about the Outlook integration functionality? Well, in On-Premise this doesn’t pose a big issue because Internet Explorer will typically use your logged in account to authenticate with CRM. But what if you are not using On-Premise, or what if you have another set of logins specifically for CRM in your Active Directory environment (not sure why you would, but it could happen).

Outlook allows a user to cache their credentials to allow communication with the CRM environment without having to log in every time. However, if you open a new window using the standard Jscript window.open function, it will open your window in Internet Explorer not Outlook. In situations where you have to log in to reach CRM (i.e. not using On-Premise with your standard Active Directory account), this will require the user to enter their credentials before opening the correct page. This really disrupts the flow of any process, and is annoying and confusing to end users.

Luckily, Microsoft provided a function to handle this situation (although it is undocumented). There is an openStdWin function that is a part of the CRM Jscript implementation that will check to determine if the user is using Outlook or Internet Explorer, and open the new window in the appropriate format. The following code displays the way this functions:

function openNewWindow(url) {
var name = "newWindow";
var width = 800;
var height = 600;
var newWindowFeatures = "status=1";
var oldWindowFeatures = "width=800,height=600,status=1";
// Regular Jscript function to open a new window
//window.open(url, name, oldWindowFeatures);

// CRM function to open a new window
openStdWin(url, name, width, height, newWindowFeatures);
// CRM function to open a new window
// with default CRM parameters
//openStdWin(url, name);
}

One point to note, if you simply pass the url and name to the openStdWin function and leave off the width, height, and windowFeatures, the window will be opened with the same parameters that regular CRM windows are opened with. (i.e. same width and height as a standard CRM pop-up with no address bar, but with the status bar and resizable)

Now you don’t have to worry if the user is in Outlook or Internet Explorer, your pop-up window will open correctly. Enjoy!

Notice: openStdWin is an internal function of CRM and may change at any given point without notice.

December 08, 2011

“Cannot authenticate your credentials” error when configuring Microsoft CRM 2011 for Outlook

A user recently reported that when she was trying to configure Microsoft CRM for Outlook to her CRM Online environment, she would get the following error:

server error (2)

I’ve seen the “Cannot connect to server” error before, but this one was a little bit different because it said it “cannot authenticate credentials.”  She could log on to the web client without issue, so we knew that her credentials were ok.

With the help of Microsoft support, we were able to resolve this error using the following steps:

1.  Log on to Microsoft CRM in a web browser

2.  Copy the full URL from your browser window

3.  Run the CRM configuration wizard (start—>all programs—>Microsoft Dynamics CRM 2011)

4.  instead of changing the Server URL to “CRM Online,” just paste the full url to your CRM Online environment to the “Server URL” field, then click “Test Connection” and enter your CRM Online credentials.

image

Using this approach we were able to configure the client to CRM Online. 

Using the CRM 2011 REST Services and Deep Insert to Create Activities

One of the nice features of CRM 2011 is the REST based OrganizationData service. Lately, I have found myself using the REST service more often as it provides a simpler and cleaner method of accessing data from client side JScript. The REST service also provides the ability to do deep inserts of entity and related records. This capability can be leveraged to provide an elegant solution to creating activity records using client side JScript.

In my particular use case, I needed to create a new email activity from the currently logged in user with the regarding record set to a new custom entity record. It would have been possible to issue a couple of calls to the REST service that created the regarding record and then the email, but it is just as easy to create the email and related records in one call avoiding the need to clean up any records should one of the calls fail.

The first thing that needs to be done is to create the activity party record for the from field on the email. The activity party is a separate entity that stores all of the parties related to an activity, i.e. sender, recipient, etc. The activity party data needs to be specified as an array of activity party entities. The following snippet creates an activity party record for the from field on the email.

   1: // Create the activity party records
   2: var emailPartyEntities [{
   3:     PartyId: { LogicalName: "systemuser", Id: Xrm.Page.context.getUserId() },
   4:     ParticipationTypeMask: { Value: 1 }
   5: }];

As I mentioned earlier, I also needed to create a custom entity record that will be set as the regarding on the created email. In my case, this custom entity is used to track an email thread. Since this is a N:1 relationship for the email entity, the record created does not need to be stored in an array and is merely an object with properties specifying the fields of my custom entity.

   1: // Build the activity thread entity
   2: var activityThreadEntity = {
   3:     cei_Department: { Value: 29669000 },
   4:     cei_Subject: "Activity Thread for Account",
   5: };

Finally, I need to build the email entity that will be passed to the REST service during the create request. In order for the deep insert to work, the activity party array and the activity thread object created earlier will need to be set to properties on the created object that specify the relationships to the related entities as shown below.

   1: // Build the email record
   2: var emailEntity = {
   3:     Subject: "Test Email",
   4:     cei_activitythread_Emails: activityThreadEntity,
   5:     email_activity_parties: emailPartyEntities,
   6: };

In the previous snippet, notice that the activityThreadEntity object and the emailPartyEntities array are set to their corresponding relationships, i.e. cei_activitythread_Emails is the name of the N:1 relationship for my custom entity to the regarding field on the email entity, and email_activity_parties is the name of the 1:N relationship from the email entity to the activity party entity.

Now that all of the required objects have been created we can issue the call to the REST service to create the email and related records. The following snippet utilizes a jQuery plugin from our custom JScript library. It is merely doing a POST request to the REST service with the data for the POST being the JSON serialized emailEntity object that was created.

   1: // Create the email by POSTing the data to the REST service
   2: var createResult = $.xrm.orgData.buildRequest().
   3:     async(false).
   4:     dataset("Email").
   5:     data(emailEntity).
   6:     create();
   7: if (createResult.errorExists) {
   8:     alert("There was an error creating the email.");
   9: } else {
  10:     alert("Success!");
  11: }

That’s it! It really is that simple. The email, activity party, and regarding records were all created in a single call.

In this example, I utilized the deep insert capabilities of the REST services to create an email, but the deep insert feature can be used on any entity in order to create multiple records in a single call. The biggest hurdle that you will probably run into is determining whether to create the related records as JScript objects or arrays of objects. Just remember that 1:N relationships require and array of objects and that N:1 relationships require a single object.

December 07, 2011

Microsoft Dynamics CRM 2011 Reporting Extension (SRS Data Connector) Installation Service Account Warning

The Microsoft Dynamics CRM 2011 Reporting Extensions, previously known as the SRS Data Connector, will sometimes return an error message during installation that is intended to be a warning, not an error. The message that you see is ‘A Microsoft Dynamics CRM Server component is using the same account as the instance of SQL Server Reporting Services.’

image

There are several conditions which will provoke this message

· A Microsoft Dynamics CRM Server 2011 component is installed on the computer where Microsoft Dynamics CRM Connector for SQL Server Reporting Services Setup is being run.

· The SQL Server Reporting Services account is a member of the Active Directory SQLAccessGroup security group. This can occur when the Reporting Services is running under the same account as another Microsoft Dynamics CRM component.

· All Microsoft Dynamics CRM Server 2011 components, SQL Server, and Reporting Services are installed on a computer that is running Microsoft Windows Server Small Business Edition where Microsoft Dynamics CRM Connector for SQL Server Reporting Services Setup is being run.

· The SQL Server Reporting Services account is set as "Local Service."

To get around this error, follow the steps below. Once this is completed, you will still see the error message however the ‘Next’ button will be available and you can continue with the installation. This does require a registry setting change, so it is recommended that the registry be backed up PRIOR to making any changes. One thing to note before using this, if you change this key on your CRM server, any checks that are supposed to take place during the CRM installation will also be ignored. This should only be used with great care and turned off after the Reporting Extensions installation is completed. Failure to do so may result in checks being ignored during other installations and could have negative consequences.

1. Close the installer window

2. Find the MSCRM key in the HKLM\SOFTWARE\MICROSOFT directory

3. If the MSCRM key does not exist, create it in the HKLM\SOFTWARE\MICROSOFT directory

4. Once you have the key, create a new DWORD value named IgnoreChecks and set the value to 1

5. Launch the installer and follow its instructions. When you get to the environment checks the ‘Next’ button will be available.

December 06, 2011

Rename Related Entity Groups on Forms

In CRM 4.0 it was a bit of a challenge to re-name a group on a form – But 2011 has added this feature to the native form editor and now it’s a snap (and it makes me happy!)

12-1-2011 12-25-19 PM12-1-2011 2-43-24 PM

To Accomplish this, open the desired form in edit mode.

In the ribbon – choose – “Navigation”, Then Select the Navigation Area you want to modify – then choose “Properties.” – Edit the Group Name and click OK – Then save and publish the form.

12-1-2011 11-59-54 AM

 

One caveat is that the users will need the “ISV Customization” permission – That permission is located in the lower section on the customization tab of all security roles -

12-1-2011 3-04-08 PM

December 02, 2011

Customer Service takes off for Signature Flight Support with the help of Microsoft CRM

Customer Effective is proud to release a new Customer Success Story highlighting Signature Flight Support, a BBA Aviation plc company.

Signature Flight Support is the world’s largest FBO with more than 100 facilities around the world. They offer a wide variety of services from fueling and ground handling for the aircraft, to arranging hotels and other amenities for the private jet crews and passengers. As a personal concierge for thousands of crew members and passengers traveling around the globe, Signature Flight Support takes its brand reputation very seriously. In order to help ensure that every flight crew member and passenger are completely satisfied with their service, Signature implemented Microsoft Dyanmics CRM and integrated their proprietary state of the art point-of-sale system, Signature SIGnet™. 

Prior to their CRM implementation, Signature’s customer information technology was limited in the ability to efficiently share information throughout their FBO network. Since Signature is part of BBA Aviation which owns multiple aviation companies, several of their customers overlap. Thanks to Microsoft CRM, they are now able to use the data they collect to create compelling sales programs across sister companies and provide superior customer service.

To learn more about Signature Flight Support's success with Microsoft CRM, visit our Customer Success Page

Microsoft Dynamics CRM 2011 Email Router Throws 5.7.1 Client Could Not be Authenticated When Sending Emails

I was working on a 2011 upgrade and came across an issue when running the Email Router on a Windows Server 2008 R2 machine. I installed the router with no issues, but when someone sent an email it failed. The following message was in the event viewer of the machine the router was installed on:

‘5.7.1 – Client could not be authenticated.’

During our troubleshooting, we found that the Email Router worked on a Windows Server 2008 machine with no Exchange authentication challenges. A Network Monitor trace confirmed the authentication challenge on the Windows Server 2008 R2 machine as an Exchange challenge. Research confirmed that Exchange 2007 was setup to accept anonymous users.

The solution to this was to set the authentication method to ‘Anonymous’ in the email router configuration manager. On the Windows Server 2008 machine, the authentication method was set to ‘Windows Authentication,’ however there is a conflict when sending authentication from a Windows Server 2008 R2 machine to an Exchange Server 2007 environment which is configured to accept anonymous users. It is also important to note that in this particular environment the Exchange server as well as the server with the Email Router are on the same network.

December 01, 2011

Golden Key gives Microsoft CRM an A+ in Managing its Student Relationships

Keeping track of the membership and needs of an educational honor society with over 2 million members, representing more than 190 countries is a daunting task. But, as the world's largest academic honor society that is just part of what of Golden Key International Honour Society has to manage. 

In order to help manage their large number of members and their 5,000 student volunteers, Golden Key enlisted Customer Effective to help them implement Microsoft Dynamics CRM. The CRM system enables Golden Key to fulfill its mission of helping their members realize their potential through advancement of academics, leadership and service.


With 400 chapters in colleges and universities around the world, membership is based solely on academic performance and is only open to those who have been invited. Students must be in the top 15 percent of their class and must be a sophomore, junior, senior or graduate student.

Golden Key now uses CRM as a tool that allows students to apply for scholarships and awards, learn more about campus events, register for events and more. It also greatly expedites their spring and fall membership campaigns which target more than 600,000 students all over the world, and helps them keep track of alumni, faculty members, university officials and leading businesses that support Golden Key. 

To read more about Golden Key International Honour Society's success with Microsoft CRM, please visit our Customer Success Page

CRM 2011–Excessive Sub-Gridding

Sub-grids enhance the user experience by conveniently providing associated information.  Within a sub-grid the user can easily view, create, or modify a related entity.  By default, Microsoft will auto-populate up to four sub-grids. 

image

 

One thing to note however is that if the form contains more than four sub-grids, then sub-grids 5+ will contain a message inside the sub-grid “To load x records, click here”.  To populate the sub-grid, the user has to click the refresh button or the link.

image

 

CRM 2011 does this intentionally to make sure the User is presented with the Form as quickly as possible.  Each sub-grid is another Fetch call to the database, so reducing those inherently speeds up the form. 

Now what if you only need a few more sub-grids and you are ok with the potential performance trade-off?  Well, let’s add a little JavaScript to auto load all of our sub-grids that didn’t auto load already:

function getLinksWithClassName(classname)  {
    var bdy = document.getElementsByTagName("body")[0];
    var els = [];
    var re = new RegExp('\\b' + classname + '\\b');
    var lnks = bdy.getElementsByTagName("a");

    for(var i=0,j=lnks.length; i<j; i++)
        if(re.test(lnks[i].className))
            els.push(lnks[i]);

    return els;
}

var lnksUnloaded = getLinksWithClassName('ms-crm-List-LoadOnDemand');

for (var i = 0; i < lnksUnloaded.length; i++){
   lnksUnloaded[i].click();
}

 

Now adding the bottom four lines to our OnLoad event will cause all of our sub-grids to auto-load.  Hope you enjoy!

Search The Blog

  • Search the Blog
     

    WWW
    this blog

Twitter Updates

    follow me on Twitter