ขอคำแนะนำหรือแนวคิด เรื่องการตัดสต็อกแบบ FIFO พร้อม Update ค่าสต็อกคงเหลือ
วันนี้ ผมมีเรื่อง ๆ หนึ่ง คือ อยากจะขอ คำแนะนำ หรือ แนวคิด หลักการของ การตัดสต็อกสินค้า แบบ FIFO
ก่อนอื่นนั้น ผมได้ จัดทำ เกี่ยวกับระบบจัดการฟาร์มไข่ไก่ ขึ้นมาครับ แต่ติดปัญหาเรื่องการตัดสต็อกไข่ไก่ ครับ ขออธิบายแบบ ง่าย ๆ รวดเร็วละกันครับ ในฐานข้อมูล ผมได้สร้างตารางสต็อกไข่ ประกอบด้วย (PK)egg_id, stk_total(จำนวนที่เก็บ) และ (PK)pick_date
ปัญหาที่ผมเจอคือ หาใน ตารางสต็อกไข่ ได้ทำการจัดเก็บ
ไข่เบอร์ 3 จำนวน 75 ฟอง วันที่เก็บ 12/2/2554 ..... (1)
ไข่เบอร์ 3 จำนวน 40 ฟอง วันที่เก็บ 13/2/2554
------- > (1) เมือลูกค้าซื้อ จะต้องตัดสต็อกจาก Record (1) ก่อนใช่ไหมครับ ปัญหาที่ผมว่าคือ เมื่อลูกค้าซื้อในจำนวน 90 ฟอง แล้ว มันตัด จำนวน 75 ฟองก็จริงครับ แต่มันไม่ยอมไป ตัดอีกRecord คือไข่เบอร์ 3 ของวันที่ 13/2/2554
ซึ่งพอผม Update ค่าสต็อกไข่ลงเหลือ ก็จะกลายเป็นว่า วันที่ 12/2/2554 จะเป็นสต็อกไข่ ติดลบ (-15)
********* ท่านใดพอมีคำแนะนำ หรือ แนวคิดหลักการ เกี่ยวกับเรื่องนี้ไหมครับ ว่าจะทำไง ให้ตัดสต็อก ไม่ติดค่าลบ ขอเรื่องการ Update สต็อกลงเหลือด้วยครับ ****** ปล.ขอบคุณล่วงหน้าครับ ด้านล่าง Code ที่ผมเขียนไว้ครับ
Code (VB.NET)
Dim sql As String = ""
Dim sqlSave As String = ""
sqlSave = sql.ToString()
Dim i As Integer
Dim EggId As String
Dim EggPrice As Double = 0.0
Dim EggQuan As Integer = 0
Dim EggTotal As Double = 0.0
Dim OldAmount As Integer
Dim NewAmount As Integer
Dim StkDate As Date
'วนลูปเก็บค่าสินค้าใน listview มาใส่ในตัวแปร เพื่อ การตัดสต็อกสินค้า และ Update ค่าสต็อกคงเหลือ ลงในตาราง Stok
For i = 0 To lsvEggList.Items.Count - 1
EggId = lsvEggList.Items(i).SubItems(0).Text
EggPrice = CDbl(lsvEggList.Items(i).SubItems(1).Text)
EggQuan = CInt(lsvEggList.Items(i).SubItems(2).Text)
EggTotal = CDbl(lsvEggList.Items(i).SubItems(3).Text)
sql.Remove(0, sql.Length)
sql = "SELECT * FROM stok WHERE egg_id = @egg_id ORDER BY pick_date ASC"
sqlSave = sql.ToString()
_cmd = New OleDbCommand(sql, _conn)
With _conn
_cmd.CommandText = sqlSave
_cmd.Parameters.Clear()
_cmd.Parameters.Add("egg_id", OleDbType.Char).Value = EggId
Dim reader As OleDbDataReader = _cmd.ExecuteReader()
If reader.HasRows Then
reader.Read()
OldAmount = reader("stk_total")
StkDate = reader("pick_date")
reader.Close()
NewAmount = (OldAmount - (EggQuan * 30))
sql.Remove(0, sql.Length)
sql = "UPDATE stok SET stk_total = @SumPick, pick_date = @date WHERE egg_id = @eggid AND pick_date = @date"
sqlSave = sql.ToString
_cmd = New OleDbCommand(sql, _conn)
With _conn
_cmd.CommandText = sqlSave
_cmd.CommandType = CommandType.Text
_cmd.Parameters.Clear()
_cmd.Parameters.Add("SumPick", OleDbType.Integer).Value = NewAmount
_cmd.Parameters.Add("date", OleDbType.Date).Value = StkDate
_cmd.Parameters.Add("eggid", OleDbType.Char).Value = EggId
_cmd.ExecuteNonQuery()
End With
End If
End With
Tag : .NET, Ms Access, VBScript, Class Library, VB.NET, VS 2008 (.NET 3.x)
ประวัติการแก้ไข 2011-02-12 17:31:16
Date :
2011-02-12 17:21:45
By :
iSOON_zA
View :
4150
Reply :
14
มีท่านใด พอมีแนวทาง หรือ คำแนะนำ บ้างครับ ยังแก้ไม่ได้เลยครับ ติดตรง การขาย ตัดสต็อก และ Update สต็อกนี่แหละครับ
ยังไงก็ต้องขอคำแนะนำ ทุก ๆ ท่าน .......... ขอบคุณล่วงหน้า มา ณ ที่นี้ ด้วยครับ
Date :
2011-02-13 16:08:04
By :
iSOON_zA
สงสัยจะยาก หรือผมอธิบายไม่เข้าใจ
ขอถามอีกทีครับ
Code (VB.NET)
Dim reader As OleDbDataReader = _cmd.ExecuteReader()
If reader.HasRows Then
reader.Read()
OldAmount = reader("stk_total")
StkDate = reader("pick_date")
reader.Close()
คำสั่ง reader อ่ะครับ ถ้าผมต้องการ ค่าของวันที่ reader("pick_date") แล้วเป็น แถวที่ 2 ผมต้องเขียน code ไงครับ
พอมีใคร จะอธิบายได้ไหมครับ ประมาณว่า เลือก แถวที่ 2 ของวันที่ อ่ะครับ จะเขียนเป็นคำสั่ง reader ยังไง ?
ขอขอบคุณ ล่วงหน้า ครับ
Date :
2011-02-13 23:45:32
By :
iSOON_zA
ไม่แน่ใจตารางเก็บสต็อคไข่ของคุณ
มีแค่ 3 ฟิล์ดนี้หรือไม่ egg_id, pick_date, stk_total
เพราะผมมองว่าน้อยไป
อย่างน้อยมันน่าจะเป็น
egg_id เบอร์ไข่
stk_date วันที่ปรับปรุงยอด
stk_amt จำนวนไข่
stk_balance จำนวนไข่คงเหลือ
ตัวอย่างข้อมูล
egg_id, stk_date, stk_amt, stk_balance
3 2011-02-12@10:00 75 75
3 2011-02-13@10:00 40 115
3 2011-02-14@9:00 -90 25
คล้ายๆ กับสมุดบัญชีธนาคาร
ประวัติการแก้ไข 2011-02-14 09:01:36 2011-02-14 09:01:53
Date :
2011-02-14 09:00:53
By :
หางอึ่ง
ที่ ท่านแนะนำ คือยังไงครับ ประมาณว่า
เบอร์ไข่ จำนวนเก็บ จำนวนคงเหลือ วันที่เก็บ
3 100 100 12/2/2554
3 70 70 13/2/2554
***********************************************************
แบบนี้ใช่ไหมครับ ถ้าผมจะตัดแบบ FIFO ผมต้องตัด จากจำนวนคงเหลือ ของวันที่ 12/2/2554 ก่อนใช่หรือไม่ครับ
ถ้าขายไข่ เบอร์ 3 ไป 120 ฟอง ผมต้องตัด วันที่ 12/2/2554 ออกไป 100 = 0 ส่วน 20 ฟองที่เหลือ ตัดว่าที่ 13/2/2554
มันจะแตกต่างจาก ฐานข้อมูลเก่าที่ผมเขียนไว้ตรงไหนครับ ยังงง
พอจะอธิบาย หลักการ ตัดและUpdate ข้อมูล เวลาขายแล้วตัดสต็อกออก ได้ไหมครับ
ยังไงก็ขอบคุณที่ยังพอมีคำแนะนำดี ๆ แบบนี้ครับ ^___^
Date :
2011-02-14 09:12:13
By :
iSOON_zA
ออ พอจะเข้าใจที่ท่านอธิบาย ล่ะ ครับ ประมาณว่า เก็บผมรวมแล้ว ตัด
แต่ก่อนอื่นผมต้องขออธิบายเลยครับ ว่า ระบบที่ทำไว้ เมื่อเราเก็บไข่ในแต่ละวัน เราจะต้องจัดเก็บสต็อกตามวันครับ
พอเวลาขาย เขาจะต้องตัดสต็อกของวันที่เราเก็บไข่เข้าสต็อกก่อนก่อนครับ ประมาณว่า เก็บก่อน ขายก่อน (FIFO)
เพราะว่า ที่ทำแบบนี้ คือ ไข่ไก่สด จะมีระยะอายุความสดไว้ เพราะฉะนั้น จึงต้องตัดตามวันที่ ๆ เราเก็บมาก่อนครับ
(ระบายไข่ออก เดียวไข่เสีย) นี่แหละครับ เหตุผลที่ว่าทำไมผมต้องเก็บแล้วตัดเป็นวัน ๆ ไป
ยังไงก็ต้องขอคำแนะนำต่อไปครับ เพราะตอนนี้ ติดอยู่ตรง ตัด อัพเดท นี่แหละครับ
ขอบคุณ ล่วงหน้าอีกทีครับ
Date :
2011-02-14 10:54:42
By :
iSOON_zA
select * from table where stk_total < 0
ถ้า มีค่า
ก็แก้ค่าที่ติดลบให้เป็น 0 ซะ
แล้วเอาค่า ติดลบไปรวม กับวันที่ถัดไป
ทำอย่างงี้ไปเรื่อยๆจนกว่าไม่พบค่าติดลบ
แค่นี้เอง
ประวัติการแก้ไข 2011-02-14 11:28:36
Date :
2011-02-14 11:21:53
By :
cyberstein
ลองดูเรื่อง Transaction ผมว่าน่าจะใช้ได้ดี..
Date :
2011-02-14 14:19:47
By :
EvoLutionGT
while(eggQty > 0)
{
string sql = "select top 1 egg_id,stl_total,pick_date from tbl_egg where stl_total > 0 order by pick_date "
ถ้า stl_total >= eggqty ให้
update stl_total =stl_total - eggqty where eggid = ?? and pick_date = ???
eggQty = 0
จบ
ถ้า stl_total < eggqty ให้
update stl_total = 0 where eggid = ?? and pick_date = ???
eggQty -= stl_total
จบ
}
ถ้าจะให้ดีสร้าง Table ที่เก็บ History การตัด Stock ไว้ด้วยจะดีมาก
ง่ายๆ ครับ ไกด์ให้แค่นี้นะครับ
Date :
2011-02-14 16:18:06
By :
superpheak
อันนี้ที่ทำใหม่ครับ เกือบจะได้ล่ะครับ ติดตรง เรื่องอัพเดท ลงในวันที่ ถัดไปCode (VB.NET)
'วนลูปเก็บค่าสินค้าใน listview มาใส่ในตัวแปร เพื่อบันทึกลงในตาราง sale_detail
For i = 0 To lsvEggList.Items.Count - 1
EggId = lsvEggList.Items(i).SubItems(0).Text
EggPrice = CDbl(lsvEggList.Items(i).SubItems(1).Text)
EggQuan = CInt(lsvEggList.Items(i).SubItems(2).Text)
EggTotal = CDbl(lsvEggList.Items(i).SubItems(3).Text)
sql.Remove(0, sql.Length)
sql = "SELECT * FROM stok WHERE egg_id = @egg_id ORDER BY pick_date ASC"
sqlSave = sql.ToString()
_cmd = New OleDbCommand(sql, _conn)
With _conn
_cmd.CommandText = sqlSave
_cmd.Parameters.Clear()
_cmd.Parameters.Add("egg_id", OleDbType.Char).Value = EggId
Dim reader As OleDbDataReader = _cmd.ExecuteReader()
If reader.HasRows Then
reader.Read()
OldAmount = reader("stk_total")
StkDate = reader("pick_date")
reader.Close()
NewAmount = (OldAmount - (EggQuan * 30))
If NewAmount <= 0 Then
b = OldAmount - NewAmount
a = a - b
sql.Remove(0, sql.Length)
sql = "DELETE * FROM stok WHERE egg_id =@eggid AND pick_date = @date"
sqlSave = sql.ToString
_cmd = New OleDbCommand(sql, _conn)
With _conn
_cmd.CommandText = sqlSave
_cmd.CommandType = CommandType.Text
_cmd.Parameters.Clear()
'_cmd.Parameters.Add("SumPick", OleDbType.Integer).Value = NewAmount
_cmd.Parameters.Add("eggid", OleDbType.Char).Value = EggId
_cmd.Parameters.Add("date", OleDbType.Date).Value = StkDate
_cmd.ExecuteNonQuery()
End With
sql.Remove(0, sql.Length)
sql = "UPDATE stok SET stk_total = SumPick, pick_date = @date WHERE egg_id = @eggid AND pick_date = @date"
sqlSave = sql.ToString
_cmd = New OleDbCommand(sql, _conn)
With _conn
_cmd.CommandText = sqlSave
_cmd.CommandType = CommandType.Text
_cmd.Parameters.Clear()
_cmd.Parameters.Add("SumPick", OleDbType.Integer).Value = a
_cmd.Parameters.Add("date", OleDbType.Date).Value = StkDate
_cmd.Parameters.Add("eggid", OleDbType.Char).Value = EggId
_cmd.ExecuteNonQuery()
End With
Else
sql.Remove(0, sql.Length)
sql = "UPDATE stok SET stk_total = @SumPick, pick_date = @date WHERE egg_id = @eggid AND pick_date = @date"
sqlSave = sql.ToString
_cmd = New OleDbCommand(sql, _conn)
With _conn
_cmd.CommandText = sqlSave
_cmd.CommandType = CommandType.Text
_cmd.Parameters.Clear()
_cmd.Parameters.Add("SumPick", OleDbType.Integer).Value = NewAmount
_cmd.Parameters.Add("date", OleDbType.Date).Value = StkDate
_cmd.Parameters.Add("eggid", OleDbType.Char).Value = EggId
_cmd.ExecuteNonQuery()
End With
End If
ประวัติการแก้ไข 2011-02-14 19:52:28
Date :
2011-02-14 19:17:57
By :
iSOON_zA
คุณ Palm ครับ ผมก็คิดแบบเดียวกับคุณเลยครับ แต่ของผมคือ ถ้าขายแล้วตัดแล้ว ค่า ติดลบหรือ <0 ให้ ลบ Record นั้นทิ้ง
แต่ติดตรงที่วัน ผมจะอัพเดท ค่าที่ b = OldAmount - NewAmount >>> a = a - b แล้ว แล้วเอา a ไปอัพค่าสต็อกของอีกวันที่ ยังไงนี่สิครับ
จากโค้ดที่ใช้ คือ reader.HasRow อ่านค่า StkDate = reader("pick_date") <<<< ซึ่งตรงนี้มันเก็บวันที่ ของ Record แรกที่ตัดไป
ตอนนี้ว่าจะสร้างอีกตัวแปร คือเก็บค่า วันที่ ของ Record 2 อ่ะครับ แต่ติดตรงไม่รู้ code ว่าจะ reader("pick_date")ตำแหน่งที่ 2 ยังไง
-----------
คุณ EvoLutionGT ผมยังไม่ได้ศึกษาเกี่ยวคำสั่ง Transaction เลยครับ (ผมพึ่งหัดพึ่งเริ่มเป็นครั้งแรกครับสำหรับการเขียน VB) เดียวจะลองศึกษาดูครับ ขอบคุณมา ณ ที่นี้ด้วยครับ
----------
ส่วนสุดท้าย คุณ post ผมยังงง กับcode ที่ให้ครับ คือที่ While นี้ จะใช้ตอนที่ ตัดสต็อกแล้วติด ลบ หรือยังไงครับ พอจะคอมเม้นให้ทีได้ไหมครับ ซึ่งจาก code ที่ผมทำ คือ For ค่าใน Listview ไว้ แล้วก็เลือกเบอร์ไข่ ที่อยู่ใน Listview . . . ซึ่งตอนนี้ผมก็ยังไงว่าจะให้ While ตอนไหนดี ยังไงช่วย คอมเม้นให้ผมซักเล็กน้อยครับ
--------------------------------------------------------------
ยังไงก็ต้องขอบคุณทุก ๆ ท่านน่ะครับที่ให้คำปรึกษา คำแนะนำต่าง ๆ
ปล. มีท่านใดพอรู้เกี่ยวกับ คำสั่ง reader.HasRow แล้วก็ reader("pick_date")ตำแหน่งที่ 2,3,4, . . . n บ้างครับ ที่ทำไว้คือมันอ่านค่าของบรรทัดแรก แต่อยากให้มันอ่านค่าบรรทัดที่ 2 เขียนยังไงช่วยบอกทีน่ะครับ ขอบพระคุณอีกครั้งครับ
Date :
2011-02-14 19:20:04
By :
iSOON_zA
while(eggQty > 0)
{
string sql = "select top 1 egg_id,stl_total,pick_date from tbl_egg where stl_total > 0 order by pick_date "
ถ้า stl_total >= eggqty ให้
update stl_total =stl_total - eggqty where eggid = ?? and pick_date = ???
eggQty = 0
จบ
ถ้า stl_total < eggqty ให้
update stl_total = 0 where eggid = ?? and pick_date = ???
eggQty -= stl_total
จบ
}
เอาแบบละเอียดเลยนะ
คุณ เบอร์ไขจาก Listview จากที่คุณยกตัวอย่าง ขายไข่ 90 ฟอง ความต้องการคุณคือ ตัดจาก
2 recode เพราะ lot แรกมี 75 ไม่พอ ต้องตัด lot ที่ 2 อีก 15 ทำไมต้องใช้ while
การทำงานคือ
1. eggqty = 90
2. ให้นายอ่าน recode ขึ้นมา นายจะได้ เอามาเทียบกับ จำนวนที่นายจะลบ คือ 90 ปรากฏว่า 75 น้อยกว่า 90
3. นายก็ delete recode นี้ ออกหรือ update = 0 ก็ว่าไป ใน loop นี้ได้ ประกาศ eggQty -= stl_total แปลว่าให้
eggqty = 90-75 เหลือ 15
4. มันยังไม่หลุด loop while เพราะ eggqty > 0 อยู่ นายก็กลับไปอ่าน recode ต่อไปมา แล้วก็เทียบเหมือนเดิม
5. ค่าที่อ่านได้มากกว่าค่าที่จะ update ทีนี้นายก็ update stl_total = stl_total - eggqty
6. set eggnum เท่ากับ 0 มันก็จะหลุด loop while
อัพเดตติดลบ แล้วค่อยไป select แล้วไป update ไปเรื่อยๆนี่ ไม่แนะนำ มันทะแม่งๆ เขาไม่เขียนกันหรอก
Date :
2011-02-14 21:03:03
By :
superpheak
To . . . คุณ superpheak ครับ ได้แล้วครับ ต้องขอบคุณท่านมาก ๆ เลยครับ ที่ให้หลักการคิด แนวคิด หรือข้อชี้แนะ คำอธิบายต่าง ๆ อย่างชัดเจน เขียนนิดเดียวเอง ต่างจากที่ผมเขียนเลย ย้าว ยาว แถมติดปัญหาอีกต่างหาก . . . ได้แนวคิดดี ๆ จริง ๆ ครับ ยังไงต้องขอขอบคุณอย่างสุดซึ้งครับ (T-T)
--------------------------------------
To . . . คุณ หางอึ่ง ครับ ยังไงก็ต้องขอบคุณท่านครับ ที่ให้ลิ้งค์ และข้อแนะนำ ต่าง ๆ ผมลองดูละครับลิ้งค์ที่ให้ แต่พอลองทำ มันติด Error ครับ สงสัยผมจะเขียน ผิดแบบผิดหลักการการเขียน
------------------------------------------------------------
สุดท้าย ขอขอบคุณทุก ๆ ท่าน ครับ ที่เข้ามาให้ข้อแนะนำ ข้อชี้แนะ หลักการต่าง ๆ ที่ขาดไม่ได้ Thaicreate.com ครับ ที่ให้พื้นที่สำหรับข้อมูล ความรู้ต่าง ๆ ที่ให้ทุก ๆ คนมาเอื่อเฟื่อเผื่อแผ่กัน ขอบคุณทุกท่าน มา ณ ที่นี้ด้วยครับ
Date :
2011-02-14 22:50:17
By :
iSOON_zA
Load balance : Server 03