اذهب الي المحتوي
أوفيسنا

الردود الموصى بها

قام بنشر

السلام عليكم .. الاساتذة الكرام

الموضوع اليوم عن تتبع التغييرات التى تقوم بها على اى سجل موجود فى قاعدة البيانات .. لنبدأ

لنفترض ان لدى مجموعة من النماذج التى تقوم بتعديل بيانات معينة فى الجداول واريد ان اتتبع التغييرات التى تمت بحيث يتم تسجيل البيانات قبل التعديل وبعد التعديل

مثال : لدى هذا النموذج ومهمته التعديل على رصيد المخزن .. انظر للقيمة قبل التعديل :

1.png.d5cc21d8b302544811856d84695c92db.png

قمت بالتعديل وضغطت على زر الأمر ..

2.png.811ed84cf6f8084dc2fe01c9ee3f74ee.png

النتيجة .. فى جدول التعديلات TblAudit تم تسجيل التالى :

3.png.815b63f0880f49193561b6ae685e8aa7.png

القيمة قبل التعديل وبعد التعديل .. والشخص القائم بالتعديل .. وتاريخ ووقت التعديل  .. و النموذج المستخدم فى التعديل .. ومصدر بيانات هذا النموذج .

فلنجرب تعديل اكثير من حقل فى النموذج دفعة واحدة :

4.png.8f26c678c4b1e4dfa5a9000150fd4eb3.png

النتيجة :

5.png.5695b08a2ae679ed54f38652b3bab0de.png

تابع معى لتعرف الطريقة :

مبدأياً لم اكتب الكود ولكن قمت بالتعديل عليه وعملت امثلة مصمم الكود كتبت اسمها فى الكود نفسه ..

افتح موديول جديد والصق هذا الكود :

Public Function WriteAudit(frm As Form, lngID As Long) As Boolean
On Error GoTo err_WriteAudit

    Dim ctlC As Control
    Dim strSQL As String
    Dim bOK As Boolean
   
   
   
    bOK = False
    
   DoCmd.SetWarnings False
    
    ' For each control.
    For Each ctlC In frm.Controls
        If TypeOf ctlC Is TextBox Or TypeOf ctlC Is ComboBox Then
            If ctlC.Value <> ctlC.OldValue Or IsNull(ctlC.OldValue) Then
                If Not IsNull(ctlC.Value) Then
                    strSQL = "INSERT INTO tblAudit ( ID, FieldChanged, FieldChangedFrom, FieldChangedTo, User, DateofHit, FrmName , FrmRcrdSrc  ) " & _
                           " SELECT " & lngID & " , " & _
                           "'" & ctlC.Name & "', " & _
                           "'" & ctlC.OldValue & "', " & _
                           "'" & ctlC.Value & "', " & _
                           "'" & GetUserName_TSB & "', " & _
                           "'" & Now & "' , " & _
                           "'" & M & "', " & _
                           "'" & R & "'"

                    'Debug.Print strSQL
                    DoCmd.RunSQL strSQL
                End If
            End If
        End If
    Next ctlC
    
    WriteAudit = bOK
    
exit_WriteAudit:
    DoCmd.SetWarnings True
    Exit Function
    
err_WriteAudit:
    MsgBox Err.Description
    Resume exit_WriteAudit
    
End Function

اذا اردت ان تنادى هذا الكود يتم بهذه الطريقة

WriteAudit(Form Name, Record ID)

مثلا كالتالى فى زر امر  :

On Error GoTo Err_cmdClose_Click
    
    If Not IsNull(Me!ID) Then
        M = Me.Name
      '  Debug.Print M
        R = Me.RecordSource
      '  Debug.Print R
        X = WriteAudit(Me, Me!ID)
    End If
    
    DoCmd.Close

Exit_cmdClose_Click:
    Exit Sub
    
Err_cmdClose_Click:
    MsgBox Err.Description
    Resume Exit_cmdClose_Click

ملاحظة :

- يمكن استخدام الكود فى اى نموذج يقوم بتعديل البيانات وسيقوم الكود بتسجيل التعديلات وبياناتها كما اشرت سابقاً.

قام استاذنا جعفر @jjafferr بعمل موضوع رائع مشابه فى الفكرة ولكن يقوم بتسجيل التعديلات التى تتم على الجداول عن طريق الماكرو يمكنك مشاهدته من هنا :

مرفق مثال به نموذجين وتم استخدام نفس الاكواد فيهما .. دمتم بود :fff:

 

Dynamic Audit Trail - Amr Ashraf.accdbFetching info...

  • Like 5
  • Thanks 2
قام بنشر
  في 13‏/2‏/2022 at 15:28, Eng.Qassim said:

اقتراحي ان يتم التعديل عليه بان ياخذ GetUserName من جدول ال Users

