Run เล่มที่ เลขที่ ในใบเสร็จฯ
กระทู้เก่าบอร์ด อ.Yeadram

 17,922   31
URL.หัวข้อ / URL
Run เล่มที่ เลขที่ ในใบเสร็จฯ

รบกวนอาจารย์ทั้งหลายอีกแล้วครับ

เวลาเราออกใบเสร็จรับเงิน มันจะรันเล่มที่ เลขที่เองอัตโนมัติ โดยเลขที่ถ้าถึง100
จะขึ้นเล่มใหม่ แล้วเลขที่จะขึ้น 1 ไปเรื่อยๆ ถ้าเราทำทีละใบ ผมทำให้รันอัตโนมัติได้ครับ แต่ตอนนี้ปัญหาคือ ต้องการทำทีเดียวทั้งหมด โดยบันทึกข้อมูลไปก่อน แต่ไม่ได้บันทึกตัวเลขเล่มที่ เลขที่ เข้าไป เวลาเปิด Report ก็จะสามารถเปิดดูตั้งแต่คนที่ 1 ถึง สุดท้ายได้

ปัญหาของผมคือ จะรันเล่มที่ เลขที่ยังงัยให้เลข ต่อจากของเก่า โดยเมื่อรันเลขถึงร้อย ก็จะขึ้นเล่มใหม่

ฝากอาจารย์ทั้งหลายช่วยหน่อยครับ อย่างน้อยวิธีคิดก่อนก็ยังดี เพราะคิดเท่าไหร่ก็ไม่ออก

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

1 @R07281
คิดดูตอนนี้มันมี อยู่ 2 แนวคือ เอาข้อมูลใส่ตารางก่อนแล้วค่อยพรีวิว ตามข้อมูล หรือ พรีวิวโดยให้รันตามที่ต้องการ(ยังไม่รู้ทำได้ปะ)แล้วเอาข้อมูลสุดท้ายเก็บไว้ ใครพอมีวิธีดีกว่านี้มั้ยครับ
2 @R07282
อ่านแล้วไม่เข้าใจ

ปัญหาแรกคือการรันเลขที่เล่มที่ให้เอกสารหลายๆใบพร้อมกันใช่ไหมครับ ถ้าทำใบเดียวได้ ก็น่าจะทำหลายใบได้ ไม่เข้าใจเหมือนกันว่าคุณติดตรงไหน ลองเอาโค้ดที่ทำแล้วมาแสดงดูหน่อย

แล้วเหมือนมีอีกปัญหาที่เกี่ยวกับการออกรายงาน มันเกี่ยวข้องกันอย่างไรกับการออกเลขที่เล่มที่
3 @R07285
อย่างนี้ครับอาจารย์
อันที่ทำได้แล้วคือ ผมทำฟอร์มบันทึกข้อมูลในใบเสร็จฯ โดยรันเล่มที่เลขที่ ตามที่บอก
แล้วสั่งปริ้น เป็นคนๆ แต่ มันใช้เวลามาก ถ้าต้องทำ100คน ผมกำลังทำแบบบันทึกข้อมูลทีเดียว 100คนแล้วสั่งปริ้นออก100คนทีเดียวเลย
แบบที่ทำได้ในฟอร์มที่บันทึกผมใส่ค่าเริ่มต้นเป็น DMax เล่มที่เลขที่ แต่พอผมบันทึกทีละ100คน
ผมไม่รู้จะทำให้ใบเสร็จฯของผมรันไปได้ยังงัยครับ เพราะทำแบบเดิม มันจะเป็นเล่มที่เลขที่เดียวกัน
ทั้ง100ใบเลยครับ
4 @R07289
ผมคิดว่าในโปรแกรมที่คุณจะกำหนดเลขที่/เล่มที่ให้แก่ใบเสร็จ ก็จะมีโครงเป็นไปในลักษณะนี้

   Dim DB as DAO.Database
   Dim RS as DAO.Recordset
   Dim SQNo as ... ' เลขที่
   Dim BookNo as ... ' เล่มที่

   Set DB = CurrentDB
   Set RS = DB.OpenRecordset("select * from ... where ใบเสร็จที่ยังไม่กำหนดเลขที่/เล่มที่ order by เรียงตามฟิลด์อะไรที่จะเป็นตัวกำหนดลำดับของใบเสร็จที่จะไ้ด้เลขที่/เล่มที่")
   Do While not RS.EOF
      SQNo = ... อาจมาจาก DMAX(... )
      BookNo = ... อาจมาจาก DMAX(... )

      RS.Edit
        RS!ฟิลด์เลขที่ = SQNo
        RS!ฟิลด์เล่มที่ = BookNo
      RS.Update

      RS.MoveNext
   Loop

   RS.Close : Set RS = Nothing
   DB.Close : Set DB = Nothing

นี่หรือเปล่าที่คุณต้องการ ???

อีกเรื่องที่ต้องทำคือ คุณจะรู้ได้อย่างไรว่า เลขที่/เล่มที่เลขอะไรถึงเลขอะไรที่เพิ่งสร้างไป เพราะคุณต้องใช้ในโปรแกรมที่พิมพ์ใบเสร็จ มันก็มีหลายแนวทาง เช่น

- แสดงช่วงของเลขที่ที่เพิ่งสร้างไปออกมาให้ผู้ใช้ได้ทราบ

- เพิ่มฟิลด์ในใบเสร็จเพื่อบันทึกค่าอะไรสักค่า ที่จะบ่งบอกให้ผู้ใช้ทราบได้ว่านี่เป็นเอกสารที่เพิ่งกำหนดเลขที่/เล่มที่ให้ อาจเป็น วันที่และเวลาที่สร้างหมายเลข หรือ รหัสที่ผู้ใช้เป็นคนกำหนดเอง แล้วก็ใ้ห้แสดงค่านี้ออกมาให้ผู้ใช้ได้ทราบอีกทีเพื่อใช้ในการสั่งพิมพ์

สุดท้าย ผมก็ยังนึกไม่ออกว่า ระหว่างทำทีละใบแล้วพิมพ์ใบเสร็จ มันใช้เวลาต่างจากป้อนที 100 ใบแล้วพิมพ์ใบเสร็จทั้ง 100 ใบตรงไหน ???

5 @R07290
ขอบคุณอ.สันติสุขครับ
-จริงๆ แล้วผมเขียนเป็นโคตไม่เป็นครับแต่ถ้ามีต้นแบบผมเอามาปรับปรุงได้เดี๋ยวผมจะลองทำแบบที่อาจารย์ทำให้ดูครับ
-จริงๆ ใบเสร็จที่ทำที่ละชุดไม่ใช่ร้อยใบแต่เป็นเกลือบพันใบครับ ร้อยใบผมสมมุติ
-การออกใบเสร็จของผมมี 2 แบบคือคนที่เดินมาจ่ายที่หน้าเค้าเตอร์ ก็จะทำเป็นใบๆ แต่ในแต่ละเดือนจะเก็บข้อมมูลของคนที่จะจ่ายไว้อยู่แล้วแค่แก้นิดหน่อยในบางคน ทำคิวรีให้โชว์ทีเดียวแล้วสั่งปริ้นครับ เร็วกว่ากันเป็นวันๆ เลยครับ แล้วช่วงปริ้น ก็ไปทำอย่างอื่นได้ไม่ต้องรอสั่งปริ้นที่ละใบ
-ในการทำแต่ละคนผมทำโดยใช้คิวรีอย่างเดียวเขียนโคตไม่เป็น โดยเก็บเลขที่เล่มที่ไว้คนละฟิลด์ครับ แต่พอทำที่ละมากๆ คิดไม่ออกว่าจะทำแบบไหน ก็อย่างที่โพสบอกแล้วคือ คิดไว้ 2 แบบ อย่างแรกพอสั่งพรีวิว ผมว่าจะใช้คิวรี แอพเพนไปตารางเก็บก่อนแล้วตอนแอพเพนนี้ก็จะให้สร้างเลขที่เล่มที่เลยครับ(อันนี้ยังไม่ได้ลอง)ไม่รู้ได้หรือไม่ แบบที่สองคือ พรีวิวเลย แล้วสั่งปริ้นค่อยไปเก็บค่า

