22 04 2013
Get All PerformancePoint Filter Value selections in a Site Collection For the Current User
Here’s some code to get all PerformancePoint filter selections for the current user in a web site.
This is a fairly straightforward operation. First you need a collection of strings, each of which is the URL to a PerformancePoint Filter stored in SharePoint. In this code snippet I use SPSiteDataQuery (in the DiscoverFilterUrls() method). You might want to cache this, though in my implementation where I use this code I’m using the singleton pattern to instantiate this class and to store an in-memory copy of this data.
Once you have this collection of URLs, you need to iterate over them and use the PerformancePoint Monitoring API to get the Filter instance defined at that URL, and call the GetFilterDisplayData method. This will return a DataTable of the filter options. Note the useSavedUserSelections parameter, if I set this to true I will get the saved user selections, otherwise this should return all the options available in the filter. You might also want to do this, just modify the code as needed.
In my code I’m looking for the ‘MemberUniqueName’ column, as I’m dealing primarily with MDX Member Selection Filters in PerformancePoint, and these contain this column. You may have to modify the code in your implementation to extract the appropriate column.
I have a utility method in here which I use when generating the Dictionary of filters and their values, called IsFilterEncodedInSet. In my implementation, my web.config has an AppSetting called ‘ChartParametersEncodedAsSet’, which I define a semi-colon separated list of PerformancePoint Filter Names which are passed in as sets. You can find out another way how to do this that’s either more dynamic or more configurable (like storing in a SharePoint list). The only reason I use this method is to find out if I need to wrap the filter options in curly braces (‘{‘ and ‘}’) or not. This is important as MDX member sets are defined like this, and thus makes this utility class more general to allowing either single MDX member options or sets of MDX members. Note, however, that an MDX set can easily just contain a single member. My requirement needed me to only include the braces for multiple-member sets. If you have no such requirement for this, you can wrap every filter value that is returned in curly braces quite safely, and remove the dependency on the IsFilterEncodedAsSet method, and thus remove the dependency on the web.config AppSetting.
Let me know in the comments if you have more questions about this code snippet or having problems getting it to work.
Have fun!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
namespace MySampleStuff.PerformancePoint { using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Configuration; using System.Data; using Microsoft.PerformancePoint.Scorecards; using Microsoft.PerformancePoint.Scorecards.Store; using Microsoft.SharePoint; /// /// A class that can get filter values from PerformancePoint /// public class FilterClient { /// /// The filter urls /// private List filterUrls; /// /// The filter values internal /// private Dictionary filterValuesInternal; /// /// The site /// private SPSite site; /// /// The web /// private SPWeb web; /// /// Initializes a new instance of the class. /// /// The SharePoint Site which contains the Filters. public FilterClient(SPSite site) { this.site = site; this.web = site.OpenWeb(); this.DiscoverFilterUrls(); } /// /// Gets the PerformancePoint filter values in the given SharePoint Site /// /// A Dictionary of filter names - filter values public Dictionary GetFilterValues() { // return null if not configured if (this.web == null || this.site == null || this.filterUrls == null) return null; //if (this.filterValuesInternal != null) // return this.filterValuesInternal; this.filterValuesInternal = new Dictionary(); SPDataStore bistore = SPDataStore.GlobalDataStore; IBIMonitoringServiceApplicationProxy biservice = BIMonitoringServiceApplicationProxy.Default; foreach (string url in this.filterUrls) { RepositoryLocation filterLoc = new RepositoryLocation("/" + url); Filter filter = bistore.GetFilter(filterLoc); ParameterDefinitionCollection parms = filter.BeginPoints; ParameterDefinition filterParm = null; foreach (ParameterDefinition parm in parms) { // "DisplayValue" filters mean MDX Member filters, StaticList filters are SQL Table filters if (parm.DisplayColumn == "DisplayValue" || parm.ParameterProviderId == "StaticList") filterParm = parm; } if (filterParm == null) continue; DataTable displayData = biservice.GetFilterDisplayData( filterLoc, filterParm, new List(), true, true, null); string selection = string.Empty; bool isMultiple = this.IsFilterEncodedAsSet(filter.Name.Text); foreach (DataRow row in displayData.Rows) { if (displayData.Columns.Contains("MemberUniqueName")) selection += row["MemberUniqueName"].ToString() + ","; else if (displayData.Columns.Contains("MeasureName")) // specifically for Boston MAtrix, may be reused elsewhere { selection = row[0].ToString(); if (!this.filterValuesInternal.ContainsKey(filter.Name.Text + " Caption")) this.filterValuesInternal.Add(filter.Name.Text + " Caption", row["MeasureName"].ToString()); } else selection = row[0].ToString(); // All other 'sql table' type filters } selection = selection.TrimEnd(','); if (isMultiple) selection = "{" + selection + "}"; if (!this.filterValuesInternal.ContainsKey(filter.Name.Text)) this.filterValuesInternal.Add(filter.Name.Text,selection ); } return this.filterValuesInternal; } /// /// Discovers the filter urls. /// private void DiscoverFilterUrls() { if (this.web == null) return; this.filterUrls = new List(); SPSiteDataQuery query = new SPSiteDataQuery(); query.Query = "PerformancePoint Filter"; query.ViewFields = ""; query.Webs = ""; DataTable dt = this.web.GetSiteData(query); foreach (DataRow row in dt.Rows) { // we want the path to the item itself string url = row["FileRef"].ToString(); url = url.Substring(url.IndexOf('#') + 1); // These are site collection relative urls this.filterUrls.Add(url); } } /// /// Determines whether [is filter encoded as set] [the specified filter name]. /// /// Name of the filter. /// /// true if [is filter encoded as set] [the specified filter name]; otherwise, false. /// /// Charts haven't been fully configured - check ChartParametersEncodedAsSet in web.config private bool IsFilterEncodedAsSet(string filterName) { bool isSet = false; string filtersEncodedAsSet = ConfigurationManager.AppSettings["ChartParametersEncodedAsSet"]; if (string.IsNullOrEmpty(filtersEncodedAsSet)) throw new ArgumentNullException("Charts haven't been fully configured - check ChartParametersEncodedAsSet in web.config"); string[] filtersEncodedAsSetArray = filtersEncodedAsSet.Split(';'); foreach (string s in filtersEncodedAsSetArray) if (s == filterName) isSet = true; return isSet; } } } |
SPSite, FileNotFoundException and the Server Object Model in Console Applications and PowerShell Scripts Creating Custom PerformancePoint Reports in C#