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

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

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

ผมอยากรู้ว่าจะต้องทำอย่างไรบ้างครับ
ตอนนี้ผมเริ่มไปประมาณนี้ครับ
Code (C#)
private void search()
{
// Set Column
//DataGridViewTextBoxColumn c05 = new DataGridViewTextBoxColumn() { DataPropertyName = "name", HeaderText = "product name", Width = 180 };
// Add Column
//dataGridView1.Columns.AddRange(c05);
// Set DataSource
dataGridView1.DataSource = null;
dataGridView1.DataSource = GetTable(
"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 "
);
if (dataGridView1.Rows.Count == 0)
{
MessageBox.Show("No Data");
dataGridView1.DataSource = null;
}
}
private DataTable GetTable(String SQL)
{
if (conn.State == ConnectionState.Closed)
conn.Open();
SqlDataAdapter sda = new SqlDataAdapter(SQL, conn);
DataTable dt = new DataTable();
sda.Fill(dt);
return dt;
}
ผมอยากรู้ว่า ถ้าจะทำแบบ ตัวอย่างนี้อะครับจะต้องทำอย่างไรครับ แบบ ว่า ถ้ารับเข้าก็ ไห้แสดงตรงจำนวนรับเข้า ครับ ถ้าส่งออก ก็ไห้แสดงตรงส่งออก แล้วก็ การทำยอดยกมาด้วยครับ ต้องเริ่มจากที่ตรงไหนก่อนครับ

ขอบคุณครับ
Tag : .NET, Ms SQL Server 2008, C#
|
ประวัติการแก้ไข 2015-11-24 08:41:45
|
 |
 |
 |
 |
Date :
2015-11-23 10:47:18 |
By :
phuriwat |
View :
5310 |
Reply :
27 |
|
 |
 |
 |
 |
|
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
    
|
 |
 |
 |
 |
Date :
2015-11-26 08:39:27 |
By :
phuriwat |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ลองดู Query นี้แล้วลองไปปรับดูนะครับ ผมก็ได้มาอีกที จำไม่ได้ว่าท่านไหน แต่ก็ขอบคุณมากๆครับ
Code (SQL)
select '2003' as ProductID,'02/02/2009' as StockDate,614 as ProductIN,10 as ProductOUT
into #temp
union
select '2003','03/02/2009',1000,248
union
select '2003','10/02/2009',0, 6
union
select '2003','11/02/2009',0,105
union
select '2003','12/02/2009',0,302
union
select '2003','13/02/2009',0,200
union
select '2003','16/02/2009',0,200
union
select '2003','23/02/2009',0,250
union
select '2003','24/02/2009',243,0
union
select '2003','26/02/2009',0,33
union
select '2003','27/02/2009',6,0
-- แสดงผล
select a.*,
(select sum(ProductIN) - sum(ProductOUT)
from #temp
where stockdate <= a.stockdate) as balance
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#)
private void search()
{
dataGridView1.DataSource = null;
//Set Column
DataGridViewTextBoxColumn c01 = new DataGridViewTextBoxColumn() { DataPropertyName = "add_date", HeaderText = "Add Date", Width = 200 };
DataGridViewTextBoxColumn c02 = new DataGridViewTextBoxColumn() { DataPropertyName = "quantity", HeaderText = "จำนวน", Width = 200 };
DataGridViewTextBoxColumn c03 = new DataGridViewTextBoxColumn() { DataPropertyName = "balance", HeaderText = "คงเหลือ", Width = 200 };
DataGridViewTextBoxColumn c04 = new DataGridViewTextBoxColumn() { DataPropertyName = "company_name", HeaderText = "company_name", Width = 200 };
DataGridViewTextBoxColumn c05 = new DataGridViewTextBoxColumn() { DataPropertyName = "remark", HeaderText = "remark", Width = 200 };
// Add Column
dataGridView1.Columns.AddRange(c01,c02,c03,c04,c05);
// Set DataSource
dataGridView1.DataSource = GetTable(
"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 "
);
if (dataGridView1.Rows.Count == 0)
{
MessageBox.Show("No Data");
dataGridView1.DataSource = null;
}
}
private DataTable GetTable(String SQL)
{
if (conn.State == ConnectionState.Closed)
conn.Open();
SqlDataAdapter sda = new SqlDataAdapter(SQL, conn);
DataTable dt = new DataTable();
sda.Fill(dt);
return dt;
}
|
ประวัติการแก้ไข 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 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ขอถามท่านผู้รู้ครับ
กรณี so.balance กับ si.balance
กับที่ balance ใน SQL แบบไหนเหมาะสมกว่าครับ
Code (SQL)
select si.add_date,si.quantity,so.quantity,si.balance ......
พอเอา si.balance มาลง แล้ว เหมือนมันแปลกๆไม๊ครับ เพราะมันมีทั้ง so.balance กับ si.balance
แล้ว so.balance กับ si.balance ใช่ตัวเลขเดียวกันไม๊ครับ
|
ประวัติการแก้ไข 2015-11-26 16:03:35
 |
 |
 |
 |
Date :
2015-11-26 16:01:02 |
By :
lamaka.tor |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
จะบอกว่าผิดตั้งแต่ออกแบบฐานข้อมูลมาก็ไม่ใช่ เพราะต่างคนต่างเขาใจ มาว่ากันว่าจะหาข้อมูลก่อนว่าจะอย่างไง ยังไม่ตอบนะ
มาขยายคำพูดแรกก่อนนะครับ การที่เราไป 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)
IF OBJECT_ID('tempdb..#temp_in') IS NOT NULL
DROP TABLE #temp_in
IF OBJECT_ID('tempdb..#temp_out') IS NOT NULL
DROP TABLE #temp_out
select '2003' as ProductID,'02/02/2009' as StockDate,614 as ProductIN,'ST Balance' as Ref_Num
into #temp_in
union
select '2003','03/02/2009',100,'PO01-001'
union
select '2003','24/02/2009',24,'PO01-002'
union
select '2003','26/02/2009',33 ,'PO01-003'
union
select '2003','27/02/2009',40,'PO01-004'
select '2003' as ProductID,'02/02/2009' as StockDate,10 as ProductOUT,'I01-0001' as Ref_Num
into #temp_out
union
select '2003','03/02/2009',10,'I01-0002'
union
select '2003','03/02/2009',23,'I01-0003'
union
select '2003','26/02/2009',4 ,'I01-0004'
union
select '2003','27/02/2009',40,'I01-0005';
with View_CTE as (
select ProductID,StockDate,ProductIN,0as ProductOUT,Ref_Num,'A' as Stype from #temp_in
union
select ProductID,StockDate,0 as ProductIN,ProductOUT,Ref_Num,'B' as Stype from #temp_out
)
,StockCard_CTE as (
select a.*,ROW_NUMBER() OVER (ORDER BY Stockdate ,Stype) AS RowNumber
from View_CTE a )
select a.*,(select sum(ProductIN) - sum(ProductOUT)
from StockCard_CTE
where RowNumber <= a.RowNumber ) as balance
from StockCard_CTE a
DROP TABLE #temp_in;
DROP TABLE #temp_out;

