PerformancePoint Services フィルターのエディターを作成する
最終更新日: 2011年8月30日
適用対象: SharePoint Server 2010
Microsoft SharePoint Server 2010 の PerformancePoint Services では、ユーザーは、カスタム エディターを使用してカスタム オブジェクトのプロパティを設定できます。カスタム エディターでは、リポジトリ内のカスタム オブジェクトの取得と更新を行うための編集コントロールと機能が提供されます。エディターの要件と機能の詳細については、「カスタム PerformancePoint Services オブジェクトのエディター」を参照してください。
適用先: PerformancePoint Services for SharePoint Server (Enterprise バージョン)
フィルター エディターでは、フィルターの BeginPoints プロパティも初期化する必要があります。このプロパティでは、スコアカード コンシューマーとレポート コンシューマー用のパラメーター値を含む開始ポイントが定義されます。
このトピックの手順と例は、「カスタム オブジェクト サンプル」の SampleFilterEditor クラスに基づいています。エディターはシン Web アプリケーションであり、ユーザーは、これを使用して、フィルターの名前と詳細の変更、および基盤となるデータ ソースの選択ができます。クラスのための完全なコードは、このトピックの「使用例」セクションで提供されています。
注意
サンプル エディターをテンプレートとして使用することをお勧めします。サンプルは、PerformancePoint Services API でオブジェクトを呼び出す方法、(オブジェクトの作成、更新などの) リポジトリ操作のためにヘルパー オブジェクトによる呼び出しを単純化する方法、PerformancePoint Services 開発のためのベスト プラクティスを示します。
フィルター エディターを作成するには、以下の 2 つの基本手順を実行します。
エディター クラスを作成して設定する
編集機能を定義する
カスタム エディターを作成するには、エディター クラスの作成から始めます。
エディター クラスを作成して設定するには
PerformancePoint Services をインストールするか、拡張機能が使用する (手順 3. で示した) DLL をコンピューターにコピーします。詳細については、「開発シナリオで使用される PerformancePoint Services DLL」を参照してください。
Visual Studio で、C# クラス ライブラリを作成します。拡張機能のためのクラス ライブラリを既に作成している場合、新しい C# クラスを追加します。
プロジェクトに、アセンブリ参照として以下の PerformancePoint Services と SharePoint Server 2010 DLL を追加します。
Microsoft.PerformancePoint.Scorecards.Client.dll
Microsoft.PerformancePoint.Scorecards.ServerCommon.dll
Microsoft.PerformancePoint.Scorecards.ServerRendering.dll
Microsoft.PerformancePoint.Scorecards.Store.dll (ヘルパー クラスが使用)
Microsoft.SharePoint.dll (ヘルパー クラスが使用)
サンプル エディターには、System.Web.dll と System.Web.Services.dll へのアセンブリ参照も含まれます。拡張機能の機能によっては、その他のプロジェクト参照が必要になることがあります。
サンプルから以下のクラスをプロジェクトに追加します。エディターは、PerformancePoint Services リポジトリを操作するためにこれらのヘルパークラスを使用します。
DataSourceConsumerHelper.cs
ExtensionRepositoryHelper.cs
FilterRepositoryHelper.cs
IDataSourceConsumer.cs
エディター クラスで、以下の PerformancePoint Services 名前空間のための using ディレクティブを追加します。
Microsoft.PerformancePoint.Scorecards
Microsoft.PerformancePoint.Scorecards.ServerCommon
Microsoft.PerformancePoint.Scorecards.ServerRendering
拡張機能の機能によっては、その他の using ディレクティブが必要になることがあります。
エディターの実装をサポートする基底クラスから継承します。サンプルのフィルター エディターは Web アプリケーションなので、Page クラスから継承されます。他の実装では、UserControl クラス、WebPart クラスなどの基底クラスから派生できます。
エディター クラスを作成して設定した後で、エディターの機能を定義する必要があります。
編集機能を定義するには
ユーザーが参照または編集するプロパティを公開するコントロールを定義します。サンプルのフィルター エディターは、ユーザー インターフェイス コンポーネント (ASPX ページ) に定義された Web サーバー コントロールの変数を最初に宣言します。また、サンプル エディターは、変更をユーザーが送信できるようにするボタン コントロールも定義します。次に、エディターは CreateChildControls() メソッドを呼び出して、コントロールをページで使用できるようにします。
注意
エディターは、ユーザー インターフェイスとは別のプログラミング ロジックを定義します。エディターのユーザー インターフェイス コンポーネントを作成するための説明は、この文書の範囲外となります。
AllowUnsafeUpdates プロパティを true に設定します。これにより、フォーム POST 操作を使用しなくても、フィルター エディターでデータをリポジトリに書き込むことができます。
サンプルのフィルター エディターでは、手順 2. ~ 6. が Page_Load メソッドで実行されます。変数とコントロールの初期化と検証、コントロールへのデータの挿入、カスタム フィルターとヘルパー オブジェクトの状態情報の保存にも、Page_Load が使用されます。
クエリ文字列からパラメーターを取得し、それらを以下のコード例で示すローカル変数のための値として設定します。
// The URL of the site collection that contains the PerformancePoint Services repository. string server = Request.QueryString[ClickOnceLaunchKeys.SiteCollectionUrl]; // The location of the filter in the repository. string itemLocation = Request.QueryString[ClickOnceLaunchKeys.ItemLocation]; // The operation to perform: OpenItem or CreateItem. string action = Request.QueryString[ClickOnceLaunchKeys.LaunchOperation];
' The URL of the site collection that contains the PerformancePoint Services repository. Dim server As String = Request.QueryString(ClickOnceLaunchKeys.SiteCollectionUrl) ' The location of the filter in the repository. Dim itemLocation As String = Request.QueryString(ClickOnceLaunchKeys.ItemLocation) ' The operation to perform: OpenItem or CreateItem. Dim action As String = Request.QueryString(ClickOnceLaunchKeys.LaunchOperation)
クエリ文字列パラメーターの詳細については、「カスタム PerformancePoint Services オブジェクトのエディター」を参照してください。
以下のコード例で示すように、リポジトリに呼び出しをするための FilterRepositoryHelper オブジェクトを取得します。
filterRepositoryHelper = new FilterRepositoryHelper();
filterRepositoryHelper = New FilterRepositoryHelper()
以下のコード例のように、クエリ文字列パラメーターに基づいてフィルターの場所を設定します。
RepositoryLocation repositoryFilterLocation = RepositoryLocation.CreateFromUriString(itemLocation);
Dim repositoryFilterLocation As RepositoryLocation = RepositoryLocation.CreateFromUriString(itemLocation)
以下のコード例のように、クエリ文字列から実行する操作 (OpenItem または CreateItem) を取得し、カスタム フィルターを取得または作成します。
if (ClickOnceLaunchValues.OpenItem.Equals(action, StringComparison.OrdinalIgnoreCase)) { // Use the repository-helper object to retrieve the filter. filter = filterRepositoryHelper.Get(repositoryFilterLocation); if (filter == null) { displayError("Could not retrieve the filter for editing."); return; } } else if (ClickOnceLaunchValues.CreateItem.Equals(action, StringComparison.OrdinalIgnoreCase)) { filter = new Filter { RendererClassName = typeof(MultiSelectTreeViewControl).AssemblyQualifiedName, SubTypeId = "SampleFilter" }; }
If ClickOnceLaunchValues.OpenItem.Equals(action, StringComparison.OrdinalIgnoreCase) Then ' Use the repository-helper object to retrieve the filter. filter = filterRepositoryHelper.Get(repositoryFilterLocation) If filter Is Nothing Then displayError("Could not retrieve the filter for editing.") Return End If ElseIf ClickOnceLaunchValues.CreateItem.Equals(action, StringComparison.OrdinalIgnoreCase) Then filter = New Filter With {.RendererClassName = GetType(MultiSelectTreeViewControl).AssemblyQualifiedName, .SubTypeId = "SampleFilter"} End If
カスタム フィルターを取得するには、FilterRepositoryHelper.Get メソッドを使用します。
カスタム フィルターを作成するには、Filter() コンストラクターを使用して、フィルターの Name、RendererClassName、および SubTypeId プロパティを定義します。SubTypeId は、フィルターの一意の識別子であり、PerformancePoint Services web.config ファイルに指定された、カスタムフィルター用の subType 属性に一致する必要があります。RendererClassName は、レンダラーの Web サーバー コントロールを定義するクラスの完全修飾名です。これをエディターに定義しない場合、この値は、web.config ファイルに指定されたレンダラー クラスに既定設定されます。
注意
既定では、ユーザーは PerformancePoint ダッシュボード デザイナーからのみカスタム オブジェクトを作成できます。ユーザーにダッシュボード デザイナーの外でカスタム オブジェクトを作成できるようにするには、リポジトリのコンテンツ タイプから CreateItem 要求をエディターに送るメニュー項目を追加する必要があります。詳細については、「カスタム PerformancePoint Services オブジェクトのエディター」を参照してください。
フィルターの基盤となるデータ ソースをリポジトリから取得します。サンプル フィルター エディターは、FilterRepositoryHelper.DataSourceHelper プロパティを使用して、DataSourceConsumerHelper.GetDataSource メソッドを呼び出します。このメソッドは、リポジトリ内の場所によってデータ ソースを取得するために使用されます。この例を次のコード例に示します。
if (!string.IsNullOrEmpty(filter.DataSourceLocation.ItemUrl)) { RepositoryLocation repositoryDatasourceLocation = RepositoryLocation.CreateFromUriString(filter.DataSourceLocation.ItemUrl); datasource = filterRepositoryHelper.DataSourceHelper.GetDataSource(repositoryDatasourceLocation); }
If Not String.IsNullOrEmpty(filter.DataSourceLocation.ItemUrl) Then Dim repositoryDatasourceLocation As RepositoryLocation = RepositoryLocation.CreateFromUriString(filter.DataSourceLocation.ItemUrl) datasource = filterRepositoryHelper.DataSourceHelper.GetDataSource(repositoryDatasourceLocation) End If
ユーザーがフィルターのデータ ソースを選択できるようにするには、PerformancePoint Services データ ソースを使用して選択コントロールにデータを挿入します。サンプル フィルター エディター内の PopulateDataSourceDropDown メソッドは、DataSourceConsumerHelper.GetDataSourcesBySourceNames メソッドを呼び出して、データ ソースを取得します。これは、次のコード例で示されます。
// The parameter contains the default server-relative URL to the PerformancePoint Data Connections Library. // Edit this value if you are not using the default path. A leading forward slash may not be needed. ICollection dataSourceCollection = filterRepositoryHelper.DataSourceHelper.GetDataSourcesBySourceNames ("/BICenter/Data%20Connections%20for%20PerformancePoint/", new[] { "WSTabularDataSource", DataSourceNames.ExcelWorkbook });
' The parameter contains the default server-relative URL to the PerformancePoint Data Connections Library. ' Edit this value if you are not using the default path. A leading forward slash may not be needed. Dim dataSourceCollection As ICollection = filterRepositoryHelper.DataSourceHelper.GetDataSourcesBySourceNames ("("/BICenter/Data%20Connections%20for%20PerformancePoint/", { "WSTabularDataSource", DataSourceNames.ExcelWorkbook })
サンプル フィルター エディターでは 2 種類のデータ ソースのみが取得されますが、このメソッドを変更して、他のデータ ソースの種類をサポートしたり、取得するデータ ソースの種類をユーザーに要求したりできます。特定の種類のネイティブ データ ソースを参照するには、DataSourceNames クラスのフィールドを返す SourceName プロパティを使用します。カスタム データ ソースを参照するには、データ ソースの SubTypeId プロパティを使用します。この値は、PerformancePoint Services web.config ファイルに登録された、データ ソース拡張機能の subType 属性と同じです。
このメソッドを変更する場合、サンプル フィルターのデータ プロバイダー内の GetDisplayDataInternal メソッドに、対応する変更を加える必要があります。
BeginPoints プロパティで表される、フィルターの開始ポイントを定義します。これは、フィルター値のソースを定義します。また、フィルターでデータをスコアカードおよびレポートに送信できるようにするには、これが必要です。
ParameterDefinition オブジェクトを作成します。BeginPoints は、ParameterDefinition オブジェクトのみを含む ParameterDefinitionCollection オブジェクトを返します。
フィルターのデータ プロバイダーを指定するには、ParameterProviderId プロパティを、データ プロバイダーの一意の識別子に設定します。この値は、データ プロバイダーの GetId() メソッドから返される値に一致する必要があります。
フィルター値のキー識別子のソースを指定するには、KeyColumn プロパティを、キー識別子を含む表示データ テーブル内の列に設定します。サンプル フィルター エディターでは、このプロパティは、"Symbol" 列として定義されています。
フィルター コントロールの表示値のソースを指定するには、DisplayColumn プロパティを、表示値を含む表示データ テーブル内の列に設定します。サンプル フィルター エディターでは、このプロパティは、"Symbol" 列として定義されています。
注意
表示データ テーブルは、DisplayValues プロパティによって返されます。また、表示データ デーブルは、フィルター データ プロバイダーが GetDisplayDataInternal メソッドを呼び出すときに初期化されます。データ テーブルに他の列が含まれる場合、他の列マッピングを定義して、追加の機能を提供できます。
if (0 == filter.BeginPoints.Count) { ParameterDefinition paramDef = new ParameterDefinition(); // Reference the data provider. paramDef.ParameterProviderId = "SampleFilterDataProvider"; paramDef.DefaultPostFormula = string.Empty; // Specify the column that contains the key identifiers and the column // that contains the display values. The sample uses the same column // for both purposes. // These values must match the structure of the data table that is // returned by the ParameterDefinition.DisplayValues property. paramDef.KeyColumn = "Symbol"; paramDef.DisplayColumn = "Symbol"; // You can use this property to store custom information for this filter. paramDef.CustomDefinition = string.Empty; filter.BeginPoints.Add(paramDef); }
If 0 = filter.BeginPoints.Count Then Dim paramDef As New ParameterDefinition() ' Reference the data provider. paramDef.ParameterProviderId = "SampleFilterDataProvider" paramDef.DefaultPostFormula = String.Empty ' Specify the column that contains the key identifiers and the column ' that contains the display values. The sample uses the same column ' for both purposes. ' These values must match the structure of the data table that is ' returned by the ParameterDefinition.DisplayValues property. paramDef.KeyColumn = "Symbol" paramDef.DisplayColumn = "Symbol" ' You can use this property to store custom information for this filter. paramDef.CustomDefinition = String.Empty filter.BeginPoints.Add(paramDef) End If
サンプル エディターでは、その開始ポイントが VerifyFilter メソッドに定義されています。また、VerifyFilter を使用して、必要なプロパティが設定されていることが検証され、選択モード (オプションのプロパティ) が定義されています。
フィルターのクエリを実行し、データ ソースからデータを取得して、フィルターを初期化します。サンプル フィルター エディター内の buttonOK_Click メソッドが FilterRepositoryHelper.GetParameterDisplayData メソッドを呼び出して、フィルターを初期化します。
注意
エディターは、フィルター オブジェクトを更新する前に、FilterRepositoryHelper.GetParameterDisplayData を 1 回以上呼び出す必要があります。
ユーザー定義の変更を使用してフィルターを更新します。サンプル フィルター エディター内の buttonOK_Click メソッドは、FilterRepositoryHelper.Update メソッドを呼び出して、リポジトリ内にあるフィルターの Name、Description、および DataSourceLocation プロパティを更新します。また、buttonOK_Click を使用して、コントロールのコンテンツを検証し、カスタム フィルターとヘルパー オブジェクトの状態情報を取得します。
注意
ユーザーは、カスタム オブジェクトの Name、Description、および Owner ([責任者]) プロパティを設定して、ダッシュボード デザイナーおよび PerformancePoint Services リポジトリからカスタム オブジェクトを直接削除することができます。
次の手順: フィルター エディター (必要な場合は、そのユーザー インターフェイスも含む) とデータ プロバイダーを作成した後、「[方法] PerformancePoint Services の拡張機能を手動で登録する」に説明されているとおりに拡張機能を展開します。フィルター拡張機能のサンプルをインストールおよび設定する方法の詳細については、「コード サンプル: カスタム レポート、フィルター、および表形式データ ソース オブジェクト」の「サンプルのレポート、フィルター、およびデータ ソース オブジェクトのインストール」セクションを参照してください。
例
以下のコード例は、リポジトリ内のカスタム フィルターの作成、取得、および更新を行い、ASPX ページに定義されたコントロールのプログラミング ロジックを提供します。
注意
このコード例をコンパイルする前に、「エディター クラスを作成して設定するには」で説明されているとおりに開発環境を設定する必要があります。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.PerformancePoint.Scorecards;
using Microsoft.PerformancePoint.Scorecards.ServerCommon;
using Microsoft.PerformancePoint.Scorecards.ServerRendering;
namespace Microsoft.PerformancePoint.SDK.Samples.SampleFilter
{
// Represents the class that defines the sample filter editor.
public class SampleFilterEditor : Page
{
// Declare private variables for the ASP.NET controls defined in the user interface.
// The sample's user interface is an ASPX page that defines the controls in HTML.
private TextBox textboxName;
private TextBox textboxDescription;
private Label labelErrorMessage;
private DropDownList dropdownlistDataSource;
private Button buttonOK;
private ListBox listboxStocks;
// Make the controls available to this class.
protected override void CreateChildControls()
{
base.CreateChildControls();
if (null == textboxName)
textboxName = FindControl("textboxName") as TextBox;
if (null == textboxDescription)
textboxDescription = FindControl("textboxDescription") as TextBox;
if (null == dropdownlistDataSource)
dropdownlistDataSource = FindControl("dropdownlistDataSource") as DropDownList;
if (null == labelErrorMessage)
labelErrorMessage = FindControl("labelErrorMessage") as Label;
if (null==buttonOK)
buttonOK = FindControl("buttonOK") as Button;
if (null==listboxStocks)
listboxStocks = FindControl("listboxStocks") as ListBox;
}
// Handles the Load event of the Page control.
// Methods that use a control variable should call the Control.EnsureChildControls
// method before accessing the variable for the first time.
protected void Page_Load(object sender, EventArgs e)
{
// Required to enable custom report and filter editors to
// write data to the repository.
ServerUtils.AllowUnsafeUpdates = true;
// Initialize controls the first time the page loads only.
if (!IsPostBack)
{
EnsureChildControls();
FilterRepositoryHelper filterRepositoryHelper = null;
try
{
// Get information from the query string parameters.
string server = Request.QueryString[ClickOnceLaunchKeys.SiteCollectionUrl];
string itemLocation = Request.QueryString[ClickOnceLaunchKeys.ItemLocation];
string action = Request.QueryString[ClickOnceLaunchKeys.LaunchOperation];
// Validate the query string parameters.
if (string.IsNullOrEmpty(server) ||
string.IsNullOrEmpty(itemLocation) ||
string.IsNullOrEmpty(action))
{
displayError("Invalid URL.");
return;
}
// Retrieve the repository-helper object.
filterRepositoryHelper =
new FilterRepositoryHelper();
// Set the filter location.
RepositoryLocation repositoryFilterLocation = RepositoryLocation.CreateFromUriString(itemLocation);
Filter filter;
DataSource datasource = null;
// Retrieve or create the filter object, depending on the operation
// passed in the query string (OpenItem or CreateItem).
if (ClickOnceLaunchValues.OpenItem.Equals(action, StringComparison.OrdinalIgnoreCase))
{
// Retrieve the filter object by using the repository-helper object.
filter = filterRepositoryHelper.Get(repositoryFilterLocation);
if (filter == null)
{
displayError("Could not retrieve the filter for editing.");
return;
}
}
else if (ClickOnceLaunchValues.CreateItem.Equals(action, StringComparison.OrdinalIgnoreCase))
{
// Create a filter.
// CreateItem requests can be sent from a SharePoint list, but
// you must create a custom menu item to send the request.
// Dashboard Designer can send edit requests only.
filter = new Filter
{
// Specify the class that defines the renderer
// Web server control. The sample filter uses a native
// PerformancePoint Services renderer.
// Defaults to the value specified in the web.config file
RendererClassName = typeof(MultiSelectTreeViewControl).AssemblyQualifiedName,
// Specify the unique identifier for the filter.
// The SubTypeId property must match the
// subType attribute in the web.config file.
SubTypeId = "SampleFilter"
};
}
else
{
displayError("Invalid Action.");
return;
}
VerifyFilter(filter);
// Retrieve filter's underlying data source.
if (!string.IsNullOrEmpty(filter.DataSourceLocation.ItemUrl))
{
RepositoryLocation repositoryDatasourceLocation =
RepositoryLocation.CreateFromUriString(filter.DataSourceLocation.ItemUrl);
datasource =
// Gets a PerformancePoint Services data source by using the
// DataSourceHelper property to call the
// DataSourceConsumerHelper.GetDataSource method.
filterRepositoryHelper.DataSourceHelper.GetDataSource(repositoryDatasourceLocation);
}
// Save the original filter and helper objects across page postbacks.
ViewState["action"] = action;
ViewState["filter"] = filter;
ViewState["filterrepositoryhelper"] = filterRepositoryHelper;
ViewState["itemlocation"] = itemLocation;
// Populate the child controls.
textboxName.Text = filter.Name.ToString();
textboxDescription.Text = filter.Description.ToString();
// Populate the dropdownlistDataSource control with data sources of specific
// types from the PerformancePoint Services repository.
// This method looks up the passed data source in the data sources
// that are registered in the web.config file.
// Although the sample retrieves data sources of two specific types,
// you can modify it to prompt the user for a data source type.
PopulateDataSourceDropDown(datasource);
// Call the SelectedIndexChanged event directly to populate the
// listbox control with preview data.
dropdownlistDataSource_SelectedIndexChanged(null, null);
}
catch (Exception ex)
{
displayError("An error has occurred. Please contact your administrator for more information.");
if (filterRepositoryHelper != null)
{
// Add the exception detail to the server event log.
filterRepositoryHelper.HandleException(ex);
}
}
}
}
// Handles the SelectedIndexChanged event of the dropdownlistDataSource control.
protected void dropdownlistDataSource_SelectedIndexChanged(object sender, EventArgs e)
{
EnsureChildControls();
// Check if a valid data source is selected.
if (null != dropdownlistDataSource.SelectedItem &&
!string.IsNullOrEmpty(dropdownlistDataSource.SelectedItem.Text))
{
// Retrieve the data source object.
FilterRepositoryHelper filterRepositoryHelper =
(FilterRepositoryHelper)ViewState["filterrepositoryhelper"];
string selectedDataSourceItemUrl = dropdownlistDataSource.SelectedItem.Value;
RepositoryLocation repositoryDatasourceLocation =
RepositoryLocation.CreateFromUriString(selectedDataSourceItemUrl);
DataSource datasource = filterRepositoryHelper.DataSourceHelper.GetDataSource(repositoryDatasourceLocation);
ViewState["datasource"] = datasource;
// Populate the listboxStocks control with the preview data for the selected
// data source.
PopulateListBoxData(datasource);
}
else
{
ClearStocksListBox();
}
}
// Clears the listboxStocks control.
// The sample filter works with a Web service that provides stock information.
private void ClearStocksListBox()
{
listboxStocks.DataSource = null;
listboxStocks.DataBind();
listboxStocks.Items.Clear();
}
// Handles the Click event of the buttonOK control.
protected void buttonOK_Click(object sender, EventArgs e)
{
EnsureChildControls();
// Verify that the controls contain values.
if (string.IsNullOrEmpty(textboxName.Text))
{
labelErrorMessage.Text = "A filter name is required.";
return;
}
if (dropdownlistDataSource.SelectedIndex == 0)
{
labelErrorMessage.Text = "A data source is required.";
return;
}
// Clear any pre-existing error message.
labelErrorMessage.Text = string.Empty;
// Retrieve the filter, data source, and helper objects from view state.
string action = (string)ViewState["action"];
string itemLocation = (string) ViewState["itemlocation"];
Filter filter = (Filter)ViewState["filter"];
DataSource datasource = (DataSource)ViewState["datasource"];
FilterRepositoryHelper filterRepositoryHelper = (FilterRepositoryHelper)ViewState["filterrepositoryhelper"];
// Update the filter object with form changes.
filter.Name.Text = textboxName.Text;
filter.Description.Text = textboxDescription.Text;
filter.DataSourceLocation = datasource.Location;
foreach (ParameterDefinition parameterDefinition in filter.BeginPoints)
{
parameterDefinition.DisplayName = filter.Name.Text;
}
// Initialize the filter. This method runs the filter's query and retrieves preview data.
filterRepositoryHelper.GetParameterDisplayData(ref filter);
// Save the filter object to the PerformancePoint Services repository.
try
{
filter.Validate();
if (ClickOnceLaunchValues.CreateItem.Equals(action,StringComparison.OrdinalIgnoreCase))
{
Filter newFilter = filterRepositoryHelper.Create(
string.IsNullOrEmpty(filter.Location.ItemUrl) ? itemLocation : filter.Location.ItemUrl, filter);
ViewState["filter"] = newFilter;
ViewState["action"] = ClickOnceLaunchValues.OpenItem;
}
else
{
filterRepositoryHelper.Update(filter);
}
}
catch (Exception ex)
{
displayError("An error has occurred. Please contact your administrator for more information.");
if (filterRepositoryHelper != null)
{
// Add the exception detail to the server event log.
filterRepositoryHelper.HandleException(ex);
}
}
}
// Displays the error string in the labelErrorMessage label.
void displayError(string msg)
{
EnsureChildControls();
labelErrorMessage.Text = msg;
// Disable the OK button because the page is in an error state.
buttonOK.Enabled = false;
return;
}
// Verifies that the properties for the filter object are set.
static void VerifyFilter(Filter filter)
{
if (null != filter)
{
// Verify that all required properties are set.
if (string.IsNullOrEmpty(filter.SubTypeId))
{
// This value must match the subType attribute specified
// in the web.config file.
filter.SubTypeId = "SampleFilter";
}
if (string.IsNullOrEmpty(filter.RendererClassName))
{
filter.RendererClassName = typeof (MultiSelectTreeViewControl).AssemblyQualifiedName;
}
// Define the BeginPoints property so the filter can send a parameter value to
// scorecards and reports.
// The value must be from the KeyColumn of the display
// DataTable object, which is defined in the data provider. The data table is
// returned by the FilterRepositoryHelper.GetParameterDisplayData method.
// A filter has one beginpoint only, and it is represented by a
// ParameterDefinition object. The ParameterDefinition object defines how
// the filter accesses the data.
if (0 == filter.BeginPoints.Count)
{
ParameterDefinition paramDef = new ParameterDefinition
{
// This value must match the value returned
// by the data provider's GetId method.
ParameterProviderId = "SampleFilterDataProvider",
// Reference the data provider.
DefaultPostFormula = string.Empty,
// Specify the column that contains
// the key identifiers and the column
// that contains the display values.
// The sample uses the same column
// for both purposes.
// These values must match the structure
// of the data table that is returned
// by the ParameterDefinition.DisplayValues property.
KeyColumn = "Symbol",
DisplayColumn = "Symbol",
// You can use this property to store
// extra information for this filter.
CustomDefinition = string.Empty
};
filter.BeginPoints.Add(paramDef);
}
// Set optional properties. The renderer can return multiple values.
filter.SelectionMode = FilterSelectionMode.MultiSelect;
}
}
// Populates the dropdownlistDataSource control.
void PopulateDataSourceDropDown(DataSource filterDataSource)
{
EnsureChildControls();
FilterRepositoryHelper filterRepositoryHelper =
(FilterRepositoryHelper)ViewState["filterrepositoryhelper"];
// Retrieve data sources from the repository by using the DataSourceHelper
// property to call the DataSourceConsumerHelper object.
// If you modify the types of data source to retrieve, you must make the corresponding
// change in the filter's data provider.
// The parameter contains the default server-relative URL to the PerformancePoint Data Connections Library.
// Edit this value if you are not using the default path. A leading forward slash may not be needed.
ICollection dataSourceCollection = filterRepositoryHelper.DataSourceHelper.GetDataSourcesBySourceNames("/BICenter/Data%20Connections%20for%20PerformancePoint/",
new[] { "WSTabularDataSource", DataSourceNames.ExcelWorkbook });
if (null == dataSourceCollection)
{
displayError("No available data sources were found.");
return;
}
// Create a list of name/value pairs for the dropdownlistDataSource control.
var dataSources = new List<KeyValuePair<string, string>>();
int selectedIndex = 0;
int i = 1;
dataSources.Add(new KeyValuePair<string, string>(string.Empty, string.Empty));
foreach (DataSource ds in dataSourceCollection)
{
dataSources.Add(new KeyValuePair<string, string>(ds.Name.Text, ds.Location.ItemUrl));
// Check if the entry is the originally selected data source.
if ((filterDataSource != null) &&
(string.Compare(ds.Name.Text, filterDataSource.Name.Text) == 0))
{
selectedIndex = i;
}
++i;
}
dropdownlistDataSource.DataSource = dataSources;
dropdownlistDataSource.DataTextField = "Key";
dropdownlistDataSource.DataValueField = "Value";
dropdownlistDataSource.DataBind();
dropdownlistDataSource.SelectedIndex = selectedIndex;
}
// Populate the list box data.
void PopulateListBoxData(DataSource datasource)
{
EnsureChildControls();
ClearStocksListBox();
FilterRepositoryHelper filterRepositoryHelper =
(FilterRepositoryHelper)ViewState["filterrepositoryhelper"];
// Retrieve the first 100 rows of the preview data from the data source
DataSet dataSet = filterRepositoryHelper.DataSourceHelper.GetDataSet(100, datasource);
if (null != dataSet && null != dataSet.Tables[0])
{
listboxStocks.DataTextField = "Symbol";
listboxStocks.DataValueField = "Value";
listboxStocks.DataSource = dataSet.Tables[0];
listboxStocks.DataBind();
}
}
}
}
'INSTANT VB NOTE: This code snippet uses implicit typing. You will need to set 'Option Infer On' in the VB file or set 'Option Infer' at the project level:
Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Data
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports Microsoft.PerformancePoint.Scorecards
Imports Microsoft.PerformancePoint.Scorecards.ServerCommon
Imports Microsoft.PerformancePoint.Scorecards.ServerRendering
Namespace Microsoft.PerformancePoint.SDK.Samples.SampleFilter
' Represents the class that defines the sample filter editor.
Public Class SampleFilterEditor
Inherits Page
' Declare private variables for the ASP.NET controls defined in the user interface.
' The sample's user interface is an ASPX page that defines the controls in HTML.
Private textboxName As TextBox
Private textboxDescription As TextBox
Private labelErrorMessage As Label
Private dropdownlistDataSource As DropDownList
Private buttonOK As Button
Private listboxStocks As ListBox
' Make the controls available to this class.
Protected Overrides Sub CreateChildControls()
MyBase.CreateChildControls()
If Nothing Is textboxName Then
textboxName = TryCast(FindControl("textboxName"), TextBox)
End If
If Nothing Is textboxDescription Then
textboxDescription = TryCast(FindControl("textboxDescription"), TextBox)
End If
If Nothing Is dropdownlistDataSource Then
dropdownlistDataSource = TryCast(FindControl("dropdownlistDataSource"), DropDownList)
End If
If Nothing Is labelErrorMessage Then
labelErrorMessage = TryCast(FindControl("labelErrorMessage"), Label)
End If
If Nothing Is buttonOK Then
buttonOK = TryCast(FindControl("buttonOK"), Button)
End If
If Nothing Is listboxStocks Then
listboxStocks = TryCast(FindControl("listboxStocks"), ListBox)
End If
End Sub
' Handles the Load event of the Page control.
' Methods that use a control variable should call the Control.EnsureChildControls
' method before accessing the variable for the first time.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
' Required to enable custom report and filter editors to
' write data to the repository.
ServerUtils.AllowUnsafeUpdates = True
' Initialize controls the first time the page loads only.
If Not IsPostBack Then
EnsureChildControls()
Dim filterRepositoryHelper As FilterRepositoryHelper = Nothing
Try
' Get information from the query string parameters.
Dim server As String = Request.QueryString(ClickOnceLaunchKeys.SiteCollectionUrl)
Dim itemLocation As String = Request.QueryString(ClickOnceLaunchKeys.ItemLocation)
Dim action As String = Request.QueryString(ClickOnceLaunchKeys.LaunchOperation)
' Validate the query string parameters.
If String.IsNullOrEmpty(server) OrElse String.IsNullOrEmpty(itemLocation) OrElse String.IsNullOrEmpty(action) Then
displayError("Invalid URL.")
Return
End If
' Retrieve the repository-helper object.
filterRepositoryHelper = New FilterRepositoryHelper()
' Set the filter location.
Dim repositoryFilterLocation As RepositoryLocation = RepositoryLocation.CreateFromUriString(itemLocation)
Dim filter As Filter
Dim datasource As DataSource = Nothing
' Retrieve or create the filter object, depending on the operation
' passed in the query string (OpenItem or CreateItem).
If ClickOnceLaunchValues.OpenItem.Equals(action, StringComparison.OrdinalIgnoreCase) Then
' Retrieve the filter object by using the repository-helper object.
filter = filterRepositoryHelper.Get(repositoryFilterLocation)
If filter Is Nothing Then
displayError("Could not retrieve the filter for editing.")
Return
End If
ElseIf ClickOnceLaunchValues.CreateItem.Equals(action, StringComparison.OrdinalIgnoreCase) Then
' Create a filter.
' CreateItem requests can be sent from a SharePoint list, but
' you must create a custom menu item to send the request.
' Dashboard Designer can send edit requests only.
filter = New Filter With {.RendererClassName = GetType(MultiSelectTreeViewControl).AssemblyQualifiedName, .SubTypeId = "SampleFilter"}
' Specify the class that defines the renderer
' Web server control. The sample filter uses a native
' PerformancePoint Services renderer.
' Defaults to the value specified in the web.config file
' Specify the unique identifier for the filter.
' The SubTypeId property must match the
' subType attribute in the web.config file.
Else
displayError("Invalid Action.")
Return
End If
VerifyFilter(filter)
' Retrieve filter's underlying data source.
If Not String.IsNullOrEmpty(filter.DataSourceLocation.ItemUrl) Then
Dim repositoryDatasourceLocation As RepositoryLocation = RepositoryLocation.CreateFromUriString(filter.DataSourceLocation.ItemUrl)
' Gets a PerformancePoint Services data source by using the
' DataSourceHelper property to call the
' DataSourceConsumerHelper.GetDataSource method.
datasource = filterRepositoryHelper.DataSourceHelper.GetDataSource(repositoryDatasourceLocation)
End If
' Save the original filter and helper objects across page postbacks.
ViewState("action") = action
ViewState("filter") = filter
ViewState("filterrepositoryhelper") = filterRepositoryHelper
ViewState("itemlocation") = itemLocation
' Populate the child controls.
textboxName.Text = filter.Name.ToString()
textboxDescription.Text = filter.Description.ToString()
' Populate the dropdownlistDataSource control with data sources of specific
' types from the PerformancePoint Services repository.
' This method looks up the passed data source in the data sources
' that are registered in the web.config file.
' Although the sample retrieves data sources of two specific types,
' you can modify it to prompt the user for a data source type.
PopulateDataSourceDropDown(datasource)
' Call the SelectedIndexChanged event directly to populate the
' listbox control with preview data.
dropdownlistDataSource_SelectedIndexChanged(Nothing, Nothing)
Catch ex As Exception
displayError("An error has occurred. Please contact your administrator for more information.")
If filterRepositoryHelper IsNot Nothing Then
' Add the exception detail to the server event log.
filterRepositoryHelper.HandleException(ex)
End If
End Try
End If
End Sub
' Handles the SelectedIndexChanged event of the dropdownlistDataSource control.
Protected Sub dropdownlistDataSource_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
EnsureChildControls()
' Check if a valid data source is selected.
If Nothing IsNot dropdownlistDataSource.SelectedItem AndAlso (Not String.IsNullOrEmpty(dropdownlistDataSource.SelectedItem.Text)) Then
' Retrieve the data source object.
Dim filterRepositoryHelper As FilterRepositoryHelper = CType(ViewState("filterrepositoryhelper"), FilterRepositoryHelper)
Dim selectedDataSourceItemUrl As String = dropdownlistDataSource.SelectedItem.Value
Dim repositoryDatasourceLocation As RepositoryLocation = RepositoryLocation.CreateFromUriString(selectedDataSourceItemUrl)
Dim datasource As DataSource = filterRepositoryHelper.DataSourceHelper.GetDataSource(repositoryDatasourceLocation)
ViewState("datasource") = datasource
' Populate the listboxStocks control with the preview data for the selected
' data source.
PopulateListBoxData(datasource)
Else
ClearStocksListBox()
End If
End Sub
' Clears the listboxStocks control.
' The sample filter works with a Web service that provides stock information.
Private Sub ClearStocksListBox()
listboxStocks.DataSource = Nothing
listboxStocks.DataBind()
listboxStocks.Items.Clear()
End Sub
' Handles the Click event of the buttonOK control.
Protected Sub buttonOK_Click(ByVal sender As Object, ByVal e As EventArgs)
EnsureChildControls()
' Verify that the controls contain values.
If String.IsNullOrEmpty(textboxName.Text) Then
labelErrorMessage.Text = "A filter name is required."
Return
End If
If dropdownlistDataSource.SelectedIndex = 0 Then
labelErrorMessage.Text = "A data source is required."
Return
End If
' Clear any pre-existing error message.
labelErrorMessage.Text = String.Empty
' Retrieve the filter, data source, and helper objects from view state.
Dim action As String = CStr(ViewState("action"))
Dim itemLocation As String = CStr(ViewState("itemlocation"))
Dim filter As Filter = CType(ViewState("filter"), Filter)
Dim datasource As DataSource = CType(ViewState("datasource"), DataSource)
Dim filterRepositoryHelper As FilterRepositoryHelper = CType(ViewState("filterrepositoryhelper"), FilterRepositoryHelper)
' Update the filter object with form changes.
filter.Name.Text = textboxName.Text
filter.Description.Text = textboxDescription.Text
filter.DataSourceLocation = datasource.Location
For Each parameterDefinition As ParameterDefinition In filter.BeginPoints
parameterDefinition.DisplayName = filter.Name.Text
Next parameterDefinition
' Initialize the filter. This method runs the filter's query and retrieves preview data.
filterRepositoryHelper.GetParameterDisplayData(filter)
' Save the filter object to the PerformancePoint Services repository.
Try
filter.Validate()
If ClickOnceLaunchValues.CreateItem.Equals(action, StringComparison.OrdinalIgnoreCase) Then
Dim newFilter As Filter = filterRepositoryHelper.Create(If(String.IsNullOrEmpty(filter.Location.ItemUrl), itemLocation, filter.Location.ItemUrl), filter)
ViewState("filter") = newFilter
ViewState("action") = ClickOnceLaunchValues.OpenItem
Else
filterRepositoryHelper.Update(filter)
End If
Catch ex As Exception
displayError("An error has occurred. Please contact your administrator for more information.")
If filterRepositoryHelper IsNot Nothing Then
' Add the exception detail to the server event log.
filterRepositoryHelper.HandleException(ex)
End If
End Try
End Sub
' Displays the error string in the labelErrorMessage label.
Private Sub displayError(ByVal msg As String)
EnsureChildControls()
labelErrorMessage.Text = msg
' Disable the OK button because the page is in an error state.
buttonOK.Enabled = False
Return
End Sub
' Verifies that the properties for the filter object are set.
Private Shared Sub VerifyFilter(ByVal filter As Filter)
If Nothing IsNot filter Then
' Verify that all required properties are set.
If String.IsNullOrEmpty(filter.SubTypeId) Then
' This value must match the subType attribute specified
' in the web.config file.
filter.SubTypeId = "SampleFilter"
End If
If String.IsNullOrEmpty(filter.RendererClassName) Then
filter.RendererClassName = GetType(MultiSelectTreeViewControl).AssemblyQualifiedName
End If
' Define the BeginPoints property so the filter can send a parameter value to
' scorecards and reports.
' The value must be from the KeyColumn of the display
' DataTable object, which is defined in the data provider. The data table is
' returned by the FilterRepositoryHelper.GetParameterDisplayData method.
' A filter has one beginpoint only, and it is represented by a
' ParameterDefinition object. The ParameterDefinition object defines how
' the filter accesses the data.
If 0 = filter.BeginPoints.Count Then
Dim paramDef As ParameterDefinition = New ParameterDefinition With {.ParameterProviderId = "SampleFilterDataProvider", .DefaultPostFormula = String.Empty, .KeyColumn = "Symbol", .DisplayColumn = "Symbol", .CustomDefinition = String.Empty}
' This value must match the value returned
' by the data provider's GetId method.
' Reference the data provider.
' Specify the column that contains
' the key identifiers and the column
' that contains the display values.
' The sample uses the same column
' for both purposes.
' These values must match the structure
' of the data table that is returned
' by the ParameterDefinition.DisplayValues property.
' You can use this property to store
' extra information for this filter.
filter.BeginPoints.Add(paramDef)
End If
' Set optional properties. The renderer can return multiple values.
filter.SelectionMode = FilterSelectionMode.MultiSelect
End If
End Sub
' Populates the dropdownlistDataSource control.
Private Sub PopulateDataSourceDropDown(ByVal filterDataSource As DataSource)
EnsureChildControls()
Dim filterRepositoryHelper As FilterRepositoryHelper = CType(ViewState("filterrepositoryhelper"), FilterRepositoryHelper)
' Retrieve data sources from the repository by using the DataSourceHelper
' property to call the DataSourceConsumerHelper object.
' If you modify the types of data source to retrieve, you must make the corresponding
' change in the filter's data provider.
' The parameter contains the default server-relative URL to the PerformancePoint Data Connections Library.
' Edit this value if you are not using the default path. A leading forward slash may not be needed.
Dim dataSourceCollection As ICollection = filterRepositoryHelper.DataSourceHelper.GetDataSourcesBySourceNames("/BICenter/Data%20Connections%20for%20PerformancePoint/", {"WSTabularDataSource", DataSourceNames.ExcelWorkbook})
If Nothing Is dataSourceCollection Then
displayError("No available data sources were found.")
Return
End If
' Create a list of name/value pairs for the dropdownlistDataSource control.
Dim dataSources = New List(Of KeyValuePair(Of String, String))()
Dim selectedIndex As Integer = 0
Dim i As Integer = 1
dataSources.Add(New KeyValuePair(Of String, String)(String.Empty, String.Empty))
For Each ds As DataSource In dataSourceCollection
dataSources.Add(New KeyValuePair(Of String, String)(ds.Name.Text, ds.Location.ItemUrl))
' Check if the entry is the originally selected data source.
If (filterDataSource IsNot Nothing) AndAlso (String.Compare(ds.Name.Text, filterDataSource.Name.Text) = 0) Then
selectedIndex = i
End If
i += 1
Next ds
dropdownlistDataSource.DataSource = dataSources
dropdownlistDataSource.DataTextField = "Key"
dropdownlistDataSource.DataValueField = "Value"
dropdownlistDataSource.DataBind()
dropdownlistDataSource.SelectedIndex = selectedIndex
End Sub
' Populate the list box data.
Private Sub PopulateListBoxData(ByVal datasource As DataSource)
EnsureChildControls()
ClearStocksListBox()
Dim filterRepositoryHelper As FilterRepositoryHelper = CType(ViewState("filterrepositoryhelper"), FilterRepositoryHelper)
' Retrieve the first 100 rows of the preview data from the data source
Dim dataSet As DataSet = filterRepositoryHelper.DataSourceHelper.GetDataSet(100, datasource)
If Nothing IsNot dataSet AndAlso Nothing IsNot dataSet.Tables(0) Then
listboxStocks.DataTextField = "Symbol"
listboxStocks.DataValueField = "Value"
listboxStocks.DataSource = dataSet.Tables(0)
listboxStocks.DataBind()
End If
End Sub
End Class
End Namespace
コードのコンパイル
このコード例をコンパイルする前に、「エディター クラスを作成して設定するには」で説明されているとおりに開発環境を設定する必要があります。
セキュリティ
DLL には厳密な名前で署名する必要があります。さらに、DLL によって参照されたすべてのアセンブリが厳密な名前を持つことを確認してください。厳密な名前を使用してアセンブリに署名する方法の詳細、および公開/秘密キーのペアを作成する方法の詳細については、「How to: Create a Public/Private Key Pair」を参照してください。
関連項目
タスク
[方法] PerformancePoint Services フィルターのデータ プロバイダーを作成する
概念
カスタム PerformancePoint Services オブジェクトのエディター
PerformancePoint Services フィルター