jueves, 28 de mayo de 2020

Power Query: Formula.Firewall y los Niveles de Privacidad

En muchas ocasiones nuestras consultas requieren conexiones a fuentes externas, a múltiples orígenes, para posteriormente combinarlas entre sí.
Nada especial sin duda.

Lo que veremos hoy es cómo solucionar un problema con los Niveles de privacidad y los permisos de acceso a esos Orígenes de datos. Hablaremos del error Formula.Firewall

Power Query: Formula.Firewall y los Niveles de Privacidad



Este problema indica una alerta de seguridad, diciéndonos que los orígenes de datos contienen datos confidenciales... al menos de acuerdo a los permisos otorgados en las conexiones.

La solución más rápida consiste en acceder al Editor de Power Query > menú Archivo > Opciones y Configuración > Opciones de Consulta

Power Query: Formula.Firewall y los Niveles de Privacidad


En la ventana de Opciones de Consulta entraremos en los items de LIBRO ACTUAL > Privacidad y marcaremos Ignorar los niveles de privacidad y mejorar el rendimiento potencialmente

Power Query: Formula.Firewall y los Niveles de Privacidad


Esto únicamente modifica las opciones de privacidad de este libro, para cambiarlo y aplicarlo a cualquier consulta abierta en nuestro equipo lo cambiaremos en las Opciones de la consulta > GLOBAL > Privacidad.

En ocasiones ni siquiera modificando esta opción conseguimos evitar el fallo de Formula.Firewall y nos veremos obligados a modificar individualmente los permisos de cada conexión, ya que podría ocurrir que diferentes conexiones a orígenes (luego combinadas) tuvieran distintas privacidades.

Recordemos que, en general, tenemos cuatro niveles:
Ninguno: sin nivel de privacidad
Público: este tipo mantiene visibles los datos que contiene para todos los usuarios. En teoría, solo se pueden marcar con Público los datos de libros, con orígenes de datos de Internet o de archivos de acceso general, sin restricciones.
Organizativo: este origen de datos organizativo limita su visibilidad a un grupo de personas de confianza. Está aislado de todos los orígenes de datos públicos pero permanece visible para el resto de orígenes de datos organizativos
Privado: estos contienen información confidencial y su visibilidad puede restringirse solo a los usuarios autorizados. Está completamente aislado de otros orígenes de datos.

