 |
|
ขอคำแนะนำการตัดสต๊อกแบบ FIFO ครับ ภาษา VB.net ใช้ SQL Server 2005 ครับ (win app) |
|
 |
|
|
 |
 |
|
sb คืออะไรอะครับ พอจะคอมเม้นได้ไหมว่า แต่ละบรรทัด มันทำอะไร ดูแล้ว งง
|
 |
 |
 |
 |
Date :
2011-04-23 14:14:33 |
By :
duzija1 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
sb ครับ ประกาศไว้ดด้านบนอ่ะครับ
Dim sb As StringBuilder
StockLotNo คือเลขลอตสินค้า
StockQtyIn คือจำนวนสินค้าที่มีในแต่ละลอต
CAmount คือจำนวนสินค้าที่ถูกขายจากลิสวิว ครับ
|
ประวัติการแก้ไข 2011-04-23 14:18:33 2011-04-23 14:19:43
 |
 |
 |
 |
Date :
2011-04-23 14:16:48 |
By :
chopin |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
Code (VB.NET)
If StockQty >= CAmount Then << = LINE 23
dim _StockQtyIn as Integer
_StockQtyIn = StockQtyIn - CAmount
sb.Remove(0, sb.Length)
sb.Append("UPDATE Stock")
sb.Append(" SET StockQtyIn = " & _StockQtyIn )
sb.Append(" WHERE (ProductID=@ProductID)")
sb.Append(" AND (StockLotNo=@StockLotNo)")
sqlSave = sb.ToString()
CAmount = 0
ลองแบบนี้ดูนะ
|
 |
 |
 |
 |
Date :
2011-04-23 19:24:10 |
By :
duzija1 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ผมทำแล้วมันไม่อัพเดทให้ แต่ลองดีบัคไล่โคดแล้วค่ามันมาตามที่กำหนดไว้หมดและก็วนลูป ตามที่ทำ ไม่ทราบว่าใครพอจะแนะนำได้บ้างครับ
Code (VB.NET)
If StockQty >= CAmount Then
sqlStr = "UPDATE Stock Set StockQtyln =StockQty - CAmount where ProductID =@ProductID and StockLotNo=@StockLotNo"
CAmount = 0
ElseIf StockQty < CAmount Then
sqlStr = "update Stock Set StockQty = 0 where ProductID =@ProductID and StockLotNo=@StockLotNo"
CAmount = CAmount - StockQty
|
ประวัติการแก้ไข 2011-04-25 12:10:43
 |
 |
 |
 |
Date :
2011-04-25 12:10:02 |
By :
chopin |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ผมคิดว่างานลักษณะอย่างนี้ลองเขียน store procedure จะง่ายกว่านะครับ แล้วค่อยให้ .net ไป call store proc อีักทีั
ลองบอก structure table Stock หน่อยสิครับ
|
 |
 |
 |
 |
Date :
2011-04-25 14:33:49 |
By :
mi16 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
StockLotNo varchar(5) เลขที่ลอตรับสินค้า
ProductID int
StockDate datetime
StockQtyIn int จำนวนสินค้าที่มีในลอต
ผมจะตัดสินค้าโดยมีเลขลอตในการตัด สินค้าชนิดเดียวกันก็ตัดลอตที่เข้มาก่อนออก กรณีที่ลอตไม่พอก็มาตัดที่ลอตตัดไปครับประมานนี้
|
 |
 |
 |
 |
Date :
2011-04-25 14:38:27 |
By :
chopin |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
StockLotNo นี่เป็นตัวเลขอย่างเดียวเลยหรือป่าวครับ (ถ้าเป็นน่าจะใช้ Int)
แล้ว StockDate ในที่นี้มีความหมายว่าอย่างไรครับ
|
 |
 |
 |
 |
Date :
2011-04-25 14:46:47 |
By :
mi16 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
StockLotNo เป็นตัวเลขอย่างเดียวครับ
StockDate วันที่รับสินค้าเข้าลอต ครับ
|
 |
 |
 |
 |
Date :
2011-04-25 14:48:45 |
By :
chopin |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ก่อนจะกดปุ่ม ตัด stock นี้ดึงข้อมูลมา show ยังไง เขียน code ใน page โหลด หรือว่ายังไง
เอามาดูหน่อยดิครับ ที่ถามนี้เคยเจอหลาย case อยู่ที่ดึงข้อมูลมา show ใน ก่อน แล้วมี textbox ว่าจะ
รับค่าเท่าไหร่ โดย defalut ค่าเป็น 0 แล้วกด update ไม่ได้ เพราะ ไม่ได้ใส่ If not page.ispostback
|
 |
 |
 |
 |
