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

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

قام بنشر

السلام عليكم ورحمة الله وبركاته

خلال تجوالي في المنتدى وجدت الكثير من الاسئلة التي تتعلق بالجداول المرتبطة ، عن ربطها والغاء ربطها و اعادة ربطها

وفي محاولة مني بالاحاطة بالامر ساقوم بإذن الله في هذا الموضوع الاجابة عن هذه التساؤلات وما يلحقها

والحديث هنا سيكون عبر الكودات والوظائف وبشكل عام ، بعيدا عن التخصيص او التطبيق لحالة بعينها مع امكان التطبيق المخصص لبعض الحالات

 

بغض النظر عن أي مشاركات سابقة ، والتي قد نشير لها ونعزز الامر بروابطها منعاً للتكرار في المنتدى ، سواء أكانت للعبد الفقير الى الله أو لأحد الاخوة الفضلاء

 

والله المستعان

 

ونوجه النية لوجهه تعالى وهو من وراء القصد وهو حسبي ، علّ الله يغفر لي بعض ذنبي ، والدعاء بخير بظهر الغيب منكم ... غاية مأمولة

 

........

  • Like 4
  • الردود 65
  • Created
  • اخر رد

Top Posters In This Topic

قام بنشر

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

أي أن قاعدة البيانات تكون مكونة من جزئين ، الجزء الأول يحوى الجداول ويرمز له BE ، والجزء الثاني يحول النماذج و الاستعلامات و التقارير وبقية الكائنات اللازمة للقاعدة ويرمز له FE.

ويكون ذلك إحسانا في تحليل القاعدة و حماية لها وسهولة للتعامل معها و مع تطورها وتعديلها ، ويكون ايضا لتمكين تعدد المستخدمين .

وتكون اجزاء القاعدة في مجلد واحد على نفس الجهاز ، أو تكون في مجلدات مختلفة على نفس الجهاز ، أو تكون بمجلدات مختلفة على أجهزة متعددة ، وغالبا يكون جزء BE على الخادم / السيرفر ، وجزء FE على جهاز المستخدم ، مهما تعدد هؤلاء المستخدمون .

............

قام بنشر

من المهم هنا الاشارة الى أن التحليل و التطبيق يكون للتصورات الرئيسية وليس التطبيقية التابعة لتحليل معين بذاته ، بمعنى اننا نفترض تطبيقا عاماً توضيحياً لغايات التعلّم ، فليس هذا هو الوحيد مطلقاً ، فالتطبيق الفعلي ، يخضع للتحليل الحصري للقاعدة التي سيستخدم بها الأمر.

وتوضيحاً نقول : قد أطلب انشاء زر أمر ليحمل خلفهً كوداً معيناً لاستدعاء وحدة نمطية ، بينما يمكن ان تستدعى ايضاً عن طريق ماكرو ، او في حدث عند التحميل لنموذج وغيره.

فيقتضي التنويه بان المطروق هنا للتوضيح والتعلّم وليست أدوات وطرقاً حصرية ، حتى لا يؤخذ علينا الامر بضيق الأفق او التصور، وفوق كل ذي علم عليم .

قام بنشر

ونبحث الآن في ما يلزم لربط جزء قاعدة البيانات FE مع جزء BE ، بحيث يتم ربط جزء الجداول مع جزء النماذج وبقية الكائنات .

وهنا نطبق مسألة ربط كافة الجداول مرة واحدة ، وهذا يلزم ببداية التنفيذ ، وقد يلزم عند تعديل بنية جدول معين  أو عدة جداول ، أو عند إضافة جداول جديدة ، أو عند أي حال يستلزم ربط جميع الجداول .

يلزم أولاً إنشاء وحدة نمطية جديدة ضمن FE وينسخ اليها الكود التالي :

Public Function CreateLinks(strBEPath) As Boolean

On Error GoTo Err_Handler

Dim dbsFE As DAO.Database
Dim dbsBE As DAO.Database
Dim wksJET As DAO.Workspace
Dim strTableName As String
Dim strConnect As String
Dim tdfBE As DAO.TableDef
Dim tdfFE As DAO.TableDef

Set wksJET = DBEngine.Workspaces(0)

Set dbsBE = wksJET.OpenDatabase(strBEPath)

Set dbsFE = CurrentDb

