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

Vote for your favorite vizzies from the Power BI Dataviz World Championship submissions. Vote now!

Reply
rajasekaro
Helper II
Helper II

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 

rajasekaro_0-1756810848172.png

how to create this give measure 

1 ACCEPTED SOLUTION

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

View solution in original post

16 REPLIES 16
v-agajavelly
Community Support
Community Support

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.

v-agajavelly
Community Support
Community Support

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.

v-agajavelly
Community Support
Community Support

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.

v-agajavelly
Community Support
Community Support

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.

danextian
Super User
Super User

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]

danextian_0-1756814354232.png

 





Dane Belarmino | Microsoft MVP | Proud to be a Super User!

Did I answer your question? Mark my post as a solution!


"Tell me and I’ll forget; show me and I may remember; involve me and I’ll understand."
Need Power BI consultation, get in touch with me on LinkedIn or hire me on UpWork.
Learn with me on YouTube @DAXJutsu or follow my page on Facebook @DAXJutsuPBI.

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 

rajasekaro_0-1756805512821.png

2.Statement 

rajasekaro_1-1756805618793.png

 

You already posted same thread, 
https://community.fabric.microsoft.com/t5/Desktop/Inventory-opening-closing/m-p/4814555#M1431892


Did I answer your question? If so, please mark my post as a solution!


Proud to be a Super User!




LinkedIn Icon
Muhammad Hasnain



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
Shahed Shaikh

NOT working 

rajasekaro_0-1756810055626.png

 

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

MohamedFowzan1
Solution Specialist
Solution Specialist

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:

MohamedFowzan1_0-1756965154796.png

 


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. 

MohamedFowzan1
Solution Specialist
Solution Specialist

Hi @rajasekaro 

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

MohamedFowzan1_0-1756812006989.png


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:

MohamedFowzan1_1-1756812079316.png
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:

MohamedFowzan1_0-1756812850372.png


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)

MohamedFowzan1_1-1756813167563.png

 

@MohamedFowzan1 
rajasekaro_0-1756976155357.png
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 

 

pankajnamekar25
Super User
Super User

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

 

If i select any between date its not show correct value 

rajasekaro_1-1756977643608.png

state ment report 

rajasekaro_2-1756977728109.png

if i select between date 
ledger 

rajasekaro_3-1756977802475.png
statement 

rajasekaro_4-1756977841973.png

 

 

Helpful resources

Announcements
Power BI DataViz World Championships

Power BI Dataviz World Championships

Vote for your favorite vizzies from the Power BI World Championship submissions!

Sticker Challenge 2026 Carousel

Join our Community Sticker Challenge 2026

If you love stickers, then you will definitely want to check out our Community Sticker Challenge!

January Power BI Update Carousel

Power BI Monthly Update - January 2026

Check out the January 2026 Power BI update to learn about new features.

FabCon Atlanta 2026 carousel

FabCon Atlanta 2026

Join us at FabCon Atlanta, March 16-20, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.