Oct30

BDC Mapper Web Part released

Categories: SharePoint

Yesterday we released the BDC Mapper Web Part so that you can plot your line of business data on our web part that implements a Virtual Earth map.

There's a demo of the web part you can download that is valid until the 15th November, with the standard price of the web part being $300.00. Click the link below for more information and a screen cast to watch:

http://www.lightningtools.com/pages/bdc-mapper-web-part.aspx

BDC Meta Man Professional License holders get a free license of the BDC Mapper Web Part saving themselves a further $300.00 on top of the free KPI BDC Web Part license they already get. Our aim is to provide you with the tools and web parts to make the most of your back-end data!

As Dustin pointed out there is a method of plotting data using SharePoint Designer and VE, but it's the usual case with SharePoint that there's always more than one way to complete your goal. With the BDC Mapper Web Part we've just offered another solution for you to be able to make the most of your important data.

 
Oct29

BDC Meta Man and Oracle

Categories: SharePoint

I've just recorded a short new screen cast to show how easily you can get up and running with BDC Meta Man and Oracle as a data source. We cover the out of the box web parts and search. It's short and quick but will hopefully be useful.

Click here to get to it (you need to register on the site to be able to download and watch it)

 
Oct12

SharePoint User Group UK October Meetings

Categories: SharePoint

The October meetings have now both been posted on the SUGUK forums so people can register.

18th October - London, Victoria. Vendor Evening

We get contacted all the time by vendors wishing to present sessions at SUGUK meetings. We've decided to lump all these together into one evening and give them 30 minutes each to give a technical talk and demonstration of how they can add value to SharePoint 2007. We did consider running it as 'Britians Got Talent format where we had buzzers and we could get people off stage if they started talking sales and marketing but health and safety said no :-)

Also each vendor should have a nice prize to give away such as a XBOX 360 or iPod. You can get more info and register here:

http://suguk.org/forums/thread/5826.aspx

29th October - Coventry. Extranets, SharePoint and ISA Server

Matt Groves will be presenting on configuring SharePoint for Extranet access in the real world and also how to work with ISA server as a SharePoint publishing tool. I'm really looking forward to seeing this one as Matt will be able to give some great demos of ISA Server and SharePoint together. Go here for more info and to register:

http://suguk.org/forums/thread/5990.aspx

 
Oct2

BDC Mapper Web Part

Categories: SharePoint

We're very happy to announce the arrival of a new BDC web part to help you make more of your Line of Business Data, the BDC Mapper Web Part!

If your BDC data has an address or city you can plot it on the virtual earth map and add BDC fields to the pop up information. An interesting new way to display your data!

image

The BDC Mapper Web Part will be free to purchasers of BDC Meta Man Professional Edition, and $300.00 purchased separately.

We are only supplying this to BDC Meta Man Professional users at the moment so if you are already a license hold please send me an email at nick@lightningtools.com.

Remember with BDC Meta Man you also get the BDC KPI Web Part free! $700.00 of web parts free with the BDC Meta Man tool :-)

 
Oct1

Business Data Columns : updating programmatically

Categories: SharePoint

When you add a Business Data Column and additional data fields to a list or library, setting the values of this column actually stores the data in the list, rather than a pointer to the BDC data. This means the BDC data is not refreshed automatically when a users views a document or the entire library, but actually relies on them clicking the little refresh button in the list. Of course getting the BDC data to update everytime the list/library is displayed may not be ideal as it could create a huge burden on your LOB System, but a setting would be nice so users could choose which way it would work.

Anyway, this blog post originates due to the fact that I've seen this problem enquired about, and also a number of people have asked how do you programmatically set BDC additional data fields in code. SharePoint must be able to do this as it does this exact functionality when you click on the little refresh button to refresh all your fields, hopefully this blog post might give you a little insight into how to use reflector and other tools incase you need to investigate how SharePoint does stuff, so you can use it or change it for your own solution.

Out of the box to refresh your Business Data Columns you need to click the little refresh button in the document library

image

When you click the refresh button you are taken to the page _layouts/BusinessDataSynchronizer.aspx where you are asked this operation may take some time, are you sure you want to continue. As we hopefully all know all the pages that are displayed from the _layouts directory come from the 12\TEMPLATE\LAYOUTS directory on the file system. We can find our BusinessDataSynchronizer.aspx page in the LAYOUTS directory and open it up in notepad. Right at the top of the code you'll find the controls and assemblies registered that are going to be used in the page. The one that should stick out at us is:

Microsoft.SharePoint.Portal.WebControls.BusinessDataSynchronizerPage

Now we know the namespace of the code we are looking for we can open Reflector (an application that should be in every SharePoint developers toolbox) and open the Microsoft.SharePoint.Portal dll and drill down to the namespace we require. The event that actually fires the synchronization is the btnSave click event so if we select that we'll see the code disassembled that SharePoint uses.

image

So the BusinessDataSynchronizerJob looks like the class we'd want to create and then run it's start method. Clicking on the BusinessDataSynchronizer link will take us to the code that is in that class...

But what do we see? They have marked the BusinessDataSynchronizer class as Internal? Why? Why leave it un-obfuscated but mark it as Internal? Grrrrrr (Adam I feel your pain! :-))