For Each tdfBE In dbsBE.TableDefs

If Left$(tdfBE.Name, 4) <> "MSys" And _
Len(tdfBE.Connect) = 0 Then

strTableName = tdfBE.Name
strConnect = ";DATABASE=" & strBEPath
Set tdfFE = dbsFE.CreateTableDef(strTableName)
tdfFE.Connect = strConnect
tdfFE.SourceTableName = strTableName
dbsFE.TableDefs.Append tdfFE
Set tdfFE = Nothing

End If

Next tdfBE

CreateLinks = True

Exit_Handler:
On Error Resume Next
Set tdfFE = Nothing
Set tdfBE = Nothing
Set dbsFE = Nothing
dbsBE.Close
Set dbsBE = Nothing
Set wksJET = Nothing
Exit Function

Err_Handler:
MsgBox Err.Description, vbExclamation, "Error No: " & Err.Number
Resume Exit_Handler

End Function


ونقوم بحفظها بإسم ModLinkAll

حيث يقوم الكود بالتوجه لجزء القاعدة BE و يقوم بفحص الكائنات من نوع الجدول ويستثني منها جداول النظام MSys ثم يقوم بربط كل الجداول واحداً تلو الآخر بجزء FE ، كإرتباط وليس كجدول فعلي مستورد ، وبنفس الإسم.

 

ولتنفيذ هذا الربط يمكننا نثلاً أن نقوم بإنشاء نموذج جديد وننشيئ به زر أمر بإسم  cmdLinkAll  وعنوانه  Link  وخلف هذا الزر نضع الكود التالي :

Private Sub cmdLinkAll_Click()
Call CreateLinks("C:\Users\user\Desktop\My Library\LinkedTableDemo\Officena Link Project\be.accdb")
End Sub

هذا الكود يستدعي الوحدة النمطية لتعمل على إجراء الربط بين جداول جزء القاعدة BE المحدد مسارها ضمن الكود ، وبين جزء القاعدة FE التي تحوي النموذج و الوحدة النمطية.

 

وبهذا تكون جميع الجداول جاهزة لاستخدامها و التعامل معها من قبل المستخدم أو مجموعة المستخدمين في آن واحد .

 

وللحديث بقية ...

  • Like 1
قام بنشر

فاتني هنا ان أنوه بان استدعاء هذه الوظيفة يحقق الغاية سواء كان جزء القاعدة BE  في نفس المجلد و على نفس الجهاز ، أو كان بمجلد مستقل أوعلى جهاز آخر أو على الخادم ، المهم أن يتم تزويد كود استدعاء الوحدة النمطية بالمسار الكامل للملف

قام بنشر

ويلزمنا وفق روتينات العمل و تصورنا لبعض الحالات ان نقوم بإلغاء الربط للجداول ، ولتحقيق ذلك ، نستخدم الوحدة النمطية ModDeleteLinks  التالية :

Public Function DeleteLinks() As Boolean

On Error GoTo Err_Handler

Dim dbs As DAO.Database
Dim lng As Long

Set dbs = CurrentDb

With dbs.TableDefs
For lng = .Count - 1 To 0 Step -1
If (.Item(lng).Attributes And dbAttachedTable) <> 0 Then
.Delete .Item(lng).Name
End If
Next lng
End With

DeleteLinks = True

Exit_Handler:
On Error Resume Next
Set dbs = Nothing
Exit Function

Err_Handler:
MsgBox Err.Description, vbExclamation, "Error No: " & Err.Number
Resume Exit_Handler

End Function

حيث يقوم بتفقد الجداول وتحديد الجداول المرتبطة ويلغيها تاركاً الجداول المحلية

ويمكننا طبعاً إستدعاؤها بالتوقيت و الحدث او الروتين الذي نراه مناسباً ، ونقترح زر الأمربإسم cmdDeleteLink وعنوانه Delet Link ، وخلفه الكود التالي :

Private Sub cmdDeleteLink_Click()
Call DeleteLinks
End Sub

وننوه هنا لوجود نص وحدة نمطية أخرى تفي بالغرض في كشكول VBA وعلى الرابط .....

http://www.officena.net/ib/index.php?showtopic=38385&p=233619

 

