اذهب الي المحتوي
أوفيسنا
بحث مخصص من جوجل فى أوفيسنا
Custom Search

سِحر جداول الاكسس في تسجيل الوقائع


jjafferr

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

السلام عليكم 🙂

 

وما في كائنات مخفية 🙂

AccessTableMagic.gif.87bab915394c5cc3799d39ddc2409a6c.gif

 

والنتيجة النهائية ، لاحظوا الحقل الاخير على اليمين Change_Delete_Insert ، فهو يخبرنا اذا قمنا بعملة تعديل او حذف او اضافة :

image.png.4a9a5c86b03a9e550d9f93860f463731.png

.

جعفر

Access Tables Magic.accdb.zip

  • Like 9
  • Thanks 2
  • Confused 1
رابط هذا التعليق
شارك

السلام عليكم

ما هذا ؟ فعلا سحر 

حاولت افهم على عجالة ولكني فشلت .. قلت يكفيني احظى بأول رد

ما علاقة الجدولين ببعضهما .. اين يتم الربط؟

لأني اضفت جدول جديد ولكن جدول تسجيل الحركات لم يسجل له :angry: 

 

  • Like 1
رابط هذا التعليق
شارك

1 ساعه مضت, jjafferr said:

وما في كائنات مخفية 🙂

السلام عليكم .. استاذنا ما هو الرابط بين الجدولين ؟ ولماذا اذا اضفت جدول جديد لا يتم تسجيل التعديلات عليه فى جدول الحركات ؟ :wallbash:

لا يوجد علاقات .. لا يوجد كائنات مخفية .. وسؤل آخر ما هذا الفلتر ؟

([tbl_x_AuditTrail].[Change_Delete_Insert]="Browse")

الحقل ده بيسجل فيه 3 قيم فقط Update,Delete,Insert لماذا معيار الفلتر على "Browse" ?

فى انتظار الشرح استاذنا الفاضل :wavetowel:

رابط هذا التعليق
شارك

أتوقع أن السر في الماكرو After Update و After Insert و After delet 

المصاحبة للجداول

 

والله أعلم 😅✋🏻

image.png.5fe0d148cece10955a8ec7a9da24a2da.png

image.png.d5500ab274e9b4fe0111b1f270784577.png

 

تم تعديل بواسطه Moosak
  • Like 2
رابط هذا التعليق
شارك

11 ساعات مضت, Moosak said:

أتوقع أن السر في الماكرو After Update و After Insert و After delet 

المصاحبة للجداول

نعم هذا هو 

والسؤال الآن هل ما سيتم اضافته من خلال دالة يستدعيها نموذج غير منضم يحمل حقول غير منضمة لهذا الجدول 

هل سيكون نفس التأثير؟!

رابط هذا التعليق
شارك

السلام عليكم 🙂

 

مايكروسوفت عملت اضافة لجداول الاكسس 2010 (وتم ابقاء هذه الميزة للنسخ التالية) ، عملت الاحداث التالية لكل حقل (حقول النص والتاريخ والرقم (ويشمل الرقم التلقائي و العملة) فقط) وهذه الاحداث (هناك تسمى Trigger) كانت ميزة في جداول SQL Server :

للسجلات حدث بعد ادخال السجل ، حدث بعد حذف السجل ، حدث قبل حذف السجل ،

للحقول : حدث بعد تحديث الحقل ، حدث قبل تحديث الحقل

ويمكن عمل هذه الاحداث والجدول في وضع التصميم: 

image.png.9058a4ee65c4910e9742009cd433b9f0.png

.

او الجدول في وضع

image.png.4c0715372afeb11333e982798d9f1361.png

.

لغة كتابة الاحداث ليست VBA وانما الماكرو المضمن ، والذي يمكنه ان ينادي دالة في وحدة نمطية هكذا (هنا ننادي الدالة fMsgbox) :

image.png.6252aa40b83b4a3e3edffa2c0bff2cff.png

.

 

هناك طريقتين لكتابة الماكرو المضمن ، ونتيجة الكتابة النهائية هي كما نراها في الصورة التالية  