ที่อาจารย์แนะนำมาน่าจะเอาไปประยุกต์เป็นแบบแรก เดี๋ยวจะลองทำครับ

ขอบพระคุณอาจารย์มากครับ
6 @R07291
- ต้องทำหน้าจอ ที่มีปุ่มสักปุ่มเพื่อรันโค้ดที่ว่านี้ ไม่ใช่พรีวิวแล้วค่อยมารันโค้ดนี้ ไม่งั้นเดี๋ยวพรีวิว 2 หน มันก็สร้างเลขใหม่ 2 ครั้ง ทำให้เลขชุดแรกกระโดดหายไปนะครับ ไม่ทราบผมคิดอย่างนี้จะตรงกับที่คุณออกแบบไว้หรือไม่

- คุณเอาไปใช้งานจริง แต่เขียนโค้ดไม่เป็น อันนี้ผมเสียวแทนจริงๆ ทดสอบระบบให้ดีก่อนนะครับก่อนนำไปใช้   แนะนำว่า UPS เตรียมให้พร้อม , สำรองระบบประจำทุกวัน, เมื่อสร้างข้อมูลจนได้เลขที่/เล่มที่สุดท้ายแล้ว จดลงกระดาษไว้ทุกครั้ง เพราะถ้าเครื่องมีปัญหาขึ้นมา จะได้ทำด้วยแมนวลต่อได้, คิดถึงระบบที่สลับไปมาระหว่างทำโดยคอมพิวเตอร์และแมนวลไว้ด้วยก็จะดีครับ เผื่อวันนึงจำเป็นจะต้องใช้ ฯลฯ
7 @R07308

จาก Table 1 เป็นข้อมูลที่บันทึกครั้งละมากๆ ต้องการให้ข้อมูลจาก Table 1 ไปอยู่ใน Table 2 ดัง Table 3 ครับ(คือ Table 2 สมมุติ)
รายละเอียดดังนี้ครับ เนื่องจากลองใช้ Query ดูแล้วมันไม่ได้ต้องเขียนโค๊ตคำสั่ง
โดยผมจะเก็บค่าใบเสร็จเล่มที่ เลขที่สุดท้ายไว้ในตารางหนึ่ง สมมุติว่า เล่มที่ 15 เลขที่ 88 ต้องเขียนโค๊ต ยังงัย ให้ เช็ค ID_Member(เลขสมาชิก) ถ้าเป็นคนเดียวกันให้ใช้ใบเสร็จใบเดียวกัน(ดัง Table 3) แล้วเมื่อออกใบเสร็จถึงเลขที่ 100 แล้ว เลขต่อไปคือ 1 โดยเล่มที่ เปลี่ยนเป็น 16(ดัง Table 3)
เมื่อเมื่อเสร็จแล้วผมจะเก็บเล่มที่เลขที่สุดท้ายไว้ในTableเดิม
ฝากอาจารย์ด้วยครับ มันซับซ้อน ผมไม่รู้จะเขียนยังงัยให้เช็ค 2 อย่างพร้อมกันครับ
8 @R07311
- เนื่องจากคุณออกแบบให้เก็บเลขที่/เล่มที่เอาไว้เป็นอีกเทเบิลนึง ผมขอเรียกว่า tblRunNo โดยมีฟิลด์ชื่อ BKNo และ RBNo เหมือนใน table3 เช่นกัน โดยจะเก็บเป็นเลขสุดท้ายที่รันได้ ดังนั้นสิ่งที่จำเป็นเพื่อให้การอัพเดตข้อมูลลงใน table2 และ tblRunNo ถ้าอัพเดตได้ ก็ต้องอัพเดตได้ทั้ง 2 เทเบิล และถ้าอัพเดตเทเบิลใดเทเบิลหนึ่งไม่ได้ หรือเกิดปัญหาใดๆในโปรแกรมระหว่างการอัพเดต ก็ต้องยกเลิกการอัพเดตทั้ง 2 เทเบิลเสีย สิ่งนี้เ?ียกว่า Transaction Control http://www.thai-access.com/yeadram_view.php?topic_id=572

