2012 Illinois Technology Association - CityLights Finalist

BLOGS

MPS Partners provides functional and technical expertise and insights into business process management trends and Microsoft technologies.

HOT JOBS
Interested in reviewing our current job openings or submitting a resume?
CLICK HERE
Home » Blog

SP Designer 2010 Workflow- Sending Emails to Multiple Users from a Single People Picker Field

SP Designer 2010 Workflow- Sending Emails to Multiple Users from a Single People Picker Field

SP Designer 2010​ has a limitation when trying to implement a workflow action to send an email to multiple users based from lookup from a people picker control that accepts more than one user.  By default the email action will only email to the first user and will not detect multiple users.  The workaround is to first "activate" the Build Dynamic String workflow action and then set the email To: field to a variable whose value is assigned by the Build Dynamic String action.  For some reason SharePoint will only recognized the multiple users from the Build Dynamic String Action pulling the user names from the people picker field.

Step 1 – "Activate" Build Dynamic String Action

When you open SharePoint Designer 2010 and start to build a workflow you’ll notice that under Actions Build Dynamic String is no where to be found.  In order to have it appear as an action you will have to edit the WSS.Actions File found in the 14 Hive which contains all the default SDP Action.

1) Navigate to \Program Files\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\1033\Workflow on your system drive

2) Open the WSS.Actions file (this is where information about all default SPD actions is stored)

3) Find "Build Dynamic String" and change the "AppliesTo" parameter from "DisplayOnly" to "all". Save the file

4) Run IISReset, re-open SPD – you should now have the Build Dynamic String action available

BuildDynamic String.PNG
Step 2 – Workflow: Store multiple users in a custom variable built by the Build Dynamic String workflow action

In order for the email action to recognize multiple users, the multiple users must be saved into a custom workflow variable created by the Build Dynamic String action.  For some reason SharePoint will only properly record all users picked by the people picker field when the data is saved into a workflow variable with the Build Dynamic String action.  

1) In the workflow designer create action "Build Dynamic String"

2) Within the Action click "Dynamic String"

3) Lookup the users that are defined by the people picker control as a string (This example "Approved By" is a people picker field with multiple users)

4) Return the field as a string and savit to a workflow variable with type string

SetVariable.PNG

Step 3 – Assign the To: Field to Custom Variable in the Send Email workflow action

1) Create Send Email action

2) Click the address book icon next to the TO: field

3) Set the lookup to the custom workflow variable that was set in the previous step

4) Now the email will contain all users and will be recognized by SharePoint and each user will receive the email

LookupSample.PNG

Email.PNG

This workaround will now allow multiple emails to be sent by a SharePoint Designer workflow to all users defined by a single people picker field that allows multiple users with out cracking open Visual Studio.

Posted in SharePoint | Leave a comment

Custom site provisioning provider

Up until a week ago, I thought the only 2 ways to make a template for a site where Site definition and Site Template.

Both ways required that you figure out a lot of XML syntax, feature ids lists ids etc… for any code you want to run on the created site, you need to staple another feature and if you need to run code after the site is provisioned, you need to spawn another thread that will sleep until the site is provisioned. Possible but not very intuitive or easy.

Then when I needed to create a custom publishing site to be used as a template for sub sites, I found custom site provisioning provider while reading this post.

I will probably never code another site template any other way from now on.

The example shows how to do it with run as system but it is not necessary because templates are used to create sites by users with full control so they will have enough rights to run the code. The downloadable code is a good start though.

Using custom site provisioning provider is mainly implementing the SPWebProvisioningProvider interface.

All the tasks are performed in in the: public override void Provision(SPWebProvisioningProperties props)

The first thing to do is to apply a standard template to the new site so we have something to start with.

I find it best to start with "STS#1", the blank template. This gives you an empty provisioned site to add whatever is needed by the requirements. Once a template is implemented with "props.Web.ApplyWebTemplate(SITE_TEMPLATE);" the site is provisioned, so you don’t need to spawn threads and such to work with the created site, it is ready to be modified.

Little XML after all

It will not be SharePoint solution without some xml for good measures right? So here is the minimum.