Expand  

هوا بيسجل اسم المستخدم الخاص بالويندوز مش البرنامج.. وعامة زيادتها سهلة يبقوا الاتنين موجودين .. شرفنى مرورك :fff:

قام بنشر

ما شاء الله عاشت ايدك فوق الممتاز 

ولكن عندي سؤال لما استورد الوحدات النمطية للبرنامج بتاعي مش شغال الا علي الجداول االي حضرتك عملتها اما اي جدول خاص بيا مش شغال مع العمل ان جدول تسجيل التغيرات استورته لبرنامجي كما هو 

قام بنشر
  في 13‏/2‏/2022 at 17:56, moamen salem said:

ولكن عندي سؤال لما استورد الوحدات النمطية للبرنامج بتاعي مش شغال الا علي الجداول االي حضرتك عملتها اما اي جدول خاص بيا مش شغال مع العمل ان جدول تسجيل التغيرات استورته لبرنامجي كما هو 

Expand  

ارفق ما قمت به .. لا علاقة للجداول بالموضوع الفكرة كلها فى الاكواد .. الجدول الوحيد المطلوب هو TblAudit لتسجيل التغيرات به

قام بنشر
  في 13‏/2‏/2022 at 17:56, moamen salem said:

لما استورد الوحدات النمطية للبرنامج بتاعي مش شغال الا علي الجداول االي حضرتك عملتها

Expand  

طبعا استاذ مؤمن ..لو تلاحظ حضرتك لجملة السكوال في الموديول لازم تغيرها حسب جدولك بما يتطابق واسماء الكنترول الي في النموذج

قام بنشر
  في 13‏/2‏/2022 at 18:39, Eng.Qassim said:

لجملة السكوال في الموديول لازم تغيرها حسب جدولك بما يتطابق واسماء الكنترول الي في النموذج

Expand  

يا هندسة هل تقصد جدول TblAudit ؟ .. هذا هو الجدول الوحيد المطلوب استيراده مع الموديولات اما باقى الجداول لا علاقة لها بالموضوع .. أيا كانت الجداول الموجودة فى القاعدة لن يتغير فى الكود أى شئ .. تشرفت بمرورك :fff:

قام بنشر

لما سحبت النموذج اللي فيه المشكلة في قاعدة بيانات تاني فارغة وحذفت كل الاكواد اللي فيه اشتغل بدون مشكلة كدة تقريبا في بعض الاكواد متعارضة معاه هشوف كدة ان شاء الله وشكرا جدا علي المعلومة دي 

  • Like 1
قام بنشر

ولكن هتفضل عندنا مشكلة جوهرية ومحدش اتكلم فيها اللي هي النماذج الفرعية اللي بداخل النماذج الرئيسية

قام بنشر
  في 13‏/2‏/2022 at 20:08, moamen salem said:

شاء الله وشكرا جدا علي المعلومة دي 

Expand  

لا شكر على واجب , لا تنسى موافاتنا بتحليلك للمشكلة .

  في 13‏/2‏/2022 at 20:14, moamen salem said:

ولكن هتفضل عندنا مشكلة جوهرية ومحدش اتكلم فيها اللي هي النماذج الفرعية اللي بداخل النماذج الرئيسية

Expand  

أحسنت كنت مستنى حد يذكرها .. ممكن تعديل الكود ليعمل فى الحالتين سأحاول عملها فى اقرب وقت ودمجها فى الموضوع .

الموضوع فى بالى من الاول بس مستنى المناقشات .

قام بنشر
  في 13‏/2‏/2022 at 20:14, Amr Ashraf said:

لا شكر على واجب , لا تنسى موافاتنا بتحليلك للمشكلة .

Expand  

المشكلة طلعت في الكود دا 

DoCmd.GoToRecord , , acNewRec
حاطه في حدث عند التحميل اول ما احذفه الامور تكون تمام ولما اخليه ترجع المشكلة تاني

  في 13‏/2‏/2022 at 20:14, Amr Ashraf said:

لا شكر على واجب , لا تنسى موافاتنا بتحليلك للمشكلة .

أحسنت كنت مستنى حد يذكرها .. ممكن تعديل الكود ليعمل فى الحالتين سأحاول عملها فى اقرب وقت ودمجها فى الموضوع .

الموضوع فى بالى من الاول بس مستنى المناقشات .

Expand  

ان شاء الله تتوصل ليها ممكن نحط نفس الكود في حدث بعد تحديث للسجل في النموذج الفرعي وحضرتك اكيد عندك فكر احسن مني

  • Like 1
قام بنشر
  في 13‏/2‏/2022 at 20:14, moamen salem said:

