เขียนโค้ด Event On Click ให้ Save แต่ดันเด้งวนไปที่ Event Before Update



0 สมาชิก และ 1 บุคคลทั่วไป กำลังดูหัวข้อนี้

13 มิ.ย. 63 , 14:31:00
อ่าน 129 ครั้ง

Tatchawin

สวัสดีครับทุกท่าน ขอสอบถามปัญหาการเขียนโค้ด Event On Click ให้ Save แล้วมันดันเด้งวนไปที่ Event Before Update ครับ

คือผมทำฟอร์มขึ้นมา ชื่อ frmPunish ซึ่งก็จะมี Subform อยู่ด้านในอีก(สามารถดูได้จากไฟล์แนบครับ) พร้อมกับมีปุ่ม Save 2 ปุ่ม

1. Save New(cmdSave1): ไว้สำหรับเซฟ Record ใหม่ มีโค้ดดังนี้
Private Sub cmdSave1_Click()
    Me.Dirty = False
    DoCmd.SetWarnings False
    DoCmd.RunCommand acCmdSaveRecord
    Me.txtNationalID1 = Me.txtNationalID2
    Me.txtCreated = Now()
    Me.txtCreatedBy = GetUserName()
    MsgBox ("Your record has been successfully saved!")   
    DoCmd.SetWarnings True
    DoCmd.RefreshRecord
End Sub


2. Save New(cmdSave2): ไว้สำหรับเซฟการแก้ไขข้อมูลในแต่ละ Record มีโค้ดดังนี้
Private Sub cmdSave2_Click()
    Me.Dirty = False
    DoCmd.SetWarnings False
    Me.txtModified = Now()
    Me.txtModifiedBy = GetUserName()
    MsgBox ("Your record edited has been successfully saved!")
    DoCmd.SetWarnings True
    DoCmd.RefreshRecord
End Sub


ปัญหาคือ ไม่ว่าจะกดปุ่ม Save ใดก็ตาม มันจะวนมาที่ Event BeforeUpdate ทุกที ซึ่งผมเขียนโค้ดไว้เป็นเหมือนกับ prompt user saving
(ถ้ามีการเลื่อน Record หรือปิดหน้าต่างให้ถามก่อนว่าจะ Save Record นั้นหรือไม่ทุกครั้ง) ซึ่งผมต้องการแค่ว่าถ้ากดปุ่ม Save ใดๆก็ตาม
ให้มันจบแค่ Event On Click ไม่ต้องวนไปที่ Event BeforeUpdate (ซึ่งมันจะขึ้น Pop Up หลายๆครั้งมาก จนเกินไป)

จะมีวิธีใดแก้ปัญหาที่ผมเจอได้บ้าง หรือช่วยแก้โค้ดให้ผมได้ไหมครับ(ผมได้แนบไฟล์มา สามารถโหลดมาลองดูได้ เปิด frmPunish นะครับ)
ขอบคุณมากครับ

โค้ด Event BeforeUpdate
Private Sub Form_BeforeUpdate(Cancel As Integer)
   Dim ctl As Control
   Dim msg As String
   On Error GoTo Err_BeforeUpdate
   If Me.Dirty Then
        msg = (MsgBox("Are you sure you want to save change?", vbYesNo + vbQuestion, "Save Record"))
        If msg = vbNo Then
            Me.Undo
        End If
        If msg = vbYes Then
            If IsNull(Me.txtCreatedBy) And IsNull(Me.txtCreated) Then
                Me.txtNationalID1 = Me.txtNationalID2
                Me.txtCreated = Now()
                Me.txtCreatedBy = GetUserName()
                MsgBox ("Your record has been successfully saved!")
            Else
                txtModified = Now()
                txtModifiedBy = GetUserName()
                MsgBox ("Your record has been successfully saved!")
            End If
        End If
   End If
Exit_BeforeUpdate:
   Exit Sub
Err_BeforeUpdate:
   MsgBox Err.Number & " " & Err.Description
   Resume Exit_BeforeUpdate
End Sub

 

14 มิ.ย. 63 , 01:15:30
ตอบกลับ #1

สันติสุข

1. ต้องสร้างตัวแปร IsSaveClicked ในระดับของ form module ตัวนึงที่เก็บสถานะว่าได้กดปุ่ม Save ก่อนจะเกิดการบันทึกหรือไม่ แล้วค่อยทำการปรับปรุง txtCreated, txtCreatedBy, txtModified หรือ txtModifiedBy ภายใน Form_BeforeUpdate event procedure เพียงจุดเดียวตามค่าของตัวแปรนี้