- الطريقة اليدوية (وعيبها انها بطيئة ، وخصوصا اذا عندك حقول كثيرة في الجدول ، وعندك جداول كثيرة ، وعندك برامج كثيرة)

1. اذا لم يستطع الماكرو المضمن تنفيذ احد الاوامر ، فإنه يعمل جدول للاخطاء التي صادفها ، اسمه USysApplicationLog ، وتراه هنا:

image.png.6c28ecebc1067335ad519cf09f74eaf0.png

.

او

ولأنه جدول نظام ، فيكون مخفي ، الى ان تطلب من الاكسس ان يُظهر جميع جداول النظام ، فترى الجدول

image.png.8e3c9e2add346f2f6585144d4705f30a.png

.

لذا ومن واقع تجربة ، انصح بكتابة هذا السطر الاول (لتلافي اي اخطاء ، مما يؤدي لتوقف عمل الماكرو) ،

2. نكتب السطر كما هو ، بعد تغيير اسم الحقل الفريد/المميز في بياناته والمفرس بلا تكرار (انصح بأن يكون عندك حقل فريد ومميز في بياناته ، وانا دائما استعمل في برامجي حقل الترقيم التلقائي ، والذي نستفيد منه هنا استفادة قصوى ، فهو الدليل على محتويات السجل) ،

3. نظيف سجل جديد في الجدول الأخر ،

4. نبدأ بتعبئة الحقول بالامر SetField ، ثم اسم الحقل ، ثم قيمة الحقل ، ونستمر لعدد الحقول التي نريد اضافة بياناتها للجدول الآخر ،

image.png.c4069ffa0c7887fb4beef9b04277e9c6.png

.

- طريقة برمجية عن طريق عمل ملف XML نضع فيه الاوامر اعلاه ، ثم نستورده لقاعدة البيانات ،

والملف عبارة عن ملف نصي ولكن بصيغة XML ، يجمع فيه جميع الاحداث (مرفق نسخة من الملف لقاعدة البيانات التي تم ارفاقها في مشاركتي الاولى)

واليكم الجزء للحدث الذي في الصورة الاعلى

image.png.4a8294a27d9b693495ec9e8ca08ee9ac.png

.

وثم نستخدم الكود التالي لإستيراد هذا الملف:

من نفس برنامج الاكسس
application.LoadFromText acTableDataMacro, "Table_Name", "D:\xml_File.xml"
  
  
  
من برنامج اكسس خارجي
    'Insert/Load this DataMacro in the Table Events
    Dim accApp As Object
    
    Set accApp = CreateObject("Access.Application")
    accApp.OpenCurrentDatabase Me.str_DB_Name  'D:\temp\myDB.accdb
    
    accApp.LoadFromText acTableDataMacro, Me.lst_Tables, xml_File

    accApp.CloseCurrentDatabase
    accApp.Quit
    Set accApp = Nothing  

.

والطريقة التي عرفت بها الكود اعلاه ، هي:

اعمل كود في احد هذه الاحداث او في جميعها ، وليكن بضعة اسطر حتى لا نضيع في الاكواد ، واحفظ الجدول ، ثم استخدم هذا الكود لتصدير DataMacro الذي عملناه لهذا الجدول ، هكذا :

application.SaveAsText acTableDataMacro, "Table_Name", "D:\xml_File.xml"

.

 

 

 

نصائح:

  1. اختار الحقول المهمة ، ولا تستعمل جميع الحقول ،
  2. الجدول tbl_x_AuditTrail سيزداد حجمه بسرعة ، ولكن كثرة الجداول وكثرة عدد المستخدمين لا يُبطئ العمل ،
  3. في الجدول tbl_x_AuditTrail هناك حقل ChangeBy وهو اسم المستخدم عند دخوله الكمبيوتر ، وحقل ChangedOn وهو اسم الكمبيوتر الذي تم التعديل منه ، هاتان الدالتان تكونان في برنامج الواجهة ، طبعا يمكن استبدالها باسم المستخد حسب الصلاحيات ، وIP الكمبيوتر اذا كان لإسم الكمبيوتر اهمية ،
  4. الجدول tbl_x_AuditTrail لا تسمح لأحد ان يراه ، لأنه يمكن حذف وتغيير بياناه ، فيصبح عديم الفائدة ،
  5. وبما ان برنامجنا كان ذو بيانات حساسة ، فكنا نراقب من يتصفح البيانات كذلك ، بمناداة دالة عند حدث "الحالي" للنموذج ، ونستعمل "Browse" في حقل عن Change_Delete_Insert .

 