ولكن هتفضل عندنا مشكلة جوهرية ومحدش اتكلم فيها اللي هي النماذج الفرعية اللي بداخل النماذج الرئيسية

Expand  

لسه شايف الموضوع الان

ولما جربته ظهرت معايا نقطة النماذج الفرعيه وخصوصا ان اغلب الاشياء المهمه المطلوب مراقبتها فى التعديلات بتكون فى نماذج فرعيه 

 

  في 13‏/2‏/2022 at 20:14, Amr Ashraf said:

لا شكر على واجب , لا تنسى موافاتنا بتحليلك للمشكلة .

أحسنت كنت مستنى حد يذكرها .. ممكن تعديل الكود ليعمل فى الحالتين سأحاول عملها فى اقرب وقت ودمجها فى الموضوع .

الموضوع فى بالى من الاول بس مستنى المناقشات .

Expand  

اشكر شكرا جزيلا على المجهود :fff:

بارك الله فيك 

وفى انتظار تعديل حضرتك

قام بنشر
  في 14‏/2‏/2022 at 08:01, moamen salem said:

لمشكلة هنا في سند القبض للاسف الكود بيعطي رسالة خطأ

Expand  

اعتقد المشكلة في رقم المستند المرتبط بالنموذج الفرعي ..فالموديول هنا هل يقرا من الرئيسي ام الفرعي ؟

ويجب ان يكون المعرف باللغة الانكليزية =ID

قام بنشر
  في 14‏/2‏/2022 at 08:01, moamen salem said:

المشكلة هنا في سند القبض للاسف الكود بيعطي رسالة خطأ

Expand  

لأن الحقل ID عندك String او حقل نصى ولكن فى الموديول ID متعرف As Long وبالتالى الموديول بيتوقع لما يتم تمرير ID من النموذج انه هيكون رقم وليس حروف وارقام وبالتالى بيطلعلك الخطأ Type Mismatch ان الID متعرف كمتغير رقمى ولكن اللى بيطلع من النموذج متغير نصى . فهمت ؟ حل الموضوع كالتالى .. يتم تعديل الموديول ليقبل النص والرقم

Public Function WriteAudit(frm As Form, StrID As String) As Boolean
On Error GoTo err_WriteAudit

    Dim ctlC As Control
    Dim strSQL As String
    Dim bOK As Boolean
   
   
   
    bOK = False
    
   DoCmd.SetWarnings False
    
    ' For each control.
    For Each ctlC In frm.Controls
        If TypeOf ctlC Is TextBox Or TypeOf ctlC Is ComboBox Then
            If ctlC.Value <> ctlC.OldValue Or IsNull(ctlC.OldValue) Then
                If Not IsNull(ctlC.Value) Then
                    strSQL = "INSERT INTO tblAudit ( ID, FieldChanged, FieldChangedFrom, FieldChangedTo, User, DateofHit, FrmName , FrmRcrdSrc  ) " & _
                           " SELECT '" & StrID & "', " & _
                           "'" & ctlC.Name & "', " & _
                           "'" & ctlC.OldValue & "', " & _
                           "'" & ctlC.Value & "', " & _
                           "'" & GetUserName_TSB & "', " & _
                           "'" & Now & "' , " & _
                           "'" & M & "', " & _
                           "'" & r & "'"

                    'Debug.Print strSQL
                    DoCmd.RunSQL strSQL
                End If
            End If
        End If
    Next ctlC
    
    WriteAudit = bOK
    
exit_WriteAudit:
    DoCmd.SetWarnings True
    Exit Function
    
err_WriteAudit:
    MsgBox Err.Description
    Resume exit_WriteAudit
    
End Function

لاحظ هذا السطر

قديم
Public Function WriteAudit(frm As Form, lngID As Long) As Boolean

بعد التعديل
  
Public Function WriteAudit(frm As Form, StrID As String) As Boolean

جرب ووافنى بالنتيجة

@Eng.Qassim لاحظ سبب المشكلة .

 

Dynamic Audit Trail - Amr Ashraf v2.0.accdbFetching info...

قام بنشر

السادة الافاضل .. بالنسبة لمشكلة عدم عمل الكود على النموذج الفرعى Subform تم حلها بدون تعديل فى الموديول .. شرح الحل

اذا قمت بمناداة الموديول عند حدث بعد التحديث لحقول النموذج الفرعى فما سيتم انه سيقوم بالحاق نفس السجل متكرر بنفس عدد التعديلات وبالتالى اذا قمنا ب4 تعديلات فإن اول 3 تعديلات سيتم تكرارهم 4 مرات والتعديل الاخير لن يتم تكراره وذلك لأن القيم المخزنة هى قيم السجل بالكامل وليس حقل واحد وبالتالى عند الحاقها بالجدول سيقوم بتقسيم السجل الى سطور وبهذا يتم التكرار .. انظر للمثال