อย่างแรก ในลูปนอกสุด เราต้องหาเลข ID_Member ที่แตกต่างกันออกมาก่อน โดยเรียงจากน้อยไปมาก แต่ละเลขให้ดึงออกมาเพียงเรคอร์ดเดียวก็พอ วนลูปหนึ่งครั้งก็ได้ออกมา 1 เลข

ต่อมาในลูปใน เราจะหาเลขต่อไปของเล่มที่/เลขที่ แล้วปรับปรุงลง tblRunNo และจะใส่เลขที่/เล่มที่นี้ลงในเรคอร์ดใหม่ใน table2 ที่มีเลข ID_Member เท่ากับที่ได้จากลูปนอก ขั้นตอนในลูปในนี้แหล่ะที่จะต้องทำ Transaction Control

โค้ดที่มี Transaction Control ต้องค่อนข้างละเอียดเพราะต้องดักจับว่าถ้าเกิดปัญหาใดๆ เราจะต้องยกเลิก Transaction ด้วยการทำ Rollback Transaction

โค้ดก็จะเป็นลักษณะ

Public Sub ตั้งชื่อเอาเอง( )
   Dim DB as DAO.Database
   Dim RS as DAO.Recordset
   Dim RunNoRS as DAO.Recordset
   Dim NewRBNo as Integer
   Dim NewBKNo as Integer
   Dim SQL as string
   Dim InTransaction as boolean ' เป็นตัวบอกว่าอยู่ใน Transaction Control หรือไม่

   On Error Goto ErrRoutine

   Set DB = CurrentDB
   Set RS = DB.OpenRecordset("select distinct ID_Member from table1 where ใบเสร็จที่ยังไม่กำหนดเลขที่/เล่มที่ order by ID_Member") ' Distinct เป็นตัวบอกว่าเอาเฉพาะที่ไม่ซ้ำกัน
   Do While not RS.EOF ' ลูปนอก
      DBEngine.BeginTrans: InTransaction = True ' เริ่ม Transaction Control

      Set RunNoRS = DB.OpenRecordset("select * from tblRunNo") ' หาเลขที่/เล่มที่สุดท้ายที่เก็บไว้

      With RunNoRS
      ' หาเลขที่/เล่มที่ถัดไป
      if !RBNo = 100 then NewRBNo = 1 Else NewRBNo = !RBNo + 1
      if NewRBNo = 1 then NewBKNo = !BKNo + 1 Else NewBKNo = !BKNo
       
      ' ปรับปรุงลง tblRunNo
      .Edit
        !RBNo = NewRBNo
        !BKNo = NewBKNo
      .Update
      End With

      RunNoRS.Close: Set RunNoRS = Nothing

      ' สร้างคำสั่ง SQL-Insert Into Statement เพื่อใส่เรคอร์ดลงใน table2 ตรงนี้อาจวุ่นวายสักหน่อย
      SQL = "insert into Table2(IM, AccCode, ...) select(ID_Member, AccCode, Unit, """ & NewBKNo & """, """ & NewRBNo & """) from Table1 where ID_Member = " & RS!ID_Member
      DBEngine.Execute SQL, dbFailOnError

      DBEngine.CommitTrans dbForceOSFlush : InTransaction = False ' บอกให้ปิด Transaction Control และเขียนลงดิสก์ทันที

      RS.MoveNext
   Loop

   RS.Close : Set RS = Nothing
   DB.Close : Set DB = Nothing

ExitRoutine:
   ' ถ้ามี error เกิดขึ้นในโปรแกรมและอยู่ระหว่าง Transaction Control เราต้อง Rollback Transaction ไม่เช่นนั้นจะเกิดปัญหาในภายภาคหน้าได้
   If InTransaction then DBEngine.Rollback
   exit sub

ErrRtn:
   Msgbox Err.Code & " : " & Err.Description
   Resume ExitRoutine
End Sub

หมายเหตุ : ผมไม่ได้ทดสอบโค้ดนี้นะครับ คุณลองเอาไปทดสอบแล้วกัน
9 @R07313
ทดสอบ ทำไมโพสยาวๆ ไม่ได้
10 @R07314

ขออนุญาติโพสเป็นรูปครับ
11 @R07315

ต่อจากข้างบนครับ
12 @R07316
สรุปรันแล้วติด Error 2-3 ที่ ลองแก้ดูโดยตัดบรรทัดที่ Error ออกแล้วรันได้แต่ Table2 ไม่มีข้อมูลมาครับ ฝากอาจารย์ชี้แนะอีกนิดครับ
13 @R07317
คุณแก้โดยการตัดบรรทัดที่ error ออก แล้วโปรแกรมมันก็ทำงานไม่ได้ตามที่ควรจะเป็นสิครับ มี error ก็ต้องแก้ด้วยการแก้โปรแกรมให้ถูก มันอาจผิด syntax (ไวยกรณ์) หรืออื่นๆครับ ไม่ใช่แก้ด้วยการตัดออก

ตอนนี้ที่พบคือ
- บรรทัด DBEngine.Execute แก้เป็น DB.Execute
- บรรทัด ErrRtn: แก้เป็น ErrRoutine:

ให้คอมไพล์ก่อนหลังการแก้ไขทุกครั้ง อยู่ใน VBEditor - Debug - Compile ....
14 @R07318
และที่บอกว่า ID_Member ไม่มีอยู่ใน Table1   ก็แก้เป็นชื่อฟิลด์ที่ถูกต้องครับ
15 @R07319
DB.Execute SQL.dbFailOnError แก้เป็น DB.Execute แล้วติด Err ตรง SQL ครับ

SQL = "insert into Table2(IM, AccCode,Unit,BKno,RBno) select(ID_Member, AccCode, Unit, """ & NewBKNo & """, """ & NewRBNo & """) from Table1 where ID_Member = " & RS!ID_member
ส่วนบรรทัดนี้ ตรงเครื่องหมายฟันหนู หน้า insert ไม่มี เครื่องหมายปิด ไม่แน่ใจว่าปิดตรงไหนครับ
16 @R07320
SQL.dbFailOnError แก้เป็น SQL, dbFailOnError ครับ
17 @R07321

18 @R07322
ใบเสร็จที่ยังไม่กำหนดเลขที่/เล่มที่ - หมายถึงอันนี้ครับ ไม่เข้าใจว่าคืออะไรครับ
19 @R07323
หมายถึงเงื่อนไขที่บอกว่าเรคอร์ดใดบ้างใน Table1 ที่จะนำเข้า Table2 ถ้านำเข้าทั้งหมด ก็ตัด Where ใบเสร็จที่ยังไม่กำหนดเลขที่/เล่มที่ ออกไปได้เลย
20 @R07324

มัน Error บรรทัดที่แจ้ง Error ครับ ลองตัดออก ขี้อมูลมันก็ยังไม่เข้า table2 ครับ ไม่แน่ใจว่าจะเกี่ยวกับบรรทัดนี้มั้ยครับ
SQL = "insert into Table2(IM, AccCode,Unit,BKno,RBno) select(ID_Member, AccCode, Unit, """ & NewBKNo & """, """ & NewRBNo & """) from Table1 where ID_Member = " & RS!ID_member
ตรงเครื่องหมายฟันหนู หน้า insert ไม่มี เครื่องหมายปิด ไม่แน่ใจว่าปิดตรงไหนครับ
@ ประกาศใช้งานเว็บบอร์ดใหม่ => บอร์ดเรียนรู้ Access สำหรับคนไทย
แล้วจะใส่ลิ้งอ้างอิงมาที่โพสต์เก่านี้หรือไม่ก็ตามสะดวกครับ
Time: 0.2454s