Join us at FabCon Atlanta from March 16 - 20, 2026, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.
Register now!The Power BI Data Visualization World Championships is back! It's time to submit your entry. Live now!
Tenemos dos tablas: una de Inventario y una de Pedidos de Venta , ambas vinculadas por el ID de Artículo.
Cuando se realiza una orden de venta, se asigna al inventario disponible más cercano para ese artículo en función de las limitaciones de longitud y ancho .
Por ejemplo, para el ID de Artículo "ABC", supongamos que el inventario tiene una longitud de 500 y un ancho de 200. Si recibimos 5 pedidos de venta para el artículo ABC, cada uno requiriendo un ancho de 180 y una longitud de 100, entonces este único registro de inventario es suficiente para cumplir con los 5 pedidos. En este caso, el mismo ID de inventario debe asignarse a las 5 órdenes de venta en una columna o medida calculada.
Una vez que ese registro de inventario se consume por completo, no debe asignarse a pedidos de venta posteriores.
Conceptualmente, esto se asemeja a un proceso de asignación en bucle o secuencial :
para cada orden de venta, selecciona el inventario que mejor coincide, asigna el ID de inventario, reduce la cantidad restante disponible (longitud/ancho) y luego traslada el saldo restante para pedidos posteriores.
¿Es posible implementar este tipo de lógica en Power BI?
Datos de ejemplo a continuación para 1 artículo (Inventario y orden de compra)
| ID de inventario | Id de ítem | Longitud | Ancho |
| PIO-001100 | BKFL578812 | 10000 | 200 |
| PIO-001101 | BKFL578812 | 100000 | 240 |
| PIO-001102 | BKFL578812 | 80000 | 600 |
| Orden de venta | Línea de ventas nº | ARTÍCULO DE VENTA | Duración de las ventas | Ancho de venta | Cantidad de ventas |
| LODEO-00235878 | 2 | BKFL578812 | 5868 | 90 | 3 |
| LODEO-00236882 | 2 | BKFL578812 | 2291 | 40 | 3 |
| LODEO-00236882 | 3 | BKFL578812 | 2470 | 40 | 3 |
| LODEO-00236882 | 4 | BKFL578812 | 2649 | 40 | 3 |
| LODEO-00236882 | 9 | BKFL578812 | 3544 | 40 | 3 |
| LODEO-00236882 | 8 | BKFL578812 | 3365 | 40 | 3 |
| LODEO-00236882 | 18 | BKFL578812 | 5154 | 40 | 3 |
| LODEO-00236882 | 17 | BKFL578812 | 4975 | 40 | 3 |
Hola @Vivek26 ,
Me tomaría un momento para darle las gracias a @SavioFerraz , por participar activamente en el foro comunitario y por las soluciones que has estado compartiendo en el foro comunitario. Tus contribuciones marcan una verdadera diferencia.
Quería comprobar si tuviste la oportunidad de revisar la información proporcionada. No dudes en contactarnos si tienes más preguntas
Hola @Vivek26 ,
Quería comprobar si tuviste la oportunidad de revisar la información proporcionada. No dudes en contactarnos si tienes más preguntas
Hola @Vivek26
Opción 1: Power Query (M) – Asignación secuencial
Lógica de alto nivel en Power Query:
1. Filtrar inventario por ID de artículo
2. Ordenar el inventario por prioridad (tamaño más cercano / ajuste más pequeño)
3. Ordenar pedidos de venta por fecha / número de línea
4. Para cada pedido de venta:
-Encuentra el primer inventario donde:
Inventario.Duración >= Ventas.Duración * Cantidad
Inventario.Ancho >= Ventas.Ancho
-Asignar ID de inventario
-Reducir inventario. Longitud
-Llevar la longitud restante hacia adelante
AllocateInventory = (SalesTable como tabla, InventoryTable como tabla) =>
Sea
SortedSales = Table.Sort(SalesTable, {{"Sales Line no", Order.Ascending}}),
Asignación =
List.Generate(
() => [i = 0, Inventario = Tabla de Inventario],
cada [i] < Tabla.RowCount(SortedSales),
cada [
Inventario = ActualizaciónInventario([Inventario], SortedSales{i}),
i = [i] + 1
],
cada AsignaciónInventoryID([Inventario], SortedSales{i})
)
en
Asignación
Opción 2: Columna calculada (SOLO si se cumplen las suposiciones)
Esto solo funciona si:
-El inventario nunca se comparte entre los objetos
-Los pedidos se procesan en una secuencia estricta
-El ancho es un filtro duro
-La longitud se consume de forma lineal
Paso 1: Crea una demanda acumulada por artículo
Longitud acumulada requerida =
CALCULATE(
SUMX(
FILTER(
Ventas,
Ventas[ID de artículo] = ANTES(Ventas[ID de artículo]) &&
Ventas[Línea de Ventas nº <= ANTES(Ventas[Línea de Ventas nº])
),
Ventas[Duración de ventas] * Ventas[Cantidad de ventas]
)
)
Paso 2: Asignar ID de inventario (lógica de primer ajuste)
ID de inventario asignado =
VAR ReqLength = Ventas[Duración acumulada requerida]
DEVOLUCIÓN
CALCULATE(
MIN(Inventario[ID de inventario]),
FILTER(
Inventario,
Inventario[ID de artículo] = Ventas[ARTÍCULO DE Venta] & &
Inventario[Ancho] >= Ventas[Ancho de Venta] &&
Inventario[Longitud] >= Longitud requerida
)
)
Opción 3: Medir → IMPOSIBLE
No se puede actualizar el inventario
No se puede persistir el estado
Recalcula cada interacción visual
Así que la asignación en bucle es matemáticamente imposible en las medidas.
Hola @Vivek26
👉 Este tipo de lógica de bucle / asignación secuencial no puede implementarse correctamente usando DAX (medidas o columnas calculadas).
Por qué esto no es factible en DAX
Lo que describes es un proceso secuencial y con estado:
Acepta la primera orden de venta
Encuentra el registro de inventario que mejor coincida
Asigna el ID de inventario
Reduce la longitud / anchura disponible restante
Pasa a la siguiente orden de venta y repite usando el saldo actualizado
Esto requiere:
Iteración fila a fila
Memoria de asignaciones anteriores
Mutación de las cantidades restantes de inventario
DAX no soporta esto.
DAX es:
Declarativo (no procedimental)
Apátridas
Evaluado de forma independiente por fila o contexto de filtro
Por eso:
Las medidas no pueden "recordar" las filas anteriores
Las columnas calculadas no pueden recorrer las filas en orden
No puedes decrementar el inventario progresivamente entre líneas de venta
Cualquier solución DAX solo se vería correcta visualmente, pero se rompería en cuanto cambiaran el orden, los filtros o el contexto.
La forma correcta de resolver esto
✅ Opción 1 — Power Query (Recomendado dentro de Power BI)
Si la lógica de asignación puede hacerse en tiempo de refresco, entonces:
Usa Power Query (M)
Ordena las órdenes de venta de forma determinista (por ejemplo, por fecha del pedido, número de línea)
Para cada ID de Artículo:
Iterar por las filas de ventas
Asignar inventario
Longitud / Anchura restante de vía
Saca el ID de inventario asignado como una columna real
Esta es la opción más fiable dentro de Power BI.
✅ Opción 2 — Procesamiento upstream (Buenas prácticas)
Para escenarios de producción:
Realizar asignación en:
SQL
Python
Cuadernos Spark / Fabric
Guarda el resultado como:
Una tabla de datos
O una tabla puente (ID de Línea → Inventario de Ventas)
Luego Power BI se vuelve puramente analítico, que es exactamente para lo que está diseñado.
❌ Qué no hacer
No intentes forzar esto con medidas DAX
No te fíes de la clasificación + los totales acumulados para "simular" el consumo
No intentes una lógica circular entre las tablas de inventario y ventas
Esos enfoques no serán estables ni correctos.
Ilustración conceptual
Inventario (inicial)
PIO-001100 → Longitud: 10000, Ancho: 200
Pedidos de venta (secuenciales)
La orden 1 → consume 100x180
Inventario restante → 9900 x 20
La orden 2 → consume 100x180
Inventario restante → 9800 x 20
...
Orden N → hasta agotarse
El siguiente pedido → pasar al siguiente ID de inventario
Este tipo de mutación con estado debe ocurrir antes de que los datos lleguen al modelo Power BI.
Resumen
❌ No es posible en DAX (por diseño)
✅ Posible en Power Query (lógica de tiempo de refresco)
✅ Mejor resuelto en upstream (SQL / Fabric / Python)
✔ Power BI debería consumir el resultado, no calcularlo
Si esta explicación te ha ayudado, por favor considera darle un kudos 👍
Y si responde a tu pregunta, siéntete libre de marcarla como la Respuesta ✔ Aceptada