------------------------------------------

2024-10-30 قاعدة بيانات وبها نموذج لعمل الجميع اعلاه برمجيا

 

 

جعفر

tbl_info_DataMacro.xml.zip

  • Like 8
  • Thanks 1
رابط هذا التعليق
شارك

15 ساعات مضت, Moosak said:

أتوقع أن السر في الماكرو After Update و After Insert و After delet 

المصاحبة للجداول

 

يعني .. الاستاذ موسى جابها .. 

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

 

رابط هذا التعليق
شارك

السلام عليكم 🙂

 

هذه الطريقة من نوادر و درر الاكسس التي يعرفها القلة ، وخصوصا انها مخبأة في الجداول ، وحسب فهمنا القديم للجداول انها لا تُبرمج !!

في الواقع هناك الكثير من الاستعمالات التي ممكن ان نستفيدها من هذه البرمجة ، وخصوصا بإستخدامها لمناداة دوال ، والتي يمكنها بقية الاوامر دون التقيد بأوامر DataMacro القليلة 🙂

 

6 ساعات مضت, ابوخليل said:

يعني .. الاستاذ موسى جابها .. 

اخوي ابوخليل ، كان لازم تربط بين اسم الموضوع "سِحر ..." ، وبجنسية أخونا موسى العماني 😄

ولكن هذه النقطة ما فاتت اخوي ابوجودي:

12 ساعات مضت, ابو جودي said:

:biggrin::biggrin::biggrin: وبهذا يا اصدقائى نكون قد تأكدنا وتيقنا من البخور العمانى وعمايله

 

 

23 ساعات مضت, Amr Ashraf said:

الحقل ده بيسجل فيه 3 قيم فقط Update,Delete,Insert لماذا معيار الفلتر على "Browse" ?

10 ساعات مضت, أبو عبدالله الحلوانى said:

والسؤال الآن هل ما سيتم اضافته من خلال دالة يستدعيها نموذج غير منضم يحمل حقول غير منضمة لهذا الجدول 

هل سيكون نفس التأثير؟!

تم الاجابة على هذا السؤال في النقطة 5 من مشاركتي اعلاه ، وهذه طريقة عملهم (طبعا من برنامج الواجهة) :

 

Call FormAudit("Salaries", 0, 0, fOSUsername(), fOSMachineName(), "Browse", "", "")

---------------

وهذه الدالة اعلاه

Public Function FormAudit(FormName, PageName, RecordID, ChangeBy, ChangedOn, Change_Delete_Insert, Full_Name, Employee_ID)

'ChangeID    ChangeDate  TableName   Fieldname   RecordID    OldValue    NewValue    ChangeBy    ChangedOn   Change_Delete_Insert    Full_Name   Employee_ID

        Dim db As DAO.Database
        Dim mySQL As String
        Dim Path As String
        Call BE_or_FE
        
        Path = Replace(BE_Path, "Personnel_Images", "") & "ABC_BE.accdb"
        Set db = OpenDatabase(Path)
        
        mySQL = "INSERT INTO tbl_x_AuditTrail ( TableName, Fieldname, RecordID, ChangeBy, ChangedOn, Change_Delete_Insert, Full_Name, Employee_ID ) IN '" & Path & "'"
        mySQL = mySQL & " SELECT '" & FormName & "','" & PageName & "','" & RecordID & "','" & ChangeBy & "','" & ChangedOn & "','" & Change_Delete_Insert & "','" & Full_Name & "'," & Nz(Employee_ID, 0)
        
        'Debug.Print mySQL
        db.Execute mySQL ', dbFailOnError
        
        Set db = Nothing
        
