subform ไม่บันทึกทึกค่าที่ต้องการ โดยใช้ Transaction



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

17 มี.ค. 64 , 14:15:08
อ่าน 260 ครั้ง

Jiw Jewel

สวัสดีค่ะ เรากำลังทำการบันทึกข้อมุลโดยมีโครงสร้างโปรแกรม คือ มีฟอร์มย่อย 1 ฟอร์มในฟอร์มหลักค่ะ
ตัวอย่างโปรแกรมนะคะ



ต่อไปเป็นโค้ดที่ใช้นะคะ

Option Compare Database
Option Explicit
Dim Prefix As String
Dim vLast As Variant
Dim iNext As Integer
Dim msg As Integer
Dim Saved As Boolean
Dim runNo As Variant
Dim tradeID As String
Dim doc_id As String

Private Sub C_cancelF_Click()
        DoCmd.OpenForm "Home", acNormal, "", "", , acNormal
        DoCmd.Close acForm, "form_proRequest"
End Sub


ส่วนนี้ไม่มีอะไรค่ะ แค่โค้ดกำหนดค่าตัวเลขเอกสารเฉยๆค่ะ
Private Sub DistChannel_AfterUpdate()
    If Not IsNull(Me.DistChannel.Value) Then
        Prefix = Me.DistChannel.Value
        'find max value of runing_NO in table ProRequest
        vLast = DMax("[runing_NO]", "[ProRequest]", "[runing_NO] LIKE '" & Format([proReq_date], "yy\*\'"))
        If IsNull(vLast) Then
            iNext = 1
        Else
            vLast = Val(Right(vLast, 3))
            vLast = vLast + 1
            iNext = vLast
        End If
        runNo = Format([proReq_date], "yy") & Format(iNext, "000")
        Me.run_Number = runNo
        Me.proReq_ID = Prefix & Me.run_Number
        'set button enable
        Me.next_btn.Enabled = True
        Me.save_btn.Enabled = True
    Else
        Me.run_Number = ""
        Me.proReq_ID = ""
        'set button enable disable
        Me.next_btn.Enabled = False
        Me.save_btn.Enabled = False
    End If

End Sub


ส่วนตรงนี้เป็น Table ของ sub form ค่ะ Form ค่ะ
Private Sub Form_Current()
'Set Me.sub_proRequrest_Detail.Form.Recordset = CurrentDb.OpenRecordset("SELECT * FROM [proRequest Detail] WHERE proReq_ID = '" & Me.proReq_ID & "'", dbOpenDynaset, dbAppendOnly)
End Sub

Private Sub Form_Dirty(Cancel As Integer)
    If Me.Dirty = False Then
        DBEngine.BeginTrans
    End If
End Sub

ส่วนตรงนี้เป็น Table ของ Main Form ค่ะ
Private Sub Form_Open(Cancel As Integer)
Set Me.Recordset = CurrentDb.OpenRecordset("SELECT * FROM ProRequest", dbOpenDynaset, dbAppendOnly)
End Sub


