Partilhar via


Grupos de cálculo

Aplica-se a: SQL Server 2019 e serviços de análise posteriores Azure Analysis Services Fabric e Power BI Premium

Os grupos de cálculo podem reduzir significativamente o número de medidas redundantes agrupando expressões de medidas comuns como itens de cálculo. Os grupos de cálculo são suportados em modelos tabulares no nível de compatibilidade 1500 e superior.

Benefícios

Os grupos de cálculo abordam um problema em modelos complexos, onde pode haver uma proliferação de medidas redundantes usando os mesmos cálculos - mais comuns com cálculos de inteligência de tempo. Por exemplo, um analista de vendas deseja visualizar os totais de vendas e pedidos por mês até à data (MTD), trimestre até à data (QTD), ano até à data (YTD), pedidos do ano anterior até à data (PY) e assim por diante. O modelador de dados tem que criar medidas separadas para cada cálculo, o que pode levar a dezenas de medidas. Para o utilizador, isto pode significar ter de ordenar o mesmo número de medidas e aplicá-las individualmente ao seu relatório.

Vamos primeiro examinar como os grupos de cálculo aparecem para os usuários em uma ferramenta de relatório como o Power BI. Em seguida, veremos o que compõe um grupo de cálculo e como eles são criados em um modelo.

Os grupos de cálculo são mostrados em clientes de relatório como uma tabela com uma única coluna. A coluna não é como uma coluna ou dimensão típica, em vez disso, representa um ou mais cálculos reutilizáveis ou itens de cálculo que podem ser aplicados a qualquer medida já adicionada ao filtro Valores para uma visualização.

Na animação a seguir, um usuário está analisando dados de vendas para os anos de 2012 e 2013. Antes de aplicar um grupo de cálculo, a medida de base comum Sales calcula uma soma do total de vendas para cada mês. O utilizador então deseja aplicar cálculos de inteligência temporal para obter totais de vendas para mês até à data, trimestre até à data, ano até à data e assim por diante. Sem grupos de cálculo, o usuário teria que selecionar medidas individuais de inteligência de tempo.

Com um grupo de cálculo, neste exemplo chamado Inteligência de Tempo, quando o usuário arrasta o item Cálculo de Tempo para a área de filtro Colunas , cada item de cálculo aparece como uma coluna separada. Os valores para cada linha são calculados a partir da medida base, Sales.

Grupo de cálculo sendo aplicado no Power BI

Os grupos de cálculo trabalham com medidas DAX explícitas . Neste exemplo, Vendas é uma medida explícita já criada no modelo. Os grupos de cálculo não funcionam com medidas DAX implícitas. Por exemplo, no Power BI, as medidas implícitas são criadas quando um usuário arrasta colunas para elementos visuais para exibir valores agregados, sem criar uma medida explícita. Neste momento, o Power BI gera DAX para medidas implícitas escritas como cálculos DAX embutidos - o que significa que as medidas implícitas não podem funcionar com grupos de cálculo. Uma nova propriedade de modelo visível no modelo de objeto tabular (TOM) foi introduzida, DiscourageImplicitMeasures. Atualmente, para criar grupos de cálculo, essa propriedade deve ser definida como true. Quando definido como true, o Power BI Desktop no modo Live Connect desabilita a criação de medidas implícitas.

Os grupos de cálculo também suportam consultas MDX (Multidimensional Data Expressions). Isso significa que os usuários do Microsoft Excel, que consultam modelos de dados tabulares usando MDX, podem aproveitar ao máximo os grupos de cálculo em tabelas dinâmicas e gráficos de planilha.

Como funcionam

Agora que você já viu como os grupos de cálculo beneficiam os usuários, vamos ver como o exemplo de grupo de cálculo de Inteligência de Tempo mostrado é criado.

Antes de entrarmos nos detalhes, vamos apresentar algumas novas funções DAX especificamente para grupos de cálculo:

SELECTEDMEASURE - Usado em expressões que utilizam itens de cálculo para referenciar a medida que está atualmente no contexto. Neste exemplo, a medida "Vendas".

SELECTEDMEASURENAME - Usado por expressões em itens de cálculo para determinar a medida que está no contexto pelo nome.

ISSELECTEDMEASURE - Usado por expressões em itens de cálculo para determinar se a medida que está no contexto está especificada numa lista de medidas.