In a module named "ProvisioningData" add a file named as your project with the features that will be used in the site (Later I will show how to find out the GUIDs for the features)

In the {SharePointRoot}\Template\1033\XML folder , we need a file named webtemp_{your project name}.xml

It will include the name, title, description, image URL, Display category and a reference to the provisioning data.

The Display category and the image URL will allow distinguishing your template in the UI

Image, Category and description

Adding features

The example shows how to iterate the provisioning data for features but they can be added directly in the code too, using the ID.

For the site site.Features.Add(new Guid({the ID of the feature}));

For the sub site web.Features.Add(new Guid({the ID of the feature}));

Make sure you know the scope the feature is for and not to add a feature that exists in the scope alread. (Activated)

Adding Lists

What can be better than figuring IDs of list types? Intellisense off course. Adding lists is as simple as this:

You can add fields to your lists at the same time to further your customization without figuring out the XML syntax like building ONET.XML. Again Intellisense is much easier

Adding pages

Pages can be added as files to a module; text can be changed to customize the particular provisioning (for example, embed in the text, the site title or instructions for the administrator) then added to the root or a folder in the site.

See method "AddPage" in the attached example.

Adding web parts in pages

If we started with a blank site, the web parts are not incorporated in the pages yet.

So we have the opportunity to insert web parts in the zones we want in our pages. We must know the zone IDs of the page and the order in the zone we want the web parts to go in.

There are few types of web parts; the example uses 2 of them:

  1. WebPart for this type you need the existence of the template to be in the web part gallery of the site collection (activated)
  2. ListViewWebPart this will show an existing list or library with a view.

Controlling Navigation

We also have the opportunity to customize the top and quick launch links. The example shows the publishing navigation because the template has the publishing feature but the same can be done with none publishing only the classes will be from Microsoft.SharePoint.Navigation Namespace rather than publishing.

We can:

  1. Programmatically decide how pages and sub sites will be referenced.
    1. "Global" refers to the top navigation
    2. "Current" refers to the quick launch.
  2. Programmatically remove the headers (Libraries, Lists etc…)
  3. Programmatically reorder the links and add new custom ones.

 

Finding GUIDs of features

I found out from a utility that gives you the name by GUID of feature in CodePlex that you can enumerate the Feature Definitions of a farm like so:

SPFarm oFarm = SPFarm.Local;

foreach (var oFeatureDev in oFarm.FeatureDefinitions)

