Share via


Calculated Measure Representation (Tabular)

A calculated measure is a named DAX expression evaluated every time it is used; one of the benefits of being evaluated every time it is used if the fact that the calculated measure is dynamically evaluated depending on the context it being used.

Calculated Measure Representation

A calculated measure is a named DAX expression ready to be evaluated, that can also be referenced in other DAX expressions by its name.

Calculated Measure in AMO

When using AMO to manage a Tabular Model Calculated Measure there is a one-to-one match between the logical Calculated Measure object and a measure defined in a Command object of the MdxScript object; each different Calculated Measure is defined as a CREATE MEASURE expression inside a Command object and separated by a semicolon. All calculated measures in a tabular model correspond to the collection CREATE MEASURE string in one command object in a MdxScript object; also, for each calculated measure there is one-to-one mapping with a CalculationProperty.

The following code snippet shows how to create a calculated measure.

        private void addCalculatedMeasure(
                           AMO.Cube modelCube
                         , string cmTableName
                         , string cmName
                         , string newCalculatedMeasureExpression
                     )
        {
            //Verify input requirements
            if (string.IsNullOrEmpty(cmName) || string.IsNullOrWhiteSpace(cmName))
            {
                MessageBox.Show(String.Format("Calculated Measure name is not defined."), "AMO to Tabular message", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (string.IsNullOrEmpty(newCalculatedMeasureExpression) || string.IsNullOrWhiteSpace(newCalculatedMeasureExpression))
            {
                MessageBox.Show(String.Format("Calculated Measure expression is not defined."), "AMO to Tabular message", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            StringBuilder measuresCommand = new StringBuilder();

            AMO.MdxScript mdxScript = modelCube.MdxScripts["MdxScript"];

            //ToDo: Verify if measure already exits and ask user what wants to do next

            if (mdxScript.Commands.Count == 1)
            {
                measuresCommand.AppendLine("-------------------------------------------------------------");
                measuresCommand.AppendLine("-- Tabular Model measures command (do not modify manually) --");
                measuresCommand.AppendLine("-------------------------------------------------------------");
                measuresCommand.AppendLine();
                measuresCommand.AppendLine();
                mdxScript.Commands.Add(new AMO.Command(measuresCommand.ToString()));

            }
            else
            {
                measuresCommand.Append(mdxScript.Commands[1].Text);
            }
            measuresCommand.AppendLine(string.Format("CREATE MEASURE '{0}'[{1}]={2};", cmTableName, cmName, newCalculatedMeasureExpression));


            mdxScript.Commands[1].Text = measuresCommand.ToString();


            if (!mdxScript.CalculationProperties.Contains(cmName))
            {
                AMO.CalculationProperty cp = new AMO.CalculationProperty(cmName, AMO.CalculationType.Member);
                cp.FormatString = ""; // ToDo: Get formatting attributes for the member
                cp.Visible = true;
                mdxScript.CalculationProperties.Add(cp);
            }

            try
            {
                modelCube.Update(AMO.UpdateOptions.ExpandFull, AMO.UpdateMode.UpdateOrCreate);
                MessageBox.Show(String.Format("Calculated Measure successfully defined."), "AMO to Tabular message", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (AMO.OperationException amoOpXp)
            {
                MessageBox.Show(String.Format("Calculated Measure expression contains syntax errors, or references undefined or missspelled elements.\nError message: {0}", amoOpXp.Message), "AMO to Tabular message", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            catch (AMO.AmoException amoXp)
            {
                MessageBox.Show(String.Format("AMO exception accessing the server.\nError message: {0}", amoXp.Message), "AMO to Tabular message", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            catch (Exception)
            {
                throw;
            }
        }

AMO2Tabular sample

To have an understanding on how to use AMO to create and manipulate calculated measure representations see the source code of the AMO to Tabular sample; specifically check in the following source file: AddCalculatedMeasure.cs. The sample is available at Codeplex. An important note about the code: the code is provided only as a support to the logical concepts explained here and should not be used in a production environment; nor should it be used for other purpose other than the pedagogical one.