Para controlar este acceso iremos a la Configuración de orígenes de datos dentro del Editor de Power Query (en la ficha Archivo > Opciones y Configuración > Configuración de orígenes de datos, o en la Ficha Inicio > Orígenes de datos > Configuración de orígenes de datos

Power Query: Formula.Firewall y los Niveles de Privacidad


Seleccionamos la conexión en cuestión, y presionamos el botón de la parte inferior Editar Permisos; en la siguiente ventana, según la conexión podríamos exigirnos unos credenciales de acceso, y en todo caso, elegiremos la Privacidad deseada.
La alternativa sería configurarlo como Ninguno o Público, o que al menos todas las conexiones involucradas tuvieran el mismo nivel de privacidad

martes, 26 de mayo de 2020

Opciones de la Barra de Estado: Modo de celda

Es curioso cómo de desconocida es la barra de estado en Excel, pero cuánta información y funcionalidad puede proporcionarnos!.
En la entrada del blog anterior, sobre las estadísticas de libro, vimos un claro ejemplo.

La barra de estado, en la parte inferior de Excel (en realidad de todos los programas de Office) muestra el estado de las opciones que están seleccionadas; muchas opciones están seleccionadas por defecto.
Para personalizar esta barra de estado, haremos clic derecho con el ratón sobre ella y, a continuación, clic en las opciones que deseemos...

Recuerda que mediante programación en VBA es posible ocultar esta barra de estado (ver como).

Repasaremos hoy solo algunas de ellas.

Opciones de la Barra de Estado



De entre las opciones que veremos en este post:
Modo de celda
Relleno rápido de celdas en blanco
Relleno rápido en las celdas modificadas
Estadísticas del libro


Me centraré especialmente en el Modo de celda.

Pero una rápida de los otros items sería:
Relleno rápido de celdas en blanco: esta opción indica el número de celdas que se han dejado en blanco después de una operación de relleno rápido (marcada por defecto).

Opciones de la Barra de Estado

Observamos que tras completar los dos primeros C3:C4, seleccionamos el rango C3:C9 y aplicamos el Relleno rápido... al finalizar se muestra el mensaje en la barra de estado, donde nos dice cuántas celdas han quedado vacías...

Relleno rápido en las celdas modificadas: esta opción indica el número de celdas que se rellenaron con el relleno rápido (seleccionada de forma predeterminada)

Opciones de la Barra de Estado

En la imagen, tras completar los dos primeros C3:C4, seleccionamos el rango C3:C8 y aplicamos el Relleno rápido... al finalizar se muestra el mensaje en la barra de estado.

Estadísticas del libro: explicado en post anterior. Ofrece estadísticas de la hoja actual y del todo el libro.


Interesante, cierto?... seguramente nunca te hayas percatado de esto!.
Si esto te ha resultado curioso, la siguiente opción de Modo de celda, además es MUY necesaria.

Debemos saber que existen cuatro posibilidades de estado para la celda o modo (según las versiones los cuatro nombres pueden cambiar... pero con igual significado):

Listo: indica un estado general, i.e., listo para trabajar.

Opciones de la Barra de Estado


Introducir: para indicar el modo de entrada de contenido. Se muestra al seleccionar una celda y empezar a escribir, o al presionar F2.

Opciones de la Barra de Estado


Modificar: para indicar el modo de edición en la celda. Se muestra al hacer doble clic en una celda o al presionar F2 para que se pueda escribir o modificar datos existentes en una celda.

Opciones de la Barra de Estado


Señalar: Elija indicar el modo de selección de celdas de fórmula. Se muestra al iniciar una fórmula y, a continuación, hacer clic en las celdas que deseamos incluir en la fórmula.

Opciones de la Barra de Estado



Fundamental, por tanto, conocer el modo celda en que nos encontramos, ya que el comportamiento que tendrá el cursor (nuestras cuatro flechas) será distinto en cada caso!.

Estos modos de celda cobran especial relevancia cuando trabajamos en los cuadros diálogos de Nombres definidos, Validación de datos, Gráficos, etc... ya que el resultado de desplazarnos con el cursor tiene repercusiones distintas.

Podemos cambiar en Señalar y Modificar presionando F2.

En resumen, y en general independientemente de donde estemos, si el modo es Señalar accionar el cursor nos mostrará un movimiento de selección de celda.
Si nuestro estado es Introducir, y nos desplazamos con el cursor el estado cambia a Señalar... pero presionando F2 lo ajustamos a Modificar, por lo que al usar el cursor nos movemos DENTRO del campo o celda donde estemos, en lugar de seleccionar otras celdas...

Algo confuso quizá, pero muy fácil de comprobar ;-)

jueves, 21 de mayo de 2020

Estadísticas del Libro de Excel

Sencilla herramienta pero muy práctica para hoy: Estadísticas del Libro.

No todo tiene que ser difícil y retorcido, ya tenemos bastante con el día a día, a veces Excel nos facilita la 'existencia'... en este caso con estas simple herramienta de 'Estadísticas del libro.'

Estadísticas del Libro de Excel



Lo primero es saber donde se encuentra esta funcionalidad (te sorprenderá de cómo a la vista está!).
Accede a la ficha Revisar > grupo Revisión > botón Estadísticas de libro.
O bien personaliza la barra de estado mostrando la herramienta.

Su uso es bien simple, basta presionar cualquiera de las dos opciones anteriores que abrirán una pequeña ventana con las Estadísticas del libro, que se divide en dos secciones:
1- Estadísticas de la hoja actual:
- Final de la hoja
- Celdas con datos
- Tablas
- Fórmulas
2- Estadísticas de libro:
- Número de hojas
- Celdas con datos
- Tablas
- Fórmulas

Estadísticas del Libro de Excel