{

System.Diagnostics.Debug.WriteLine(string.Format("Feature {0} Id= {1} scope {2} "

, oFeatureDev.DisplayName, oFeatureDev.Id ,oFeatureDev.Scope));

 

So you can get a dictionary of name and ID of features that you can use.

You can also use PowerShell

 

 

The attached solution includes 2 types of provisioning projects, guess which of them I preferJ.

Posted in SharePoint | Leave a comment

Restore Strategy – Site Collections, Sites, Libraries, Lists, Documents, and Items

What happens when a user comes to you and says my document is missing or I accidentally deleted my project site?  There are ways to empower the users to help themselves and easy ways to help yourself as administrator to solve user restore issues.
 
Restore Components
Recycle Bins
SharePoint contains two recycle bins, a first level or end user recycle bin and a second level or site collection recycle bin.  Recycle Bins can be turned off in Central Administration, if this occurs then all recycle bins will be immediately emptied.  Recycle bins are turned on by default.
Recycle Bin Settings
Recycle bin settings are managed through Central Administration at the Web Application Level. 
     1.      Navigate to Central Administration, select Manage Web Applications
     2.      Select the web application that you would like to change the settings for, click General Settings.
     3.      Towards the bottom of the window pane, there is a heading called Recycle Bins. Set the number of days that an item should be kept in the recycle bin.
     4.      Also, if quota templates are in place, a percent of live site quota can be set for the second stage recycle bin. Click OK.
End User Recycle Bin
Each site has its’ own End User Recycle Bin, items from these first level bins can also be viewed in the Site Collection Recycle Bin via the End User Recycle Bins view.  This bin will contain deleted Lists, Items, Documents, and Libraries. Items will remain in this recycle bin for the specified amount of days set in CA, the default is 30 days.
Site Collection Recycle Bin
Each site collection has a second level recycle bin (only accessible to site collection administrators) that shows a roll up of all first level recycle bin as well as those items that have been deleted from the first level recycle bin manually or automatically.  This bin will contain objects from the end user recycle bin as well as deleted sites (available in SP1).  Items will remain in this recycle bin for the specified amount of days set in CA, the default is 30 days.  If site quotas are utilized a recycle bin quote percentage can be set.  Recycle bin items do not count towards the standard site quote, the percentage is added in addition to it.  Once quotas are in place items will be deleted based on the days or the recycle bin quota, whichever is met first.
Central Administration Backup and Restore Options
SharePoint 2010 allows an administrator to restore Lists, Sites, and Site Collections from unattached databases.  This means that the database is unattached to the SharePoint Farm, not a detached database in SQL.  Granular backups can also be taken through Central Administration.
 
Restore Scenarios
To restore a deleted document, item, library or list.
     1.      Check the End User Recycle Bin of the site where the object was deleted.  Select the object and click Restore Selection.
     2.      Check the Site Collection Recycle Bin of the Site Collection of the site where the object was deleted.  Select the item and click Restore Selection.
     3.      Restore the object from an unattached database. See restore from unattached database section below for instruction.
      ***An import will explicitly overwrite anything that the export file contains. So, if the file only contains a list and the list is going to be restored to the same location, it will be overwritten. If only items that have been deleted from the list should be restored and items that currently exist should not be overwritten add the following parameter to the import-spweb powershell command. -updateversion ignore
To restore a deleted site.
     1.      Check the Site Collection Recycle Bin of the Site Collection of the site where the site was deleted.
     2.      Restore the site from an unattached database. See restore from unattached database section below for instruction.
     ***This will explicitly overwrite the site at the url listed in the PowerShell –url attribute. The site that is being overwritten must be using the same site template of the site that is in the export file.
To restore a deleted Site Collection
     1.      Restore via PowerShell. 
      ***This method is only valid if attempting to restore the site collection within the specified number of days in the recycle bin settings.  The unattached database method must be used if restoring after the allotted number of days.
         ·        Open a new PowerShell, run as administrator
         ·        Run the PowerShell command below. Replace {PATH} variable with the path where the file should be stored (ex – e:\admin)
         ·        Get-spdeletedsite | out-file {PATH}\getspdeletedsite.txt
         ·        Open the text file created in the above step. Fine the Path that matches the Site collection that has been deleted. The SiteId GUID will be used in the next step.
         ·        Run the PowerShell command below. Replace the {SiteId} variable with the GUID for the Site ID you will be restoring
         ·        Restore-spdeletedsite –identity {SiteId}
         ·        Navigate to the site to make sure it has been restored properly.
***The larger the site the longer it will take to restore. Be Patient!
      2.      Restore the site collection from an unattached database. See restore from unattached database section below for instruction.
***This will explicitly overwrite the site at the url listed in the PowerShell –url attribute. The site that is being overwritten must be using the same site template of the site that is in the export file.
To restore a corrupt item, document, list, library, site, or site collection
      1.      If this is a document or item. First try and revert to a previous version if one is available.  This is NOT an option for lists, libraries, sites, or site collections.
      2.      Restore the object from an unattached database. See restore from unattached database section below for instruction.
***An import will explicitly overwrite anything that the export file contains. So, if the file only contains a list and the list is going to be restored to the same location, it will be overwritten. If only items that have been deleted from the list should be restored and items that currently exist should not be overwritten add the following parameter to the import-spweb powershell command. -updateversion ignore
 
Restore form an unattached database
    1.      Go to CA and View All Site Collections
     2.      Navigate to the Web Application of the Site Collection from which the object was deleted
     3.      Select the name of the Site Collection. Note the Database Name.
     4.      Restore that database .bak file to a new database with a new name on the SharePoint SQL server
     5.      Go to CA, select Backup and Restore, select Recover data from an unattached content database
     6.      Enter the name of the database that the .bak file was restored to.
     7.      Choose Browser Content. Click Next.
     8.      Select the Site Collection, Site (if necessary), and then List (if necessary) that needs to be restored.
     9.      Chose Export site or list.  Click Next.
     10.   Enter a filepath (on the WFE) and file name ending in .cmp, where the export can be stored.
     11.   Select appropriate security and version options. Click Start Export.
     12.   Open a new powershell, run as administrator
     13.   Run the following commands, replace the necessary variables.
               Import-spweb –identity {URL TO RESTORE TO} -path {EXPORT FILE PATH AND NAME}
      ***Exports do not include user alerts or workflows.
Posted in SharePoint | Leave a comment

Removing a broken SharePoint 2010 Feature

Great SharePoint Utility: FeatureAdmin 

 

Like most developers I am constantly trying different things on my local development machines to test different approaches and techniques to resolve a variety of programming requirements (no matter what anyone says there is always room for improvement). And like all of those developers I occasionally try something that does not work so well and I end up breaking my development environment (this is why we test on our machines before deploying code for a client to see!). 

Recently this happened to me with a SharePoint feature, I was testing something (not sure what) but I ended up getting a feature stuck in my farm that was not actually "deployed" anywhere.  I of course found this a month later so all I could remember is this feature was a test of something but I had no clue what.  Since it was not deployed in any scope in SharePoint (Farm, WebApplication, Site, or Web) there way no way in  Central Admin for me to easily uninstall it, the only reason I found it is by running the Get-SPFeature powershell command and I found the feature was there but the Scope column was blank.

So how did I remove it? I’m sure there is a way to do this in powershell but I wanted to see if there was a utility to visually see what features are activated where because if I broke one feature I may have broken others.  I stumbled across a great little tool on CodePlex called  FeatureAdmin, see the screen shot below but in essence you open it up you can choose a scope to see what features are activated.  You can also load a list of all Features installed in the farm and it will flag broken features with an error, you simply highlight the broken feature and remove it.  Solved my problem, if anyone else has any odd Feature issues I highly recommend trying this utility because it can save you a lot of headaches to quickly find a feature problem.

FeatureAdmin.png

Posted in SharePoint | Leave a comment

BI Technical Series: Using Images within PowerView

​Placeholder

Posted in Business Intelligence | Leave a comment

BI Technical Series: Flattening a SSAS Cube Balanced Hierarchy

Suppose we have a balance hierarchy in a SSAS cube that looks as follows:

And you wanted to flatten the hierarchy such that Category, Subcategory and Product appear on rows and the associated measures appear on the columns. The first instinct may be to do the following:

SELECT {[Measures].[Sales Amount]} ON COLUMNS,
CROSSJOIN(CROSSJOIN([Product].[Product Categories].[Category].members,[Product].[Product Categories].[Subcategory].members),[Product Categories].[Category].[Product].members]) ON ROWS
FROM [Adventure Works]

 