SELECTEDMEASUREFORMATSTRING - Usado por expressões para itens de cálculo para recuperar a cadeia de caracteres de formato da medida que está no contexto.

Exemplo de Inteligência de Tempo

Nome da tabela - Time Intelligence
Nome da coluna - Cálculo de Tempo
Precedência - 20

Itens de cálculo de Inteligência Temporal

Atual

SELECTEDMEASURE()

MTD

CALCULATE(SELECTEDMEASURE(), DATESMTD(DimDate[Date]))

QTD

CALCULATE(SELECTEDMEASURE(), DATESQTD(DimDate[Date]))

YTD

CALCULATE(SELECTEDMEASURE(), DATESYTD(DimDate[Date]))

PY

CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR(DimDate[Date]))

PY MTD

CALCULATE(
    SELECTEDMEASURE(),
    SAMEPERIODLASTYEAR(DimDate[Date]),
    'Time Intelligence'[Time Calculation] = "MTD"
)

PY QTD

CALCULATE(
    SELECTEDMEASURE(),
    SAMEPERIODLASTYEAR(DimDate[Date]),
    'Time Intelligence'[Time Calculation] = "QTD"
)

PY YTD

CALCULATE(
    SELECTEDMEASURE(),
    SAMEPERIODLASTYEAR(DimDate[Date]),
    'Time Intelligence'[Time Calculation] = "YTD"
)

YOY

SELECTEDMEASURE() -
CALCULATE(
    SELECTEDMEASURE(),
    'Time Intelligence'[Time Calculation] = "PY"
)

YOY%

DIVIDE(
    CALCULATE(
        SELECTEDMEASURE(),
        'Time Intelligence'[Time Calculation]="YOY"
    ),
    CALCULATE(
        SELECTEDMEASURE(),
        'Time Intelligence'[Time Calculation]="PY"
    )
)

Para testar esse grupo de cálculo, execute a seguinte consulta DAX. Nota: MTD, YOY e YOY% são omitidos deste exemplo de interrogação.

Consulta de Inteligência Temporal

EVALUATE
CALCULATETABLE (
    SUMMARIZECOLUMNS (
        DimDate[CalendarYear],
        DimDate[EnglishMonthName],
        "Current", CALCULATE ( [Sales], 'Time Intelligence'[Time Calculation] = "Current" ),
        "QTD",     CALCULATE ( [Sales], 'Time Intelligence'[Time Calculation] = "QTD" ),
        "YTD",     CALCULATE ( [Sales], 'Time Intelligence'[Time Calculation] = "YTD" ),
        "PY",      CALCULATE ( [Sales], 'Time Intelligence'[Time Calculation] = "PY" ),
        "PY QTD",  CALCULATE ( [Sales], 'Time Intelligence'[Time Calculation] = "PY QTD" ),
        "PY YTD",  CALCULATE ( [Sales], 'Time Intelligence'[Time Calculation] = "PY YTD" )
    ),
    DimDate[CalendarYear] IN { 2012, 2013 }
)

Retorno da consulta Time Intelligence

A tabela de retorno mostra cálculos para cada item de cálculo aplicado. Por exemplo, veja QTD para o mês de março de 2012, que é a soma de janeiro, fevereiro e março de 2012.

Resultado da consulta de inteligência temporal

Cadeias de caracteres de formato dinâmico

Cadeias de caracteres de formato dinâmico com grupos de cálculo permitem a aplicação condicional de cadeias de caracteres de formato a medidas sem forçá-las a retornar cadeias de caracteres.

Os modelos tabulares suportam a formatação dinâmica de medidas usando a função FORMAT do DAX. No entanto, a função FORMAT tem a desvantagem de retornar uma cadeia de caracteres, forçando medidas que de outra forma seriam numéricas a também serem retornadas como uma cadeia de caracteres. Isso pode apresentar algumas limitações, como a incompatibilidade com a maioria dos visuais do Power BI, que exigem valores numéricos, como gráficos.

No Power BI, as cadeias de caracteres de formato dinâmico para medidas também permitem a aplicação condicional de cadeias de caracteres de formato a uma medida específica sem forçá-las a retornar uma cadeia de caracteres e sem o uso de grupos de cálculo. Para saber mais, consulte Cadeias de caracteres de formato dinâmico para medidas.

Cadeias de caracteres de formato dinâmico para inteligência de tempo