dos secciones con una información muy clara y útil...


Personalmente empleo con bastante frecuencia dos de los items...
1- Final de la hoja actual, equivaldría a hacer Ctrl+Fin, indicándome cuál es la última celda que Excel reconoce como empleada... Útil para saber si la hoja está 'corrompida' (echa un vistazo aquí).

2- Número de hojas de libro, que me indica rápida y visualmente si hay hojas 'ocultas' o 'muy ocultas'.


Rápidamente podemos comprobar cuántas fórmulas tenemos en nuestro libro (un número muy elevado ralentizará los procesos de recálculo.
E igualmente cuántas tablas hemos construido. Con un número alto de ellas, y el consumo de recursos del equipo consecuente, se nos puede complicar el trabajo en el libro.

¿Podemos pedir algo más a algo tan sencillo?.

martes, 19 de mayo de 2020

Office Scripts: mi primer script

Hace un tiempo publiqué el anuncio de la nueva aventura en Excel: Office Scripts (ver aquí).

Ya tenía pendiente escribir mi primer Script.. y aquí lo tengo.

La verdad es que he leído largo y tendido sobre este 'nuevo juguete' en la poca documentación que existe al respecto, y completado mi lectura con lenguaje JavaScript genérico. Supongo que para los que no somos informáticos, aprender nuevos lenguajes se nos hace un poco cuesta arriba.

Me he dado cuenta que, aunque a primera vista, el aspecto se asemeja a nuestro conocido VBA para Excel (las macros de toda la vida), y tiene puntos en común: Ambos son lenguajes basados en objetos, son solo semejanzas y no coincidencias...
Sinceramente no sabría decir si esto nos beneficia o perjudica, por la mezcla posible entre lenguajes a la que nos puede llevar.

En todo caso, el Editor de código de Office Scripts disponible, de momento, solo para la versión de Excel Online (en la Web), tiene habilitada la funcionalidad de 'intellisense', lo que ayuda bastante a la hora de escribir nuestro scripts.


Un aspecto importante, antes de comenzar, es que todos nuestros scripts están disponibles en una carpeta de OneDrive en la subcarpeta de Documentos > Script de Office

Office Scripts: mi primer script


Dentro encontraremos distintos archivos con extensión .osts que contienen el código generado y que tendremos disponible desde el Editor de Scripts desde cualquier libro que abramos!.

Ten presente, y no olvides, que los scripts de Office se escriben en TypeScript o JavaScript , y usan las API de JavaScript de scripts de Office para interactuar con los libros de Excel.

La grabadora de acciones genera código en TypeScript (superconjunto de JavaScript).
La documentación de scripts de Office usa TypeScript, pero si estás más familiarizado con JavaScript, desde luego puedes usarlo en su lugar.


Más que tenemos que saber antes de empezar... nuestros scripts son 'Case Sensitive' (sensible a las mayúsculas y minúsculas) !!!. OJO con este punto !!.

Y un punto importante más... Atención por que los índices son en base 0, i.e., el primer elemento de cualquier colección será el 0 siempre....


Veamos algunos de los operadores necesarios más habituales... (listado no completo!!).
Listemos operadores aritméticos permitidos:
+ Suma
- Sustracción
* Multiplicación
** Potencia (elevado a)
/ División
% División entera
++ Incremento
-- Decremento


Operadores de comparación:
== igual
=== igual valor y tipo
!= no igual / distinto
!== distinto valor o distinto tipo
> mayor que
< menor que
>= mayor o igual que
<= menor o igual que


Operadores lógicos:
&& lógico Y (AND)
|| lógico O (OR)
! lógico NO (NOT)


Operador de texto:
+ Añade o concatena cadenas de texto


Añadir comentarios en el script:
// para líneas sencillas
/* ... */ para multilíneas.


Algunas de las sentencias de control básicas como condicionales y bucles.

Sentencias condicionales:
equivale al clásico IF ... THEN ... ELSE ... en VBA.
if (condición) {
  //  código a ejecutar si se cumple la condición
}

if (condición) {
  //  código a ejecutar si se cumple la condición
} else {
  //  código a ejecutar si NO se cumple la condición
}
}

