Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Power BI is turning 10! Let’s celebrate together with dataviz contests, interactive sessions, and giveaways. Register now.

Reply
Syndicate_Admin
Administrator
Administrator

LASTNONBLANK para cada cliente, ignorando otros filtros

Estoy tratando de determinar la fecha de inventario más reciente de un cliente y usarla para decidir si hacer referencia al inventario real o a un cálculo del inventario proyectado en una fórmula.

Tengo una tabla de hechos de inventario de canal con todo tipo de campos: OrganizationID, SubisidiaryID, ProductID, DateID, Quantity.

Tengo tablas diminutas para Organización, Cliente, Subsidiaria, Producto y Fecha.

Tengo una tabla de asignación entre los campos de Organización y Cliente.

Tengo una medida calculada que devuelve los datos de inventario asignados al cliente en lugar de a la organización:

Channel Inventory Qty (Customer) = 
CALCULATE(
    'Channel Inventory'[Channel Inventory Quantity],
    TREATAS(
        VALUES('CFO Account Level'[Top Parent Name]),
        Organization[Top Parent Name]
    ),
    REMOVEFILTERS('CFO Account Level'[Customer Group Name]),REMOVEFILTERS(Customer[Customer Group Name])
)

Tengo medidas para calcular el inventario de la semana pasada y el inventario proyectado:

Last Week Inventory = 
VAR LastWeek = max('Date'[Fiscal Week])-7
RETURN
CALCULATE([Channel Inventory Qty (Customer)],
    REMOVEFILTERS('Date'),KEEPFILTERS('Date'[Fiscal Week]=LastWeek)
)

Projected Inventory = 
[Last Week Inventory] + [Last Week SI] - [Actuals + CPFR Forecast Sell Thru Unlocked (Units)]

Estoy tratando de escribir una medida que reemplazaría [Inventario de la semana pasada] en la fórmula de Inventario proyectado:

Last Week Inventory or Projection = 
VAR LastWeek = MAX('Date'[Fiscal Week])-7
VAR LastInventory = LASTNONBLANK('Date'[Fiscal Week],'Channel Inventory'[Channel Inventory Quantity])
RETURN 
CALCULATE(
	IF(
		LastInventory >= LastWeek,
		[Channel Inventory Qty (Customer)],
		[Projected Inventory]
	),
    REMOVEFILTERS('Date'),KEEPFILTERS('Date'[Fiscal Week]=LastWeek)
)

La parte que me resulta complicada es que quiero calcular el LastInventory para el cliente en su conjunto, sin desglosar por producto, subsidiaria o cualquiera de los otros campos de la tabla de inventario de canales o en los filtros de página y los elementos visuales.

La relación TREATAS() entre el cliente y la organización también podría plantear un problema. ¿Quizás necesito duplicar eso en el código de la variable? (Tenga en cuenta que [SI de la semana pasada] y [Datos reales + Pronóstico de CPFR Venta desbloqueada (unidades)] están asociados con el cliente; solo la cantidad de inventario del canal está asociada con la organización).

Y, por supuesto, no sé si la recursividad también va a ser un problema.

Y otra parte más complicada: solo ocasionalmente se retrasa el informe de inventario de un cliente. Actualmente, nadie llega tarde, por lo que no puedo verificar si la parte del cálculo que elige el inventario proyectado cuando falta el inventario real está funcionando realmente.

Entonces, tengo dos preguntas:

  1. ¿El código, tal como está escrito, hará lo que espero, que es elegir si utilizar el inventario real o el inventario proyectado para cada combinación de cliente, subsidiaria y producto? Si no es así, ¿cómo lo soluciono?
  2. ¿Cómo hago que el código elija real frente a proyectado para cada cliente en su conjunto?
1 ACCEPTED SOLUTION

Mierda, lo descubrí. En lugar de construir cada semana sobre la semana anterior, necesito construir cada semana sobre el último inventario y la suma de SI o ST para todas las semanas entre el último inventario y ahora. Con este método, puede calcular una semana futura arbitraria sin necesidad de calcular cada semana intermedia.

Este es el código:

Projected Inventory = 
VAR CurrentWeek = MAX('Date'[Fiscal Week])
VAR LastInventory = 
    CALCULATE(
        LASTNONBLANK( 
            'Date'[Fiscal Week], 
            'Americas Retail'[Channel Inventory Qty (Customer)]
        ),
        REMOVEFILTERS( 'Date' ), 
        REMOVEFILTERS( 'Product' ), 
        REMOVEFILTERS( 'Subsidiary' ), 
        KEEPFILTERS( 'Date'[Fiscal Week] < CurrentWeek) 
    )