อาจจะบ้านๆนะครับ เพราะจริงๆแล้วเราอาจจะไปสร้าง view หรือ stored procedure ใช้ cursor loop เอาค่ามาก็ได้เหมือนกัน
|
 |
 |
 |
 |
Date :
2015-11-26 21:07:37 |
By :
บัญดิษฐ |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
si.balance = สินค้าในคลัง +กับจำนวนรับ
so.balacne = สินค้าในคลัง -กับจำนวนเบิกครับ
Code (SQL)
select si.add_date,si.quantity,so.quantity,xyz......
SQL น่าจะประมาณนี้
ผมแค่ดึงมาจากฐานข้อมูลที่ ท่าน phuriwat ออกแบบไว้นะครับ
ตามความจริง xyz ควรจะเป็น สินค้าในคลัง
ว่าแต่
สินค้าในคลัง =??
เหมือนเล่นงูกินหางเลย
26/11/2558 รับ ปากกา มา 50 แท่ง รวมทั้งหมด 50 แท่ง
27/11/2558 รับ ปากกา มา 10 แท่ง รวมทั้งหมด 60 แท่ง >> 50+10
28/11/2558 รับ ปากกา มา 40 แท่ง รวมทั้งหมด 100 แท่ง >> 60+40
28/11/2558 เบิก ปากกา มา 20 แท่ง รวมทั้งหมด 80 แท่ง >> 100-20
อ้าว....หาย 26/11/2558 ลงข้อมูลผิด เปลี่ยนจาก 50 เป็น 55 เราต้องมาแก้ข้อมูลหลัง 26/11/2558 ใหม่หมด
แล้วถ้าลงผิดตั้งแต่ เดือน 1 ละ ครับ
|
 |
 |
 |
 |