if (condición_1) {
  //  código a ejecutar si se cumple la condición_1
} else if (condición_2) {
  //  código a ejecutar si NO se cumple la condición_1 y la condición_2 es Verdadera
} else {
  //  código a ejecutar si las condiciones previas son todas Falsa
}

Otra sentencia condicional es SWITCH, que equivaldría a SELECT CASE ... END SELECT en VBA.
switch(expresión) {
  case x:
    // código
    break;
  case y:
    // código
    break;
  default:
    // código
}
Precaución de no olvidar incluir la instrucción 'break', si la omites se ejecutará el siguiente CASE aunque no se cumpla!.


Otras sentencias importantes son los BUCLES.
Por ejemplo el FOR simple:
for (statement_1; statement_2; statement_3) {
  // código a ejecutar
}
siendo:
Statement_1: se lee y ejecuta la primera vez (solo una) antes de nuestro bloque de código. El punto de inicio del bucle.
Statement_2: define la condición para ejecutar nuestro bloque de código. Condición final.
Statement_3: se ejecuta cada vez después del bloque de código. Tipo de incremento/decremento... el step.

Ejemplo:
for (i = 0; i < 13; i++) {
  text += "Nuestro número es " + i ;
}
Otro bucle clásico es WHILE:
while (condition) {
  // code block to be executed
}
Ejemplo: El siguiente código ejecuta, una y otra vez, mientras la variable 'i' sea menor a 13.
let i=0;
while (i < 13) {
  console.log( "El valor del numero es " + i);
  i++;
}
Con este breve adelanto, estamos listos para ver mi primer ejemplo de Script en Office. Accedemos a Excel Online desde nuestra cuenta de Office, y vamos a la ficha de Automatizar > grupo Herramientas de scripting > botón Editar de código. Se abrirá a la derecha el panel donde o bien buscaremos alguno de nuestros SCripts o Crearemos un nuevo. En este caso presionaremos Crear Script y copiaremos el siguiente código en la ventana:
async function main(context: Excel.RequestContext) {
  let hoja = context.workbook.worksheets.getActiveWorksheet();
  let rango = hoja.getUsedRange().load("Values, rowCount, columnCount");

  await context.sync();
  let UF=rango.rowCount ;
  let UC=rango.columnCount;

  //rango de recorrido
  let rngPais = hoja.getRangeByIndexes(2, 2, UF, 1).load("values")
  let rngUds = hoja.getRangeByIndexes(2, 3, UF , 1).load("values")

  await context.sync();

  // bucle para completar el Precio con un condicional 
  for (let i = 0; i < UF-1; i++) {
    let pais = rngPais.values[i];
    let uds = rngUds.values[i];
    let pz : number;

    // miramos país y unidades.
    if (pais[0] == 'ES') {
      pz = 100;
    } else if (pais[0] == 'FR') {
      pz = 20;
    } else if (pais[0] == 'PT') {
      pz = 3;
    } else { 
      pz = 0;
    }

    //además añadimos fórmula para Total
    let multiplica: any;
    let f=i+3;
    switch (true) {
      case (uds < 30):
        multiplica = "=1.05*D" + f + "*E" + f;
        break;
      case (uds< 60):
        multiplica = "=1.15*D" + f + "*E" + f;
        break;
    }

    await context.sync();
    rango.getCell(i + 1, 3).values = [[pz]];
    rango.getCell(i + 1, 4).formulas = [[multiplica]];
  }
}

Office Scripts: mi primer script

En entradas siguientes detallaré y explicaré algo más el script de arriba. Básicamente identifica en la hoja de cálculo donde hay datos, e inserta de forma condicionada en la columna E los precios según el país... y además, según el número de unidades, añadimos un total u otro.

jueves, 14 de mayo de 2020

PowerPivot: Ocultar en herramienta cliente