Se olharmos para o exemplo de Inteligência de Tempo mostrado acima, todos os itens de cálculo, exceto YOY% devem usar o formato da medida atual no contexto. Por exemplo, o YTD calculado sobre a medida base de Vendas deve ser em moeda. Se este fosse um grupo de cálculo para algo como uma medida base de Pedidos, o formato seria numérico. YOY%, no entanto, deve ser uma porcentagem, independentemente do formato da medida base.

Para YOY%, podemos substituir a cadeia de caracteres de formato definindo a propriedade format string expression como 0,00%;-0,00%;0,00%. Para saber mais sobre as propriedades da expressão de cadeia de caracteres de formato, consulte Propriedades da célula MDX - Conteúdo da cadeia de caracteres de formato.

Neste visual de matriz no Power BI, você vê Sales Current/YOY e Orders Current/YOY mantêm suas respetivas cadeias de caracteres de formato de medida base. Sales YOY% e Orders YOY%, no entanto, substitui a string de formato para usar o formato percentagem.

Inteligência temporal em matriz visual

Cadeias de caracteres de formato dinâmico para conversão de moeda

As cadeias de caracteres de formato dinâmico facilitam a conversão de moeda. Considere o seguinte modelo de dados da Adventure Works. É modelado para conversão de moeda um-para-muitos, conforme definido pelos tipos de conversão.

Taxa de câmbio no modelo tabular

Uma coluna FormatString é adicionada à tabela DimCurrency e preenchida com cadeias de caracteres de formato para as respetivas moedas.

Formatar coluna de cadeia de caracteres

Neste exemplo, o seguinte grupo de cálculo é definido como:

Exemplo de conversão de moeda

Nome da tabela - Conversão de moeda
Nome da coluna - Cálculo de Conversão
Precedência - 5

Itens de cálculo para conversão de moeda

Sem conversão

SELECTEDMEASURE()

Moeda convertida

IF(
    //Check one currency in context & not US Dollar, which is the pivot currency:
    SELECTEDVALUE( DimCurrency[CurrencyName], "US Dollar" ) = "US Dollar",
    SELECTEDMEASURE(),
    SUMX(
        VALUES(DimDate[Date]),
        CALCULATE( DIVIDE( SELECTEDMEASURE(), MAX(FactCurrencyRate[EndOfDayRate]) ) )
    )
)

Formatar expressão de cadeia de caracteres

SELECTEDVALUE(
    DimCurrency[FormatString],
    SELECTEDMEASUREFORMATSTRING()
)

Observação

As expressões de seleção para grupos de cálculo podem ser usadas para implementar a conversão automática de moeda em grupos de cálculo, eliminando a necessidade de ter dois itens de cálculo separados.

A expressão de cadeia de caracteres de formato deve retornar uma cadeia de caracteres escalar. Ele usa a nova função SELECTEDMEASUREFORMATSTRING para reverter para a cadeia de caracteres do formato de medida base se houver várias moedas no contexto do filtro.

A animação seguinte mostra a conversão dinâmica de formato de moeda da medida Sales num relatório.

Cadeia de caracteres de formato dinâmico de conversão de moeda aplicada

Expressões de seleção

As expressões de seleção são propriedades opcionais definidas para um grupo de cálculo. Existem dois tipos de expressões de seleção:

  • multipleOrEmptySelectionExpression. Esta expressão de seleção é aplicada quando:
    • foram selecionados vários elementos de cálculo,
    • tiver sido selecionado um elemento de cálculo não existente, ou
    • Foi feita uma seleção contraditória.
  • noSelectionExpression. Esta expressão de seleção é aplicada quando o grupo de cálculo não é filtrado.

Ambas as expressões de seleção também têm uma expressão formatStringDefinition de cadeia de formato dinâmico.

Em resumo, em um grupo de cálculo, o seguinte pode ser definido, por exemplo, usando TMDL:

...
table Scenarios
	calculationGroup
		...
    multipleOrEmptySelectionExpression = <expression>
        formatStringDefinition = <format string>
    noSelectionExpression= <expression>
        formatStringDefinition = <format string>
...

Observação

Estas expressões, se especificadas, são aplicadas apenas para as situações específicas mencionadas. As seleções para um único item de cálculo não são afetadas por essas expressões.

Aqui está uma visão geral dessas expressões e seu comportamento padrão, se não especificado:

Tipo de seleção Expressão de seleção não definida (padrão) Expressão de seleção definida
Seleção única A seleção é aplicada A seleção é aplicada
Seleção múltipla O grupo de cálculo não é filtrado Retornar o resultado da avaliação de expressão de seleção múltipla ou vazia
Seleção vazia O grupo de cálculo não é filtrado Retornar o resultado da avaliação de expressão de seleção múltipla ou vazia
Sem seleção O grupo de cálculo não é filtrado Retornar o resultado da avaliação de noSelectionExpression

Observação

Use a configuração selectionExpressionBehavior do modelo para influenciar ainda mais o que um grupo de cálculo retorna quando as expressões de seleção não são definidas.

Configuração do modelo SelectionExpressionBehavior

Os modelos têm uma configuração selectionExpressionBehavior que permite um controle adicional sobre como os grupos de cálculo nesse modelo se comportam. Essa configuração aceita os três valores a seguir:

  • Automático. Este é o valor padrão e é o mesmo que não visual. Isso garante que os modelos existentes não alterem o comportamento. Os modelos acima de um nível de compatibilidade futuro definido como automático utilizarão o visual . Haverá um anúncio nesse momento.
  • Não visual. Se o grupo de cálculo não definir uma expressão multipleOrEmptySelection , o grupo de cálculo retornará SELECTEDMEASURE() e, ao agrupar pelo grupo de cálculo, os valores de subtotal ficarão ocultos.
  • Visual Se o grupo de cálculo não definir uma expressão multipleOrEmptySelection , o grupo de cálculo retornará BLANK(). Ao agrupar pelo grupo de cálculo, os valores de subtotal são determinados avaliando a medida selecionada no contexto do grupo de cálculo.

Use TMDL para definir a propriedade no seu modelo:

createOrReplace
    model Model
        ...
        selectionExpressionBehavior: <automatic|nonvisual|visual>
...

Seleção múltipla ou vazia

Se forem feitas várias seleções no mesmo grupo de cálculo, o grupo de cálculo avaliará e retornará o resultado de "multipleOrEmptySelectionExpression", se definido. Se essa expressão não tiver sido definida, o grupo de cálculo retornará o seguinte resultado se a configuração selectionExpressionBehavior do modelo estiver definida como automática ou não visual:

SELECTEDMEASURE()

Se a configuração selectionExpressionBehavior do modelo estiver definida como visual, o grupo de cálculo retornará:

BLANK()

Como exemplo, vamos examinar um grupo de cálculo chamado MyCalcGroup que tem um multipleOrEmptySelectionExpression configurado da seguinte maneira:

IF (
ISFILTERED ( 'MyCalcGroup' ),
    "Filters: " 
         & CONCATENATEX ( 
  	            FILTERS ( 'MyCalcGroup'[Name] ),
            'MyCalcGroup'[Name], 
            ", "
     	   )
)

Agora, imagine a seguinte seleção no grupo de cálculo:

EVALUATE
{
    CALCULATE (
        [MyMeasure],
        'MyCalcGroup'[Name] = "item1" || 'MyCalcGroup'[Name] = "item2"
    )
}

Aqui, selecionamos dois itens no grupo de cálculo, "item1" e "item2". Esta é uma seleção múltipla e, portanto, o multipleOrEmptySelectionExpression é avaliado e retorna o seguinte resultado: "Filtros: item1, item2".

Em seguida, faça a seguinte seleção no grupo de cálculo:

EVALUATE
{
    CALCULATE (
        [MyMeasure],
        'MyCalcGroup'[Name] = "item4" -- item4 does not exists
    )
}

Este é um exemplo de uma seleção vazia, pois "item4" não existe neste grupo de cálculo. Portanto, o multipleOrEmptySelectionExpression é avaliado e retorna o seguinte resultado: "Filtros: ".

Sem seleção

O noSelectionExpression num grupo de cálculo será aplicado se o grupo de cálculo não tiver sido filtrado. Isso é usado principalmente para executar ações padrão sem a necessidade de o usuário tomar uma ação enquanto ainda fornece flexibilidade ao usuário para substituir a ação padrão. Por exemplo, vamos examinar a conversão automática de moeda com o dólar americano como moeda central de referência.

Podemos configurar um grupo de cálculo com a seguinte expressão sem seleção (noSelectionExpression):

