Forum Discussion

rajasekaro's avatar
rajasekaro
Helper III
1 year ago
Solved

Inventory opening closing

i have inventory data need to calculate opeing closing to create detail ledger 

ItemDocdateQTYTYPEdocid
BP Monitor19-03-2024150RCPTdo1
BP Monitor17-04-202410ISSUdo2
BP Monitor01-07-2024150RCPTdo3
BP Monitor03-07-202410ISSUdo4
BP Monitor04-07-2024300RCPTdo5
BP Monitor02-12-2024100ISSUdo6
BP Monitor27-12-2024250RCPTdo7
BP Monitor21-01-2025250RCPTdo8
BP Monitor19-02-2025150RCPTdo9
BP Monitor13-03-2025100RCPTdo10
BP Monitor15-04-2025250RCPTdo11
BP Monitor30-04-2025200ISSUdo12
BP Monitor05-07-2025300ISSUdo13
BP Monitor21-08-2025200RCPTdo14

EXPECTED OUTPUT
1.Detail Ledger 

how to create this give measure 

  • Anonymous's avatar
    Anonymous
    11 months ago

    Hi rajasekaro ,

    Let me give you the ready-to-use Power Query (M) solution that will works for you.

    1. Sort the data by Docdate.
    2. Create Received and Issued columns.
    3. Calculate Running Closing balance.
    4. Calculate Opening (previous closing, first row = 0).
    5. Produce two outputs.
      • Detail Ledger (row-wise)
      • Summary Statement (Opening=0, total Received, total Issued, Closing).

    use the bellow M code.

    let
        // Replace with your source table name
        Source = YourTable,  
        // 1. Sort by Docdate
        Sorted = Table.Sort(Source, {{"Docdate", Order.Ascending}}),
        // 2. Add Received & Issued columns
        AddReceived = Table.AddColumn(Sorted, "Received", each if [TYPE] = "RCPT" then [QTY] else 0, type number),
        AddIssued   = Table.AddColumn(AddReceived, "Issued", each if [TYPE] = "ISSU" then [QTY] else 0, type number),
        // 3. Add Index column
        AddIndex = Table.AddIndexColumn(AddIssued, "Index", 1, 1, Int64.Type),
        // 4. Add Closing as running balance
        AddClosing = Table.AddColumn(AddIndex, "Closing", each
            List.Sum(List.FirstN(AddIndex[Received],[Index]))
            - List.Sum(List.FirstN(AddIndex[Issued],[Index]))
        , type number),
        // 5. Add Opening = Previous row Closing (first row = 0)
        AddOpening = Table.AddColumn(AddClosing, "Opening", each
            if [Index] = 1 then 0
            else AddClosing[Closing]{[Index]-2}
        , type number),
        // 6. Reorder columns
        DetailLedger = Table.ReorderColumns(AddOpening, {"Item","Docdate","Opening","Received","Issued","Closing"}),
        // 7. Create Summary Statement
        OpeningVal = 0,
        ReceivedVal = List.Sum(DetailLedger[Received]),
        IssuedVal = List.Sum(DetailLedger[Issued]),
        ClosingVal = OpeningVal + ReceivedVal - IssuedVal,
        Statement = #table({"Item","Docdate","Opening","Received","Issued","Closing"}, {{"Statement","",OpeningVal,ReceivedVal,IssuedVal,ClosingVal}})
    in
    [DetailLedger = DetailLedger, Statement = Statement]


    If you still face any issues, let us know happt to help.

    Thanks,
    Akhil

