 |
|
[.NET]
การทำ stock card ให้มาแสดง ใน datagridview ต้องทำอย่างไรบ้าง ครับ |
|
 |
|
|
 |
 |
|
ผม มีตาราง รับเข้า และส่งออกสินค้า ครับ

หน้าตาโปรแกรม ของผมครับ

ผมต้องการทำหน้าตาโปรแกรมแบบนี้ครับ

ผมอยากรู้ว่าจะต้องทำอย่างไรบ้างครับ
ตอนนี้ผมเริ่มไปประมาณนี้ครับ
Code (C#)
01. private void search()
02. {
03.
04.
05.
06.
07.
08.
09.
10.
11. dataGridView1.DataSource = null ;
12.
13. dataGridView1.DataSource = GetTable(
14. "select si.add_date,si.quantity,si.balance ,sup.company_name,si.remark ,so.add_date ,so.quantity ,so.balance from products p join stock_incomings si on si.product_id=p.id join receives re on re.id=si.receive_id join suppliers sup on sup.id=re.supplier_id join stock_outgoings so on so.product_id=p.id join disburse dis on dis.id=so.disburse_id where p.id = '" + P_category.SelectedValue + "' and si.add_date between CONVERT(varchar(50), '" + selectday1 + "')and CONVERT(varchar(50), '" + selectday2 + "') and so.add_date between CONVERT(varchar(50), '" + selectday1 + "')and CONVERT(varchar(50), '" + selectday2 + "') ORDER BY si.add_date ASC , so.add_date ASC "
15. );
16. if (dataGridView1.Rows.Count == 0)
17. {
18. MessageBox.Show( "No Data" );
19. dataGridView1.DataSource = null ;
20. }
21. }
22.
23. private DataTable GetTable(String SQL)
24. {
25. if (conn.State == ConnectionState.Closed)
26. conn.Open();
27. SqlDataAdapter sda = new SqlDataAdapter(SQL, conn);
28. DataTable dt = new DataTable();
29. sda.Fill(dt);
30. return dt;
31. }
ผมอยากรู้ว่า ถ้าจะทำแบบ ตัวอย่างนี้อะครับจะต้องทำอย่างไรครับ แบบ ว่า ถ้ารับเข้าก็ ไห้แสดงตรงจำนวนรับเข้า ครับ ถ้าส่งออก ก็ไห้แสดงตรงส่งออก แล้วก็ การทำยอดยกมาด้วยครับ ต้องเริ่มจากที่ตรงไหนก่อนครับ

ขอบคุณครับ
Tag : .NET, Ms SQL Server 2008, C#
|
ประวัติการแก้ไข 2015-11-24 08:41:45
|
 |
 |
 |
 |
Date :
2015-11-23 10:47:18 |
By :
phuriwat |
View :
5333 |
Reply :
27 |
|
 |
 |
 |
 |
|
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
    
|
 |
 |
 |
 |
Date :
2015-11-26 08:39:27 |
By :
phuriwat |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ลองดู Query นี้แล้วลองไปปรับดูนะครับ ผมก็ได้มาอีกที จำไม่ได้ว่าท่านไหน แต่ก็ขอบคุณมากๆครับ
Code (SQL)
01. select '2003' as ProductID, '02/02/2009' as StockDate,614 as ProductIN,10 as ProductOUT
02. into # temp
03. union
04. select '2003' , '03/02/2009' ,1000,248
05. union
06. select '2003' , '10/02/2009' ,0, 6
07. union
08. select '2003' , '11/02/2009' ,0,105
09. union
10. select '2003' , '12/02/2009' ,0,302
11. union
12. select '2003' , '13/02/2009' ,0,200
13. union
14. select '2003' , '16/02/2009' ,0,200
15. union
16. select '2003' , '23/02/2009' ,0,250
17. union
18. select '2003' , '24/02/2009' ,243,0
19. union
20. select '2003' , '26/02/2009' ,0,33
21. union
22. select '2003' , '27/02/2009' ,6,0
23.
24. select a.*,
25. ( select sum (ProductIN) - sum (ProductOUT)
26. from # temp
27. where stockdate <= a.stockdate) as balance
28. from # temp a
|
 |
 |
 |
 |
Date :
2015-11-26 09:02:59 |
By :
บัญดิษฐ |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
แบ่งเป็น 2 ส่วนอ่ะครับ
ส่วนที่ 1 ใช้คำสั่ง SQL ดึงข้อมูลมา
ส่วนนี้จะเป็นข้อมูลทั้งหมดที่โชว์ใน DataGrid ยกเว้นตรงช่อง จำนวน คงเหลือ หรืออาจจะทำได้ก็ได้ (แต่ผมไม่ทราบว่าทำยังไง)
ข้อมูลที่ดึงมาก็มี
1. ยอดคงเหลือของเดือนที่แล้ว (หรือยอดคงเหลือของเดือนที่แล้ว - ยอดออก + ยอดเข้า ในกรณีที่ระบุวันที่อื่น ที่ไม่ใช่วันที่ 1 ของเดือน)
2. ยอดสินค้าเข้า
3. ยอดขาย
ก็พยายามดึงข้อมูลมาให้เหมือนกับที่อยากโชว์ใน Datagrid เลยครับ
ส่วนที่ 2 คือช่อง จำนวนคงเหลือ
อันนี้ผมใช้วิธี update ทีหลังอ่ะครับ
ก็ใช้วิธีไล่ยอดไปเรื่อย ๆ จากบรรทัดแรกจนถึงบรรทัดสุดท้าย
|
 |
 |
 |
 |
Date :
2015-11-26 10:09:26 |
By :
fonfire |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ครับ ผมลอง Query ดูแล้วอะครับ ได้แบบ นี้ครับ ถ้าช่องคงเหลือเพิ่มคือการรับเข้านะครับ ถ้าลดคือจะส่งออก
#แล้วถ้าต้องการจะแยก ไส่แบบ ถ้ารับเข้าไส่ช่องนี้ ส่งออก ไส่ช่องนี้ ทำยังไงครับ(แบบรูปภาพด้านบน รูป 04)
อันนี้คือข้อมูลที่ผม Query มาได้นะครับ คือข้อมูลของผม ได้ คำนวนมาในการ เบิก-ฝาก ของแต่ละครั้งแล้วครับ แล้วเก็บค่าของวันที่ เบิก-ฝากไว้ในตาราง

อันนี้โค๊ดที่ทำอยู่ครับ
Code (C#)
01. private void search()
02. {
03. dataGridView1.DataSource = null ;
04.
05.
06. DataGridViewTextBoxColumn c01 = new DataGridViewTextBoxColumn() { DataPropertyName = "add_date" , HeaderText = "Add Date" , Width = 200 };
07. DataGridViewTextBoxColumn c02 = new DataGridViewTextBoxColumn() { DataPropertyName = "quantity" , HeaderText = "จำนวน" , Width = 200 };
08. DataGridViewTextBoxColumn c03 = new DataGridViewTextBoxColumn() { DataPropertyName = "balance" , HeaderText = "คงเหลือ" , Width = 200 };
09. DataGridViewTextBoxColumn c04 = new DataGridViewTextBoxColumn() { DataPropertyName = "company_name" , HeaderText = "company_name" , Width = 200 };
10. DataGridViewTextBoxColumn c05 = new DataGridViewTextBoxColumn() { DataPropertyName = "remark" , HeaderText = "remark" , Width = 200 };
11.
12.
13. dataGridView1.Columns.AddRange(c01,c02,c03,c04,c05);
14.
15.
16. dataGridView1.DataSource = GetTable(
17. "select si.add_date,si.quantity,si.balance,sup.company_name,si.remark from products p join stock_incomings si on si.product_id=p.id join receives re on re.id=si.receive_id join suppliers sup on sup.id=re.supplier_id where p.id = '" + P_category.SelectedValue + "' and si.add_date between CONVERT(varchar(50), '" + selectday1 + "')and CONVERT(varchar(50), '" + selectday2 + "') union all select so.add_date,so.quantity,so.balance,cus.company_name,so.remark from products p join stock_outgoings so on so.product_id=p.id join disburse dis on dis.id=so.disburse_id join customers cus on cus.id=dis.customer_id where p.id = '" + P_category.SelectedValue + "' and so.add_date between CONVERT(varchar(50), '" + selectday1 + "')and CONVERT(varchar(50), '" + selectday2 + "') ORDER BY add_date ASC "
18.
19. );
20.
21.
22.
23. if (dataGridView1.Rows.Count == 0)
24. {
25. MessageBox.Show( "No Data" );
26. dataGridView1.DataSource = null ;
27. }
28. }
29.
30. private DataTable GetTable(String SQL)
31. {
32. if (conn.State == ConnectionState.Closed)
33. conn.Open();
34. SqlDataAdapter sda = new SqlDataAdapter(SQL, conn);
35. DataTable dt = new DataTable();
36. sda.Fill(dt);
37. return dt;
38. }
|
ประวัติการแก้ไข 2015-11-26 14:39:22
 |
 |
 |
 |
Date :
2015-11-26 14:36:16 |
By :
phuriwat |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
การแยกช่องผมทำแบบง่าย ๆ ครับ
คำสั่ง sql ก็ใช้ union แต่มีเทคนิคง่าย ๆ โดยการเพิ่มคอลัมภ์เข้าไป
-- ยอดคงเหลือ
select product,StockBegin, 0 as StockIn , 0 as StockOut from tableA
union all
--ยอดรับเข้า
select product,0 as StockBegin, StockIn , 0 as StockOut from tableB
union all
--ยอดจำหน่าย
select product,0 as StockBegin, 0 as StockIn , StockOut from tableB
|
 |
 |
 |
 |
Date :
2015-11-26 14:57:42 |
By :
fonfire |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
เห็นมี field si.balance อันนี้คือยอด Balance ณ เวลานั้นใช่ไหมครับ
|
 |
 |
 |
 |
Date :
2015-11-26 15:05:30 |
By :
fonfire |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
select si.add_date,si.quantity,si.balance,sup.company_name,si.remark
คอลัมน์ไหน คือ รับเข้า หรือ ส่งออก ครับ
|
 |
 |
 |
 |
Date :
2015-11-26 15:12:59 |
By :
lamaka.tor |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ถ้ามียอด balance ณ เวลานั้น
แล้วเกิดมีการแก้ไขจำนวนเข้า/ออก ยอด balance หลังจากนั้นจะผิดทั้งหมดน่ะครับ
อันนี้มีการแก้ไขไว้แล้วใช่ไหมครับ
|
 |
 |
 |
 |
Date :
2015-11-26 15:33:12 |
By :
fonfire |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
จะบอกว่าผิดตั้งแต่ออกแบบฐานข้อมูลมาก็ไม่ใช่ เพราะต่างคนต่างเขาใจ มาว่ากันว่าจะหาข้อมูลก่อนว่าจะอย่างไง ยังไม่ตอบนะ
มาขยายคำพูดแรกก่อนนะครับ การที่เราไป update ยอด balance โดยตรงนั้น OK มันก็ง่ายล่ะ(สำหรับวันนี้)
ดูเอาเองนะ
วันที่หนึ่ง รับมา 10 ก็จะเป็นว่า update balance +10 ยอด balance ในเทเบิลรับ สมมติว่ามี 10
วันที่สอง รับมา 20 ก็จะเป็นว่า update balance +20 ยอด balance ในเทเบิลรับ 30
....
วันที่เก้า รับมา 100 ก็จะเป็นว่า update balance +20 ยอด balance ในเทเบิลรับ 500
อีกสิบวันต่อมา เอาละหว่ารับของวันที่หนึ่งผิด จะไม่ต้องไปวน loop อีกเก้าวันย้อนหลังเหรอครับ
อันนี้ยังไม่ได้พูดถึงการเบิกหรือจ่ายออกนะครับ เพราะอย่างไงก็ต้องมีผิดพลาดเกิดขึ้น
ระบบที่ผมทำงานอยู่นี้ เขามีเทเบิลที่เป็นตัวกลางของทุกอย่างคือเทเบิล matltran
ไม่ว่าจะรับ เบิก ย้าย ทิ้ง แต่เข้าแยกเป็น Type เอาครับ เพราะมันจะหายอดคงเหลือได้เร็วมาก
ส่วนคำตอบรอเช้านะครับ วันนี้ไปรดผักก่อนครับ
|
 |
 |
 |
 |
Date :
2015-11-26 17:36:18 |
By :
บัญดิษฐ |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ว่าจะตอบให้ตอนเช้า กลัวนอนไม่หลับ(คนตอบนะ) ไม่รู้ว่าจะถูกต้องตามคำตอบที่ต้องการหรือเปล่านะครับ เป็นแค่ตัวอย่างนะครับ
Code (SQL)
01. IF OBJECT_ID( 'tempdb..#temp_in' ) IS NOT NULL
02. DROP TABLE #temp_in
03.
04. IF OBJECT_ID( 'tempdb..#temp_out' ) IS NOT NULL
05. DROP TABLE #temp_out
06.
07. select '2003' as ProductID, '02/02/2009' as StockDate,614 as ProductIN, 'ST Balance' as Ref_Num
08. into #temp_in
09. union
10. select '2003' , '03/02/2009' ,100, 'PO01-001'
11. union
12. select '2003' , '24/02/2009' ,24, 'PO01-002'
13. union
14. select '2003' , '26/02/2009' ,33 , 'PO01-003'
15. union
16. select '2003' , '27/02/2009' ,40, 'PO01-004'
17.
18.
19. select '2003' as ProductID, '02/02/2009' as StockDate,10 as ProductOUT, 'I01-0001' as Ref_Num
20. into #temp_out
21. union
22. select '2003' , '03/02/2009' ,10, 'I01-0002'
23. union
24. select '2003' , '03/02/2009' ,23, 'I01-0003'
25. union
26. select '2003' , '26/02/2009' ,4 , 'I01-0004'
27. union
28. select '2003' , '27/02/2009' ,40, 'I01-0005' ;
29.
30. with View_CTE as (
31. select ProductID,StockDate,ProductIN,0as ProductOUT,Ref_Num, 'A' as Stype from #temp_in
32. union
33. select ProductID,StockDate,0 as ProductIN,ProductOUT,Ref_Num, 'B' as Stype from #temp_out
34. )
35. ,StockCard_CTE as (
36. select a.*,ROW_NUMBER() OVER ( ORDER BY Stockdate ,Stype) AS RowNumber
37. from View_CTE a )
38.
39. select a.*,( select sum (ProductIN) - sum (ProductOUT)
40. from StockCard_CTE
41. where RowNumber <= a.RowNumber ) as balance
42.
43. from StockCard_CTE a
44.
45.
46. DROP TABLE #temp_in;
47. DROP TABLE #temp_out;

อาจจะบ้านๆนะครับ เพราะจริงๆแล้วเราอาจจะไปสร้าง view หรือ stored procedure ใช้ cursor loop เอาค่ามาก็ได้เหมือนกัน
|
 |
 |
 |
 |
Date :
2015-11-26 21:07:37 |
By :
บัญดิษฐ |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ลองเอา query นี้ไปรันดูก่อนนะครับ เขียนสดไม่รู้จะผิดตรงไหน รันนี้ไม่ใช้เอาไปแปะที่ code ของโปรแกรมนะ
ให้เอาไปรันที่ query database
Code (SQL)
01. with View_CTE as (
02. select si.product_id, si.add_date,si.quantity as qty_receives,0 as qty_outgoings
03. ,sup.company_name,si.remark , 'I' as Stype
04. from stock_incomings si
05. left join receives re on re.id=si.receive_id
06. left join suppliers sup on sup.id=re.supplier_id
07. union
08. select so.product_id,so.add_date ,0 as qty_receives,so.quantity as qty_outgoings
09. , '' as company_name, '' as remark , 'O' as Stype
10. from stock_outgoings so
11. ),StockCard_CTE as (
12. select a.*,ROW_NUMBER() OVER ( ORDER BY product_id,add_date ,Stype) AS RowNumber
13. from View_CTE a )
14.
15. /*ตรงการจะ join อะไรมาทำตรงนี้ แต่ถ้ามากว่านี้ให้ไปเพิ่มที่ View_CTE ก่อน
16. select a.*,( select sum (qty_receives) - sum (qty_outgoings)
17. from StockCard_CTE
18. where RowNumber <= a.RowNumber ) as balance
19.
20. from StockCard_CTE a
|
 |
 |
 |
 |
Date :
2015-11-27 11:52:14 |
By :
บัญดิษฐ |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ได้แล้วครับ

อันนี้ข้อมูล

อันนี้โค๊ด
Code (SQL)
01. with View_CTE as (
02. select si.product_id, si.add_date,si.quantity as qty_receives,0 as qty_outgoings
03. ,sup.company_name,si.remark , 'I' as Stype
04.
05. from stock_incomings si
06. left join receives re on re.id=si.receive_id
07. left join suppliers sup on sup.id=re.supplier_id
08. union
09. select so.product_id,so.add_date,0 as qty_receives,so.quantity as qty_outgoings
10. ,cus.company_name,so.remark , 'O' as Stype
11.
12. from stock_outgoings so
13. left join disburse dis on dis.id=so.disburse_id
14. left join customers cus on cus.id=dis.customer_id
15. ),StockCard_CTE as (
16. select a.*,ROW_NUMBER() OVER ( ORDER BY product_id,add_date ,Stype) AS RowNumber
17. from View_CTE a )
18.
19. /*ตรงการจะ join อะไรมาทำตรงนี้ แต่ถ้ามากว่านี้ให้ไปเพิ่มที่ View_CTE ก่อน*/
20. select a.*,( select sum (qty_receives) - sum (qty_outgoings)
21. from StockCard_CTE
22. where RowNumber <= a.RowNumber ) as balance
23.
24. from StockCard_CTE a
แล้วต้องทำยังไงต่อครับ คืออันนี้ ยังไม่มียอดยกมาไช่ป่ะครับ
|
 |
 |
 |
 |
Date :
2015-11-27 14:46:58 |
By :
phuriwat |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ใช่ครับยังไม่มียอดยกมา แต่ถ้าจะเริ่มระบบถ้าโปรแกรมไม่ได้ออกแบบไว้
ก็ทำการ Insert เข้า Table รับ เข้าระบบไปก่อนที่จะทำการรับจ่ายแบบปกติทั่วไปครับ
เพราะอย่างไง Record แรกที่เกิดขึ้นของเทเบิลรับก็คือยอดยกมาครับ
ส่วนสรุปรายเดือนเช่นยอกยกมา ยอดยกไป ของแต่ละเดือนให้ศึกษาจาก Query นี้ก็ได้ครับ ประยุกต์เอาครับ
|
 |
 |
 |
 |
Date :
2015-11-27 15:09:52 |
By :
บัญดิษฐ |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
|
|