เรียงลำดับ ID ใหม่
กระทู้เก่าบอร์ด อ.Yeadram

 1,364   14
URL.หัวข้อ / URL
เรียงลำดับ ID ใหม่

ผมมีฟิลด์ ID เป็น number ฟิลด์ DateRec เป็น Datetime
ข้อมูลผมมันเรียงไม่เป็นลำดับอยู่ ดังนี้
ID        DateRec
5        2/12/2560
6        2/12/2560
10       3/12/2560
7        4/12/2560
3        5/12/2560
11       5/12/2560

อยากให้ ID เรียงใหม่ตามวันที่ดังนี้
ID        DateRec
5        2/12/2560
6        2/12/2560
7       3/12/2560
8        4/12/2560
9        5/12/2560
10       5/12/2560

มันต้องเขียนโคตยังงัยครับ

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

1 @R24460
วางโค้ดนี้ใน Module (ไปเปลี่ยนชื่อเทเบิลเองนะครับ) แล้วกด Ctrl-G เพื่อเปิด Immediate Window แล้วสั่ง ReSortID ครับ

Public Sub ReSortID()
    Dim DB As DAO.Database
    Dim RS As DAO.Recordset
    Dim NextID As Long
    
    Set DB = CurrentDb
    Set RS = DB.OpenRecordset("select * from เทเบิล order by DateRec")
    NextID = RS("ID")
    
    Do Until RS.EOF
        RS.Edit
        RS("ID") = NextID
        RS.Update
       
        NextID = NextID + 1
        RS.MoveNext
    Loop
    RS.Close
End Sub
2 @R24462
ผมสร้างปุ่มคำสั่งขึ้นมาแล้วนำโค๊ตของอาจารย์ไปไว้ในปุ่ม
พอรันคำสังแล้ว เกิด Error ดังรูปครับ



ผมไม่ได้บอกอาจารย์ว่าฟิลด์ ID มันเป็น Pimarykey ครับ
และก็ยังเชื่อมโยงกับอีกตารางหนึ่ง ไม่รู้ว่าเกี่ยวด้วยมั้ยครับ
ต้องแก้ไขอย่างไรครับ
3 @R24464
เกี่ยวอย่างมากครับ แล้วฟิลด์ ID เป็น AutoNumber ด้วยหรือไม่ ?
4 @R24469
ID เป็น Number Long Integer ครับอาจารย์
5 @R24472
มันมีสองเรื่องที่ต้องทำ คือเปลี่ยนค่าใน ID และค่าของ Foreign Key ในเทเบิลอื่นๆที่อ้างมายัง ID นี้ด้วย (Foreign Key หมายถึง ฟิลด์ในเทเบิลอื่น ที่อ้างมายัง Primary Key หรือ Unique Key ของเทเบิลหลัก) มันมีวิธีที่ทำให้ทั้งสองเรื่องเกิดไปพร้อมกันได้คือ เราไปที่เมนู Tools - Relationships แล้วโยงความสัมพันธ์ระหว่างฟิลด์ ID กับ
Foreign Key ในเทเบิลอื่นๆ และเลือกตัวเลือก Enforce Referential Integrity กับ Cascade Update Relation Fields แล้วก็รันโค้ดตัวใหม่นี้

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

Public Sub ReSortID()
    Dim DB As DAO.Database
    Dim RS As DAO.Recordset
    
    Dim InTrans As Boolean
    
    Dim FirstID As Long
    Dim NextID As Long

On Error GoTo ErrHandler

    Set DB = CurrentDb

    ' เก็บค่า ID ค่าแรกที่พบเมื่อเรียงตาม DateRec
    Set RS = DB.OpenRecordset("select ID from T order by DateRec")
    FirstID = RS("ID")

    ' หาค่า ID ที่มากที่สุด+1
    Set RS = DB.OpenRecordset("select Max(ID) + 1 as NextID from T")
    NextID = RS("NextID")
    
    RS.Close
    
    ' กำหนดจุดเริ่มต้นของ Transaction
    DBEngine.BeginTrans: InTrans = True
    
    ' เปลี่ยน ID เป็นค่า NextID และเพิ่มทีละ 1
    Set RS = DB.OpenRecordset("select ID from T order by DateRec", dbOpenDynaset)
    Do Until RS.EOF
        RS.Edit: RS("ID") = NextID: RS.Update

        NextID = NextID + 1
        RS.MoveNext
    Loop

    ' เปลี่ยน ID เป็นค่า ID แรกที่พบที่เก็บไว้ก่อนหน้านี้ และเพิ่มทีละ 1
    RS.MoveFirst
    NextID = FirstID
    Do Until RS.EOF
        RS.Edit: RS("ID") = NextID: RS.Update

        NextID = NextID + 1
        RS.MoveNext
    Loop
    
    ' ปิด Transaction และยืนยันการเปลี่ยนแปลง
    DBEngine.CommitTrans: InTrans = False
    