2. Me.Dirty = False และ DoCmd.RunCommand acCmdSaveRecord ทำงานเหมือนกันคือสั่งให้บันทึกเรคอร์ดบนฟอร์มลงฐานข้อมูล ดังนั้นเลือกคำสั่งใดคำสั่งหนึ่งก็พอ

3. Form_BeforeUpdate event procedure จะทำงานเสมอเมื่อจะบันทึกข้อมูลบนฟอร์มลงฐานข้อมูล เมื่อโค้ดในปุ่ม Save สั่งบันทึกปั๊ป โค้ดจะกระโดดมา Form_BeforeUpdate event procedure ทันที และตามด้วย Form_AfterUpdate event procedure  แล้วค่อยกลับมาที่โค้ดบรรทัดต่อไปในปุ่ม Save

4. การตรวจสอบว่าเป็นเรคอร์ดเก่าหรือใหม่ สามารถเช็คจาก Me.NewRecord ได้ จึงคิดว่าไม่ต้องแยกปุ่มบันทึกเรคอร์ดใหม่และเก่าแยกกัน

5. Form_AfterUpdate event procedure เป็นตำแหน่งที่เหมาะสมที่จะวางโค้ดแสดงข้อความว่าได้บันทึกแล้วเอาไว้ที่นี่ เราจะใช้สถานะความเป็นเรคอร์ดเก่าหรือใหม่เพื่อแสดงข้อความที่แตกต่างกัน แต่เนื่องจากเมื่อบันทึกเรคอร์ดแล้ว Me.NewRecord property จะให้ค่าเป็น FALSE เสมอ ดังนั้นใน event นี้จึงเช็คจาก property นี้ไม่ได้ จึงต้องเก็บสถานะว่าเป็นเรคอร์ดใหม่เอาไว้ในตัวแปร IsNewRecord เพิ่มเติมตั้งแต่อยู่ใน  Form_BeforeUpdate event procedure

หมายเหตุ ผมไม่ได้เปิดโปรแกรมคุณหรือทดสอบโค้ดนี้ คุณเอาไปลองหรือปรับปรุงเองนะครับ

โค๊ด: [Select]
Option Compare Database
Option Explicit

Dim IsSaveClicked   As Boolean
Dim IsNewRecord     As Boolean

Private Sub cmdSave_Click()
    IsSaveClicked = True
    Me.Dirty = False
End Sub

Private Sub Form_BeforeUpdate(Cancel As Integer)

On Error GoTo Err_BeforeUpdate

    If Not IsSaveClicked Then
        If MsgBox("Are you sure you want to save change?", vbYesNo + vbQuestion, "Save Record") = vbNo Then
            Me.Undo
            GoTo Exit_BeforeUpdate
        End If
    End If
    If Me.NewRecord Then
        Me.txtNationalID1 = Me.txtNationalID2
        Me.txtCreated = Now()
        Me.txtCreatedBy = GetUserName()
        IsNewRecord = True
    Else
        Me.txtModified = Now()
        Me.txtModifiedBy = GetUserName()
    End If
   
Exit_BeforeUpdate:
   Exit Sub
   
Err_BeforeUpdate:
   MsgBox Err.Number & " " & Err.Description
   Resume Exit_BeforeUpdate
End Sub

Private Sub Form_AfterUpdate()
    If IsNewRecord Then
        MsgBox "Your record has been successfully saved!"
    Else
        MsgBox "Your edited record has been successfully saved!"
    End If
    IsNewRecord = False
    IsSaveClicked = False
End Sub

Private Sub Form_Undo(Cancel As Integer)
    IsSaveClicked = False
    IsNewRecord = False
End Sub

Private Sub Form_Error(DataErr As Integer, Response As Integer)
    IsSaveClicked = False
    IsNewRecord = False
End Sub

ช่วยพกถุงผ้า/ถุงพลาสติกใช้แล้วไปซื้อของเพื่อลดการใช้พลาสติก ขยะ รักษาสิ่งแวดล้อม และไม่ให้ภาวะโลกร้อนวิกฤติเร็วขึ้นกว่านี้
ช่วยคลิกโฆษณาข้างล่างนี้ เพื่อสนับสนุนเวปบอร์ดด้วยครับ
:nice day:
 
โพสต์นี้ได้รับคำขอบคุณจาก: Tatchawin

18 มิ.ย. 63 , 13:34:38
ตอบกลับ #2

Tatchawin

ขอบคุณมากๆครับ ทำได้แล้วครับ

 


บอร์ดเรียนรู้ Access สำหรับคนไทย