16 Replies

  • Providing the final working measures:

    Closing Measure = 
    VAR CurrentDate = MAX('Table'[Docdate])
    RETURN
        CALCULATE(
            SUMX(
                'Table',
                SWITCH(
                    TRUE(),
                    'Table'[TYPE] = "RCPT", 'Table'[QTY],
                    'Table'[TYPE] = "ISSU", -'Table'[QTY],
                    0
                )
            ),
            FILTER(ALL('Table'), 'Table'[Docdate] <= CurrentDate)
        )

     

    Issue Measure Measure = 
    VAR Result =
        CALCULATE(
            SUM('Table'[QTY]),
            FILTER(
                'Table',
                'Table'[TYPE] = "ISSU" &&
                'Table'[Docdate] = MAX('Table'[Docdate])
            )
        )
    RETURN
        IF(ISBLANK(Result), 0, Result)

     

    Opening Measure = 
    VAR CurrentDate = MAX('Table'[Docdate])
    VAR PreviousDate =
        CALCULATE(
            MAX('Table'[Docdate]),
            FILTER(ALL('Table'),'Table'[Docdate] < CurrentDate)
        )
    RETURN
        IF(
            ISBLANK(PreviousDate),
            0,
            CALCULATE([Closing Measure], FILTER(ALL('Table'), 'Table'[Docdate] = PreviousDate))
        )

     

    Received Measure = 
    VAR Result =
        CALCULATE(
            SUM('Table'[QTY]),
            FILTER(
                'Table',
                'Table'[TYPE] = "RCPT" &&
                'Table'[Docdate] = MAX('Table'[Docdate])
            )
        )
    RETURN
        IF(ISBLANK(Result), 0, Result)


    Result:

     


    For a detailed summary on the possibilities or you would like 0 instead of blanks please review my previous comment. For just the measures, please use these. 

  • Hello rajasekaro 

    Try with below measures

     

    Inward =

    SUMX (

        FILTER ( Inventory, Inventory[TYPE] = "RCPT" ),

        Inventory[QTY]

    )

     

    Outward =

    SUMX (

        FILTER ( Inventory, Inventory[TYPE] = "ISSU" ),

        Inventory[QTY]

    )

     

     

    Running Balance (Closing Stock)

    Closing Stock =

    VAR CurrentDate = MAX ( Inventory[DocDate] )

    RETURN

    CALCULATE (

        SUMX (

            Inventory,

            IF ( Inventory[TYPE] = "RCPT", Inventory[QTY], -Inventory[QTY] )

        ),

        FILTER ( Inventory, Inventory[DocDate] <= CurrentDate )

    )

     

     

    Opening Stock (Previous Closing)

    Opening Stock =

    VAR CurrentDate = MAX ( Inventory[DocDate] )

    VAR PreviousClosing =

        CALCULATE (

            [Closing Stock],

            FILTER ( Inventory, Inventory[DocDate] < CurrentDate )

        )

    RETURN

    COALESCE ( PreviousClosing, 0 )


    If my response helped you, please consider clicking
    Accept as Solution and giving it a Like 👍 – it helps others in the community too.


    Thanks,


    Connect with me on:

    LinkedIn

     

    • rajasekaro's avatar
      rajasekaro
      Helper III

      If i select any between date its not show correct value 

      state ment report 

      if i select between date 
      ledger 


      statement 

       

       

  • Hi rajasekaro 

    I was able to create this (Make sure to sort the data by DocDate first):


    After loading the data create the necessary calculated columns:

    Closing = 'Table'[Opening] + 'Table'[Received] - 'Table'[Issue]
    
    Issue = IF('Table'[TYPE] = "ISSU", 'Table'[QTY], 0)
    
    Opening = 
    VAR CurrentDate = 'Table'[Docdate]
    VAR CurrentIndex = 
        RANKX(
            FILTER('Table', 'Table'[Item] = EARLIER('Table'[Item])),
            'Table'[Docdate],
            ,
            ASC,
            Dense
        )
    RETURN
    IF(
        CurrentIndex = 1,
        0,
        CALCULATE(
            SUM('Table'[Received]) - SUM('Table'[Issue]),
            FILTER(
                'Table',
                RANKX(
                    FILTER('Table', 'Table'[Item] = EARLIER('Table'[Item])),
                    'Table'[Docdate],
                    ,
                    ASC,
                    Dense
                ) = CurrentIndex - 1
            )
        )
    )
    
    Received = IF('Table'[TYPE] = "RCPT", 'Table'[QTY], 0)


    Final Output:


    The above should work, if your data is huge and donot want to use EARLIER function,

    In Powerquery,
    Sort by DocDate Ascending
    Add an Index Column starting from 1.

    Add calculated columns:

    Received and Issue as before.

    Closing as before.

    Add the Opening column using the below DAX:

    Opening =
    VAR CurrentIndex = 'Table'[Index]
    RETURN
    IF(
        CurrentIndex = 1,
        0,
        LOOKUPVALUE('Table'[Closing], 'Table'[Index], CurrentIndex - 1)
    )


    If not Columns, and you need to use measures:

    Closing Measure = 
    VAR CurrentDate = MAX('Table'[Docdate])
    RETURN
        CALCULATE(
            SUMX(
                'Table',
                SWITCH(
                    TRUE(),
                    'Table'[TYPE] = "RCPT", 'Table'[QTY],
                    'Table'[TYPE] = "ISSU", -'Table'[QTY],
                    0
                )
            ),
            FILTER(ALL('Table'), 'Table'[Docdate] <= CurrentDate)
        )
    
    
    Issue Measure = 
    CALCULATE(
        SUM('Table'[QTY]),
        'Table'[TYPE] = "ISSU"
    )
    
    Opening Measure = 
    VAR CurrentDate = MAX('Table'[Docdate])
    VAR PreviousDate =
        CALCULATE(
            MAX('Table'[Docdate]),
            FILTER(ALL('Table'),'Table'[Docdate] < CurrentDate)
        )
    RETURN
        IF(
            ISBLANK(PreviousDate),
            0,
            CALCULATE([Closing Measure], FILTER(ALL('Table'), 'Table'[Docdate] = PreviousDate))
        )
    
    Received Measure = 
    CALCULATE(
        SUM('Table'[QTY]),
        'Table'[TYPE] = "RCPT"
    )


    Output with measures:


    Got rid of the blanks:
    Use:

    Issue Measure Measure = 
    VAR Result =
        CALCULATE(
            SUM('Table'[QTY]),
            FILTER(
                'Table',
                'Table'[TYPE] = "ISSU" &&
                'Table'[Docdate] = MAX('Table'[Docdate])
            )
        )
    RETURN
        IF(ISBLANK(Result), 0, Result)
    
    Received Measure = 
    VAR Result =
        CALCULATE(
            SUM('Table'[QTY]),
            FILTER(
                'Table',
                'Table'[TYPE] = "RCPT" &&
                'Table'[Docdate] = MAX('Table'[Docdate])
            )
        )
    RETURN
        IF(ISBLANK(Result), 0, Result)

     

    • rajasekaro's avatar
      rajasekaro
      Helper III

      MohamedFowzan1 

      the statement report not showing correct value 
      and if i show the closing qty in KPI its also showing wrong value how to fix this 

       

  • Hi rajasekaro 

    Create the following measures:

    Sum of qty = 
    SUM ( inventory[QTY] )
    
    Opening =
    CALCULATE (
        [Received] - [Issued],
        FILTER (
            ALL ( inventory[Docdate] ),
            inventory[Docdate] < MIN ( inventory[Docdate] )
        )
    )
    
    Received = 
    CALCULATE ( [Sum of qty], KEEPFILTERS ( inventory[TYPE] = "RCPT" ) )
    
    Issued = 
    CALCULATE ( [Sum of qty], KEEPFILTERS ( inventory[TYPE] = "ISSU" ) )
    
    Closing = 
    CALCULATE (
        [Received] - [Issued],
        FILTER (
            ALL ( inventory[Docdate] ),
            inventory[Docdate] <= MAX ( inventory[Docdate] )
        )
    )
    
    or 
    
    Closing =
    [Opening] + [Received] - [Issued]

     

    • rajasekaro's avatar
      rajasekaro
      Helper III

      i have inventory data need to calculate opeing closing to create detail ledger 
      Table: STOCKVALUE

      ItemDocdateQTYTYPEdocid
      BP Monitor19-03-2024150RCPTdo1
      BP Monitor17-04-202410ISSUdo2
      BP Monitor01-07-2024150RCPTdo3
      BP Monitor03-07-202410ISSUdo4
      BP Monitor04-07-2024300RCPTdo5
      BP Monitor02-12-2024100ISSUdo6
      BP Monitor27-12-2024250RCPTdo7
      BP Monitor21-01-2025250RCPTdo8
      BP Monitor19-02-2025150RCPTdo9
      BP Monitor13-03-2025100RCPTdo10
      BP Monitor15-04-2025250RCPTdo11
      BP Monitor30-04-2025200ISSUdo12
      BP Monitor05-07-2025300ISSUdo13
      BP Monitor21-08-2025200RCPTdo14


      EXPECTED OUTPUT
      1.Detail Ledger 

      2.Statement 

       

      • Shahid12523's avatar
        Shahid12523
        Community Champion

        Do it in Power Query (easiest):

        1.Sort by Docdate.

        2.Add columns:

        • Received = if TYPE="RCPT" then QTY else 0
        • Issued = if TYPE="ISSU" then QTY else 0

        3.Add Closing = running sum of (Received – Issued).

        4.Add Opening = Previous row Closing (shifted down, first = 0).

         

        Result → Detail Ledger.

         

        For Statement:

        • Opening = 0
        • Received = SUM(Received) = 1800
        • Issued = SUM(Issued) = 620
        • Closing = 1180
  • Anonymous's avatar
    Anonymous
    Not applicable

    Hi rajasekaro ,

    Thanks to the pankajnamekar25  , MohamedFowzan1  and danextian  for sharing the detailed approaches .
    rajasekaro  do you think the solutions shared above will work for your case? Please let us know if you run into anything that doesn’t work as expected, so we can help you further.

    Regards,
    Akhil.

  • Anonymous's avatar
    Anonymous
    Not applicable

    Hi rajasekaro ,

    Is super users shared solutions were you able to try out any of these solutions yet? If you hit any roadblocks or something doesn’t behave as expected, feel free to share back so we can dive deeper.

    Regards,
    Akhil.

  • Anonymous's avatar
    Anonymous
    Not applicable

    Hi rajasekaro ,

    Just circling back, did you get a chance to test any of the super users solutions? If one of them worked, please mark it as the accepted solution so it can help others in the community as well.

    Regards,
    Akhil.

  • Anonymous's avatar
    Anonymous
    Not applicable

    Hi rajasekaro ,

    I hope the response provided helped in resolving the issue. If you still have any questions, please let us know we are happy to address.

    Thanks,
    Akhil.