Cambios de inventario usando DAX: dilema de apertura y cierre dentro de la ubicación

Un usuario Pregunto ✅

mwimberger

Hola amigos

Tengo un problema interesante que resolver. Implica calcular los saldos de apertura y cierre para ubicaciones de inventario o existencias. La operación tiene un sistema de seguimiento de material que rastrea el material movido desde la fuente hasta los destinos para una operación a cielo abierto. En la mayoría de los casos, los saldos de apertura y cierre se resuelven utilizando las siguientes medidas:

Opening Stock Tonnes =
CALCULATE ( [Tonnage Movement],
     FILTER (
         ALLEXCEPT ( Data, Data[Stockpile_ID],Data[Stockpile_ID_Detail] )
       ,'Data'[Date] < min('Data'[Date])
    )
	

Closing Stock Tonnes = 
CALCULATE (
    [Tonnage Movement],
    FILTER (
        ALLEXCEPT ( Data, Data[Stockpile_ID] ),
        'Data'[Date] <= MAX ( 'Data'[Date] )
    )
)

Tonnage Movement =
CALCULATE ( SUMX ( 'Data', 'Data'[Tonnes] ), 'Data'[In_Code] = "IN" )
    - CALCULATE ( SUMX ( 'Data', 'Data'[Tonnes] ), 'Data'[In_Code] = "OUT" )

Todo esto funciona bien hasta que haya intrastockpile movimientos – o movimientos Entre arsenales. No debería ocurrir, pero la realidad, por supuesto, está en juego.

El problema se resume en las siguientes imágenes:

Diagrama.jpg

¡El problema ocurre en el signo de exclamación! arriba – en que la Reserva C tiene toneladas restadas, la Reserva D tiene toneladas agregadas, todo en una línea de transacción en la base de datos. Mi columna «In_Code» no es capaz de manejar, obviamente, tanto un código «In» y «Out» simultáneamente.

Hoja de cálculo.jpg

La hoja de cálculo anterior es un intento de mostrar en fórmulas lo que deberían Suceda con los tonelajes.

¿Alguien tiene una idea para manejar esto elegantemente en DAX? Tengo alrededor de 1.4 millones de filas de transacciones y sé que necesito optimizar un poco los cálculos (creo que mis iteradores SUMX posiblemente estén ralentizando las cosas) además del hecho de que los usuarios quieren esta información en una tabla de matriz que también se suma a los gastos generales . Pero lo primero es lo primero: ¿cómo manejar los movimientos dentro de las existencias? 🤷‍♂️😥

Cualquier ayuda sería muy apreciada. He estado intentando / luchando con USERELATIONSHIP pero me estaba saliendo de los problemas de memoria, y me he quedado sin pelo para sacarlo.

Gracias por adelantado

Manfred

roset03

Hola manfred

También necesito resolver un problema similar, también para los movimientos del bloque de mineral para apilar y de la trituradora para una operación a cielo abierto … con una tabla idéntica.
¡Me pregunto si lograste resolver este problema y si podrías compartir algunos detalles!

Muchas gracias,

Tim

mwimberger

En respuesta a roset03

Hola Tim

Me las arreglé para resolver esto. Mi solución inicial fue usar USERELATIONSHIP, pero esto no estuvo completamente libre de problemas, ya que parecía ralentizar las cosas.

Lo que luego me decidí fue una segunda consulta referenciada (subconjunto de los datos iniciales) y una relación de esta consulta con la lista de ubicaciones distintas (entradas y salidas)
Pronto detallaré exactamente cómo hice esto con una publicación más larga. ¡Es bueno ver algunos intereses relacionados con la minería!

Salud

Manfred

roset03

En respuesta a mwimberger

¡Apreciamos la actualización Manfred! Sería fantástico si pudiera actualizarnos a su debido tiempo. Con suerte, podemos comparar notas y encontrar una solución realmente agradable.

Supongo que su objetivo final es similar al mío: ¿para la planificación de mezclas para el grado de alimentación de la trituradora?

¡Muchas gracias!

Tim

mwimberger

En respuesta a roset03

Hola @ roset03

El objetivo final es, en parte, la combinación, pero, con mucho, el objetivo más grande era completar un marco completo de reconciliación de la cadena de valor que vincule a la geología, la minería y la metalurgia. Como sabrá, las existencias son generalmente un punto de transferencia entre departamentos y, por lo tanto, pueden resultar las más difíciles de administrar. Y para la mayoría de los estudios de conciliación, el Delta en las reservas es lo que se necesita para contabilizar el material que no va directamente del Pozo a la Planta.

Mi solución fue hacer lo siguiente:

Cree una tabla de datos separada (filtrada) de intrastockpile movimientos desde el Datos tabla

Data Filtered IntraStockpile =
FILTER (
    Data,
    LEFT ( Data[Unified_Origen], 6 ) = "Stock "
        && LEFT ( Data[Unified_Destination], 6 ) = "Stock "

Tenga en cuenta que creé un identificador «unificado» ya que el sistema de despacho, por alguna razón, tiene diferentes órdenes de taxonomía al nombrar fuentes y destinos.

Luego creé una tabla de dimensiones que generó una lista de la identificación de la pila y el detalle de la identificación de la pila (necesitaba pilas agrupadas en óxido, sulfuro o mixto)

tblStockpileIDUnique =
FILTER (
    SUMMARIZE ( data, Data[Stockpile_ID], Data[Stockpile_ID_Detail] ),
    Data[Stockpile_ID_Detail] <> ""
)

Esta tabla de dimensiones estaba vinculada a la tabla de datos original y a la tabla filtrada, pero usa las siguientes relaciones:

datos[Source] * —->tblStockpileIDUnique[Stockpile_ID_Detail] <---- * IntraStockpile de datos filtrados[Destination]

El tonelaje en se calcula como

Tonnage In = 
CALCULATE (
    SUM ( 'Data Filtered IntraStockpile'[TON_AJUSTADO] ),
    'Data Filtered IntraStockpile'[In_Code] = "OUT"
)
    + CALCULATE ( SUM ( 'Data'[TON_AJUSTADO] ), 'Data'[In_Code] = "IN" )

Tonelaje calculado como

Tonnage Out = calculate(sum('Data'[TON_AJUSTADO]),'Data'[In_Code]="OUT")

Movimiento de tonelaje calculado como:

Tonnage Movement = [Tonnage In]-[Tonnage Out]

Y luego aperturas y cierres definidos como:

Opening Stock Tonnes = 
VAR vLastDate = min('Data'[FECHA])
Return
CALCULATE ( [Tonnage Movement],
     FILTER (
         ALLEXCEPT ( Data, Data[Stockpile_ID],Data[Stockpile_ID_Detail] )
       ,'Data'[FECHA] < vLastDate )
    )


Closing Stock Tonnes = 
CALCULATE (
    [Tonnage Movement],
    FILTER (
        ALLEXCEPT ( Data, Data[Stockpile_ID], Data[Stockpile_ID_Detail] ),
        'Data'[FECHA] <= MAX ( 'Data'[FECHA] )
    )

(nota Fecha significa fecha en español)
Básicamente, la solución es vincular las existencias a ambos Origen y Destino (usando las dos tablas separadas) y use el código IN o OUT para calcular sumas y restas del movimiento de material. Hay un poco más en las configuraciones que preceden a estos pasos, como definir si el material se mueve HACIA ADENTRO o HACIA FUERA (según el diagrama anterior), pero eso es bastante fácil.
Envíeme un mensaje en LinkedIn si necesita más información; con gusto lo comentaremos si necesita más ayuda.

Salud

Manfred

mwimberger

Hola amigos

Tengo un problema interesante que resolver. Implica calcular los saldos de apertura y cierre para ubicaciones de inventario o existencias. La operación tiene un sistema de seguimiento de material que rastrea el material movido desde la fuente hasta los destinos para una operación a cielo abierto. En la mayoría de los casos, los saldos de apertura y cierre se resuelven utilizando las siguientes medidas:

Opening Stock Tonnes =
CALCULATE ( [Tonnage Movement],
     FILTER (
         ALLEXCEPT ( Data, Data[Stockpile_ID],Data[Stockpile_ID_Detail] )
       ,'Data'[Date] < min('Data'[Date])
    )
	

Closing Stock Tonnes = 
CALCULATE (
    [Tonnage Movement],
    FILTER (
        ALLEXCEPT ( Data, Data[Stockpile_ID] ),
        'Data'[Date] <= MAX ( 'Data'[Date] )
    )
)

Tonnage Movement =
CALCULATE ( SUMX ( 'Data', 'Data'[Tonnes] ), 'Data'[In_Code] = "IN" )
    - CALCULATE ( SUMX ( 'Data', 'Data'[Tonnes] ), 'Data'[In_Code] = "OUT" )

Todo esto funciona bien hasta que haya intrastockpile movimientos – o movimientos Entre arsenales. No debería ocurrir, pero la realidad, por supuesto, está en juego.

El problema se resume en las siguientes imágenes:

Diagrama.jpg

¡El problema ocurre en el signo de exclamación! arriba – en que la Reserva C tiene toneladas restadas, la Reserva D tiene toneladas agregadas, todo en una línea de transacción en la base de datos. Mi columna «In_Code» no es capaz de manejar, obviamente, tanto un código «In» y «Out» simultáneamente.

Hoja de cálculo.jpg

La hoja de cálculo anterior es un intento de mostrar en fórmulas lo que deberían Suceda con los tonelajes.

¿Alguien tiene una idea para manejar esto elegantemente en DAX? Tengo alrededor de 1.4 millones de filas de transacciones y sé que necesito optimizar un poco los cálculos (creo que mis iteradores SUMX posiblemente estén ralentizando las cosas) además del hecho de que los usuarios quieren esta información en una tabla de matriz que también se suma a los gastos generales . Pero lo primero es lo primero: ¿cómo manejar los movimientos dentro de las existencias? 🤷‍♂️😥

Cualquier ayuda sería muy apreciada. He estado intentando / luchando con USERELATIONSHIP pero me estaba saliendo de los problemas de memoria, y me he quedado sin pelo para sacarlo.

Gracias por adelantado

Manfred

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *