แตก Line จำนวนที่คีย์รับในใบสั่งซื้อ
กระทู้เก่าบอร์ด อ.Yeadram

 1,454   11
URL.หัวข้อ / URL
แตก Line จำนวนที่คีย์รับในใบสั่งซื้อ

ผมกำลังหัดทำ Access คลังสินค้า อยากจะให้จำนวนที่รับเข้าแตก Line ตามจำนวน Packsize เพื่อใส่ Location จัดเก็บที่ต้องการ
ตัวอย่าง
- การคีย์รับฟอร์ม A
RunningID   PO            InvoiceNo      ReceiveDate       
001             45018945 MIT01001           28/8/17      
- ฟอร์ม B
RunningID   Sku             Description        Group - Packsize   Qty   
001              75023918   Shopping Bag     SA             500      2450

อยากให้คำนวณและแตก Line เพื่อใช้คีย์เข้าบ้านเก็บ ให้เป็นแบบนี้ครับผม
RunningID   Sku        Description        Group - Packsize   Qty   Location
001              75023918   Shopping Bag     SA        500      500 .............
001              75023918   Shopping Bag     SA        500      500 .............
001              75023918   Shopping Bag     SA        500      500 .............
001              75023918   Shopping Bag     SA        500      500 .............
001              75023918   Shopping Bag     SA        500      450 .............
ผมรบกวนอาจารย์หรือท่านผู้รู้ด้วยนะครับ ทำยังไงก็ไม่ได้ จนความดันขึ้นแล้ว ช่วย
เหลือผมหน่อยครับผมลองหาร Packsize ยังไงก็ได้แถวเดียว

11 Reply in this Topic. Dispaly 1 pages and you are on page number 1

1 @R23948
ต้องใช้ Code หรือ คำนวณอย่างไรได้บ้างครับ เพื่อให้แตก Line และใส่ Location ได้ถ้ามีตัวอย่างโปรแกรม ยิ่งดีเลยครับ ..ขอขอบพระคุณล่วงหน้านะครับ
2 @R23950
ฟอร์ม A คือฟอร์มหลัก บันทึกข้อมูลเข้าตารางหลัก tbHead
ฟอร์ม B คือฟอร์มย่อย บันทึกข้อมูลเข้าตารางย่อย tbDetail

ให้เพิ่ม control ต่างๆ ลงในฟอร์ม A ดังนี้

textbox ที่ไม่ผูกกับฟิลด์ใดๆ จำนวน 5 อัน (เขียน caption ให้สื่อความหมายว่า มันคือช่องรับข้อมูล "Sku Description Group Packsize   Qty" ตามลำดับ)
และปุ่มคำสั่ง cmdAddLine 1 อัน

แจ้งผู้ใช้ว่า ให้กรอกข้อมูลลงใน textbox ทั้ง 5 อันนี้ก่อน แล้วกดปุ่ม เพื่อให้มีการเพิ่ม line โดยอัตโนมัติดก่อน (แล้วจึงค่อยไปแก้ไข location ในฟอร์มย่อยในภายหลัง)

ในปุ่มคำสั่ง ให้เขียนโค้ด เพื่อ...
- ตรวจสอบว่า ข้อมูลใน textbox ทั้ง 5 ครบถ้วนและถูกต้องตามชนิดข้อมูลหรือไม่
- ถ้าตรวจพบว่า ข้อมูลไม่ถูกต้อง ไม่ครบถ้วนให้ แจ้งผู้ใช้ และหยุดทำงาน
- ถ้าตรวจผ่าน ให้ทำการ วนลูป เพื่อเพิ่มข้อมูลในฟอร์ม B
- - การเพิ่มข้อมูลมี สองทางให้เลื่อก (หรืออาจจะมากกว่านี้)
- - เพิ่มข้อมูลเข้าตารางย่อย จนครบรอบของลูป แล้วค่อยสั่งให้ฟอร์มย่อยทำการ requery (docmd.runsql "Insert into ...) หรือ
- - สั่งให้เคอร์เซอร์ไปที่ฟอร์ม B แล้วสั่งเพิ่มรายการ (docmd.gotorecord,, acnewrec...)

ตัวอย่างเช่น
cmdAddLine_Click()
if ข้อมูลถูกต้องครบถ้วน then
Dim xx as long
xx = txH_Qty
do while xx > 0
xx = xx - txH_Packsize

dim sql as string
sql = "Insert into tbDetail (RunningID, และชื่อฟิล์ดทั้ง 5) values (" & me.txRunningID & ... เขียนเอาข้อมูลจาก textbox เปล่าๆ เอามาเติมในสายอักขระนี้ให้ครบ...
' ส่วนช่อง qty ให้ตรวจสอบก่อนเอาไปเติม

if xx > txH_Packsize then
sql = sql & txH_Packsize
else
sql = sql & xx
end if
' อาจเขียนให้สั้นกว่านี้ได้ ตามถนัด แต่ผมให้ยาวๆ ไว้ก่อนเพื่อให้เข้าใจประเด็นได้ง่าย การเช็คอันนี้ เพื่อให้มั่นใจว่า รอบสุดท้ายของลูป ต้องเป็นจำนวนเศษที่เหลือเท่านั้น

sql = sql & ");" 'ปิดสายอักขระ statement ของเราให้สมบูรณ์ แล้วค่อยสั่งรัน
docmd.runsql sql
' สั่งวนลูป
loop
else ' กรณีข้อมูลใน textbox ทั้ง 5 ไม่ครบถ้วนถูกต้อง
msgbox "....."
exit sub
end if
end sub

3 @R23951
อาจารย์ครับ ผมลองทำดูแล้วแต่ยังไม่ได้ติดตรงคำสั่ง cmdAddLine และดูเหมือนจะคำนวณที่ละ Line ผมเลยใส่ข้อมูลในฟอร์มย่อยไปเลย โดยข้อมูล Sku ให้ลิ้งกับ Table Itemcode เพื่อไม่ให้กรอกข้อมูลรายละเอียด Sku เอง

รบกวนดูตัวอย่างไฟล์ให้หน่อยครับ
http://cloudbox.3bb.co.th/share3/MTg0OTF8MDRlMzVhYjU0Mzg4YjY5MTczNWM4YjQyMzFkMzg3YTF8MzkyMDcw

สามารถนำไปคำนวณใน Query ได้ไหมครับ มีวิธีอย่างไร เพื่อให้ได้หน้าตาแบบนี้
No     Sku      Des Group Pack Pallet Shelflife LOT MFG Qty_Pallet
1     2010018    Name A     FG     48     960     730     1     29/08/2017     960
1     2010018    Name A     FG     48     960     730     1     29/08/2017     40
1     20100189 Name B     FG     48     960     730     2     20/08/2017     960
1     20100189 Name B     FG     48     960     730     2     20/08/2017     960
1     20100189 Name B     FG     48     960     730     2     20/08/2017     80
1     20100190 Name C     FG     48     960     730     3     15/08/2017     960
1     20100190 Name C     FG     48     960     730     3     15/08/2017     960
1     20100190 Name C     FG     48     960     730     3     15/08/2017     960
1     20100190 Name C     FG     48     960     730     3     15/08/2017     120
4 @R23953
ตัวอย่างการกรอกข้อมูลครับ
5 @R23957
ไม่เห็น textbox ที่ผมบอกให้ทำเลยครับ
ไม่เห็นปุ่มคำสั่ง และโค้ดต่างๆ เลย

เอาอย่างนี้นะครับ ในตาราง tbDetail ให้สร้างใหม่ เอาให้เข้าใจแนวทางก่อน แล้วค่อยไปประยุกต์เพิ่มเอาทีหลังนะครับ
1. ให้สร้างตาราง tbDetail ใหม่ มี 4 ฟิลด์ (ของเก่าลบทิ้งหรือเปลี่ยนชื่อไปเป็นอย่างอื่นก่อน)
2. ฟิลด์ต่างๆ มีดังนี้ (RunningID, Long Integer), (SKU, Text 255), (Qty, Long Interger), (Location, Text 255)
3. สร้างฟอร์มย่อย, ตั้งชื่อว่า frm_Detail, สร้างด้วยวิซาร์ด แบบตาราง, ใช้ข้อมูลจากตาราง tbDetail ไม่ต้องใช้คิวรี่ร่วมข้อมูลกับตารางใดๆ แม้แต่ ตาราง ItemCode
4. เปิดฟอร์มหลักในมุมมองออกแบบ ลบฟอร์มย่อยอันเก่าออกทิ้งไป
5. สร้าง textbox เพิ่มมา สองอัน (txH-Sku), (txH-Qty)
6. สร้างปุ่มคำสั่ง cmdAddLine
7. เพิ่มคอนโทรลฟอร์มย่อยเข้ามา access จะให้เลือกว่าคุณจะใช้ฟอร์มไหน ก็เลือก frm_Detail ที่เราสร้างไว้ในลำดับที่ 3. ข้างต้น แล้ว access จะถามอีกว่าจะให้โยงกับฟอร์มหลักด้วยฟิลด์อะไร เราก็เลือกว่าให้เป็นฟิลด์ RunningID

แนวทางการคีย์ข้อมูลของผู้ใช้ก็คือ
a. ให้กรอกข้อมูลหัวบิลต่างๆ
b. ให้กรอกเลข sku
c. ให้กรอกจำนวนทั้งหมดที่รับเข้า (ของสินค้า sku ตัวนี้)
d. กดปุ่มคำสั่ง เพื่อแตกไลน์ (หรือสั่งให้แยกพาเลทนั่นแหละ)
e. โค้ดของเราจะทำการแตกไลน์ให้อัตโนมัติก่อน แล้วจะมีช่องข้อมูลว่างไว้ในแต่ละรายการ นั่นคือชื่อ Location
f. ให้ผู้ใช้ค่อยกรอก location เอาเองในแต่ละรายการ

แล้วคุณก็เขียนโค้ด
1. ตรวจสอบความครบถ้วนถูกต้องของ textbox ต่างๆ
2. ตรวจสอบว่า sku ที่ผู้ใช้กรอกมา มีอยู่ในตาราง ItemCode แล้วหรือไม่ (ถ้าไม่มี โค้ดจะ error เพราะเราจะไปเอาจำนวน pallet ในนั้นมาเป็นตัวหาร)
3. ถ้าตรวจสอบทุกอย่างแล้ว ก็ให้วนลูป
เอาจำนวนใน textbox ชื่อ txH-Qty มาเป็นตัวตั้ง
เอาจำนวน pallet จากตาราง itemcode ของรหัส sku นั้นๆ มาเป็นตัวลบออกในแต่ละรอบของลูป

Dim xx as long
Dim PackSize as long
Dim Sql as string
xx = me.txH-Qty
PackSize = dLookup("pallet","itemcode", "sku LIKE '" & me.txH-Sku & "'"
Do while xx > 0
Sql = "Insert into tbDetail(RunningID, Sku, Qty) VALUES(" & me.RunningID & ", '" & me.txH-Sku & "', " & iif(xx < PackSize, xx, PackSize) & ");"

docmd.setwarnings false
on error resume next
docmd.runsql Sql
if err.number <>0 then
debug.print Sql
msgbox "เพิ่มข้อมูลไม่ได้ debug"
err.clear
else
xx = xx - PackSize
end if
loop

me.ชื่อฟอร์มย่อย.requery
6 @R23966
ขอบพระคุณมากครับ ที่ช่วยดูไฟล์ให้และบอกแนวทาง ผมจะพยายามทำตามที่อาจารย์บอกมา ถ้าติดอะไร อาจจะขอรบกวนอาจารย์อีกครั้งครับ
7 @R23971
ทำตามขั้นตอนแล้ว สามารถแตก Line ได้แล้วครับอาจารย์ ดีใจมากเลยครับได้เสียที
ผมจะขอรบกวนอีกหน่อย ถ้าต้องการคีย์ LOT และ MFG เพิ่มอีก 2 ช่อง
ต้องเพิ่ม Code ยังไงครับให้ลงมาพร้อมกันตอนแตก Line เลย
ผมเพิ่มช่องต่อจาก txHSku,txhQty เป็น txHLog และ txHMfg ไว้แล้ว
รบกวนอาจารย์อีกครั้งนะครับ..ขอบพระคุณมากครับผม
8 @R23983
เพิ่มได้แล้วครับอาจารย์ แต่ทำไมเวลา MsgBox "เพิ่มข้อมูลไม่ได้ debug"ขึ้นแล้ว กดปิดยังไงก็ไม่ได้ ค้างอยู่ตรงนี้ครับ

Private Sub cmdAddLine_Click()
Dim xx As Long
Dim PackSize As Long
Dim Sql As String

xx = Me.txHQty
PackSize = DLookup("pallet", "itemcode", "sku LIKE '" & Me.txHSku & "'")
Do While xx > 0
Sql = "Insert into tbDetail(RunningID, Sku, LOT, MFG, Qty) VALUES(" & Me.RunningID & ", '" & Me.txHSku & "', '" & Me.txHLot & "', '" & Me.txHMfg & "', " & IIf(xx < PackSize, xx, PackSize) & ");"

DoCmd.SetWarnings False
On Error Resume Next
DoCmd.RunSQL Sql
If Err.Number <> 0 Then
Debug.Print Sql
MsgBox "????????????????? debug"
Err.Clear
Else
xx = xx - PackSize
End If
Loop

Me.frm_Detail.Requery
End Sub
9 @R23985
ขณะที่มันค้าง กดปุ่ม ctl+G
ดูที่หน้าต่าง immediate window ในนั้นจะมี statement
เลือกบรรทัดบนสุด ก็อบปี้มาวางให้ดูหน่อยครับ

ส่วน msgbox ที่ว่า กดเท่าไร ก็ไม่ออก ปล่อยมันไปก่อนครับ มันมี error ถ้าเราเคลียร์ปัญหา error นี้ได้ มันจะไม่มารบกวนอีกครับ

ตอนนี้ เอาปัญหาที่ว่า มาดูก่อนครับ (ก็อบปี้ มาวางในกระทู้นี้เลยครับ พรุ่งนี้ เย็นๆ จะเข้ามาดูให้ครับ ช่วงกลางวันไม่สะดวกเข้าเว็บนะครับ)
10 @R23987
ขอโทษครับไม่ได้ ขณะค้าง กดปุ๋ม Ctrl+G กดยังไงก็ไม่ไปครับอาจารณ์ ค้างอยู่อย่างนั้น
ต้องกด Ctrl+alt+Delete แล้วไป End Task ถึงจะปิดโปรแกรมได้

เดี๋ยวผมจะลองหาข้อมูลและแก้ไขดูครับ ขอบพระคุณอาจารย์มากๆครับ
ผมได้ตามความต้องการแล้ว ถ้าไม่ได้อาจารย์ช่วยคงปวดหัวไปอีกนานเลย
11 @R23992
ลองเปลี่ยนคำสั่งบางบรรทัดดังนี้ เพื่อความสะดวกในการไล่หา bug

docmd.setwarnings false
on error resume next
docmd.runsql Sql
if err.number <>0 then
debug.print Sql
err.clear
exit do
else
xx = xx - PackSize
end if

ทีนี้ เมื่อลองทดสอบแล้ว มันไม่แตกไลน์ให้ ให้สันนิษฐานว่า มันมี error (แต่เราไม่ได้ให้มันแจ้งขณะเกิด error)
ถ้ากด ctl+G เข้าไปดู จะเห็น statement ที่เราดักเอาไว้ให้มันปริ๊นท์ออกมา มันจะปริ๊นท์ออกมาเฉพาะรอบที่เกิด error
ทีนี้ก็ดูจาก statement อันนั้นแหละครับ ว่ามีอะไรที่เราเขียนผิดหรือเปล่า หรืออาจจะเป็นที่ ชนิดข้อมูลมันขัดแย้งกัน ระหว่าง ชนิดข้อมูลของเราที่รับค่ามาจาก textbox กับชนิดข้อมูลของฟิลด์ในตาราง ที่เราตั้งค่าไว้รอรับมัน

ลองดูครับ
@ ประกาศใช้งานเว็บบอร์ดใหม่ => บอร์ดเรียนรู้ Access สำหรับคนไทย
แล้วจะใส่ลิ้งอ้างอิงมาที่โพสต์เก่านี้หรือไม่ก็ตามสะดวกครับ
Time: 0.2419s