End Function

---------------

وهاتان الدالتان لإسم المستخدم واسم الكمبيوتر الذي كان يستخدمه

Private Declare PtrSafe Function apiGetUserName Lib "advapi32.dll" Alias _
    "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long

Private Declare PtrSafe Function apiGetComputerName Lib "kernel32" Alias _
    "GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long

Function fOSUsername() As String
' Returns the network login name

    'if the user logged in with his FE password, use it
    If Len(user_n & "") <> 0 Then
        fOSUsername = user_n
        Exit Function
    End If
    
Dim lngLen As Long, lngX As Long
Dim strUserName As String
    strUserName = String$(254, 0)
    lngLen = 255
    lngX = apiGetUserName(strUserName, lngLen)
    If (lngX > 0) Then
        fOSUsername = Left$(strUserName, lngLen - 1)
    Else
        fOSUsername = vbNullString
    End If
End Function

' This code was originally written by Dev Ashish.
' It is not to be altered or distributed,
' except as part of an application.
' You are free to use it in any application,
' provided the copyright notice is left unchanged.
'
' Code Courtesy of Dev Ashish

Function fOSMachineName() As String

'Returns the computername
    Dim lngLen As Long, lngX As Long
    Dim strCompName As String
    lngLen = 16
    strCompName = String$(lngLen, 0)
    lngX = apiGetComputerName(strCompName, lngLen)
    If lngX <> 0 Then
        fOSMachineName = Left$(strCompName, lngLen)
    Else
        fOSMachineName = ""
    End If
End Function

 

جعفر

  • Like 2
رابط هذا التعليق
شارك

6 ساعات مضت, jjafferr said:

هذه الطريقة من نوادر و درر الاكسس التي يعرفها القلة ، وخصوصا انها مخبأة في الجداول ، وحسب فهمنا القديم للجداول انها لا تُبرمج !!

من الأشياء المتعلقة بهذا الموضوع (تتبع التغيرات)..

في الإصدار 2007 البيانات من نوع ( ملاحظات Memo) وما بعده من الإصدارات (النصوص الطويلة Long Text)

يوجد خاصية ضمن خواص هذا النوع من البيانات اسمها (Append Only)، عند ضبطها على (On) تقوم بتكديس البيانات السابقة للحقل في الخلفية بالتاريخ والوقت

AppendOnlyField.jpg.3edd363d063582154aeb703740a5b95c.jpg1233088389_Screenshot2022-01-30183555.png.d4ac3e63d1d4e2631e664896ddcf35d9.png

 

 

 

 

 

 

 

 

 

 

 

ولإعادة طلب البيانات نستخدم التابع Application.ColumnHistory، يأخذ هذا التابع ثلاثة عوامل: العامل الأول اسم الجدول، والثاني اسم الحقل، والثالث معيار التصفية

ويعيد هذا التابع التاريخ والوقت والبيانات المتغيرة للحقل

XHistory = Application.ColumnHistory("Products", "List Price", "id=1")
  
[Version:  30/01/2022 09:55:41 ] 20
[Version:  30/01/2022 10:07:44 ] 30

يمكن معالجة البيانات باستخدام الإجراء التالي للحصول على بيانات نظيفة

Sub XColHist()
   Dim RE As New RegExp
   Dim R, M As Match
   Dim XHistory As String, P As String
   
   '-- Refer to Microsoft Docum for more info
   XHistory = Application.ColumnHistory("Products", "List Price", "id=1")
   
   '-- Data History before processing
   Debug.Print XHistory
   Debug.Print
   
   '-- Data History after processed by RegExp
   P = P & "(\d{1,2}/\d{1,2}/\d{2,4})\s"        ' date of change
   P = P & "(\d{1,2}:\d{1,2}:\d{1,2})\s\]\s"    ' time of change
   P = P & "([A-Z0-9]+)"                        ' value of change
   
   '--Refer to regexp docum for more info
   RE.Pattern = P
   RE.IgnoreCase = True
   RE.Global = True
   '--
   For Each M In RE.Execute(XHistory)
      For Each R In M.SubMatches
         Debug.Print R; Tab;
      Next
      Debug.Print
   Next