ปุ่มกด save ซึ่งสามารถทำงานได้ แต่เมื่อกดเพิ่มข้อมูลในsubform แล้ว ไม่สามรถบันทึกได้ค่ะ เพิ่งแต่ที่ตรงนี้เยอะเพระต้องการบังคับใส่ข้อมูลเฉยๆค่ะ
Private Sub next_btn_Click()
On Error GoTo Save_Error
        If IsNull(Me.DistChannel) Then
        MsgBox "กรุณาเลือกช่องทางการขาย (1)", vbCritical
        Me.DistChannel.SetFocus
        Exit Sub
    End If
    If IsNull(Me.forecast_dist) Then
        MsgBox "กรุณาเลือกช่องทางการขาย (2)", vbCritical
        Me.forecast_dist.SetFocus
        Exit Sub
    End If
    If IsNull(Me.Empp_ID) Then
        MsgBox "กรุณาเลือกพนักงานขาย", vbCritical
        Me.Empp_ID.SetFocus
        Exit Sub
    End If
    If IsNull(Me.proReq_name) Then
        MsgBox "กรุณาใส่ชื่อกิจกกรม", vbCritical
        Me.proReq_name.SetFocus
        Exit Sub
    End If
    If IsNull(Me.proReq_start_date) Then
        MsgBox "กรุณากรอกวันที่เริ่มโปรโมชั่น", vbCritical
        Me.proReq_start_date.SetFocus
        Exit Sub
    End If
    If IsNull(Me.proReq_end_date) Then
        MsgBox "กรุณากรอกวันที่สิ้นสุดโปรโมชั่น", vbCritical
        Me.proReq_end_date.SetFocus
        Exit Sub
    End If
    If IsNull(Me.proReq_date_sum) Then
        MsgBox "กรุณากรอกวันที่สรุปรายการกับฝ่ายขาย", vbCritical
        Me.proReq_date_sum.SetFocus
        Exit Sub
    End If
    If IsNull(Me.proReq_date_confirm) Then
        MsgBox "กรุณากรอกวันที่ฝ่ายขายยืนยันรายการ", vbCritical
        Me.proReq_date_confirm.SetFocus
        Exit Sub
    End If
    If (Me.C_discoubt = False) And (Me.C_exchange = False) And (Me.C_getfree = False) And (Me.C_set = False) And (Me.C_spacial = False) And (Me.C_other = False) Then
        MsgBox "กรุณาเลือกประเภทกิจกรรม", vbCritical
        Exit Sub
    End If

    If IsNull(Me.FrontMargin) Then
        MsgBox "กรุณากรอก Front margin/ส่วนลด", vbCritical
        Me.FrontMargin.SetFocus
        Exit Sub
    End If
    Me.Status_ID = 81
   CurrentDb.Execute "INSERT INTO proAssess (proAssess_ID, Sale_EMP_ID) VALUES ('" & Me.proReq_ID & "' , '" & Me.Empp_ID & "')"
    DBEngine.CommitTrans
    doc_id = Me.proReq_ID
    DoCmd.GoToRecord , , acNewRec
    DoCmd.OpenForm "Efrm_proAssess", acNormal, , "[proAssess_ID]='" & doc_id & "'"
    DoCmd.Close acForm, "form_proRequest"
    Exit Sub
   
Save_Error:
DBEngine.Rollback
MsgBox "error จ้าาาา", vbOKOnly
End Sub


ตรงนี้เป็น โค้ดสำหรับการใส่ข้อมูลในเอกสารเฉยๆค่ะ
Private Sub proReq_date_confirm_BeforeUpdate(Cancel As Integer)
minimum_date = DateAdd("m", -2, Me.proReq_start_date)
    If (Me.proReq_date_confirm >= minimum_date) Then
        MsgBox "วันที่ไม่ถูกต้อง", vbCritical
        Cancel = True
    End If
End Sub
Private Sub proReq_date_sum_BeforeUpdate(Cancel As Integer)
    If Me.proReq_date_sum <= Me.proReq_date Then
        MsgBox "วันที่ไม่ถูกต้อง", vbCritical
        Cancel = True
    End If
End Sub

Private Sub proReq_end_date_BeforeUpdate(Cancel As Integer)
    If (Me.proReq_end_date < Me.proReq_start_date) Then
        MsgBox "วันที่ไม่ถูกต้อง", vbCritical
        Cancel = True
        Me.proReq_end_date.Undo
    End If
End Sub


ตรงนี้เป็น โค้ดสำหรับการใส่ข้อมูลในเอกสารเฉยๆค่ะ
Private Sub proReq_start_date_AfterUpdate()
    Me.proReq_date_confirm = DateAdd("m", -2, Me.proReq_start_date)
End Sub

ปุ่มกด save ซึ่งสามารถทำงานได้ แต่เมื่อกดเพิ่มข้อมูลในsubform แล้ว ไม่สามรถบันทึกได้ค่ะ
Private Sub save_btn_Click()
On Error GoTo Save_Error
    If IsNull(Me.DistChannel) Then
        MsgBox "กรุณาเลือกช่องทางการขาย (1)", vbCritical
        Me.DistChannel.SetFocus
        Exit Sub
    End If
    If IsNull(Me.proReq_start_date) Then
        MsgBox "กรุณากรอกวันที่เริ่มโปรโมชั่น", vbCritical
        Me.proReq_start_date.SetFocus
        Exit Sub
    End If
    If IsNull(Me.proReq_end_date) Then
        MsgBox "กรุณากรอกวันที่สิ้นสุดโปรโมชั่น", vbCritical
        Me.proReq_end_date.SetFocus
        Exit Sub
    End If
    Me.Status_ID = 81
    DBEngine.CommitTrans
    Saved = True
    MsgBox "บันทึกแล้ว", vbOKOnly
    Exit Sub
   
Save_Error:
DBEngine.Rollback
Saved = False
MsgBox "error จ้าาาา", vbOKOnly
End Sub


สิ่งเราต้องการคือการกด save แล้วมันบันทึกตารางค่ะ แต่ทำไม่ได้ค่ะ ช่วนด้วยนะคะ งมมา 3 วันแล้วค่ะ
ส่วนด้านล่างเป็น ref ที่ดูมาเป็นไกด์ค่ะ
https://codekabinett.com/rdumps.php?Lang=2&targetDoc=how-to-access-transaction link

 