However, this typically results in the following error:

Parsing the query …
Query (2, 2) The Product Categories hierarchy is used more than once in the Crossjoin function.
Parsing complete

 

The issue being that you cannot apply a CROSSJOIN to multiple levels from the same hierarchy. There are several methods for accomplishing this. All of them have varying levels of complexity along with associated advantages and disadvantages. I am just going to provide 1 more method for solving the problem. Besides, you can’t have too many ways to solve a problem.

 

To begin the flattening process the leaves option of the DESCENDANTS() function will be used to return the lowest level of the hierarchy. Using the DESCENDANTS() function the highest level of the hierarchy is specified along with the leaves option as the last argument. The associated MDX is:

 

SELECT {[Measures].[Sales Amount]} ON COLUMNS,

DESCENDANTS ([Product].[Product Categories].[Category],,LEAVES) ON ROWS

FROM [Adventure Works]

 

Here is the result:

 

 

Now we have the lowest level of the hierarchy. To retrieve the other levels we can use the following MDX:

WITH MEMBER [Measures].[Subcategory Level] as ANCESTOR([Product].[Product Categories].CURRENTMEMBER,[Product].[Product Categories].[Subcategory]).NAME

    MEMBER [Measures].[Category Level] as ANCESTOR([Product].[Product Categories].CURRENTMEMBER,[Product].[Product Categories].[Category]).NAME

    