وهنا نصل لنتيجة جيدة ، فيمكننا ومن خلال استدعاء هاتين الوحدتين إجراء الربط و إنهاؤه متى نشاء ، وللجميع أن يتخيل و يطبق وفق ما لديه ، من تحليل وتطبيق.

 

وللحديث بقية ....

قام بنشر

وللتصور و التطبيق نقول : يمكننا أن نقوم بربط جزء FE    بأكثر من جزء BE  ، حيث نقوم باستدعاء الوحدة النمطية ModLinkAll   كما نشاء و لاكثر من BE

Call CreateLinks("C:\Users\user\Desktop\My Library\LinkedTableDemo\Officena Link Project\be.accdb")
Call CreateLinks("H:\Manager\Operations09\Data09.mdb")

وبالتالي يصبح لديك جداول مرتبطة من أكثر من Backend Table ، أي أكثر من جزء.

 

واذا كنت مستخدما للاصدار 2007 مثلاً يمكنك الربط مع جداولك ضمن ملفات accdb الخاصة به ، و ملفات mdb الخاصة بالاصدار 2003  ، والعكس طبعاً غير متاح فالاصدار الجديد يستوعب و يتعامل مع ملفات الاصدار السابق ، أما لاصدار السابق فلا يتعرف طبعاً على ملفات الاصدار اللاحق.

 

وللحديث بقية .....

 

 

قام بنشر

وقبل أن نزيد من تعقيد الأمور و التصورات و التطبيقات نود أن نطرح بعض الامور التي قد تلزمنا ضمن محاور سابقة من التحليل ، ومنها مثلاً ، ما قد يقال : أريد أن أجري إرتباطاً مع جدول معين أو جدولين من BE  محدد ، وليس لجميع الجداول ؟

وهذا متصور وله أحوله ، وله ما يلزم وهو متصور ، فدعونا نعود اليه ....

 

وللحديث بقية ....

 

......

قام بنشر

حياكم الله

أخي محمد ايمن و أخي راعي الغنم

 

شرفتمونا بمروركم الطيب ، ومتابعتكم لجهدنا المتواضع

 

.......

  • Like 1
قام بنشر

أتمنى على الإخوة الفضلاء التطبيق وموافاتي بأي إشكالات تعترضكم

ورحم الله من أهدي الي عيوبي ....

 

..........

قام بنشر

ربط   FE مع جدول أو جداول مختارة مسألة أتصورها في بعض الأحيان ، ولحاجات محددة ، فإفترضت تصوراً معيناً بأنني بحاجة لإجراء ارتباط مع BE بجدول محدد ، لاجراء تعديل أو تنفيذ استعلام أو تقرير ما ، فقمت بتحليل الامر وتثبيت المتغيرات وخرجت بوحدة نمطية دعونا نسميها ModTableLink ، نقوم من خلالها باجراء عملية ربط مع BE معينة و مع جدول معين محدد  Co ، كما احتسبت بالبال مسألة كلمة السر للجدول ، و حاجتي لتغيير اسم الجدول لأنني أتعامل مع وضع استثنائي افترض به انني أنبه نفسي و أذكرها بانني أتعامل مع جدول مرتبط فاضفت لاسم الجدول المرتبط في FE عبارة link_to .

وللتنفيذ ننشيئ الوحدة النمطية الجديدة ونسخ البها :

Public Function CreateTableLink(strBEPath, strSourceTableName, strPassword) As Boolean

Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim strConnect As String
Dim strLinkName As String

strLinkName = "link_to_" & strSourceTableName

strConnect = "MS Access;PWD=" & strPassword & _
    ";DATABASE=" & strBEPath
Debug.Print strConnect
Set db = CurrentDb
Set tdf = db.CreateTableDef
tdf.Connect = strConnect
tdf.SourceTableName = strSourceTableName
tdf.Name = strLinkName
db.TableDefs.Append tdf
Set tdf = Nothing
Set db = Nothing

End Function

حيث نتعامل عند الاستدعاء مع المتغيرات الثلاثة الرئيسية : مسار القاعدة كاملاً ، واسم الجدول ، وكلمة السر حال وجودها ، واذا لم تكن موجودة نترك فراغاً بين حاصرتين "" .

ونتعرف على الجزء BE واسم الجدول وكلمة السر ونقوم بإجراء الربط .

 

