Display CRM Business Unit Organization Hierarchy in a TreeView

Hi guys,

I've see several people and customer requested this feature in CRM.
The hiearchical view of BU in CRM is not something provided out of the box and I don't understand why because it could be very handy.

The CRM SDK offers the possibility to do this using the RetrieveBusinessHierarchyBusinessUnitRequest() and RetrieveBusinessHierarchyBusinessUnitResponse() Classes.

The Response contains the BusinessEntityCollection we are interested in. This is a collection of instances of the businessunit class.

Question is now: How will be do the sort and triage of all the BusinesUnits retrieved in order to find the correct hiearchy?, which BU is the child of which one?, etc........

1°) Each BusinessUnit object has several properties, we will use these properties to identify and test which BU is the child of which one.

We will only need 3 of these for the sorting and display.

businessunitid Specifies the ID of the business unit. (we will use it to identify the BU we are currently working on)
name Specifies the name of the business unit.(we will use it for display in the TreeView)
parentbusinessunitid

Specifies the ID for the parent business unit. (we will use it to retrieve Parent/Child links between BUs)

2°) We will perform the operation in 2 steps:

-> Retrieve the Root BusinessUnit

-> Retrieve all the Childs hiearchy from this point using a nested loop.
for each businnesunit retrieved, we will check the parentbusinessunit property, if this property matches the businessunitid of the current businees unit, we found its child. This is as simple as that.

3°) For each BU we will retrieve we will create a new node in our TreeView (we can add a pictures for all the BU for a cool display :-))

4°) Here is how the final app is supposed to look like:

App Screenshot

(Just create a Windows Form, add a TreeView and Button control to it)

Now the code sample:

using MSCRM30RetrieveBUHierarchy.crmsdk; // crmsdk is the name I choose for the CRM WebService Reference, don't forget that :-)

// Classic.... just creating a function to Init my WebService instance.
public CrmService InitSvc()
{
CrmService csvc = new CrmService();
csvc.Credentials = System.Net.CredentialCache.DefaultCredentials;
csvc.PreAuthenticate = true;
csvc.UnsafeAuthenticatedConnectionSharing = true;
return csvc;
}

// This function implements the test logic to find which are the childs of the current BU.
public void GetChildBu(Guid myBUid, TreeNode myBUNode,RetrieveBusinessHierarchyBusinessUnitResponse allBu)
{
foreach (businessunit bu in allBu.BusinessEntityCollection.BusinessEntities)
{
if(bu.parentbusinessunitid!=null) // we skeep the root bu.....
{
Guid currentBUid = bu.businessunitid.Value;
Guid currentBUparentBUid = bu.parentbusinessunitid.Value;

if(currentBUparentBUid == myBUid)
{
// Add each child to the treeview.
TreeNode myBUNode2 = myBUNode.Nodes.Add(bu.name.ToString());
// Loop again into the function........
GetChildBu(currentBUid,myBUNode2,allBu);
}
}
}
}

// This is the MAIN function needed to be triggered by the Button on your form.
public void RetrieveHierachy()
{
// Init the WebService......
CrmService mysvc = InitSvc();

// Define the columnset, we only care about 3 attributes: name, busineesunitid and parentbusinessunitid
ColumnSet cols = new ColumnSet();
cols.Attributes = new string[] {"name","businessunitid","parentbusinessunitid"};

// Prepare the query to retrieve the BusinessUnit collection...
RetrieveBusinessHierarchyBusinessUnitRequest retrieve = new RetrieveBusinessHierarchyBusinessUnitRequest();
retrieve.ColumnSet = cols;

// Here you need to pass the Root BusinessUnitId you can find within MSCRMDb from a simple SQL Query
// SELECT BusinessUnitId FROM BusinessUnitBase WHERE CREATEDBY IS NULL
retrieve.EntityId = new Guid("A18918BE-8E63-DA11-BC4B-0003FF0D54C9");

// The collection will be now retrieved.......
RetrieveBusinessHierarchyBusinessUnitResponse retrieved = (RetrieveBusinessHierarchyBusinessUnitResponse)mysvc.Execute(retrieve);

// Init the root BU node of our treeview.
TreeNode rootNode = null;

// Retrieve the rootBU
foreach (businessunit bu in retrieved.BusinessEntityCollection.BusinessEntities)
{
if(bu.parentbusinessunitid==null) // if no parent, we have the root!
{
// we get the RootBU then
string rootBUName = bu.name.ToString();

// we create the RootBU node on our treeview.
rootNode = treeView.Nodes.Add(rootBUName);
}
}

// Retrieve the other BU......
GetChildBu(retrieve.EntityId,rootNode,retrieved);
}

// And this of course :-)
private void button1_Click(object sender, System.EventArgs e)
{
RetrieveHierachy();
}

You can download the project file here.

Hope this helps

Benjamin