18 มี.ค. 64 , 10:54:10
ตอบกลับ #1

PNR

: subform ไม่บันทึกทึกค่าที่ต้องการ โดยใช้ Transaction
« ตอบกลับ #1 เมื่อ: 18 มี.ค. 64 , 10:54:10 »


Private Sub Form_Dirty(Cancel As Integer)
    If Me.Dirty = False Then
        DBEngine.BeginTrans
    End If
End Sub
ตรง Event นี้  If Me.Dirty = False Then เงื่อนไขคือถ้าไม่มีการทำงาน เพิ่มเติมข้อมูลหรือแก้ไขข้อมูลแล้วถึงจะ BeginTrans
แต่การเพิ่มข้อมูลใหม่หรือทำงานบนฟอร์ม ทำให้เงื่อนไขนี้คือ Me.Dirty = true ทำให้ไม่เข้าเกณฑ์การทำงานของเงื่อนไขหรือเปล่า

ทำให้เมื่อเพิ่มข้อมูลใน ซัฟฟอร์มแล้ว CommitTrans ไม่ทำงานครับ

ลองดูรูปแบบที่อาจารย์สันติสุข เคยโพสไว้เพิ่มเติมดูนะครับ
https://www.thai-access.com/topic_post.asp?CategoryID=1&TopicID=4896
« แก้ไขครั้งสุดท้าย: 18 มี.ค. 64 , 10:59:16 โดย PNR »
Time to stop for me  :dizzy:
 
โพสต์นี้ได้รับคำขอบคุณจาก: Jiw Jewel

19 มี.ค. 64 , 08:46:15
ตอบกลับ #2

Jiw Jewel

: subform ไม่บันทึกทึกค่าที่ต้องการ โดยใช้ Transaction
« ตอบกลับ #2 เมื่อ: 19 มี.ค. 64 , 08:46:15 »
ขอตอบคำถามที่ถามมานะคะ

Private Sub Form_Dirty(Cancel As Integer)
    If Me.Dirty = False Then
        DBEngine.BeginTrans
    End If
End Sub

ตอนแรกเราเองก็คิดแบบเดียวกันค่ะ แต่พอลอง debug ดูปรากฏว่ามันเข้าเงื่อนไขค่ะ แต่ในทางกลับกันพอเปลี่ยนเป็น true มันไม่เข้าเงื่อนไข แล้วขึ้นerror ตรง rollback บอกว่าไม่มีการ DBEngine.BeginTrans ทำให้ rollback ไม่สามารถทำงานได้ค่ะ

เราเองก็ไม่เข้าใจค่ะ เพราะปกติมันจะเป็น true ซึ่งก็ยังงงอยู่ค่ะ
แล้วจากที่ลองทดสอบมาหลายวันและหลายรอบก็ได้รู้ว่าปัญหาจริงๆ มันอยู่ตรง subform ค่ะ ซึ่งเรายังหาวิธีแก้ไขไม่ได้เลยค่ะ ลองปรับการ link form ก็ยังไม่ได้ค่ะ

ส่วนตัวอย่างที่แปะมาจะลองไปอ่านดูค่ะ ขอบคุณนะคะ ได้เรื่องยังไงเดี๋ยวมาบอกค่ะ

 

19 มี.ค. 64 , 17:05:41
ตอบกลับ #3

Jiw Jewel

: subform ไม่บันทึกทึกค่าที่ต้องการ โดยใช้ Transaction
« ตอบกลับ #3 เมื่อ: 19 มี.ค. 64 , 17:05:41 »
Update ค่ะ

ตอนนี้ทำได้แล้วนะคะ ปัญหามันอยู่ที่ เวลาเข้าไปกรอกข้อมูลใน sub form แล้ว ออกออกมากรอกข้อมูลใน main form ใหม่ ทำให้ คำสั่ง DBEngine.BeginTrans ตรง Private Sub Form_Dirty ทำงานใหม่ทุกครั้งค่ะ (แม้ว่าในความเป็นจริงแล้วเราจะไม่ค่อยเข้าใจก็ตามว่าการที่มันstart ใหม่ทุกครั้งมีปัญหาอะไรค่ะเพราะ error ไม่ขึ้นค่ะ)

ซึ่งทางแก้ของเราคือการใส่เงื่อนไขการเข้า ออก ของ sub form เพื่อดักไม่ให้คำสั่งดังกล่าวทำงานนั่นเองค่ะ

 


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