أما الاستدعاء فيتم كمقترح ، خلف زر أمر إسمه cmdTableLink ، وبعنوان Table Link

ونضع خلفه الكود التالي :

Call CreateTableLink("H:\Manager\Operations09\Data09.mdb", "co", "")

حيث يتم التعامل مع مسار قاعدة البيانات Data09 ثم الجدول Co وبدون كلمة سر ، ويتم الربط حسب هذه الضوابط و المتغيرات .

 

وللحديث بقية .....

  • Like 1
قام بنشر

وكما يمكننا التعامل مع الوحدة النمطية  ModTableLink  باستدعائها كما نشاء لربط وجلب أي جدول من أي  BE نشاء ، ولطرح المثال و التوضيح ، يمكننا :

Call CreateTableLink("H:\Manager\Operations09\Data09.mdb", "co", "")
Call CreateTableLink("H:\Manager\Operations09\Data09.mdb", "Emp", "1256")
Call CreateTableLink("\\Server\Manager\Operations2014\Data14.accdb ", " tblSeaLine ", "")

من أي مسار و أي إمتداد ، ووفق المتغيرات المحددة ، فكل ما ضمن العلم متاح ...

 

وللحديث بقية ...

  • Like 1
قام بنشر

و نعود قليلاً لربط كافة الجداول في BE مرة واحدة ، ونطرح أمامكم وحدة نمطية أخرى بمنهج مختلف تؤدي نفس الغرض ، ونسميها ModLinkAll_1

Function LinkTables(DbPath As String) As Boolean

Dim rs As Recordset

    On Error Resume Next

'get tables in back end database
    Set rs = CurrentDb.OpenRecordset("SELECT Name " & _
                                    "FROM MSysObjects IN '" & DbPath & "' " & _
                                    "WHERE Type=1 AND Flags=0")
    If Err <> 0 Then Exit Function

'link the tables
    While Not rs.EOF
        If DbPath <> Nz(DLookup("Database", "MSysObjects", "Name='" & rs!Name & "' And Type=6")) Then
            'delete old link, assuming front and back end table have the same name
            DoCmd.DeleteObject acTable, rs!Name
            'make new link
            DoCmd.TransferDatabase acLink, "Microsoft Access", DbPath, acTable, rs!Name, rs!Name
        End If
        rs.MoveNext
    Wend
    rs.Close

    LinkTables = True
End Function

ونستدعيها بنفس المنهج خلف زر أمر

Private Sub cmdLink1_Click()
Call LinkTables("H:\Manager\Operations09\Data09.mdb")
End Sub

ولكم حرية الخيار في التطبيق ....

 

وللحديث بقية .....

قام بنشر

جزاك الله كل خير استاذي و اخي أبو آدم و اسمح لي بإضافة بسيطة

وحدة نمطية لأخينا BlueMind لتسريع الاتصال بقاعدة البيانات سواء كانت على الشبكة او على الجهاز المحلي

Public Sub OpenAllDatabases(pfInit As Boolean)
  ' Open a handle to all databases and keep it open during the entire time the application runs.
  ' Params  : pfInit   TRUE to initialize (call when application starts)
  '                                     FALSE to close (call when application ends)
  ' Source  : Total Visual SourceBook
  Dim x As Integer
  Dim strName As String
  Dim strMsg As String

  ' Maximum number of back end databases to link
  Const cintMaxDatabases As Integer = 2
  ' List of databases kept in a static array so we can close them later
  Static dbsOpen() As DAO.Database

  If pfInit Then
        ReDim dbsOpen(1 To cintMaxDatabases)
        For x = 1 To cintMaxDatabases
          ' Specify your back end databases
          Select Case x
                Case 1:
                  strName = Path1 'CurrentProject.Path & "\data.mdb"
          End Select
          strMsg = ""
          On Error Resume Next
          Set dbsOpen(x) = OpenDatabase(strName)
          If Err.Number > 0 Then
                strMsg = "Trouble opening database: " & strName & vbCrLf & _
                                 "Make sure the drive is available." & vbCrLf & _
                                 "Error: " & Err.Description & " (" & Err.Number & ")"
          End If
          On Error GoTo 0
          If strMsg <> "" Then
                MsgBox strMsg
                Exit For
          End If
        Next x
  Else
        On Error Resume Next
        For x = 1 To cintMaxDatabases
          dbsOpen(x).Close
        Next x
  End If