En nuestros modelos de datos es frecuente encontrarnos con múltiples columnas, medidas creadas, jerarquías, etc. que finalmente acaban mostrándose en nuestros paneles de lista de campos de los informes de tablas dinámicas generados, de manera innecesaria...
Un ejemplo de esto sería

PowerPivot: Ocultar en herramienta cliente



Por comodidad visual, por temas de espacio, y sobre todo para no 'aturullar' al usuario final con elementos innecesarios para él, disponemos de esta característica que permite, para los elementos que queramos, Ocultar/Mostrar en la herramienta cliente.
Esto acción NO impide nuestros cálculos en el modelo de datos.


Tenemos un par de formas para ocultar elementos.

Una primera desde la vista de Datos del editor de PowerPivot, y haciendo clic derecho sobre las columnas o medidas que queramos ocultar.

PowerPivot: Ocultar en herramienta cliente


o

PowerPivot: Ocultar en herramienta cliente



Una vez configurado como Oculto, desde la ficha Inicio > grupo Ver > botón Mostrar Oculto podemos decidir si hacerlos visibles a nivel interno del editor o no... para facilitar, si así lo queremos, nuestro trabajo.

PowerPivot: Ocultar en herramienta cliente



Otra forma de Ocultar o Mostrar en la herramienta cliente es desde la Vista de diagrama, igualmente haciendo clic derecho con el ratón en los elementos deseados (columnas, medidas, kpi, jerarquías,...)

PowerPivot: Ocultar en herramienta cliente



Igualmente desde la ficha Inicio > grupo Ver > botón Mostrar Oculto controlamos si queremos ver los elementos ocultos o no a nivel interno del editor.

Es posible hacer selecciones múltiples.

Una vez ocultos los elementos comprobamos el aspecto del panel de la lista de campos en la hoja de cálculo...

PowerPivot: Ocultar en herramienta cliente



Hay unan gran diferencia para el usuario en claridad ;-)

martes, 12 de mayo de 2020

PowerPivot: uso de variables VAR con DAX

Hoy toca un post realmente interesante por el trabajo que nos puede ahorrar al trabajar en nuestros modelos de datos, además de la limpieza y claridad que aporta a nuestras medidas y cálculos.
Hablaremos del uso de las variables VAR en el lenguaje DAX para PowerPivot.

Algunos conceptos a considerar.
VAR almacena el resultado de una expresión como una variable con nombre que después se puede pasar como argumento a otras expresiones de medida. Una vez que se han calculado los valores resultantes de una expresión variable, esos valores no cambian, aunque se haga referencia a la variable en otra expresión.

Por tanto, el valor devuelto es una variable con nombre que contiene el resultado del argumento de expresión.

Una expresión pasada como argumento a VAR puede contener otra declaración VAR.
Al hacer referencia a una variable:
-Las medidas no pueden hacer referencia a variables definidas fuera de la expresión de medida, pero pueden hacer referencia a variables de ámbito funcional definidas dentro de la expresión.
-Las variables pueden hacer referencia a medidas.
-Las variables pueden hacer referencia a variables definidas previamente.
-No se puede hacer referencia a columnas de variables de tabla mediante la sintaxis TableName[ColumnName].


Continuando con las entradas del blog anteriores a esta y con el modelo de datos de la imagen:

PowerPivot: uso de variables VAR con DAX



Supongamos queremos calcular, sobre nuestro modelo, el Margen de Ventas por Año y Cliente.
Sabiendo que el margen corresponde con:
(Ventas-Costes) / Ventas

Lo más simple sería crear una única medida:
MVentas%:=
VAR PC= SUMX(TblVentas;TblVentas[Unidades]*[PCM_total])
VAR PV= SUMX(TblVentas;TblVentas[Unidades]*TblVentas[Precio Venta unitario])
RETURN
DIVIDE(PV-PC;PV)


PowerPivot: uso de variables VAR con DAX



Antes de comprobar el resultado en un informe de tabla dinámica en la hoja de cálculo veremos la alternativa 'desgranada' en varías medidas.

Una primera medida para el 'Precio de Venta':
Pz_Venta_:=SUMX(TblVentas;TblVentas[Unidades]*TblVentas[Precio Venta unitario])