SELECT {[Measures].[Subcategory Level],

    [Measures].[Category Level],

    [Measures].[Internet Sales Amount]} ON COLUMNS,

     DESCENDANTS([Product].[Product Categories].[Category],,LEAVES) ON ROWS

FROM [Adventure Works]

 

 

The calculated members [Measures].[Subcategory Level] and [Measures].[Category] level are using the current member which happens to be a leaf member to navigate up the hierarchy using the ANCESTOR() function and the intrinsic NAME member property to return the name of the member at the specified level.

A couple of items to note; the above approach is a bottom-up approach in that the respective parents of a member are being returned starting at the leaf level. Also, if you have direct access to the attributes that make up the hierarchy you can simply use the CROSSJOIN() function because the attribute hierarchies are different but, if you must use the user defined hierarchy, then the issue arises on how to flatten the hierarchy. This approach can also be used to flatten recursive hierarchies.

So, does anyone have a different approach to flattening hierarchies; if so, drop me a line.

 

Ray Johnson | Director – Intelligent Business | ray.johnson@mpspartners.com

MPS Partners, LLC. an SPR Company

http://www.mpspartners.com

 

Posted in Business Intelligence | Leave a comment

BI Technical Series: Flattening a SSAS Cube Balanced Hierarchy

Suppose we have a balance hierarchy in a SSAS cube that looks as follows:

And you wanted to flatten the hierarchy such that Category, Subcategory and Product appear on rows and the associated measures appear on the columns. The first instinct may be to do the following:

SELECT {[Measures].[Sales Amount]} ON COLUMNS,
CROSSJOIN(CROSSJOIN([Product].[Product Categories].[Category].members,[Product].[Product Categories].[Subcategory].members),[Product Categories].[Category].[Product].members]) ON ROWS
FROM [Adventure Works]

 

However, this typically results in the following error:

Parsing the query …
Query (2, 2) The Product Categories hierarchy is used more than once in the Crossjoin function.
Parsing complete

 

The issue being that you cannot apply a CROSSJOIN to multiple levels from the same hierarchy. There are several methods for accomplishing this. All of them have varying levels of complexity along with associated advantages and disadvantages. I am just going to provide 1 more method for solving the problem. Besides, you can’t have too many ways to solve a problem.

 

To begin the flattening process the leaves option of the DESCENDANTS() function will be used to return the lowest level of the hierarchy. Using the DESCENDANTS() function the highest level of the hierarchy is specified along with the leaves option as the last argument. The associated MDX is:

 

SELECT {[Measures].[Sales Amount]} ON COLUMNS,

DESCENDANTS ([Product].[Product Categories].[Category],,LEAVES) ON ROWS

FROM [Adventure Works]

 

Here is the result:

 

 

Now we have the lowest level of the hierarchy. To retrieve the other levels we can use the following MDX:

WITH MEMBER [Measures].[Subcategory Level] as ANCESTOR([Product].[Product Categories].CURRENTMEMBER,[Product].[Product Categories].[Subcategory]).NAME

    MEMBER [Measures].[Category Level] as ANCESTOR([Product].[Product Categories].CURRENTMEMBER,[Product].[Product Categories].[Category]).NAME

    

SELECT {[Measures].[Subcategory Level],

    [Measures].[Category Level],

    [Measures].[Internet Sales Amount]} ON COLUMNS,

     DESCENDANTS([Product].[Product Categories].[Category],,LEAVES) ON ROWS

FROM [Adventure Works]

 

 

The calculated members [Measures].[Subcategory Level] and [Measures].[Category] level are using the current member which happens to be a leaf member to navigate up the hierarchy using the ANCESTOR() function and the intrinsic NAME member property to return the name of the member at the specified level.

A couple of items to note; the above approach is a bottom-up approach in that the respective parents of a member are being returned starting at the leaf level. Also, if you have direct access to the attributes that make up the hierarchy you can simply use the CROSSJOIN() function because the attribute hierarchies are different but, if you must use the user defined hierarchy, then the issue arises on how to flatten the hierarchy. This approach can also be used to flatten recursive hierarchies.