Date :
2015-11-27 09:11:50 |
By :
lamaka.tor |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ลองเอา query นี้ไปรันดูก่อนนะครับ เขียนสดไม่รู้จะผิดตรงไหน รันนี้ไม่ใช้เอาไปแปะที่ code ของโปรแกรมนะ
ให้เอาไปรันที่ query database
Code (SQL)
with View_CTE as (
select si.product_id, si.add_date,si.quantity as qty_receives,0 as qty_outgoings
,sup.company_name,si.remark ,'I' as Stype
from stock_incomings si
left join receives re on re.id=si.receive_id
left join suppliers sup on sup.id=re.supplier_id
union
select so.product_id,so.add_date ,0 as qty_receives,so.quantity as qty_outgoings
,'' as company_name,'' as remark ,'O' as Stype
from stock_outgoings so
),StockCard_CTE as (
select a.*,ROW_NUMBER() OVER (ORDER BY product_id,add_date ,Stype) AS RowNumber
from View_CTE a )
/*ตรงการจะ join อะไรมาทำตรงนี้ แต่ถ้ามากว่านี้ให้ไปเพิ่มที่ View_CTE ก่อน
select a.*,(select sum(qty_receives) - sum(qty_outgoings)
from StockCard_CTE
where RowNumber <= a.RowNumber ) as balance
from StockCard_CTE a
|
 |
 |
 |
 |
Date :
2015-11-27 11:52:14 |
By :
บัญดิษฐ |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ได้แล้วครับ

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

อันนี้โค๊ด
Code (SQL)
with View_CTE as (
select si.product_id, si.add_date,si.quantity as qty_receives,0 as qty_outgoings
,sup.company_name,si.remark ,'I' as Stype
from stock_incomings si
left join receives re on re.id=si.receive_id
left join suppliers sup on sup.id=re.supplier_id
union
select so.product_id,so.add_date,0 as qty_receives,so.quantity as qty_outgoings
,cus.company_name,so.remark ,'O' as Stype
from stock_outgoings so
left join disburse dis on dis.id=so.disburse_id
left join customers cus on cus.id=dis.customer_id
),StockCard_CTE as (
select a.*,ROW_NUMBER() OVER (ORDER BY product_id,add_date ,Stype) AS RowNumber
from View_CTE a )
/*ตรงการจะ join อะไรมาทำตรงนี้ แต่ถ้ามากว่านี้ให้ไปเพิ่มที่ View_CTE ก่อน*/
select a.*,(select sum(qty_receives) - sum(qty_outgoings)
from StockCard_CTE
where RowNumber <= a.RowNumber ) as balance
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 :
บัญดิษฐ |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
|
|