IF (
    //Check one currency in context & not US Dollar, which is the pivot currency:
    SELECTEDVALUE (
        DimCurrency[CurrencyName],
        "US Dollar"
    ) = "US Dollar",
    SELECTEDMEASURE (),
    SUMX (
        VALUES ( DimDate[DateKey] ),
        CALCULATE (
            DIVIDE ( SELECTEDMEASURE (), MAX ( FactCurrencyRate[EndOfDayRate] ) )
        )
    )
)

Também definiremos um formatStringDefinition para esta expressão:

SELECTEDVALUE(
  DimCurrency[FormatString],
  SELECTEDMEASUREFORMATSTRING()
)

Agora, se nenhuma moeda for selecionada, todas as moedas serão convertidas automaticamente para a moeda pivot (dólar americano), conforme necessário. Além disso, você ainda pode escolher outra moeda para converter para essa moeda sem ter que alternar itens de cálculo, como faria sem o noSelectionExpression.

Precedência

Precedência é uma propriedade definida para um grupo de cálculo. Ele especifica a ordem em que os grupos de cálculo são combinados com a medida subjacente ao usar SELECTEDMEASURE() no item de cálculo.

Exemplo de precedência

Vejamos um exemplo simples. Este modelo tem uma medida com um valor especificado de 10 e dois grupos de cálculo, cada um com um único item de cálculo. Vamos aplicar os itens de cálculo de ambos os grupos de cálculo à medida. É assim que o configuramos:

'Measure group'[Measure] = 10

O primeiro grupo de cálculo é 'Calc Group 1 (Precedence 100)' e o item de cálculo é 'Calc item (Plus 2)':

'Calc Group 1 (Precedence 100)'[Calc item (Plus 2)] = SELECTEDMEASURE() + 2

O segundo grupo de cálculo é 'Calc Group 2 (Precedence 200)' e o item de cálculo é 'Calc item (Times 2)':

'Calc Group 2 (Precedence 200)'[Calc item (Times 2)] = SELECTEDMEASURE() * 2

Você pode ver que o grupo de cálculo 1 tem um valor de precedência de 100 e o grupo de cálculo 2 tem um valor de precedência de 200.

Usando o SQL Server Management Studio (SSMS) ou uma ferramenta externa com recursos de leitura e gravação XMLA , como o Editor de Tabelas de código aberto, você pode usar scripts XMLA para criar grupos de cálculo e definir os valores de precedência. Aqui acrescentamos "Calc group 1 (Precedence 100)":

{
  "createOrReplace": {
    "object": {
      "database": "CHANGE TO YOUR DATASET NAME",
      "table": "Calc group 1 (Precedence 100)"
    },
    "table": {
      "name": "Calc group 1 (Precedence 100)",
      "calculationGroup": {
        "precedence": 100,
        "calculationItems": [
          {
            "name": "Calc item (Plus 2)",
            "expression": "SELECTEDMEASURE() + 2",
          }
        ]
      },
      "columns": [
        {
          "name": "Calc group 1 (Precedence 100)",
          "dataType": "string",
          "sourceColumn": "Name",
          "sortByColumn": "Ordinal",
          "summarizeBy": "none",
          "annotations": [
            {
              "name": "SummarizationSetBy",
              "value": "Automatic"
            }
          ]
        },
        {
          "name": "Ordinal",
          "dataType": "int64",
          "isHidden": true,
          "sourceColumn": "Ordinal",
          "summarizeBy": "sum",
          "annotations": [
            {
              "name": "SummarizationSetBy",
              "value": "Automatic"
            }
          ]
        }
      ],
      "partitions": [
        {
          "name": "Partition",
          "mode": "import",
          "source": {
            "type": "calculationGroup"
          }
        }
      ]
    }
  }
}

E este script acrescenta "Calc group 2 (Precedence 200)":

