Rappresentazione dell'indicatore di prestazioni chiave (tabulare)
Un indicatore KPI viene utilizzato per misurare le prestazioni di un valore, definito mediante una misura di base, rispetto a un valore di destinazione.
Rappresentazione dell'indicatore di prestazioni chiave
Nei modelli a oggetti tabulari un indicatore di prestazioni chiave -kpi- è una misura con informazioni aggiuntive per l'applicazione client per visualizzarla graficamente. Un indicatore KPI dispone in genere di informazioni su un obiettivo da raggiungere e sullo stato della misura confrontato con l'obiettivo nonché di informazioni per lo strumento client sulla visualizzazione grafica dello stato.
Indicatore di prestazioni chiave in AMO
Se si utilizza AMO per gestire un indicatore di prestazioni chiave (KPI) in un modello tabulare, non vi è corrispondenza di oggetti uno-a-uno per un indicatore KPI in AMO, l'oggetto Kpi AMO non viene utilizzato per questo scopo; in AMO, per i modelli tabulari, un indicatore KPI è rappresentato il da una serie di oggetti creata in uno degli elementi nella raccolta Commands e nell'oggetto CalculationProperties.
Nel frammento di codice seguente viene mostrato come creare una di molte possibili definizioni KPI.
private void addStaticKPI(object sender, EventArgs e)
{
double KPIGoal = 0, status1ThresholdValue = 0, status2ThresholdValue = 0
, redAreaValue = 0, yellowAreaValue = 0, greenAreaValue = 0;
string clientStatusGraphicImageName = "Three Circles Colored";
//Verify input requirements
//Goal values
if (staticTargetKPI.Checked)
{//Static KPI Goal selected
if (string.IsNullOrEmpty(staticTargetKPIGoal.Text)
|| string.IsNullOrWhiteSpace(staticTargetKPIGoal.Text)
|| !double.TryParse(staticTargetKPIGoal.Text, out KPIGoal))
{
MessageBox.Show(String.Format("Static Goal is not defined or is not a valid number."), "AMO to Tabular message", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
else
{//Measure KPI Goal selected
if (!TargetMeasureForKPISelected)
{
MessageBox.Show(String.Format("Measure Goal is not selected."), "AMO to Tabular message", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
//Status
if (string.IsNullOrEmpty(firstStatusThresholdValue.Text)
|| string.IsNullOrWhiteSpace(firstStatusThresholdValue.Text)
|| !double.TryParse(firstStatusThresholdValue.Text, out status1ThresholdValue)
|| string.IsNullOrEmpty(secondStatusThresholdValue.Text)
|| string.IsNullOrWhiteSpace(secondStatusThresholdValue.Text)
|| !double.TryParse(secondStatusThresholdValue.Text, out status2ThresholdValue))
{
MessageBox.Show(String.Format("Status Threshold are not defined or they are not a valid number."), "AMO to Tabular message", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(statusValueRedArea.Text)
|| string.IsNullOrWhiteSpace(statusValueRedArea.Text)
|| !double.TryParse(statusValueRedArea.Text, out redAreaValue)
|| string.IsNullOrEmpty(statusValueYellowArea.Text)
|| string.IsNullOrWhiteSpace(statusValueYellowArea.Text)
|| !double.TryParse(statusValueYellowArea.Text, out yellowAreaValue)
|| string.IsNullOrEmpty(statusValueGreenArea.Text)
|| string.IsNullOrWhiteSpace(statusValueGreenArea.Text)
|| !double.TryParse(statusValueGreenArea.Text, out greenAreaValue))
{
MessageBox.Show(String.Format("Status Area values are not defined or they are not a valid number."), "AMO to Tabular message", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
//Set working variables
string kpiTableName = ((DataRowView)MeasuresInModelList.CheckedItems[0])[0].ToString();
string kpiMeasureName = ((DataRowView)MeasuresInModelList.CheckedItems[0])[1].ToString();
//Verify if KPI is already defined
if (modelCube.MdxScripts["MdxScript"].CalculationProperties.Contains(string.Format("KPIs.[{0}]", kpiMeasureName)))
{
//ToDo: Verify with the user if wants to update KPI or exit
//If user wants to update then remove KPI from mdxScripts and continue with the creating the KPI
//
// Until the code to remove KPI is finished we'll have to exit with a message of no duplicated KPIs are allowed
MessageBox.Show(String.Format("Another KPI exists for the same measeure."), "AMO to Tabular message", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
StringBuilder kpiCommand = new StringBuilder();
AMO.MdxScript mdxScript = modelCube.MdxScripts["MdxScript"];
kpiCommand.Append(mdxScript.Commands[1].Text);
string goalExpression;
if (staticTargetKPI.Checked)
{//Static KPI Goal selected
goalExpression = KPIGoal.ToString();
}
else
{//Measure KPI Goal selected
string measureGoalMeasureName = ((DataRowView)KpiTargetMeasures.CheckedItems[0])[1].ToString();
goalExpression = string.Format("[Measures].[{0}]", measureGoalMeasureName);
}
kpiCommand.AppendLine(string.Format("CREATE MEMBER CURRENTCUBE.Measures.[_{1} Goal] AS '{2}', ASSOCIATED_MEASURE_GROUP = '{0}';"
, kpiTableName, kpiMeasureName, goalExpression));
string statusExpression;
if (staticTargetKPI.Checked)
{//Static KPI Goal selected
statusExpression = string.Format("KpiValue(\"{0}\")", kpiMeasureName).Trim();
}
else
{//Measure KPI Goal selected
string measureGoalMeasureName = ((DataRowView)KpiTargetMeasures.CheckedItems[0])[1].ToString().Trim();
string M = string.Format("[Measures].[{0}]", kpiMeasureName);
string T = string.Format("[Measures].[{0}]", measureGoalMeasureName);
if (KpiRelationDifference.Checked)
{
statusExpression = string.Format("{1} - {0}", M, T);
}
else
{
if (KpiRelationRatioMT.Checked)
{
statusExpression = string.Format("{0} / {1}", M, T);
}
else
{
statusExpression = string.Format("{1} / {0}", M, T);
}
}
}
kpiCommand.AppendLine(string.Format("CREATE MEMBER CURRENTCUBE.Measures.[_{1} Status] "
+ " AS 'Case When IsEmpty({9}) Then Null "
+ " When ({9}) {2} {3} Then {4} "
+ " When ({9}) {5} {6} Then {7} "
+ " Else {8} End'"
+ ", ASSOCIATED_MEASURE_GROUP = '{0}';"
, kpiTableName, kpiMeasureName // 0, 1
, statusThreshold1ComparisonOperator.Text, status1ThresholdValue, redAreaValue // 2, 3, 4
, statusThreshold2ComparisonOperator.Text, status2ThresholdValue, yellowAreaValue, greenAreaValue // 5, 6, 7, 8
, statusExpression // 9
));
kpiCommand.AppendLine(string.Format("CREATE MEMBER CURRENTCUBE.Measures.[_{1} Trend] AS '0', ASSOCIATED_MEASURE_GROUP = '{0}';"
, kpiTableName, kpiMeasureName));
kpiCommand.AppendLine(string.Format("CREATE KPI CURRENTCUBE.[{1}] AS Measures.[{1}]"
+ ", ASSOCIATED_MEASURE_GROUP = '{0}'"
+ ", GOAL = Measures.[_{1} Goal]"
+ ", STATUS = Measures.[_{1} Status]"
+ ", TREND = Measures.[_{1} Trend]"
+ ", STATUS_GRAPHIC = '{2}'"
+ ", TREND_GRAPHIC = '{2}';"
, kpiTableName, kpiMeasureName, clientStatusGraphicImageName));
{//Adding Calculation Reference for the Measure itself
if (!mdxScript.CalculationProperties.Contains(kpiMeasureName))
{
AMO.CalculationProperty cp = new AMO.CalculationProperty(kpiMeasureName, AMO.CalculationType.Member);
cp.FormatString = ""; // ToDo: Get formatting attributes for the member
cp.Visible = true;
mdxScript.CalculationProperties.Add(cp);
}
}
{//Adding Calculation Reference for the Goal measure
AMO.CalculationProperty cp = new AMO.CalculationProperty(string.Format("Measures.[_{0} Goal]", kpiMeasureName), AMO.CalculationType.Member);
cp.FormatString = ""; // ToDo: Get formatting attributes for the member
cp.Visible = false;
mdxScript.CalculationProperties.Add(cp);
}
{//Adding Calculation Reference for the Status measure
AMO.CalculationProperty cp = new AMO.CalculationProperty(string.Format("Measures.[_{0} Status]", kpiMeasureName), AMO.CalculationType.Member);
cp.FormatString = ""; // ToDo: Get formatting attributes for the member
cp.Visible = false;
mdxScript.CalculationProperties.Add(cp);
}
{//Adding Calculation Reference for the Status measure
AMO.CalculationProperty cp = new AMO.CalculationProperty(string.Format("Measures.[_{0} Trend]", kpiMeasureName), AMO.CalculationType.Member);
cp.FormatString = ""; // ToDo: Get formatting attributes for the member
cp.Visible = false;
mdxScript.CalculationProperties.Add(cp);
}
{//Adding Calculation Reference for the KPI
AMO.CalculationProperty cp = new AMO.CalculationProperty(string.Format("KPIs.[{0}]", kpiMeasureName), AMO.CalculationType.Member);
cp.FormatString = ""; // ToDo: Get formatting attributes for the member
cp.Visible = true;
mdxScript.CalculationProperties.Add(cp);
}
try
{
newDatabase.Update(AMO.UpdateOptions.ExpandFull, AMO.UpdateMode.UpdateOrCreate);
MessageBox.Show(String.Format("KPI successfully defined."), "AMO to Tabular message", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (AMO.OperationException amoOperationException)
{
//ToDo: remove anything left in mdxScript up to the point where the exception was thrown
MessageBox.Show(String.Format("Error creating KPI for Measure '{0}'[{1}]\nError message: {2}", kpiTableName, kpiMeasureName, amoOperationException.Message), "AMO to Tabular message", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
Esempio AMO2Tabular
Per comprendere la modalità di utilizzo di AMO per la creazione e la gestione delle rappresentazioni dell'indicatore di prestazioni di chiave, vedere il codice sorgente dell'esempio Da AMO a tabulare. In particolare effettuare un controllo nel seguente file di origine: AddKPIs.cs. L'esempio è disponibile in Codeplex. Nota importante sul codice: il codice viene fornito solo come supporto ai concetti logici illustrati in questo argomento e non deve essere utilizzato in un ambiente di produzione né deve essere utilizzato per altro scopo se non quello formativo.