Click here to Skip to main content
15,892,927 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
How to Fetch Stock Calculation Fastest Way in vb.net

Hi i need to retrive fastest way to calculate stock,
my formula is

Stock = Opening Stock + PURCHASE STOCK - OUTGOING STOCK + CREDIT NOTE STOCK - DEBIT NOTE STOCK

while single item it comes fast but with multiple item it will take too much time


My BACK END IS SQL SERVER 2012 and FRONT END IS VB.NET

Please reply
thanks in advance

What I have tried:

I just used

First i fire query from Product in that i retrieve data from diff. diff table like Purhcase , INVOICE, CREDIT NOTE , DEbit Note and all
but it takes too much time if item is 50 then only it takes time please suggest i applied index on all table also


MY CODe CODE

VB.NET
sqlSelect.CommandText = "Select Opening_Stock,ProdId from Product_tbl"
    adp.SelectCommand = sqlSelect
    adp.Fill(ds, "PrdList")

    While i <= ds.Tables("PrdList").Rows.Count - 1
        strCate = ""
        strSubCate = ""
        iStock = 0
        iGRN = 0
        iOrdQty = 0
        iCrd = 0
        iDbt = 0
        iWrkStock = 0
        iOrdWorkQty = 0
        iOpn = 0
        iIncStock = 0


        iStockTransFrom = 0
        iStockTransTo = 0
        iAssem = 0
        iAssemOth = 0
        iShortFall = 0


strProdId = (ds.Tables("PrdList").Rows(i).Item("Prod_Id").ToString)

        iOpn = Val(ds.Tables("PrdList").Rows(i).Item("Opening_Stock").ToString)


        sqlSelectInnr.CommandText = "Select ISNULL(SUM(Qty),0) as GRNQty from GRNTable where GRN_Type='Local' and Prod_Id=" & strProdId
        dtAdtInnr.SelectCommand = sqlSelectInnr
        dtAdtInnr.Fill(dtStInnr, "GRN_Stock")
        If dtStInnr.Tables("GRN_Stock").Rows.Count - 1 >= 0 Then
            iGRN = Val(dtStInnr.Tables("GRN_Stock").Rows(0).Item("GRNQty").ToString)
        End If
        dtStInnr.Tables("GRN_Stock").Rows.Clear()



        sqlSelectInnr.CommandText = "select ISNULL(SUM(Qty_FullFill),0) as Qty from Order_tbl where Prod_Id=" & strProdId & ""

        dtAdtInnr.SelectCommand = sqlSelectInnr
        dtAdtInnr.Fill(dtStInnr, "Ord_Dtls")
        If dtStInnr.Tables("Ord_Dtls").Rows.Count - 1 >= 0 Then
            iOrdQty = Val(dtStInnr.Tables("Ord_Dtls").Rows(0).Item("Qty").ToString)
        End If
        dtStInnr.Tables("Ord_Dtls").Rows.Clear()



        sqlSelectInnr.CommandText = "Select ISNULL(SUM(Qty),0) as CrdQty from CrditNote_tb where Prod_Id=" & strProdId
        dtAdtInnr.SelectCommand = sqlSelectInnr
        dtAdtInnr.Fill(dtStInnr, "Crd_Dtls")
        If dtStInnr.Tables("Crd_Dtls").Rows.Count - 1 >= 0 Then
            iCrd = Val(dtStInnr.Tables("Crd_Dtls").Rows(0).Item("CrdQty").ToString)
            End If
        dtStInnr.Tables("Crd_Dtls").Rows.Clear()

        sqlSelectInnr.CommandText = "Select ISNULL(SUM(Qty),0) as DbtQty from DebitNote_tb where Prod_Id=" & strProdId
        dtAdtInnr.SelectCommand = sqlSelectInnr
        dtAdtInnr.Fill(dtStInnr, "Dbt_Dtls")
        If dtStInnr.Tables("Dbt_Dtls").Rows.Count - 1 >= 0 Then
            iDbt = Val(dtStInnr.Tables("Dbt_Dtls").Rows(0).Item("DbtQty").ToString)
            End If
        dtStInnr.Tables("Dbt_Dtls").Rows.Clear()





        iStock = iOpn + iGRN - iOrdQty + iCrd - iDbt

        If iStock < 0 Then
            iStock = 0

            End If

        dgvData.Rows.Add(strProdId, ds.Tables("PrdList").Rows(i).Item("Prod_Name").ToString, iStock) ',  strItemType, ds.Tables("PrdList").Rows(i).Item("HSN_Code").ToString, strCate, ds.Tables("PrdList").Rows(i).Item("Location_Name").ToString, ds.Tables("PrdList").Rows(i).Item("Rack_No").ToString, ds.Tables("PrdList").Rows(i).Item("Tax3_Per").ToString, Val(ds.Tables("PrdList").Rows(i).Item("WQty").ToString), Val(ds.Tables("PrdList").Rows(i).Item("MIQ").ToString), iWrkStock, iIncStock, ds.Tables("PrdList").Rows(i).Item("Product_Description").ToString)

            k += 1


        i += 1
    End While

    ds.Tables("PrdList").Rows.Clear()
Posted
Updated 1-Feb-20 3:45am
v4
Comments
Richard MacCutchan 1-Feb-20 5:04am    
Please edit your question and show the code that causes the problem. No one can guess what your program is doing.
hareshdgr8 1-Feb-20 5:14am    
ok sir
Patrice T 1-Feb-20 13:44pm    
"while single item it comes fast but with multiple item it will take too much time"
Define "fast" and "too much time".
Patrice T 1-Feb-20 13:49pm    
By the way, database structure, relations and indexes matters too

At the first look - too many select queries!
VB.NET
sqlSelectInnr.CommandText = "Select ISNULL(SUM(Qty),0) as GRNQty from GRNTable where GRN_Type='Local' and Prod_Id=" & strProdId
'...
sqlSelectInnr.CommandText = "select ISNULL(SUM(Qty_FullFill),0) as Qty from Order_tbl where Prod_Id=" & strProdId & ""
'...
sqlSelectInnr.CommandText = "Select ISNULL(SUM(Qty),0) as CrdQty from CrditNote_tb where Prod_Id=" & strProdId
'...
sqlSelectInnr.CommandText = "Select ISNULL(SUM(Qty),0) as DbtQty from DebitNote_tb where Prod_Id=" & strProdId
'...


I'd strongly recommend to use Joins[^]. For further details, please read this: Visual Representation of SQL Joins[^]

SQL
SELECT ISNULL(SUM(G.Qty),0) as GRNQty, ISNULL(SUM(O.Qty_FullFill),0) as Qty, ISNULL(SUM(C.Qty),0) as CrdQty, ISNULL(SUM(D.Qty),0) as DbtQty
FROM GRNTable AS G
    INNER JOIN Order_tbl AS O ON O.Prod_Id = G.Prod_Id
    INNER JOIN CrditNote_tb AS C.Prod_Id = G.Prod_Id
    INNER JOIN DebitNote_tb AS D.Prod_Id = G.Prod_Id
WHERE G.GRN_Type='Local' and G.Prod_Id=@prodid


You'll probably in need to use GROUP BY statement[^].

I have to warn you about SqlInjection[^].
Instead of concatenated strings, you have to use parameterized queries[^]!

Below is an OleDb example.
VB.NET
Try
    Dim sConn As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=DatabaseName.accdb;Persist Security Info =False;"
    Dim oRdr As OleDbDataReader
    Dim dt As DataTable = New DataTable()
    Dim empIdToFind As Integer = 111

    Using oConn As OleDbConnection = New OleDbConnection(sConn)
        oConn.Open()
        Using oComm AS OleDbCommand = New OleDbCommand()
            oComm.Connection = oConn
            oComm.CommandType = CommandType.Text
            oComm.CommandText =  "SELECT * FROM EmployeeTbl WHERE EmpId=@empid;"
            oComm.Parameters.AddWithValue("@empid", empIdToFind)
            oComm.ExecuteNonQuery()
            oRdr = oComm.ExecuteReader()
            dt.Load(oRdr)
        End Using
        oConn.Close()
    End Using

    dt.Dump()