Una segunda medida para el 'Precio de Coste':
Pz_Coste:=SUMX(TblVentas;TblVentas[Unidades]*[PCM_total])

(ver entrada anterior para ver el cálculo de la medida [PCM_total]!!)

Y una última medida para componer el cálculo del Margen:
MargenVentas:=([Pz_Venta_]-[Pz_Coste])/[Pz_Venta_]

PowerPivot: uso de variables VAR con DAX



Comprobamos como el resultado de ambos procesos es idéntico... como cabía esperar.


Otro ejemplo del uso de VAR sería el siguiente:
TV_VAR:=
CALCULATE(
VAR PV=SUMX(TblVentas;TblVentas[Unidades]*TblVentas[Precio Venta unitario])
RETURN
PV;
CROSSFILTER(TblDirector[Cod país];TblPais[Cod país];Both)
)


que sustituiría a estas dos medidas dependientes...
PV:=SUMX(TblVentas;TblVentas[Unidades]*TblVentas[Precio Venta unitario])
y
TV_VAR:=CALCULATE([PV];CROSSFILTER(TblDirector[Cod país];TblPais[Cod país];Both))

Es un ejemplo muy sencillo, donde seguramente las variables no parecen aportar gran cosa, pero da la idea de su potencial...


Resulta curioso comprobar lo poco extendido que está la instrucción VAR de DAX entre los usuarios habituales de las herramientas Power (yo mismo me incluyo), por preferirse crear diferentes medidas 'parceladas' para finalmente componer el cálculo final...

Mas aún teniendo presente su funcionamiento, según los conceptos indicados al inicio del post, donde básicamente se indica que hay un proceso donde según definimos variables se graban en memoria, por lo que variables definidas posteriormente no pueden procesar cálculos (con CALCULATE por ejemplo, pero también operaciones con filtros); y segundas, terceras,... variables podrían no operar sobre previas, dejando huérfanos nuestros cálculos :-(

jueves, 7 de mayo de 2020

PowerPivot: LOOKUPVALUE como alternativa a CROSSFILTER en DAX

Continuando con el modelo de datos de los posts anteriores, explicaremos una función LOOKUPVALUE alternativa al uso de 'CROSSFILTER'.
Ver post anterior aquí.

Nuestro modelo de datos sigue siendo:

PowerPivot: LOOKUPVALUE como alternativa a CROSSFILTER en DAX



La función CROSSFILTER redefine el sentido de una relación ya existente, por lo que obviamente exige como requisito esa existencia... pues la función de hoy LOOKUPVALUE no requiere de relaciones existentes :O
LOOKUPVALUE( result_columnName; search_columnName; search_value[; search_columnName; search_value]…[; alternateResult])

siendo
result_columnName: Nombre de una columna existente que contiene el valor que se quiere devolver. Se debe asignar un nombre a la columna mediante la sintaxis DAX estándar, normalmente, completa. No puede ser una expresión.
search_columnName: Nombre de una columna existente, en la misma tabla que result_columnName o en una tabla relacionada, en la que se realiza la búsqueda. Se debe asignar un nombre a la columna mediante la sintaxis DAX estándar, normalmente, completa. No puede ser una expresión.
search_value: Expresión escalar que no hace referencia a ninguna columna de la misma tabla en la que se busca.
alternateResult(Opcional): Valor devuelto cuando el contexto de result_columnName se ha filtrado a cero o a más de un valor distinto. Cuando no se proporciona, la función devuelve BLANK() si result_columnName se filtra a cero o a un error cuando hay más de un valor distinto.

Algunos apuntes...
El valor de result_column en la fila donde todos los pares de search_column y search_value tienen una coincidencia.
Si no hay ninguna coincidencia que cumpla todos los valores de búsqueda, se devuelve BLANK o alternateResult, si se proporciona. En otras palabras, la función no devolverá un valor de búsqueda si solo coinciden algunos de los criterios.
Si varias filas coinciden con los valores de búsqueda y en todos los casos los valores de result_column son idénticos, se devuelve ese valor. Pero si result_column devuelve valores distintos, se devuelve un error o alternateResult, si se proporciona.


Detallados los aspectos teóricos de la función, veamos un ejemplo.

Definimos una primera medida:
Pz_Coste_medio:=AVERAGEX(TblVentas;LOOKUPVALUE(TblPdtoPrecio[Precio unitario coste];TblPdtoPrecio[Id Pdto];TblVentas[Producto ID]))

donde usamos LOOKUPVALUE para recuperar el 'Precio unitario coste' de la tabla T'blPdtoPrecio' cuando coincida el Id Pdto de esa tabla con el Producto ID de la TblVentas!.
Así evitamos el uso de CROSSFILTER para aquellos casos en lo que no existiera relación creada!... increíble, verdad?.

En segunda instancia aplicamos el ya conocido CROSSFILTER en la medida siguiente
PCosteMedio_CROSS:=CALCULATE([Pz_Coste_medio];CROSSFILTER(TblDirector[Cod país];TblPais[Cod país];Both))

PowerPivot: LOOKUPVALUE como alternativa a CROSSFILTER en DAX



Al generar nuestro informe de tabla dinámica, como en las entradas previas publicadas, observamos idéntico resultado al ejemplo de doble CROSSFILTER

PowerPivot: LOOKUPVALUE como alternativa a CROSSFILTER en DAX



Sin duda una buena opción LOOKUPVALUE a tener presente ;-)