ExitProc:
    On Error Resume Next
    
    ' ถ้า Transaction ยังเปิดอยู่ แสดงว่าเกิด error ขึ้น
    ' ก็ให้ยกเลิกการเปลี่ยนแปลงทุกอย่างใน Transaction
    If InTrans Then DBEngine.Rollback
    
    RS.Close
    Exit Sub
    
ErrHandler:
    MsgBox "Error " + Str(Err.Number) + " : " + Err.Description
    Resume ExitProc
End Sub


6 @R24473
สนใจสนับสนุนเพจได้ที่ ขายหนังสือเพื่อเว็ป
7 @R24476
มันขึ้น Error แบบนี้ครับ

Err 3061 : Too few parameters. Expected 1.

ในตารางยังไม่มีอะไรเกิดขึ้นครับ
8 @R24477
ผมลองโค้ดนี้แล้ว ไม่มี error นะครับ ได้ทำการเปลี่ยนชื่อเทเบิล T ไปเป็นชื่อที่ใช้จริงหรือยัง
9 @R24478
เปลี่ยนแล้วทุกบรรทัดครับ
10 @R24479
ถ้า debug เป็น ก็ทำดูครับ ไม่งั้นไม่ทราบว่าบรรทัดไหน
11 @R24480
อีกอย่างคือ Compile หรือยังครับ
12 @R24481
ลอง Compile หมดแล้วครับ
พอรันมันขึ้น Error ที่บอก เป็นกล่องข้อความครับ
ไม่ไม่ขึ้น Debug เลยครับ
13 @R24482
การ debug เราต้องทำเองนะครับ ไม่ใช่อะไรที่เป็นสิ่งอัตโนมัคิ ผมแนะนำว่าให้ไปศึกษาเรื่องนี้ดู จะช่วยหาที่ผิดของโปรแกรมได้ ตอนนี้แนะนำว่าเอาโค้ดอันใหม่นี้ไปแทนของเดิม มันจะบอกว่าผิดที่บรรทัดไหนออกมาเพิ่มเติม

Public Sub ReSortID()
          Dim DB As DAO.Database
          Dim RS As DAO.Recordset
          
          Dim InTrans As Boolean
          
          Dim FirstID As Long
          Dim NextID As Long

10    On Error GoTo ErrHandler

20        Set DB = CurrentDb

          ' เก็บค่า ID ค่าแรกที่พบเมื่อเรียงตาม DateRec
30        Set RS = DB.OpenRecordset("select ID from T order by DateRec")
40        FirstID = RS("ID")

          ' หาค่า ID ที่มากที่สุด+1
50        Set RS = DB.OpenRecordset("select Max(ID) + 1 as NextID from T")
60        NextID = RS("NextID")
          
70        RS.Close
          
          ' กำหนดจุดเริ่มต้นของ Transaction
80        DBEngine.BeginTrans: InTrans = True
          
          ' เปลี่ยน ID เป็นค่า NextID และเพิ่มทีละ 1
90        Set RS = DB.OpenRecordset("select ID from T order by DateRec", dbOpenDynaset)
100       Do Until RS.EOF
110           RS.Edit: RS("ID") = NextID: RS.Update

120           NextID = NextID + 1
130           RS.MoveNext
140       Loop

          ' เปลี่ยน ID เป็นค่า ID แรกที่พบที่เก็บไว้ก่อนหน้านี้ และเพิ่มทีละ 1
150       RS.MoveFirst
160       NextID = FirstID
170       Do Until RS.EOF
180           RS.Edit: RS("ID") = NextID: RS.Update

190           NextID = NextID + 1
200           RS.MoveNext
210       Loop
          
          ' ปิด Transaction และยืนยันการเปลี่ยนแปลง
220       DBEngine.CommitTrans: InTrans = False
          
ExitProc:
230       On Error Resume Next
          
          ' ถ้า Transaction ยังเปิดอยู่ แสดงว่าเกิด error ขึ้น
          ' ก็ให้ยกเลิกการเปลี่ยนทุกอย่างใน Transaction
240       If InTrans Then DBEngine.Rollback
          
250       RS.Close
260       Exit Sub
          
ErrHandler:
270       MsgBox "Error at line " + Str(Erl) + " code " + Str(Err.Number) + " : " + Err.Description
280       Resume ExitProc
End Sub

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