So, does anyone have a different approach to flattening hierarchies; if so, drop me a line.

 

Ray Johnson | Director – Intelligent Business | ray.johnson@mpspartners.com

MPS Partners, LLC. an SPR Company

http://www.mpspartners.com

Posted in Business Intelligence | Leave a comment

BI Technical Series: Flattening a SSAS Cube Balanced Hierarchy

Suppose we have a balance hierarchy in a SSAS cube that looks as follows:


Your first instinct may be to do the following:

SELECT {[Measures].[Sales Amount]} ON COLUMNS,
CROSSJOIN([Product].[Product Categories].[Category].members,[Product].[Product Categories].[Subcategory].members) ON ROWS
FROM [Adventure Works]

 

This typically results in the following error:

Parsing the query …
Query (2, 2) The Product Categories hierarchy is used more than once in the Crossjoin function.
Parsing complete

 

The issue being that you cannot apply a CROSSJOIN to multiple levels from the same hierarchy. There are several methods for accomplishing this. All of them have varying levels of complexity along with associated advantages and disadvantages. I am just going to provide 1 more method for solving the problem. Besides, you can’t have too many ways to solve a problem.

 

To being the flattening process the leaves option of the DESCENDANTS() function will return the lowest level of the hierarchy. Using the DESCENDANTS() function the highest level of the hierarchy is specified along with the leaves option as the last argument. The associated MDX is:

 

SELECT {[Measures].[Sales Amount]} ON COLUMNS,

DESCENDANTS ([Product].[Product Categories].[Category],,LEAVES) ON ROWS

FROM [Adventure Works]

 

Here are the results:

 


Now we have the lowest level of the hierarchy. To retrieve the other levels we can use the following MDX:

WITH MEMBER [Measures].[Subcategory Level] as ANCESTOR([Product].[Product Categories].CURRENTMEMBER,[Product].[Product Categories].[Subcategory]).NAME

    MEMBER [Measures].[Category Level] as ANCESTOR([Product].[Product Categories].CURRENTMEMBER,[Product].[Product Categories].[Category]).NAME

    

SELECT {[Measures].[Subcategory Level],

    [Measures].[Category Level],

    [Measures].[Internet Sales Amount]} ON COLUMNS,

     DESCENDANTS([Product].[Product Categories].[Category],,LEAVES) ON ROWS

FROM [Adventure Works]


 


 

Posted in Integration | Leave a comment

Incorporating SQL 2012 Columnstore Indexes into your data retrieval strategy

A traditional BI architectural practice is to build a data warehouse with a data cube on top of it.   One of the reasons you would do this is that data cubes contain pre aggregated data, thus your reports and queries that use the cube will render much faster than if you were querying directly off of your data warehouse. That being said, there can be infrastructure, support, and resourcing related concerns that need to be addressed if you chose to move your BI strategy in that direction.

If data retrieval performance ranks near the top of your priorities and you don’t yet have a valid business need for data cubes, then there is a simpler way to significantly reduce your data retrieval times with SQL Server 2012 by using Columnstore indexes.  Columnstore indexes can transform the data warehousing experience for users by enabling faster performance for common data warehousing queries such as filtering, aggregating, grouping, and star-join queries.  Columnstore indexes perform exponentially faster than traditional row based indexes.
 
Here are some things to know about Columnstore indexes:
·        The enterprise edition of SQL 2012 is required.
·        The solution is intended to benefit ad-hoc queries and reports that require aggregated data.
·        You can only have one Columnstore index per table, but that can be used in conjunction with many traditional row indexes per table.  The optimizer will chose the best path.
·        Tables with Columnstore indexes can not be updated.
·        Columnstore indexes are best built with columns that have non-unique, repetitive data.
·        More advantage is gained from bigger data with queries that aggregate the data.
·        Don’t use these for single-row queries or for detail data, like reports that display lists.  This is not for ‘SELECT * FROM table’.
·        Know that like data cubes, Columnstore indexes are memory-intensive to build and execute.
·        Not every data type is allowed in a Columnstore index. 
·        Columnstore indexes improve buffer pool usage, I/O, and disk utilization compared to a group of non-clustered indexes.
·        Columnstore indexes reduce the overnight aggregations associated with data cubes
·        Processes chunks of columns in batches, reducing CPU usage
·        Clustered index key required to be part of Columnstore index
 