martes, 5 de mayo de 2020

PowerPivot: Doble CROSSFILTER con DAX

Continuando con el modelo de datos del post anterior, expondré un ejemplo adicional de cómo y cuándo emplear un 'doble CROSSFILTER'.
Ver post anterior aquí.

El modelo de datos:

PowerPivot: Doble CROSSFILTER con DAX



Un apunte relevante para estos casos:
Si las expresiones de CALCULATE están anidadas y más de una expresión de CALCULATE contiene una función CROSSFILTER, la instancia de CROSSFILTER más interna es la que prevalece en caso de conflicto o ambigüedad.


El ejercicio de hoy consiste en lograr un informe que muestre un resultado de los Precios de coste por tipos de IVA y por Zonas.

Así pues comenzaremos creando una primera medida donde se emplea CROSSFILTER para saltarse el sentido inverso de la relación entre las tablas
TblProducto y TblPdtoPrecio
La medida sería:
PCM:=AVERAGEX(TblVentas;CALCULATE(SUM(TblPdtoPrecio[Precio unitario coste]);CROSSFILTER(TblProducto[Id Pdto];TblPdtoPrecio[Id Pdto];Both)))

La siguiente medida que se basa en la anterior (para facilitar su comprensión) y donde empleamos la segunda función CROSSFILTER sobre las tablas:
TblDirector y TblPais
sería:
PCM_total:=CALCULATE([PCM];CROSSFILTER(TblDirector[Cod país];TblPais[Cod país];Both))

PowerPivot: Doble CROSSFILTER con DAX



Al generar el informe de tabla dinámica en la hoja de cálculo, empleando estas medidas vemos los diferentes comportamientos...

PowerPivot: Doble CROSSFILTER con DAX



Observamos que la primera de las medidas [PCM] donde solo teníamos en cuenta una de las 'relaciones inversas' al usar CROSSFILTER(TblProducto[Id Pdto];TblPdtoPrecio[Id Pdto];Both), en la columna C de la hoja, donde deberíamos ver el dato cruzado de Tipo de IVA y Zona, solo se muestra el cruce de uno de ellos... sin considerar los elementos del otro... con valores en todas las zonas, incluso donde no existen datos ¿!?.
Llegamos solo al Precio de Coste asociado por producto, pero no a la Zona!!.

Sin embargo, comprobamos que sobre la segunda medida [PCM_total], donde si aplican los cambios en las dos relaciones... (con el segundo CROSSFILTER(TblDirector[Cod país];TblPais[Cod país];Both) )si llegamos al dato cruzado correcto.