End Sub
        
Data History before processing
[Version:  30/01/2022 09:55:41 ] 20
[Version:  30/01/2022 10:07:44 ] 30

Data History after processed by RegExp
30/01/2022    09:55:41      20            
30/01/2022    10:07:44      30            

لمزيد من المعلومات أرجو زيارة الرابط التالي Docs.Microsoft.ColumnHistory

AppendOnly.accdb

  • Like 2
رابط هذا التعليق
شارك

51 دقائق مضت, أبو إبراهيم الغامدي said:

في الإصدار 2007 البيانات من نوع ( ملاحظات Memo) وما بعده من الإصدارات (النصوص الطويلة Long Text)

يوجد خاصية ضمن خواص هذا النوع من البيانات اسمها (Append Only)،

جميل ، شكرا اخوي ابوابراهيم ، لم اكن اعرف هذه الخاصية🙂

والكود الذي ارفقته ، لم تظهر نتائج RegExp !!

 

جعفر

رابط هذا التعليق
شارك

15 دقائق مضت, jjafferr said:

والكود الذي ارفقته ، لم تظهر نتائج RegExp !!

أهلا أستاذ جعفر..

المثال مطبق على قاعدة البيانات المرفقة..

أرجو منك تكرماً تعديل بيانات الحقل List Price لسجل معين أكثر من مرة ثم إعادة تجربة الشفرة.. لا تنس تحديد قيمة لمعامل معيار التصفية

رابط هذا التعليق
شارك

لم اغير في الشفرة ، بل اضفت طريقتي للحصول على بيانات نظيفة كما في المربع الاحمر (ونتائجه) ، وتأكدت ان المكتبات كلها موجودة ،

وعملت 3 تعديلات على الحقل ، 

الكود كان يقف على السطر الذي عليه السهم ، ثم الى سطر End Function دون الدخول في حلقة For الاولى 

 

image.png.09c67a9817ae214b523898b26bbcb614.png

.

طبعا كلامنا ليس على الموضوع الذي تفضلت به ، ولكن كلامنا عن نتائج RegExp .

 

جعفر

رابط هذا التعليق
شارك

12 ساعات مضت, jjafferr said:

لم اغير في الشفرة ، بل اضفت طريقتي للحصول على بيانات نظيفة كما في المربع الاحمر (ونتائجه) ، وتأكدت ان المكتبات كلها موجودة ،

طلبي كان إعادة تجربة الشفرة بعد إدخال البيانات فقط

نعم هناك طرق كثيرة لمعالجة البيانات وأبسط بكثير من RegExp  

إذا كانت البيانات في المقطع الأخير نصية وبها فراغات فإن استخدام Split في الدورة الثانية سوف يحدث خللا في البيانات

وبما أن السجل التاريخي ذو بيانات ثابتة إلى المقطع الأخير فيمكن استخدام الطريقة التالية

Sub SplitHistory()
   Dim XHistory
   Dim L, D, T, V
   XHistory = Split(Application.ColumnHistory("Products", "List Price", "id=1"), vbCrLf)
   For Each L In XHistory
      Debug.Print L
      D = Mid(L, 12, 10)   ' Date
      T = Mid(L, 23, 8)    ' Time
      V = Mid(L, 34)       ' Value
      Debug.Print D, T, V
      Debug.Print
   Next
End Sub

 

  • Like 1
رابط هذا التعليق
شارك

طريقة ColumnHistory فعالة وجديرة بالاهتمام لإختزالها الكثير من الخطوات (وحتى مافي داعي نراقب هذا الحقل من جدول آخر 🙂 ) ،

اخي الاستاذ ابو إبراهيم ، شكرا على الشرح والتوضيح ، فإمكانياتك على الشرح بأمثلة جدا مميزة 🙂

 

جعفر

  • Thanks 1
رابط هذا التعليق
شارك

  • 2 years later...

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



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

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

Important Information