Well even though it is marked as Internal at least we can see what it does. And the answer is nothing that clever. It gets the data from the LOB System and then sets new values, iterating through the BDC Data Columns aditional fields also setting the values when it matches. Reflector does a good job of decompiliing the code in the BusinessDataSyncronizer class, but it does come up with a lot of GOTO and LABEL statements. Hopefully the BDC team didn't really include code like that and this is just Reflectors interpretation of 'foreach' and 'if' statements. But from this code we can see what they are doing, and we can piece it all together to perform the same work. The original question I had was how do you programatically set additional BDC Data Column fields, which this code will do, but I'm sure you'll be able to take it and fit it to whatever scenario you want to use it for. The code here will actually refresh every list item and the respective BDC data column although I'm sure you can see how to do it for one individual item if you needed. Also note I have hard coded the name of the SSP...

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Microsoft.SharePoint; using Microsoft.Office.Server.ApplicationRegistry.Infrastructure; using Microsoft.SharePoint.Portal.WebControls; using Microsoft.Office.Server.ApplicationRegistry.MetadataModel;
namespace SetBDCData { public partial class Form1 : Form { public Form1() { InitializeComponent(); }
 private void Form1_Load(object sender, EventArgs e) { SPSite siteCollection = new SPSite("http://localhost");
 SPWeb site = siteCollection.AllWebs["bdc"];
 SPList list = site.Lists["Tasks"];
 RefreshBDCFields refreshF = new RefreshBDCFields(); refreshF.List = list; refreshF.ColumnName = "Product";
 refreshF.DoWork(); 
 } }
 public class RefreshBDCFields { public SPList List = null; public string ColumnName = "";
 LobSystemInstance sysinst = null; Entity entity = null; Microsoft.Office.Server.ApplicationRegistry.MetadataModel.View specificFinderView = null; SPListItemCollection items = null;
 public RefreshBDCFields(SPList list, string columnName) { this.List = list; this.ColumnName = columnName; }
 public RefreshBDCFields() { }
 public void DoWork() { SPField fieldByInternalName = List.Fields.GetFieldByInternalName(this.ColumnName); if (!(fieldByInternalName is BusinessDataField)) { throw new BusinessDataListConfigurationException("The field " + this.ColumnName + " is not a business data field"); } BusinessDataField bizDataField = (BusinessDataField)fieldByInternalName;
 string[] secondaryFieldsNames = bizDataField.GetSecondaryFieldsNames(); string[] secondaryWssFieldNames = new string[0]; string property = bizDataField.GetProperty("SecondaryFieldWssNames");
 secondaryWssFieldNames = property.Split(new char[] { ':' });
 SqlSessionProvider.Instance().SetSharedResourceProviderToUse("SharedServices1");
 sysinst = ApplicationRegistry.GetLobSystemInstanceByName(bizDataField.SystemInstanceName); entity = sysinst.GetEntities()[bizDataField.EntityName]; specificFinderView = entity.GetSpecificFinderView(); items = List.Items;
 foreach (SPListItem item in items) { UpdateListItem(item, bizDataField, sysinst, entity, specificFinderView, secondaryFieldsNames, secondaryWssFieldNames); item.Update(); }
 }
 private void UpdateListItem(SPListItem item, BusinessDataField bizDataField, LobSystemInstance sysinst, Entity entity, Microsoft.Office.Server.ApplicationRegistry.MetadataModel.View view, string[] secondaryBdcFieldNames, string[] secondaryWssFieldNames) { string bdcFieldName = bizDataField.BdcFieldName; string encodedId = null; 
 object[] objArray; IList<object> identifierValues = null; object[] objArray2 = null; 
 List<Field>.Enumerator enumerator; encodedId = (string)item[bizDataField.RelatedField]; if (encodedId != null) { objArray = EntityInstanceIdEncoder.DecodeEntityInstanceId(encodedId); identifierValues = entity.FindSpecific(objArray, sysinst).GetIdentifierValues(); objArray2 = new object[identifierValues.Count]; }
 for (int i = 0; i < identifierValues.Count; i++) { objArray2[i] = identifierValues[i]; } 
 item[bizDataField.RelatedField] = EntityInstanceIdEncoder.EncodeEntityInstanceId(objArray2); enumerator = view.Fields.GetEnumerator();
 Microsoft.Office.Server.ApplicationRegistry.Runtime.IEntityInstance instance = entity.FindSpecific(objArray2, sysinst);
 Field field; string name;
 while (enumerator.MoveNext()) { field = enumerator.Current; name = field.Name; if (name == bdcFieldName) { item[bizDataField.InternalName] = Convert.ToString(instance.GetFormatted(field)); }
 for (int i = 0; i < secondaryBdcFieldNames.Length; i++) { if (secondaryBdcFieldNames[i] == field.Name) { item[secondaryWssFieldNames[i]] = Convert.ToString(instance.GetFormatted(field)); } }
 item.Update(); 
 }
 } }
}

Sure the code could do with a few comments and a bit more error checking but hopefully you get the jist.

So what could you do with this code? Well if you wanted to update Business Data Columns nightly or hourly why not wrap it up in site a Timer job? I'm still thinking of how it can be used to get LOB data every time a document library is viewed. Unfortunately there is nothing simple such as a View event, and of course updating the doc lib every time it was viewed may be hitting your LOB system quite a bit.

We're working on an administration Feature so you can setup a timer job to update these BDC fields at set times. What this space for more info on that soon.