End Sub

يمثل path1 مسار قاعدة البيانات BE  ( التي تحتوي على الجداول الأساسية )

 

يتم الاستدعاء بهذا الشكل

طبعا يجب ان يكون الاستدعاء في اول نموذج يتم تشغيله في قاعدة البيانات FE ( التي تحتوي على النماذج و التقارير و الاستعلامات ..... )

OpenAllDatabases True

وقبل انهاء التطبيق

OpenAllDatabases False

قام بنشر

شاكرين ومقدرين مشاركة الأخ محمد ايمن لنا بوحدة نمطية لأخينا BlueMind لتسريع الاتصال بقاعدة البيانات ، نتابع  تقدمنا بدراسة تصورات الحاجات التي تتصل بموضوعنا ، وقد نعود لأي نقطة نحتاج للعودة اليها، وأنتقل لتفعيل تصور تغيير مسار جزء BE ، حيث ينقطع الاتصال بين الجزئين FE  و BE .

وبذلك تنعدم الفائدة والفاعلية لقاعدة البيانات بجزئيها ، ونبدأ توضيح التصورات وبناء سيناريوهاتها والحلول المقترحة .

 

و للحديث بقية ....

 

.............

قام بنشر

السلام عليكم

حياكم الله اخونا ابو ادم على هذا المجهود الاكثر من رائع

ولدينا سؤال اذا امكن

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

وتعمل بصوره صحيحه

بالتوفيق

قام بنشر

أخي محمد ايمن

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

سيأتى معنا لاحقا - قيد العمل - كيفية التأكد من الربط

وسأجيبك عنه في حينه

واعذرني لان جهازي هذا هو جهازي العزيز 2003 ويحمل معظم اعمالي القديمة ولا يحمل 2007

ساطلع على مرفقكم غدا صباحا بإذن الله

 

.........

قام بنشر

أخي SSM

سجلنا هنا ملاحظة بتفصيل مسألة

النسخ الاحتياطي للجداول المحلية و المرتبطة

اختيار النسخة التي يود العمل عليها من النسخ الاحتياطية

 

أرجو تذكيري حين نصل لمسألة النسخ الاحتياطي

 

وشكرا لتواصلك الطيب آملا منك التفضل علينا وتعديل اسم الظهور باسمكم الطيب حتى نحسن ندائنا لكم باحب الاسماء اليكم

 

 

....

قام بنشر

بالتصور و التطبيق برزت لنا حاجة بضرورة وجود وحدة نمطية لفحص الجداول المرتبطة ومعرفة عددها

فكان لنا حاجة بهذه الوحدة الجديدة صممتها وسميتها ModCountLinks وخلفها نكتب :

'By Nart Lebzo for Officena.net

Public Function CountLinks()

Dim TblCount As Integer
TblCount = 0
    For Each tdf In CurrentDb.TableDefs
     ' If the table has a connect string, it's a linked table.
        If Len(tdf.Connect) > 0 Then
            TblCount = TblCount + 1
        End If
    Next tdf
CountLinks = TblCount
'MsgBox " عدد الجداول المرتبطة بقاعدة البيانات " & vbCrLf & CountLinks, vbExclamation, "Linked with Back End"
End Function

وهذه تقوم بالتعرف على الجداول المرتبطة و تمر عليها وتعدها كي نتمكن من التعرف على العدد و استخدامه لاحقاً

وطبعاً يظهر لكم أنني عطلت ظهور الرسالة لبيان الخيار فقد تحتاج ظهور رسالة و قد لاتحتاجه ضمن الوحدة ، وقد تضمنه لأي كود ضمن النموذج مثلاً.

 

و للحديث بقية ......

 

.............

  • Like 1
قام بنشر (معدل)

شكر الله سعيك يابوادم

لكن وبعد متابعتي للاكواد اولا باول فان الارتباط لحد الان بقاعدة بيانات وحيدة فقط

لكن كيف في حالة تعدد قواعد البيانات لأكثر من قاعدة بيانات

لا اريد ان اسبق الاحداث لكن اخشى ان تنسى هذه النقطة وجل من لا يسهو او ينسى سبحانه...

تم تعديل بواسطه راعي الغنم

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