Keep in mind that implementing Columnstore indexes does not replace all of the features and functionality associated with data cubes, but it can offer an alternative and more simplistic approach to speeding up data retrieval against your data warehouse.

 

Posted in Business Intelligence | Leave a comment

Managing Metadata with Master Data Services – Part 1

This is the first in a series of blog entries that will discuss how to manage metadata as master data using Microsoft’s Master Data Services. In this first entry we discuss metadata as master data provide an Introduction to Master Data Services capabilities and what are its key components.

Meta data is data about data. Organizations employ many methods for managing their metadata (file systems, databases, spreadsheets, enterprise content management applications, etc.). There are also different types of metadata:

  • Technical metadata
    • Line of Business applications
    • Database schemas
    • Development standards and conventions
  • Business metadata
    • Business concepts
    • Business entities
    • Business processes

For both types of aforementioned metadata, related processes change, organizations evolve and technologies come and go. The question is how to manage these changes with respect to organizational metadata.

Typically master data would consist of business entities, their associated attributes and members; for instance, a customer master consisting of a list of customer attributes and customers. But what defines a customer. What is its context and how does it evolve over time. I submit that organizational metadata should be treated as master data and a formal tool and process should be used to manage it.

One such tool is Microsoft’s Master Data Services. Master Data Services provides the following capabilities:

  • Centralized hub for storing authoritative and certified data
  • Supports implementation of business rules and workflows for maintaining data quality
  • Supports hierarchies and attribute level domain constraints
  • Role based security
  • Multiple user interfaces (Web, Excel 2010)
  • Model for batch imports and exports to/from external systems

The following figure defines the basic steps in defining, developing and maintaining our master data services solution. In this post we will only address master data structures as they relate to metadata.

The following data structures are available and need to be defined within Master Data Services:

Models – Models organize the structure of your master data. You can have one or many models. In the case of metadata the model will be a container for concepts. For example, the model would be the metadata model defining the concepts of Business Entity Metadata, Attribute Entity Metadata, etc.

Entities – An entity is a container for the attributes, attribute groups, hierarchies and collections that define a specific concept. There can be as many entities as required to fully define the concept. In the case of metadata there can be an entity defined as follows from a membership perspective:

 

 

Where

Business Entity Metadata – The name of the entity

Name – The entity being defined (Customer, Product, Account, etc.)

Description – Definition of the entity (Customer is an individual or organization that purchases our products)

Owner – The name of the individual or organization responsible the definition of the entity

Attributes – Attributes can be viewed as columns within an entity. In the case of our Metadata model and our entity Business Metadata Entity we would have the following:


Business Entity Metadata

Name

Description

Owner

Customer

An individual or organization that purchases our goods or services

Customer Service

Account

A cost collection point defining cash flow into and out of the organization

Finance

Product

A manufactured good or a service sold to a Customer

Operations

 

Attribute Groups – An Attribute Group provides the ability to manage attributes by grouping them into tabs. From a usability perspective this becomes important when there are a large number of attributes need to be viewed. Attributes can be logically group based on their relationship to one another.

Domain Based Attributes - A domain-based attribute is an attribute with values that are populated by members from another entity. You can think of a domain-based attribute as a constrained list; domain-based attributes prevent users from entering attribute values that are not valid. To select an attribute value, the user must pick from a list. The domain-based attribute can be used in multiple entities.

Once the structures have been built, it is now time to populate them with data. In the next post we will fully define all the metadata entities and discuss their relationships to one another and the types of data that will populate them.

 

 

 

 

Posted in Business Intelligence | Leave a comment
 
View By Author
  • View By Category
View By Date
Part Of SPR COMPANIES
© 2012 SPR Companies. All rights reserved. About | Competencies | Products | Solutions | Clients | Events & Resources | Careers | Site Map | Legal/Privacy