{
  "createOrReplace": {
    "object": {
      "database": "CHANGE TO YOUR DATASET NAME",
      "table": "Calc group 2 (Precedence 200)"
    },
    "table": {
      "name": "Calc group 2 (Precedence 200)",
      "calculationGroup": {
        "precedence": 200,
        "calculationItems": [
          {
            "name": "Calc item (Times 2)",
            "expression": "SELECTEDMEASURE() * 2"
          }
        ]
      },
      "columns": [
        {
          "name": "Calc group 2 (Precedence 200)",
          "dataType": "string",
          "sourceColumn": "Name",
          "sortByColumn": "Ordinal",
          "summarizeBy": "none",
          "annotations": [
            {
              "name": "SummarizationSetBy",
              "value": "Automatic"
            }
          ]
        },
        {
          "name": "Ordinal",
          "dataType": "int64",
          "isHidden": true,
          "sourceColumn": "Ordinal",
          "summarizeBy": "sum",
          "annotations": [
            {
              "name": "SummarizationSetBy",
              "value": "Automatic"
            }
          ]
        }
      ],
      "partitions": [
        {
          "name": "Partition",
          "mode": "import",
          "source": {
            "type": "calculationGroup"
          }
        }
      ]
    }
  }
}

No Power BI Desktop, temos um cartão visual mostrando a medida e um filtro para cada um dos grupos de cálculo na vista do relatório.

Medir separadamente as expressões de um grupo.

Quando ambas as segmentações de dados estão ativadas, precisamos combinar as expressões DAX. Para fazer isso, começamos com o item de cálculo de precedência mais alta, 200, e depois substituímos o argumento SELECTEDMEASURE() pelo próximo mais alto, 100.

Portanto, a nossa expressão DAX do item de mais alta precedência de cálculo é:

SELECTEDMEASURE() * 2 

E a nossa expressão DAX de precedência secundária mais alta para o cálculo é:

SELECTEDMEASURE() + 2 

Agora, eles são combinados substituindo a parte SELECTEDMEASURE() do item de cálculo de precedência mais alta pelo próximo item de cálculo de precedência mais alta, da seguinte forma:

( SELECTEDMEASURE() + 2 ) * 2

Então, se houver mais itens de cálculo, continuamos até chegarmos à medida subjacente. Há apenas dois grupos de cálculo neste modelo, então agora substituímos SELECTEDMEASURE() pela medida em si, assim:

( ( [Measure] ) + 2 ) * 2

Como o nosso Measure = 10, isto é o mesmo que:

( ( 10 ) + 2 ) * 2

Quando não há mais argumentos SELECTEDMEASURE(), a expressão DAX combinada é avaliada:

( ( 10 ) + 2 ) * 2 = 24

No Power BI Desktop, quando ambos os grupos de cálculo são aplicados com um segmentador, o resultado da medida é assim:

Meça expressões combinadas de grupo.

Mas tenha em mente que a combinação está aninhada de tal modo que o resultado não será 10 + 2 * 2 = 14, como se vê aqui:

Meça expressões aninhadas de grupo.

Para transformações simples, a avaliação é de menor para maior precedência. Por exemplo, 10 tem 2 adicionado, então é multiplicado por 2. No DAX, existem funções como CALCULATE que aplicam filtros ou alterações de contexto a expressões internas. Neste caso, a maior precedência altera uma expressão de precedência inferior.

A precedência também determina qual cadeia de caracteres de formato dinâmico é aplicada à expressão DAX combinada para cada medida. A cadeia de caracteres de formato dinâmico do grupo de cálculo com a mais alta precedência é a única aplicada. Se uma medida em si tiver uma cadeia de caracteres de formato dinâmico, ela será considerada uma precedência menor para qualquer grupo de cálculo no modelo.

Exemplo de precedência com médias

Vejamos outro exemplo usando o mesmo modelo mostrado no exemplo de inteligência de tempo descrito anteriormente neste artigo. Mas, desta vez, vamos também adicionar um grupo de cálculo de Médias . O grupo de cálculo de médias contém cálculos de média que são independentes da inteligência de tempo tradicional, pois não alteram o contexto do filtro de data - apenas realizam cálculos de média dentro dele.

Neste exemplo, um cálculo de média diária é definido. Cálculos como barris médios de petróleo por dia são comuns em aplicações de petróleo e gás. Outros exemplos de negócios comuns incluem a média de vendas em lojas no varejo.

Embora esses cálculos sejam calculados independentemente dos cálculos de inteligência temporal, pode muito bem haver a necessidade de combiná-los. Por exemplo, um usuário pode querer ver barris de petróleo por dia YTD para visualizar a taxa diária de petróleo do início do ano até a data atual. Nesse cenário, a precedência deve ser definida para itens de cálculo.

Os nossos pressupostos são:

O nome da tabela é Médias.
O nome da coluna é Cálculo Médio.
A precedência é 10.