RETURN
CALCULATE( // Inventory from the calculated LastInventory date
    'Americas Retail'[Channel Inventory Qty (Customer)],
	REMOVEFILTERS( 'Date' ),
	KEEPFILTERS( 'Date'[Fiscal Week] = LastInventory )
)+
CALCULATE( // Sell In from the LastInventory date through to the week before CurrentWeek
	[Actuals + CPFR Forecast Sell In Unlocked (Units)],
	REMOVEFILTERS( 'Date' ),
	KEEPFILTERS( 'Date'[Fiscal Week] >= LastInventory && 'Date'[Fiscal Week] < CurrentWeek)
) -
CALCULATE( // Sell Thru from the week after the LastInventory date through to the CurrentWeek
	[Actuals + CPFR Forecast Sell Thru Unlocked (Units)],
	REMOVEFILTERS( 'Date' ),
	KEEPFILTERS( 'Date'[Fiscal Week] > LastInventory && 'Date'[Fiscal Week] <= CurrentWeek)
)

Tendré que volver a comprobar el cálculo de LastInventory la próxima vez que alguien se retrase en el envío de sus datos: ahora mismo todos los clientes muestran correctamente la misma fecha de LastInventory. Pero aparte de verificar ese pequeño caso extremo, ¡se ejecuta y produce los resultados correctos!

View solution in original post

7 REPLIES 7
Syndicate_Admin
Administrator
Administrator

Hola @shadowsong42

Conceptualmente, está en el camino correcto, pero el problema radica en la evaluación contextual de la variable LastInventory. Al usar LASTNONBLANK como lo ha hecho, sigue siendo sensible al contexto de evaluación actual, en particular los filtros por producto, subsidiaria u otros campos relacionados, por lo que no se calcula a nivel de cliente a menos que se le indique explícitamente. Para evitar esto, debe quitar esas dimensiones adicionales de la evaluación para que LastInventory refleje solo la última fecha de inventario por cliente, independientemente de otros filtros. Puede lograr esto aplicando ALLEXCEPT() para retener solo el contexto de nivel de cliente (o lo que defina a un cliente de manera única en su modelo). Además, dado que usas TREATAS() en tu medida [Cantidad de inventario de canal (cliente)], es posible que debas imitar esa lógica para garantizar la coherencia entre las medidas relacionadas. Esta es una versión refinada de la lógica que calcula la última fecha de inventario a nivel de cliente y cambia al inventario proyectado en consecuencia:

Last Week Inventory or Projection = 
VAR LastWeek = MAX('Date'[Fiscal Week]) - 7
VAR LastInventory = 
    CALCULATE(
        LASTNONBLANK('Date'[Fiscal Week], 'Channel Inventory'[Channel Inventory Quantity]),
        REMOVEFILTERS('Date'),
        ALLEXCEPT(Customer, Customer[Customer ID])  -- or substitute with the correct customer identifier
    )
RETURN
CALCULATE(
    IF(
        LastInventory >= LastWeek,
        [Channel Inventory Qty (Customer)],
        [Projected Inventory]
    ),
    REMOVEFILTERS('Date'),
    KEEPFILTERS('Date'[Fiscal Week] = LastWeek)
)

Esta estructura garantiza que LastInventory se determine únicamente en el nivel de cliente, sin que se vea afectado por otras segmentaciones de datos o objetos visuales que filtren por producto, subsidiaria u otras columnas. Asegúrese de que sus relaciones y la lógica de asignación en TREATAS() estén correctamente alineadas tanto en [Cantidad de inventario de canal (cliente)] como en esta medida. Una vez que tenga datos tardíos reales, puede validar la lógica de conmutación; Mientras tanto, considere la posibilidad de simular un retraso excluyendo las últimas semanas del inventario de un cliente para probar la ruta de reserva proyectada.

Apasionado por aprovechar el análisis de datos para impulsar la toma de decisiones estratégicas y fomentar el crecimiento empresarial.

Conéctate conmigo en LinkedIn: Rohit Kumar.

  1. ¿Cómo se prueba esto con DAX Studio? No puedo entender dónde deben ir los diversos DEFINEs y EVALUATEs.
  2. La cantidad de inventario del canal no está asociada con el cliente. ¿Puedo usar [Cantidad de inventario del canal (cliente)] en la variable LastInventory en su lugar?
  3. ¿La recursividad va a ser un problema, si [Inventario o proyección de la última semana] hace referencia a [Inventario proyectado] y [Inventario proyectado] hace referencia a [Inventario o proyección de la semana pasada]? Recuerde que la nueva fórmula para [Inventario proyectado] es
[Last Week Inventory or Projection] + [Last Week SI] - [Actuals + CPFR Forecast Sell Thru Unlocked (Units)]​

Hola @shadowsong42 ,
¡Gracias @rohit1991 y @danextian por la pronta respuesta!

1.Pruebas en DAX Studio: puede usar DEFINE y EVALUATE para probar su lógica fuera de los objetos visuales. El ejemplo de @rohit1991 código, simplemente modifique la parte SUMMARIZECOLUMNS para centrarse en el nivel de cliente que desea analizar.

