181
ห้อง MS Access / : สอบถามการใช้ Auto Number ครับ
« เมื่อ: 24 มิ.ย. 62 , 00:36:09 »
ผมคิดออกแต่วิธีทื่อๆตรงๆนะครับ ไม่เทคนิคอะไร ผมคิดว่าต้องทำการป้อนผ่านฟอร์มเท่านั้นเพราะจะต้องเขียนโค้ดใน Form_BeforeUpdate event เพื่อควบคุมและค้นหาเลขตัวต่อไปของ Autonumber ซึ่event นี้จะเกิดก่อนที่จะบันทึกเรคอร์ด สิ่งที่ต้องทำก็คือ
1. เปลี่ยนประเภทข้อมูลของฟิลด์ Autonumber (สมมุติว่าชื่อฟิลด์คือ A แล้วกัน) ให้เป็น Long Integer เพื่อโปรแกรมจะได้ควบคุมค่านี้เอง เราจะไม่ปล่อยให้ Access หาค่ามาใส่ให้อย่างแต่ก่อนอีกแล้ว และต้องกำหนด A ให้คุณสมบัติ Unique Index เป็น True ด้วย ถ้า A เป็น PrimaryKey อยู่แล้ว ก็จะเป็น Unique Index โดยอัตโนมัติ
2. เพิ่มฟิลด์อีกฟิลด์เพื่อบอกให้เรารู้ว่า นี่เป็นเรคอร์ดของกลุ่มเดียวกันใน 26 เรคอร์ด เรียกชื่อว่าฟิลด์ DT สำหรับใส่ TimeStamp ก็แล้วกัน DT มีประเภทข้อมูลเป็น Date/Time โปรแกรมจะใส่วันเวลาปัจจุบันลงไปใน DT ให้เรคอร์ดแรกของกลุ่ม (#2.1) ส่วนเรคอร์ดอื่นๆ โปรแกรมจะก็อปปี้ค่า DT จากเรคอร์ดชุดสุดท้ายมาใส่ให้แทน (#2.2) หมายเหตุ : ฟิลด์ DT ไม่จำเป็นต้องใส่ในฟอร์ม
3. ในฟอร์ม ถ้ามันเป็นเรคอร์ดแรกในชุดของ 26 เรคอร์ดชุดใหม่ โปรแกรมจะใช้ค่าในฟิลด์ A ที่คุณต้องป้อนในฟอร์ม (#3.1) นำมาเป็นค่าเริ่มต้น แต่ถ้าไม่ใช่เรคอร์ดแรก โปรแกรมจะไม่สนใจค่าที่คุณป้อน แต่จะหาค่าล่าสุดของ A ในกลุ่ม 26 เรคอร์ดสุดท้าย บวกด้วย 1 แล้วเอามาใส่ที่ฟิลด์ A แทน (#3.2)
4. ถ้าเกิดกรณีที่ป้อนค่า A ซ้ำ โปรแกรมจะให้ป้อนใหม่ (#4.1) ถ้ากรณีบวก 1 แล้วเจอค่าซ้ำกับเรคอร์ดเก่า โปรแกรมจะบวก 1 เพิ่มเติมต่อไปเรื่อยๆจนกว่าจะไม่ซ้ำ (#4.2)
ไปเปลี่ยนชื่อฟิลด์ของเทเบิลและบนฟอร์มให้ตรงกับที่คุณมีด้วยครับ
1. เปลี่ยนประเภทข้อมูลของฟิลด์ Autonumber (สมมุติว่าชื่อฟิลด์คือ A แล้วกัน) ให้เป็น Long Integer เพื่อโปรแกรมจะได้ควบคุมค่านี้เอง เราจะไม่ปล่อยให้ Access หาค่ามาใส่ให้อย่างแต่ก่อนอีกแล้ว และต้องกำหนด A ให้คุณสมบัติ Unique Index เป็น True ด้วย ถ้า A เป็น PrimaryKey อยู่แล้ว ก็จะเป็น Unique Index โดยอัตโนมัติ
2. เพิ่มฟิลด์อีกฟิลด์เพื่อบอกให้เรารู้ว่า นี่เป็นเรคอร์ดของกลุ่มเดียวกันใน 26 เรคอร์ด เรียกชื่อว่าฟิลด์ DT สำหรับใส่ TimeStamp ก็แล้วกัน DT มีประเภทข้อมูลเป็น Date/Time โปรแกรมจะใส่วันเวลาปัจจุบันลงไปใน DT ให้เรคอร์ดแรกของกลุ่ม (#2.1) ส่วนเรคอร์ดอื่นๆ โปรแกรมจะก็อปปี้ค่า DT จากเรคอร์ดชุดสุดท้ายมาใส่ให้แทน (#2.2) หมายเหตุ : ฟิลด์ DT ไม่จำเป็นต้องใส่ในฟอร์ม
3. ในฟอร์ม ถ้ามันเป็นเรคอร์ดแรกในชุดของ 26 เรคอร์ดชุดใหม่ โปรแกรมจะใช้ค่าในฟิลด์ A ที่คุณต้องป้อนในฟอร์ม (#3.1) นำมาเป็นค่าเริ่มต้น แต่ถ้าไม่ใช่เรคอร์ดแรก โปรแกรมจะไม่สนใจค่าที่คุณป้อน แต่จะหาค่าล่าสุดของ A ในกลุ่ม 26 เรคอร์ดสุดท้าย บวกด้วย 1 แล้วเอามาใส่ที่ฟิลด์ A แทน (#3.2)
4. ถ้าเกิดกรณีที่ป้อนค่า A ซ้ำ โปรแกรมจะให้ป้อนใหม่ (#4.1) ถ้ากรณีบวก 1 แล้วเจอค่าซ้ำกับเรคอร์ดเก่า โปรแกรมจะบวก 1 เพิ่มเติมต่อไปเรื่อยๆจนกว่าจะไม่ซ้ำ (#4.2)
ไปเปลี่ยนชื่อฟิลด์ของเทเบิลและบนฟอร์มให้ตรงกับที่คุณมีด้วยครับ
โค๊ด: [Select]
Private Sub Form_BeforeUpdate(Cancel As Integer)
Const MaxRec = 26
Dim DB As DAO.Database
Dim RS As DAO.Recordset
Dim MaxDTStr As String ' วันเวลาล่าสุดของกลุ่มเรคอร์ด (แต่เป็น string เพื่อลดความยาวของโค้ด)
Dim MaxA As Long ' ค่าสูงสุดของ A ในกลุ่มเรคอร์ดล่าสุด
Dim NeedA As Boolean ' TRUE = ระบบต้องการค่า A บนฟอร์ม
NeedA = False
Set DB = CurrentDb
Set RS = DB.OpenRecordset("select max(DT) as MaxDT from TB")
If IsNull(RS!MaxDT) Then
NeedA = True
Else
' #2.2
MaxDTStr = Format$(RS!MaxDT, "dd/mmm/yyyy hh:nn:ss")
Set RS = DB.OpenRecordset("select count(*) as N from TB where DT = #" & MaxDTStr & "#")
If RS!N = 0 Or RS!N >= MaxRec Then NeedA = True
End If
If NeedA Then
' #3.1
If Nz(Me.A, 0) = 0 Then
MsgBox "ป้อน A ด้วย"
Me.A.SetFocus
Cancel = True: Exit Sub
End If
If Not DB.OpenRecordset("select A from TB where A = " & CStr(Me.A)).EOF Then ' #4.1
MsgBox "A ซ้ำของเดิม"
Me.A.SetFocus
Cancel = True: Exit Sub
End If
Me.DT = Now() ' #2.1
Else
' #3.2
Me.A = DB.OpenRecordset("select max(A) as MaxA from TB where DT = #" & MaxDTStr & "#")!MaxA
Do
Me.A = Me.A + 1
Loop Until DB.OpenRecordset("select A from TB where A = " & CStr(Me.A)).EOF ' #4.2
Me.DT = CDate(MaxDTStr) ' #2.2
End If
End Sub
โพสต์นี้ได้รับคำขอบคุณจาก: Nick_1234