529957604_Recording2022-02-14at10_33_03.thumb.gif.c6377f63bfb1eb0c6c100ce498c62e29.gif

كما تلاحظ تم تكرار التعديل الاول مرتين والثانى لم يتم تكراره لأن ليس هناك تعديلات بعده

وبالتالى لكى تعمل الطريقة يجب ان يتم استدعاء الكود فى حدث Before Update للنموذج الفرعى نفسه وليس الحقول بداخله وايضا نفس الموضوع للنموذج الرئيسى وبهذا سيقوم بتسجيل التعديلات التى تتم على النموذج الرئيسى والنموذج الفرعى وذلك بدون تعديل على الاكواد فى شئ .

مرفق التعديل على مرفق الاستاذ @moamen salem , انظر التعديل @عمر ضاحى

 

Dynamic Audit Trail + Subforms - Amr Ashraf v3.0.accdbFetching info...

  • Like 1
قام بنشر
  في 14‏/2‏/2022 at 10:08, Amr Ashraf said:

لأن الحقل ID عندك String او حقل نصى ولكن فى الموديول ID متعرف As Long وبالتالى الموديول بيتوقع لما يتم تمرير ID من النموذج انه هيكون رقم وليس حروف وارقام وبالتالى بيطلعلك الخطأ Type Mismatch ان الID متعرف كمتغير رقمى ولكن اللى بيطلع من النموذج متغير نصى . فهمت ؟ حل الموضوع كالتالى .. يتم تعديل الموديول ليقبل النص والرقم

Public Function WriteAudit(frm As Form, StrID As String) As Boolean
On Error GoTo err_WriteAudit

    Dim ctlC As Control
    Dim strSQL As String
    Dim bOK As Boolean
   
   
   
    bOK = False
    
   DoCmd.SetWarnings False
    
    ' For each control.
    For Each ctlC In frm.Controls
        If TypeOf ctlC Is TextBox Or TypeOf ctlC Is ComboBox Then
            If ctlC.Value <> ctlC.OldValue Or IsNull(ctlC.OldValue) Then
                If Not IsNull(ctlC.Value) Then
                    strSQL = "INSERT INTO tblAudit ( ID, FieldChanged, FieldChangedFrom, FieldChangedTo, User, DateofHit, FrmName , FrmRcrdSrc  ) " & _
                           " SELECT '" & StrID & "', " & _
                           "'" & ctlC.Name & "', " & _
                           "'" & ctlC.OldValue & "', " & _
                           "'" & ctlC.Value & "', " & _
                           "'" & GetUserName_TSB & "', " & _
                           "'" & Now & "' , " & _
                           "'" & M & "', " & _
                           "'" & r & "'"

                    'Debug.Print strSQL
                    DoCmd.RunSQL strSQL
                End If
            End If
        End If
    Next ctlC
    
    WriteAudit = bOK
    
exit_WriteAudit:
    DoCmd.SetWarnings True
    Exit Function
    
err_WriteAudit:
    MsgBox Err.Description
    Resume exit_WriteAudit
    
End Function

لاحظ هذا السطر

قديم
Public Function WriteAudit(frm As Form, lngID As Long) As Boolean

بعد التعديل
  
Public Function WriteAudit(frm As Form, StrID As String) As Boolean

جرب ووافنى بالنتيجة

@Eng.Qassim لاحظ سبب المشكلة .

 

Dynamic Audit Trail - Amr Ashraf v2.0.accdb 760 kB · 3 downloads

Expand  

اشتغلت ممتازة ولكن بقي مشكلة ان لو النموذج مصدره استعلام مدمج وليس اسم جدول بيحط الاستعلام كله في جدول التغيرات وليس اسم الشاشة

WhatsApp Image 2022-02-14 at 4.34.41 PM.jpeg

WhatsApp Image 2022-02-14 at 4.34.58 PM.jpeg

قام بنشر
  في 14‏/2‏/2022 at 13:35, moamen salem said:

اشتغلت ممتازة ولكن بقي مشكلة ان لو النموذج مصدره استعلام مدمج وليس اسم جدول بيحط الاستعلام كله في جدول التغيرات وليس اسم الشاشة

Expand  

عارف الموضوع ده بس مفيش ليه فكرة عندى لأنه بيجيب المصدر أياً كان هوا ايه جدول او استعلام عادى او جملة Sql , ممكن نفكر ليها فى طريقة اخرى بس حاليا معنديش

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

زائر
اضف رد علي هذا الموضوع....

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • تصفح هذا الموضوع مؤخراً   0 اعضاء متواجدين الان

    • لايوجد اعضاء مسجلون يتصفحون هذه الصفحه
×
×
  • اضف...

Important Information