Join us for an expert-led overview of the tools and concepts you'll need to pass exam PL-300. The first session starts on June 11th. See you there!
Get registeredPower BI is turning 10! Let’s celebrate together with dataviz contests, interactive sessions, and giveaways. Register now.
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:
Solved! Go to 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!
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.
[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 Fiscal | Inventario | SÍ | C | Fórmula proyectada | Resultado proyectado |
4/25/2025 | 75,957 | 1,081 | 6,624 | Prev Inv + Prev SI - Este ST | 76,644 |
5/2/2025 | 71,664 | 5,791 | 7,366 | Prev Inv + Prev SI - Este ST | 69,672 |
5/9/2025 | 71,438 | 10,513 | 7,884 | Prev Inv + Prev SI - Este ST | 69,571 |
5/16/2025 | 14,569 | 9,616 | Prev Inv + Prev SI - Este ST | 72,335 | |
5/23/2025 | 11,571 | 12,285 | Prev Proj + Prev Si - Este St | 74,619 | |
5/30/2025 | 11,508 | 12,174 | Prev 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!
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] )
)
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.