Itens de cálculo para médias

Média indisponível

SELECTEDMEASURE()

Média diária

DIVIDE(SELECTEDMEASURE(), COUNTROWS(DimDate))

Aqui está um exemplo de uma consulta DAX e tabela de retorno:

Consulta de médias

EVALUATE
    CALCULATETABLE (
        SUMMARIZECOLUMNS (
        DimDate[CalendarYear],
        DimDate[EnglishMonthName],
        "Sales", CALCULATE (
            [Sales],
            'Time Intelligence'[Time Calculation] = "Current",
            'Averages'[Average Calculation] = "No Average"
        ),
        "YTD", CALCULATE (
            [Sales],
            'Time Intelligence'[Time Calculation] = "YTD",
            'Averages'[Average Calculation] = "No Average"
        ),
        "Daily Average", CALCULATE (
            [Sales],
            'Time Intelligence'[Time Calculation] = "Current",
            'Averages'[Average Calculation] = "Daily Average"
        ),
        "YTD Daily Average", CALCULATE (
            [Sales],
            'Time Intelligence'[Time Calculation] = "YTD",
            'Averages'[Average Calculation] = "Daily Average"
        )
    ),
    DimDate[CalendarYear] = 2012
)

Média do retorno da consulta

Média do retorno da consulta

A tabela a seguir mostra como os valores de março de 2012 são calculados.

Nome da coluna Cálculo
Ano Até a Data Soma das vendas de jan, fev, Mar 2012
= 495.364 + 506.994 + 373.483
Média diária Vendas para Mar 2012 divididas por # de dias em março
= 373.483 / 31
Média diária YTD YTD para março de 2012 dividido por # de dias em janeiro, fevereiro e março
= 1.375.841 / (31 + 29 + 31)

Aqui está a definição do item de cálculo YTD, aplicado com precedência de 20.

CALCULATE(SELECTEDMEASURE(), DATESYTD(DimDate[Date]))

Aqui está a média diária, aplicada com uma precedência de 10.

DIVIDE(SELECTEDMEASURE(), COUNTROWS(DimDate))

Como a precedência do grupo de cálculo de Inteligência de Tempo é maior do que a do grupo de cálculo de Médias, ela é aplicada da forma mais ampla possível. O cálculo da média diária YTD aplica-se ao numerador e ao denominador (contagem de dias) do cálculo da média diária.

Isto equivale à seguinte expressão:

CALCULATE(DIVIDE(SELECTEDMEASURE(), COUNTROWS(DimDate)), DATESYTD(DimDate[Date]))

Não esta expressão:

DIVIDE(CALCULATE(SELECTEDMEASURE(), DATESYTD(DimDate[Date])), COUNTROWS(DimDate)))

Recursão lateral

No exemplo de Inteligência de Tempo acima, alguns dos itens de cálculo referem-se a outros no mesmo grupo de cálculo. Isso é chamado de recursão lateral. Por exemplo, YOY% faz referência a YOY e PY.

DIVIDE(
    CALCULATE(
        SELECTEDMEASURE(),
        'Time Intelligence'[Time Calculation]="YOY"
    ),
    CALCULATE(
        SELECTEDMEASURE(),
        'Time Intelligence'[Time Calculation]="PY"
    )
)

Neste caso, ambas as expressões são avaliadas separadamente porque estão usando instruções de cálculo diferentes. Outros tipos de recursão não são suportados.

Item de cálculo único no contexto do filtro

Em nosso exemplo de Inteligência de Tempo, o item de cálculo PY YTD tem uma única expressão de cálculo:

CALCULATE(
    SELECTEDMEASURE(),
    SAMEPERIODLASTYEAR(DimDate[Date]),
    'Time Intelligence'[Time Calculation] = "YTD"
)

O argumento YTD para a função CALCULATE() substitui o contexto do filtro para reutilizar a lógica já definida no item de cálculo YTD. Não é possível aplicar PY e YTD numa única avaliação. Os grupos de cálculo só são aplicados se um único item de cálculo do grupo de cálculo estiver no contexto de filtro.

Pedido

Por padrão, quando uma coluna de um grupo de cálculo é colocada em um relatório, os itens de cálculo são ordenados alfabeticamente pelo nome. A ordem em que os itens de cálculo aparecem em um relatório pode ser alterada especificando a propriedade Ordinal. Especificar a ordem dos itens de cálculo com a propriedade Ordinal não altera a precedência, a ordem na qual os itens de cálculo são avaliados. Ele também não altera a ordem em que os itens de cálculo aparecem no Gerenciador de Modelos de Tabela.