Date :
2011-04-25 15:35:36 |
By :
superpheak |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
อันนี้เป็น Code Store Procedure ที่ผมคิดว่าน่าจะใช้งานได้นะครับ ลองดูนะครับ
การใช้งานก็เรียกใช้ตรงๆ
เช่นจะตัดสินค้ารหัส 1 จำนวน 100 ชิ้นก็ใช้งานโดยส่ง SQL
proc_CheckOut_Stock 1, 100
Store Procedure ก็จะคำนวณตัดให้เองตาม Lot ที่มาถึงก่อน(ดูจากวันที่) แล้วถ้าหากมันไม่พอตัดก็จะตัดไปบางส่วน
แล้วจะ RaisError ส่วนที่เหลือว่าขาดเท่าไหร่
Create Procedure proc_CheckOut_Stock( @ProductID int, @QTY int)
as
Begin
Set nocount on
Declare @StockLotNo varchar(5)
Declare @StockQtyIn int
Declare @QTYTemp int
Set @QTYTemp = @QTY
Declare c1 cursor for
Select StockLotNo, StockQtyIn from stock order by StockDate ASC, StockLotNo ASC
Open c1
Fetch c1 into @StockLotNo, @StockQtyIn
While (@@FETCH_STATUS=0 AND @QTYTemp > 0)
Begin
if (@StockQtyIn >= @QTYTemp)
begin
Update stock
Set StockQtyIn = StockQtyIn - @QTYTemp
Where StockLotNo = @StockLotNo
Set @QTYTemp = 0
end
else if (@StockQtyIn < @QTYTemp)
begin
Update stock
Set StockQtyIn = 0
Where StockLotNo = @StockLotNo
Set @QTYTemp = @QTYTemp - @StockQtyIn
end
Fetch c1 into @StockLotNo, @StockQtyIn
End
close c1
Deallocate c1
if (@QTYTemp > 0)
begin
-- Stock ไม่พอตัด (แต่ตัดไปบางส่วนแล้ว
Declare @msg varchar(100)
Set @msg = 'Outstanding = '+CONVERT(varchar,@QTYTemp)
RaisError ( @msg, 16,1)
end
end
Go
|
 |
 |
 |
 |
Date :
2011-04-25 15:44:41 |
By :
mi16 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
มันผิดไปนิดขอเอาอันนี้ให้ละกันครับ
Create Procedure proc_CheckOut_Stock( @ProductID int, @QTY int)
as
Begin
Set nocount on
Declare @StockLotNo varchar(5)
Declare @StockDate datetime
Declare @StockQtyIn int
Declare @QTYTemp int
Set @QTYTemp = @QTY
Declare c1 cursor for
Select StockLotNo, StockDate, StockQtyIn from stock
where ProductID = @ProductID
order by StockDate ASC, StockLotNo ASC
Open c1
Fetch c1 into @StockLotNo, @StockDate, @StockQtyIn
If (@@FETCH_STATUS != 0)
begin
RaisError ( 'Product not found', 16,1)
end
else
begin
While (@@FETCH_STATUS=0 AND @QTYTemp > 0)
Begin
if (@StockQtyIn >= @QTYTemp)
begin
Update stock
Set StockQtyIn = StockQtyIn - @QTYTemp
Where StockLotNo = @StockLotNo
and StockDate = @StockDate
and ProductID = @ProductID
Set @QTYTemp = 0
end
else if (@StockQtyIn < @QTYTemp)
begin
Update stock
Set StockQtyIn = 0
Where StockLotNo = @StockLotNo
and StockDate = @StockDate
and ProductID = @ProductID
Set @QTYTemp = @QTYTemp - @StockQtyIn
end
Fetch c1 into @StockLotNo, @StockDate, @StockQtyIn
End
close c1
Deallocate c1
if (@QTYTemp > 0)
begin
-- Stock ไม่พอตัด (แต่ตัดไปบางส่วนแล้ว
Declare @msg varchar(100)
Set @msg = 'Outstanding = '+CONVERT(varchar,@QTYTemp)
RaisError ( @msg, 16,1)
end
end
end
Go
|
 |
 |
 |
 |
Date :
2011-04-25 15:48:57 |
By :
mi16 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
คือผมพึงหัดเขียนนะครับ เลยไม่ค่อยเข้าใจที่คุณ mi16 บอกมาเท่าที่ควร พอจับได้งูๆปลาๆอ่ะครับ
แบบวา่าแอบงงๆๆ อธิบายง่ายกว่านี้ได้ป่ะครับ
|
 |
 |
 |
 |
Date :
2011-04-25 15:53:44 |
By :
chopin |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
อันนี้โคดของปุ่มเซฟ
Code (VB.NET)
Private Sub btnsave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnsave.Click
If MessageBox.Show("คุณต้องการบันทึกรายการขายสินค้า ใช่หรือไม่?", "คำยืนยัน", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
Dim sqlAdd As String = ""
Dim cmdAdd As SqlCommand = New SqlCommand
Dim sqlSave As String
Dim Today As Date
sqlSave = sb.ToString()
Today = Date.Now
With Conn
If .State = ConnectionState.Open Then .Close()
.ConnectionString = strConn
.Open()
End With
Try
Auto() 'เรียกเลขออโต้
sb.Remove(0, sb.Length)
sb.Append("INSERT INTO Sell (SellID,CustomerID,SellDate,NetTotal,NetDiscount,NetVat,PriceBeforeVat,PaymentTypeID)")
sb.Append(" VALUES (@SellID,@CustomerID,@SellDate,@NetTotal,@NetDiscount,@NetVat,@PriceBeforeVat,@PaymentTypeID)")
sqlSave = sb.ToString()
tr = Conn.BeginTransaction()
With com
.CommandText = sqlSave
.CommandType = CommandType.Text
.Connection = Conn
.Parameters.Clear()
.Transaction = tr
.Parameters.Add("@SellID", SqlDbType.VarChar).Value = lblSellID.Text
.Parameters.Add("@CustomerID", SqlDbType.Int).Value = txtCustomerID.Text
.Parameters.Add("@SellDate", SqlDbType.DateTime).Value = Today
.Parameters.Add("@NetTotal", SqlDbType.Float).Value = lblNet.Text
.Parameters.Add("@NetDiscount", SqlDbType.Float).Value = lblNetDC.Text
.Parameters.Add("@NetVat", SqlDbType.Float).Value = lblNetVAT.Text
.Parameters.Add("@PriceBeforeVat", SqlDbType.Float).Value = lblTotelnet.Text
If optcash.Checked = True Then
.Parameters.Add("@PaymentTypeID", SqlDbType.Int).Value = "0"
Else
.Parameters.Add("@PaymentTypeID", SqlDbType.Int).Value = "1"
End If
.ExecuteNonQuery()
End With
Dim i As Integer
'Dim SellID As Integer
Dim CProductID As String
Dim CAmount As Integer = 0
Dim CSellPrice As Double = 0.0
Dim CTotal As Double = 0.0
Dim Cdiscount As Double = 0.0
Dim Cno As String
Dim Cvat As Double = 0.0
For i = 0 To lsvProductList.Items.Count - 1
Cno = lsvProductList.Items(i).SubItems(0).Text
CProductID = lsvProductList.Items(i).SubItems(1).Text
CAmount = CInt(lsvProductList.Items(i).SubItems(4).Text)
CSellPrice = CDbl(lsvProductList.Items(i).SubItems(3).Text)
CTotal = CDbl(lsvProductList.Items(i).SubItems(7).Text)
Cdiscount = CDbl(lsvProductList.Items(i).SubItems(6).Text)
Cvat = CDbl(lsvProductList.Items(i).SubItems(5).Text)
sb.Remove(0, sb.Length)
sb.Append("INSERT INTO SellDetail(SellID,SellNo,ProductID,qty,SellPrice,Total,DiscountPrice,Vat)")
sb.Append(" VALUES (@SellID,@SellNo,@ProductID,@qty,@SellPrice,@Total,@DiscountPrice,@Vat)")
sqlSave = sb.ToString()
With com
.CommandText = sqlSave
.CommandType = CommandType.Text
.Parameters.Clear()
.Parameters.Add("@SellID", SqlDbType.VarChar).Value = lblSellID.Text
.Parameters.Add("@SellNo", SqlDbType.VarChar).Value = Cno
.Parameters.Add("@ProductID", SqlDbType.Int).Value = CProductID
.Parameters.Add("@qty", SqlDbType.Int).Value = CAmount
.Parameters.Add("@SellPrice", SqlDbType.Float).Value = CSellPrice
.Parameters.Add("@Total", SqlDbType.Float).Value = CTotal
.Parameters.Add("@DiscountPrice", SqlDbType.Float).Value = Cdiscount
.Parameters.Add("@Vat", SqlDbType.Float).Value = Cvat
.ExecuteNonQuery()
End With
Dim StockQty As Integer = 0
While (CAmount > 0)
sb.Remove(0, sb.Length)
sb.Append("SELECT top 1 StockLotNo,ProductID,")
sb.Append("StockQtyIn")
sb.Append(" FROM Stock")
sb.Append(" WHERE (StockQtyIn>0)")
sb.Append(" AND (ProductID=@ProductID)")
sb.Append(" ORDER BY StockLotNo ")
sqlSave = sb.ToString()
With com
.CommandText = sqlSave
.Parameters.Clear()
'.Parameters.Add("@StockLotNo", SqlDbType.VarChar).Value = txtStockID.Text
.Parameters.Add("@ProductID", SqlDbType.Int).Value = CProductID
dr = .ExecuteReader()
If dr.HasRows Then
dr.Read()
StockQty = dr.GetInt32(2)
dr.Close()
If StockQty >= CAmount Then
sb.Remove(0, sb.Length)
sb.Append("UPDATE Stock")
sb.Append(" SET StockQtyIn = StockQtyIn - CAmount")
sb.Append(" WHERE (ProductID=@ProductID)")
sb.Append(" AND (StockLotNo=@StockLotNo)")
sqlSave = sb.ToString()
CAmount = 0
With com
.CommandText = sqlSave
.Parameters.Clear()
.Parameters.Add("@StockQtyIn", SqlDbType.Int).Value = CAmount
.Parameters.Add("@ProductID", SqlDbType.NVarChar).Value = CProductID
End With
ElseIf StockQty < CAmount Then
sb.Append("UPDATE Stock")
sb.Append(" SET StockQtyIn = 0")
sb.Append(" WHERE (ProductID=@ProductID)")
sb.Append(" AND (StockLotNo=@StockLotNo)")
sqlSave = sb.ToString()
CAmount = CAmount - StockQty
End If
With com
.CommandText = sqlSave
.Parameters.Clear()
.Parameters.Add("@StockQtyIn", SqlDbType.Int).Value = CAmount
.Parameters.Add("@ProductID", SqlDbType.NVarChar).Value = CProductID
End With
End If
End With
dr.Close()
End While
Next
MessageBox.Show("บันทึกรายการขายสินค้า เรียบร้อยแล้ว !!!", "ผลการทำงาน", MessageBoxButtons.OK, MessageBoxIcon.Information)
ClearNet()
ClearProduct()
tr.Commit()
Catch ex As Exception
'tr.Rollback()
MessageBox.Show("ไม่สามารถบันทึกรายการขายสินค้าได้ เนื่องจาก " & ex.Message, "ข้อผิดพลาด", MessageBoxButtons.OK, MessageBoxIcon.Warning)
btnsave.Focus()
Finally
Conn.Close()
End Try
End If
End Sub
|
 |
 |
 |
 |
Date :
2011-04-25 16:08:57 |
By :
chopin |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ผมคิดว่าการตัด stock แบบที่คุณ chopin อยากได้มันทำเป็น store procedure น่าจะสะดวกกว่า
store procedure ที่ว่าคือเป็น process ที่เราสร้างเอาไว้ผูกติดกับ database ซึ่งเห็นใช้ sql server
เลยคิดว่าใช้ .net เรียก store procedure ดีกว่าแล้วเรา code การทำงานต่างๆใน store procedure เอาเอง
ซึ่งที่ผมทำมาให้คิดว่าใช้งานได้ระดับหนึ่งแล้วครับ อาจไปปรับแต่งบางส่วนให้เข้ากับระบบที่ design ก็ได้ครับ
ส่วนวิธีการเรียก store procedure จาก .net ง่ายๆเลยก็ส่งเป็น sql statement ตามที่ผมบอกไว้ข้างบนเลยครับ
ลอง apply ดูนะครับ
|
 |
 |
 |
 |
Date :
2011-04-25 16:10:15 |
By :
mi16 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ผมว่ากลับไปไล่ Code ใหม่นะครับ เห็นเขียนแต่ ไม่สั่ง update มันจะลง database ไหม
|
 |
 |
 |
 |
Date :
2011-04-25 16:14:30 |
By :
superpheak |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ที่เห็นๆ บรรทัด 138
น่าจะแืทรก .ExecuteNonQuery()
นะครับ
|
 |
 |
 |
 |
Date :
2011-04-25 17:12:07 |
By :
mi16 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ขอบคุณทุกคำแนะนำมากครับผมจะลองไปทำดูก่อน ได้มายังไงจะมาขอคำขี้แนะอีกทีครับ
|
 |
 |
 |
 |
Date :
2011-04-25 19:59:38 |
By :
chopin |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ตอนนี้ผมลองแก้ไขแล้ว มันจะตัด ลอตเฉพาะสินค้าที่ลอตที่เข้ามาก่อนพอขาย
แต่ถ้าสมมุติลอตแรกมีอยู่5ชิ้น ลอตสองมี10 ชิ้น
ขายไป8 ชิ้น มันจะตัดลอตแรกเหลือ 0 แต่ลอตสองไม่ตัดให้ ใครพอจะชี้แนะหรือแนะนำหน่อยครับผม
Code (VB.NET)
Dim StockQty As Integer
Dim lot As String = ""
While (CAmount > 0)
sb.Remove(0, sb.Length)
sb.Append("SELECT top 1 StockLotNo,ProductID,")
sb.Append("StockQtyIn")
sb.Append(" FROM Stock")
sb.Append(" WHERE (StockQtyIn>0)")
'sb.Append(" AND (StockLotNo=@StockLotNo)")
sb.Append(" AND (ProductID=@ProductID)")
sb.Append(" ORDER BY StockLotNo ASC")
sqlSave = sb.ToString()
With com
.CommandText = sqlSave
.Parameters.Clear()
.Parameters.Add("@ProductID", SqlDbType.Int).Value = CProductID
dr = .ExecuteReader()
If dr.HasRows Then
dr.Read()
lot = dr.GetString(0)
StockQty = dr.GetInt32(2)
dr.Close()
If StockQty >= CAmount Then
sb.Remove(0, sb.Length)
sb.Append("UPDATE Stock")
sb.Append(" SET StockQtyIn=@StockQtyIn")
sb.Append(" WHERE (ProductID=@ProductID)")
sb.Append(" AND (StockLotNo=@StockLotNo)")
sqlSave = sb.ToString()
'sqlStr = "UPDATE Stock Set StockQtyIn = where ProductID =@ProductID and StockLotNo=@StockLotNo"
With com
.CommandText = sqlSave
.CommandType = CommandType.Text
.Parameters.Clear()
.Parameters.Add("@ProductID", SqlDbType.Int).Value = CProductID
.Parameters.Add("@StockLotNo", SqlDbType.VarChar).Value = lot
.Parameters.Add("@StockQtyIn", SqlDbType.Int).Value = StockQty - CAmount
.ExecuteNonQuery()
End With
CAmount = 0
ElseIf StockQty < CAmount Then
sb.Remove(0, sb.Length)
sb.Append("UPDATE Stock")
sb.Append(" SET StockQtyIn=@StockQtyIn")
sb.Append(" WHERE (ProductID=@ProductID)")
sb.Append(" AND (StockLotNo=@StockLotNo)")
sqlSave = sb.ToString()
With com
.CommandText = sqlSave
.CommandType = CommandType.Text
.Parameters.Clear()
.Parameters.Add("@ProductID", SqlDbType.Int).Value = CProductID
.Parameters.Add("@StockLotNo", SqlDbType.VarChar).Value = lot
.Parameters.Add("@StockQtyIn", SqlDbType.Int).Value = CAmount - StockQty
.ExecuteNonQuery()
End With
CAmount = CAmount - StockQty
End If
End If
End With
End While
|
 |
 |
 |
 |
Date :
2011-04-26 13:58:56 |
By :
chopin |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ผมทำได้แล้วครับ ขอบคุณทุกความคิดเห็นที่แนะนำจนทำได้ครับ
|
 |
 |
 |
 |
Date :
2011-04-27 11:29:01 |
By :
chopin |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
|
|