2.Usar [Cantidad de inventario del canal (cliente)]: Sí, tiene sentido usarlo en su variable LastInventory, ya que se alinea con el contexto del cliente al que se dirige.

3. Problema de recursividad: Tiene razón al señalar esto. Si [Inventario proyectado] se refiere a [Inventario o proyección de la semana pasada], se crea una referencia circular. Una buena solución alternativa es separar la lógica, definir una medida [Base de inventario proyectado] y, a continuación, utilizarla en la lógica de conmutación.

Para probar el comportamiento de reserva, puede filtrar temporalmente los datos de inventario más recientes de un cliente de prueba y ver cómo reacciona su medida.

¡Espero que esto ayude! Si es así, considere aceptarlo como solución.

Saludos
Pallavi.

A continuación, se muestran algunos datos de muestra que muestran cómo quiero que funcione el cálculo en función de si hay inventario disponible en la semana anterior. Básicamente, para cada semana, necesito poder hacer referencia al cálculo de la semana anterior.

¿Puedes decirme cómo lograr esto?

Semana FiscalInventarioCFórmula proyectadaResultado proyectado
4/25/202575,9571,0816,624Prev Inv + Prev SI - Este ST76,644
5/2/202571,6645,7917,366Prev Inv + Prev SI - Este ST69,672
5/9/202571,43810,5137,884Prev Inv + Prev SI - Este ST69,571
5/16/2025 14,5699,616Prev Inv + Prev SI - Este ST72,335
5/23/2025 11,57112,285Prev Proj + Prev Si - Este St74,619
5/30/2025 11,50812,174Prev Proj + Prev Si - Este St

74,016

Mierda, lo descubrí. En lugar de construir cada semana sobre la semana anterior, necesito construir cada semana sobre el último inventario y la suma de SI o ST para todas las semanas entre el último inventario y ahora. Con este método, puede calcular una semana futura arbitraria sin necesidad de calcular cada semana intermedia.

Este es el código:

Projected Inventory = 
VAR CurrentWeek = MAX('Date'[Fiscal Week])
VAR LastInventory = 
    CALCULATE(
        LASTNONBLANK( 
            'Date'[Fiscal Week], 
            'Americas Retail'[Channel Inventory Qty (Customer)]
        ),
        REMOVEFILTERS( 'Date' ), 
        REMOVEFILTERS( 'Product' ), 
        REMOVEFILTERS( 'Subsidiary' ), 
        KEEPFILTERS( 'Date'[Fiscal Week] < CurrentWeek) 
    )

RETURN
CALCULATE( // Inventory from the calculated LastInventory date
    'Americas Retail'[Channel Inventory Qty (Customer)],
	REMOVEFILTERS( 'Date' ),
	KEEPFILTERS( 'Date'[Fiscal Week] = LastInventory )
)+
CALCULATE( // Sell In from the LastInventory date through to the week before CurrentWeek
	[Actuals + CPFR Forecast Sell In Unlocked (Units)],
	REMOVEFILTERS( 'Date' ),
	KEEPFILTERS( 'Date'[Fiscal Week] >= LastInventory && 'Date'[Fiscal Week] < CurrentWeek)
) -
CALCULATE( // Sell Thru from the week after the LastInventory date through to the CurrentWeek
	[Actuals + CPFR Forecast Sell Thru Unlocked (Units)],
	REMOVEFILTERS( 'Date' ),
	KEEPFILTERS( 'Date'[Fiscal Week] > LastInventory && 'Date'[Fiscal Week] <= CurrentWeek)
)

Tendré que volver a comprobar el cálculo de LastInventory la próxima vez que alguien se retrase en el envío de sus datos: ahora mismo todos los clientes muestran correctamente la misma fecha de LastInventory. Pero aparte de verificar ese pequeño caso extremo, ¡se ejecuta y produce los resultados correctos!

Syndicate_Admin
Administrator
Administrator

Hola @shadowsong42

El problema con esta variable es que se ve afectada por el contexto de consulta introducido al agregar o quitar campos a un objeto visual.

VAR LastInventory = LASTNONBLANK('Date'[Fiscal Week],'Channel Inventory'[Channel Inventory Quantity])

Lo cambié a algo como esto:

VAR LastInventory = 
CALCULATE (
    LASTNONBLANK (
        'Date'[Fiscal Week],
        'Channel Inventory'[Channel Inventory Quantity]
    ),
    ALLEXCEPT ( tbl, tbl[customer] )
)
Syndicate_Admin
Administrator
Administrator

Hola

Comparta algunos datos con los que trabajar y muestre el resultado esperado. Comparta datos en un formato que se pueda pegar en un archivo de MS Excel.

Helpful resources

Announcements
June 2025 Power BI Update Carousel

Power BI Monthly Update - June 2025

Check out the June 2025 Power BI update to learn about new features.

June 2025 community update carousel

Fabric Community Update - June 2025

Find out what's new and trending in the Fabric community.

Top Solution Authors