Catch ex As OleDbException
    Console.WriteLine(ex.Message)

Catch ex As Exception
    Console.WriteLine(ex.Message)

End Try


Good luck!
 
Share this answer
 
Comments
hareshdgr8 1-Feb-20 7:08am    
sir can't use join because some time other table dont have product details in it we have to fetch one by one only there is only the way...
example Some product not in GRN and in Credit note there is same product thats why using too much select ... JOIN is FAIL in my scenario ....

help me more if you got my point sir
MadMyche 1-Feb-20 13:09pm    
+5
Maciej Los 1-Feb-20 15:14pm    
Thank you very much!
First things first: your code is susceptible to SQL Injection. Already covered in other answers, so I will not rehash.

Second thing on this list is that your VB code is chit-chatting with the SQL Server way too much; you need to cut down the amount of SQL Commands you are executing back to back

Third thing on this list is a recommendation of checking your database schemas; the item of interest are INDEXes, have they been created and are you indexing the right things relative to this query.

And now for my recommendations
Stop working on this block of code in Visual Studio. Install Sql Server Management Studio and use the tools within it, such as Include Actual Execution Plan; to fine tune the queries and to see what INDEX work needs to be done.
You can also do some research into using joinssubqueries in concert to see what needs to be done to utilize this. AND your set of queries can be done this way.

Once you have your query issues worked out, I would then place all of the queries into 1 Stored Procedure. This will compile all of the queries into one execution plan and optimize them once- which will make the batch run quicker and will only need one call from VB which will reduce chit-chat between servers.
I am not going to rewrite all of this for you as I don't have your schemas and this is something you should learn through research and working with the tools. BUT you may end up with something like this (which just may work for ya as is)
SQL
CREATE PROCEDURE dbo.AggregateValues (
   @ProdID NVARCHAR(16)
) AS
BEGIN
    SELECT p.ProdID
         , GRNQty   = ISNULL(SUM(g.Qty),0)
         , Qty      = ISNULL(SUM(o.Qty_FullFill)
         , CrdQty   = ISNULL(SUM(c.Qty),0)
         , DbtQty   = ISNULL(SUM(d.Qty),0)
   FROM (SELECT ProdID = @ProdID) p
   LEFT OUTER JOIN GRNTable      g ON p.ProdID = g.Prod_ID AND g.GRN_Type='Local'
   LEFT OUTER JOIN Order_tbl     o ON p.ProdID = o.Prod_ID
   LEFT OUTER JOIN CrditNote_tb  c ON p.ProdID = c.Prod_ID
   LEFT OUTER JOIN DebitNote_tb  d ON p.ProdID = d.Prod_ID
END
GO
Naturally you will get to rework your VB to accommodate this change
Here are the basics on calling this new Stored Procedure, and it is in C# so you will need to transcode it into VB but that should help you understand what is going on; and is mostly vernacular changes so it should be relatively easy. Take note of cmd.Parameters.Add... line, as that is the proper way to add variables into a SQL command to mitigate the SQL Injection Vulnerability
c#b
SqlCommand cmd = new SqlCommand("AggregateValues", connection);
cmd.CommandType =  CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@ProdID", strProdId);

SqlDataReader dr = cmd.ExecuteReader();
if ((dr != null) && (dr.Rows.Count > 0)) {
  // retrieve values from "dr" and put where you need them
 
Share this answer
 
Comments
Maciej Los 1-Feb-20 15:15pm    
5ed!
[edit]done[/edit]
hareshdgr8 3-Feb-20 5:47am    
sir u are right that i want to use left outer join thank you for your hint sorry to late reply ....

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900