Para especificar a propriedade ordinal para itens de cálculo, você deve adicionar uma segunda coluna ao grupo de cálculo. Ao contrário da coluna padrão em que Tipo de Dados é Texto, uma segunda coluna usada para ordenar itens de cálculo tem um tipo de dados Número Inteiro. A única finalidade desta coluna é especificar a ordem numérica na qual os itens de cálculo no grupo de cálculo aparecem. Como essa coluna não fornece nenhum valor em um relatório, é melhor definir a propriedade Hidden como True.

Coluna para ordenar

Depois que uma segunda coluna for adicionada ao grupo de cálculo, você poderá especificar o valor da propriedade Ordinal para os itens de cálculo que deseja ordenar.

Propriedade ordinal

Para saber mais, consulte Para ordenar itens de cálculo.

Criar um grupo de cálculo

Os grupos de cálculo são suportados no Visual Studio com o Analysis Services Projects VSIX update 2.9.2 e posterior. Os grupos de cálculo também podem ser criados usando TMSL (Tabular Model Scripting Language) ou o Editor de Tabelas de código aberto.

Para criar um grupo de cálculo usando o Visual Studio

  1. No Explorador de Modelos de Tabela, clique com o botão direito do rato em Grupos de Cálculo e, em seguida, clique em Novo Grupo de Cálculo. Por padrão, um novo grupo de cálculo tem uma única coluna e um único item de cálculo.

  2. Use Propriedades para alterar o nome e inserir uma descrição para o grupo de cálculo, coluna e item de cálculo padrão.

  3. Para inserir uma expressão de fórmula DAX para o item de cálculo padrão, clique com o botão direito do mouse e clique em Editar Fórmula para abrir o Editor DAX. Insira uma expressão válida.

  4. Para adicionar mais itens de cálculo, clique com o botão direito do rato em Itens de Cálculo e, em seguida, clique em Novo Item de Cálculo.

Para ordenar itens de cálculo

  1. No Explorador de Modelos de Tabela, clique com o botão direito do rato num grupo de cálculo e, em seguida, clique em Adicionar coluna.

  2. Nomeie a coluna Ordinal (ou algo semelhante), insira uma descrição e defina a propriedade Hidden como True.

  3. Para cada item de cálculo que você deseja ordenar, defina a propriedade Ordinal como um número positivo. Cada número é sequencial, por exemplo, um item de cálculo com uma propriedade Ordinal de 1 aparece primeiro, uma propriedade de 2 aparece em segundo e assim por diante. Os itens de cálculo com a -1 padrão não são incluídos na ordenação, mas aparecem antes dos itens ordenados num relatório.

Considerações

Assim que um grupo de cálculo for adicionado a um modelo semântico, os relatórios do Power BI usarão o tipo de dados variante para todas as medidas. Se, posteriormente, todos os grupos de cálculo forem removidos do modelo, as medidas serão retornadas aos seus tipos de dados originais novamente.

Limitações

Não há suporte para a segurança em nível de objeto (OLS) definida em tabelas de grupo de cálculo. No entanto, o OLS pode ser definido em outras tabelas no mesmo modelo. Se um item de cálculo se referir a um objeto protegido OLS, um erro genérico será retornado.

A segurança em nível de linha (RLS) não é suportada. Defina RLS em tabelas no mesmo modelo, mas não em grupos de cálculo em si (direta ou indiretamente).

As expressões de linhas de detalhe não são suportadas com grupos de cálculo.

Os visuais Smart narrative no Power BI não são suportados com grupos de cálculo.

Não há suporte para agregações de coluna implícitas no Power BI para modelos com grupos de cálculo. Atualmente, se a propriedade DiscourageImplicitMeasures estiver definida como false (padrão), as opções de agregação aparecerão, mas não poderão ser aplicadas. Se DiscourageImplicitMeasures estiver definido como true, as opções de agregação não aparecerão.

Ao criar relatórios do Power BI usando LiveConnection, as cadeias de caracteres de formato dinâmico não são aplicadas a medidas no nível de relatório.

Ver também

DAX em modelos tabulares
Referência DAX