الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

ربط النماذج الفرعيه

بدأه كوماندير في 24 يونيو 2014 · 32 رد · 2,162 مشاهدة · في قواعد بيانات Microsoft Access
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

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

 

 

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

 

المشكله بالنموذج الفرعي الثاني (OrdDetSubFrm) فقد قمت بربطه بالنموذج الاساسي عن طريق العنصر الغير منظم OrderIDDS والحمد لله تم الربط والامور ماشيه تمام التمام

 

 

لكن لدي عدد كبير من السجلات بالجدول الاساسي مصدر بيانات النموذج الاساسي وبالتالي تحتوي الجداول على عدد كبير من السجلات يتجاوز 45000 الف سجل بالجدول الاساسي والمشكله هي ثقل في النموذج الاساسي عند الفتح وعند التنقل بين السجلات .

 

 

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

 

وهذا المرفق:

 

LaboratoryDB.rar

#2

????

 

اخواني الكرام عباقرة الاكسس

اعينوني على طريقة لربط النموذج الفرعي OrdDetSubFrm  بالنموذج الفرعي SubOrderFrm غير الطريقة الموجودة والتي ربطت النموذج الفرعي OrdDetSubFrm بالنموذج الاساسي مباشرة عن طريق مربع النص OrdersIDDS الغير منظم والذي مصدر عنصر تحكمه هو =[OrdersSubf].[Form]![PLabRefID]  اي رقم الطلب بالنموذج الفرعي SubOrderFrm .

 

للأهمية

 

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

 

ارجو ان يكون طلبي واضحا

#3

وعليكم السلام :)

 

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

لذا ، اقترح ان :

1. تعمل نموذج جديد وفيه بيانات النموذج الرئيسي ، وبه تستطيع عمل البحث او التصفية او اي شئ تحتاج اليه ، ويكون فيه زر يوصلك الي PatID النموذج الحالي ،

2. في النموذج الحالي ، لا تسمح بالبحث فيه او التنقل من سجل الى آخر ،

3. الذي نصل اليه من اعلاه هو ، اننا يكون لدينا نموذج بمصدر جدول واحد فقط ، بينما في النموذج القديم فنحن نتعامل مع 3 جداول في كل عملية نقوم بها ،

4. الشئ الاخير اللي ممكن تعمله ويزيد لك سرعة البرنامج ، انك تعمل index في الجدول للحقل/حقول اللي دائما تبحث فيه.

 

جعفر

1
#4

اخي جعفر لو تكرمت ماهي الحقول التي يجب عمل فهرس لها ؟

#5
كوماندير كتب:

اخي جعفر لو تكرمت ماهي الحقول التي يجب عمل فهرس لها ؟

 

انا لا اعرفها ، ولكنك تستطيع ان تعرفها كما قلت لك: انك تعمل index في الجدول للحقل/حقول اللي دائما تبحث فيه/فيها.

 

وللعلم:

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

مثال من برنامجك:

الجدول PatientData يحتوي على الحقل PatID والذي به فهرسة ،

وانت عملت علاقة بين هذا الجدول والجدول Orders والذي كذلك به الحقل PatID ، وربطت الجدولين بالحقل PatID من كل جدول ،

لذا ، حقل PatID الذي في الجدول Orders لا يجب ان تعمل له فهرسة في الجدول ، لأنه قد تم فهرسته من العلاقة التي بينه وبين PatID من جدول PatientData .

 

طبعا السؤال الذي يُسؤل دائما هو:

اذا كانت فهرسة الحقول مهمة ، فلماذا لا نفهرس جميع الحقول (ونفك عمرنا من دوخة الرأس :) ) ،

والجواب ، ان الفهرسة تجعل البرنامج يحتفظ في هذه المعلومات في ذاكرته ، مما يضخم حجم البرنامج ، ولما تزيد حقول الفهرسة وتزيد البيانات ، يصبح حجم البرنامج غير متكافئ/مقبول!!

 

 

جعفر

تم تعديل هذه المشاركة بواسطة jjafferr في 13 يوليو 2014 في 00:41

#6

اخي جعفر هذا المرفق به ما اريد

 

فهلا تكرمت ونظرت له ؟

 

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

 

NewMedLabDb.rar

تم تعديل هذه المشاركة بواسطة كوماندير في 13 يوليو 2014 في 02:39

#7

السلام عليكم اخي :)

 

نعم ، المشكلة في الفهرسة كما كنت اعتقد :)

 

المشكلة في الجدول OrderDetails:

post-273849-0-36871500-1405276436_thumb.

 

 

والحل:

1. ازل Primary Key من الحقلين OrderNo و  TID ، وطبعا اترك الفهرسة مثل ماهي للحقلين ( Yes (Duplicate OK) ) ،

2. اعمل حقل جديد للترقيم التلقائي (هذا ليس لك ، وانما للبرنامج ، ومع انك لست محتاج اليه الآن ، ولكن نصيحة ان تعمله) ، واجعله Primary Key ،

3. Compact and Repair

 

وصلى الله وبارك :)

والسحور الليلة مندي على حسابك ، لي ولكل شباب/شابات المنتدى :)

 

 

جعفر

1
#8

الف الف الف شكر اخي جعفر

 

بكل صراح تستاهل شهادة خبير اكسس

 

 

ارجو ان تقبلني صديقا جديدا

 

 

حلت المشكلة .

#9

والسحور :)

#10

حياك الله أخي :)

 

جعفر

1
#11
jjafferr كتب:

حياك الله أخي :)

 

جعفر

 

 

ابشر اخي جعفر

 

اهلا وسهلا بك وبكل اعضاء المنتدى على مائدتي لتناول وجبة السحور ليوم غد

 

post-219801-0-57296900-1405452312.jpg

#12

الله يسلمك ويعافيك ، ويبارك لك فيما اعطاك ان شاء الله ، وبالصحة والهناء :)

#13

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

 

مساء الخيرات

 

خواتيم مباركه اخواني اعضاء المنتدى جميعا

 

 

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

 

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

يعني صار بامكاني ان اختار اكثر من صنف ( فحص ) للطلب الواحد وهذا خطاء ولا اريده ؟

 

فهل من طريقة لمنع التكرار غير وضع مفتاح اساسي لحقل اختيار الفحص وعمل التكرار ممكن في الفهرس ؟؟

#14

وعليكم السلام :)

 

آسف ما فهمت :(

 

لوسمحت تشرح لي بمثال ، ويفضل بصورة كذلك ، فانا فهمي بطيئ :)

 

جعفر

#15

اعتقد اني فهمت قصدك :)

 

هناك طريقتين في بالي ، فاختر ايهما تفضل :) :

الاولى والاصعب ، ولكني افضلها:

بأن نعمل فلتر لـ Row Source الحقل TID ، بحث عندما يضغط المستخدم على حقل TID ، فلن يرى الـ TID المستخدم سابقا لهذا OrderID :)

وهذا هو الكود (لسبب ما ، تختفي الـ TID المستخدمة في السجل! ، ولكن الـ Combobox يعطي نتائج صحيحة):

Private Sub Form_Current()
On Error GoTo err_Form_Current

    If Len(Me.TID & "") <> 0 Then
        
        'Get the used TID for this OrderID
        Set rst = Me.RecordsetClone
        rst.MoveLast: rst.MoveFirst
        
        iWhere = ""
        For i = 1 To rst.RecordCount
            iWhere = iWhere & " And TestID <>" & rst!TID
            rst.MoveNext
        Next i
        
        iWhere = Mid(iWhere, 5)
        'Debug.Print iWhere
    End If
    
    If Len(Me.TID & "") = 0 Then
        mySQL = "SELECT TestID, TestName, AllNv, TPrice"
        mySQL = mySQL & " FROM Q2"

        If Len(iWhere) <> 0 Then
            mySQL = mySQL & " WHERE" & iWhere
        End If

        'Debug.Print mySQL
        Me.TID.RowSource = mySQL
    End If

Exit Sub
err_Form_Current:

    If Err.Number = 3021 Then
        'igonr
        Resume Next
    Else
        MsgBox Err.Number & vbCrLf & Err.Description
    End If
    
End Sub

والطريقة الثانية ، والتي تعمل كما كان يعمل برنامجك سابقا ، بأن يعطي تحذير عند استخدان TID تم استخدامه سابقا (والطريقة تعمل بشكل جيد):

Private Sub TID_BeforeUpdate(Cancel As Integer)

    
    d = DCount("*", "OrderDetails", "[OrderNo]=" & Me.Parent.OrderIDSS & " And [TID]=" & Me.TID)
    
    If d > 0 Then
        MsgBox "This item is already used, you cannot use it again!"
        Me.Undo
        Cancel = True
    End If
    
End Sub

جعفر

تم تعديل هذه المشاركة بواسطة jjafferr في 19 يوليو 2014 في 17:37

#16

وطريقة ثالثة:

موازية للطريقة الثانية اعلاه ، ولكن الطريقة الثانية اعلاه تعمل استعلام للجدول وتأخذ المعلومة منه للمقارنة ،

بينما تأخذ الطريقة التالية المعلومات من النموذج مباشرة ، وهي اخف على البرنامج (حيث يكون النموذج الرئيسي استعلم بياناته من الجدول ، ثم النموذج الفرعي A ، ثم النموذج الفرعي B) :

Public iWhere As String

Private Sub Form_Current()
On Error GoTo err_Form_Current

GoTo Option3:

    If Len(Me.TID & "") <> 0 Then
        
        'Get the used TID for this OrderID
        Set rst = Me.RecordsetClone
        rst.MoveLast: rst.MoveFirst
        
        iWhere = ""
        For i = 1 To rst.RecordCount
            iWhere = iWhere & " And TestID <>" & rst!TID
            rst.MoveNext
        Next i
        
        iWhere = Mid(iWhere, 5)
        'Debug.Print iWhere
    End If
    
    If Len(Me.TID & "") = 0 Then
        mySQL = "SELECT TestID, TestName, AllNv, TPrice"
        mySQL = mySQL & " FROM Q2"

        If Len(iWhere) <> 0 Then
            mySQL = mySQL & " WHERE" & iWhere
        End If

        'Debug.Print mySQL
        Me.TID.RowSource = mySQL
    End If

'
Option3:

    If Len(Me.TID & "") <> 0 Then
        
        'Get the used TID for this OrderID
        Set rst = Me.RecordsetClone
        rst.MoveLast: rst.MoveFirst
        
        iWhere = ""
        For i = 1 To rst.RecordCount
            iWhere = iWhere & "," & rst!TID
            rst.MoveNext
        Next i
        
        iWhere = iWhere & ","
        'Debug.Print iWhere
    End If


Exit Sub
err_Form_Current:

    If Err.Number = 3021 Then
        'igonr
        Resume Next
    Else
        MsgBox Err.Number & vbCrLf & Err.Description
    End If
    
End Sub

Private Sub TID_BeforeUpdate(Cancel As Integer)

GoTo Option31

    d = DCount("*", "OrderDetails", "[OrderNo]=" & Me.Parent.OrderIDSS & " And [TID]=" & Me.TID)
    
    If d > 0 Then
        MsgBox "This item is already used, you cannot use it again!"
        Me.Undo
        Cancel = True
    End If
    
'
Option31:
    
    LL = "," & Me.TID & ","
    
    If InStr(iWhere, LL) Then
        MsgBox "This item is already used, you cannot use it again!"
        Me.Undo
        Cancel = True
    End If
    
    
End Sub

جعفر

#17

مشكور الف الف شكر اخي جعفر

 

بالنسبة للطريقة الاولى لم تضبط ؟

 

الثانيه ضبطت ولكن بعد الرساله التي يظهرها الكود تاتي رسالة اكسس ( لم يتم العثور على الخاصية ) وعند فتح التعليمات يظهر خطاء رقم 3270

 

الثالثة كذلك لم تضبط ، لا ادري لعل الخطاء عندي في ترتيب ومكان الاكواد ؟

 

 

بصراحه الذي ابحث عنه ومن زمان هو الطريقة الاولى : ولعلك وجدت بعض المواضيع قديمه لي ابحث فيها عن هذه الطريقة ؟ ياريت لو تضبط ولو بمثال اخي جعفر

#18

تفضل برنامجك وفيه كل ما ذكرت :)

 

ولكن طبعا ، ادخل في الكود وافصل بينهم :)

 

حاولت ضغط البرنامج عن طريق WinZip ، ولكنه حجمه اكبر من المسموح به :(

لفك الملف المضغوط ، يمكنك انزال برنامجه المجاني من هذا الرابط:

http://www.7-zip.org/download.html

 

 

جعفر

210.NewMedLabDb - Corrected.accdb.7z

تم تعديل هذه المشاركة بواسطة jjafferr في 19 يوليو 2014 في 22:28

#19

اخي جعفر لازالت الرساله التي بالصورة تظهر عندي ؟

 

 

post-219801-0-52506000-1405799168.jpg

 

كل مره اختار فيها بند مكرر

 

 

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

ثم ياريت لوترسل لي مثال بالطريقه الاولى ؟

تم تعديل هذه المشاركة بواسطة كوماندير في 19 يوليو 2014 في 22:59

#20

لوسمحت تعطل عمل السطر On error في الكود ، ثم تخبرني اي سطر يتوقف عنده الكود ، فانا لا يظهر عندي اي خطأ  :(

 

وبالمرفق نفس المثال اعلاه ، لكني سمحت للطريقة الاولى بالعمل :)

 

 

جعفر

 

210.NewMedLabDb - Corrected.accdb.7z

#21

اخي جعفر بالنسبة للسطر On error بعد ابعاده اختقت الرساله في المثال ، لكن عند نقل نفس الكود الى برنامجي وبدون السطر المذكور لازالت الرساله تظهر .

 

اضف الى ذلك انه عند فتح قاعدة البيانات ( المثال وبدون السطر On error ) واضافة طلب جديد واضافة فحوصات له فانه لو حصل وكررت اسم فحص لايعمل الكود ولاتظهر الرساله الا اذا انتقلت الى سجل جديد او السجل السابق في النموذج الرئيس

يعني لايحصل تحديث . فقمت بعمل Me.requery للحقل TID بعد التحديث . وعندما عملت ذلك عادة الرساله في الظهور .

 

وبالنسبه لمثالك المرفق والذي فيه اخفاء البنود ( الطريقة الاولى ) المختاره انفاً فانها تختفي من الظهور حتى ليس من الكمبوبوكس فقط  واليك الصوره :

post-219801-0-66565100-1405803789_thumb.

#22

بالنسبة للطريقة الاولى ، نعم هذا ما كان يحصل لي ، وهو شئ غريب لم اتمكن من معرفة السبب ، ولكني اشك فيها انها الاستعلام!!

 

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

 

 

جعفر

#23
jjafferr كتب:

بالنسبة للطريقة الاولى ، نعم هذا ما كان يحصل لي ، وهو شئ غريب لم اتمكن من معرفة السبب ، ولكني اشك فيها انها الاستعلام!!

 

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

 

 

جعفر

 

KmndeerNewMedLabDb - Corrected.rar

#24

السلام عليكم :)

 

اولا:

 

وبعد بحث طويل ، اتضح ان هذه المشكلة موجودة في اكسس :(

 

على العموم ، اعتقد باني توصلت الى افضل ما استطيع عمله :)

 

اللي وصلت له هو هذا الكود:

Private Sub TID_GotFocus()

    Select Case Me.NewRecord
        Case True
            mySQL = "SELECT TestID, TestName, AllNv, TPrice"
            mySQL = mySQL & " FROM Q2"
            If Len(iWhere) <> 0 Then
                mySQL = mySQL & " WHERE" & iWhere
            End If
        
            TID.RowSource = mySQL
        Case False
        
            mySQL = "SELECT TestID, TestName, AllNv, TPrice"
            mySQL = mySQL & " FROM Q2"
            
            TID.RowSource = mySQL
    End Select
    
End Sub

ويجب عمل:

post-273849-0-73458000-1405849441_thumb.

 

 

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

 

ثانيا:

 

الطريقتين الاخريين يعملان بدون رسائل خطأ (انا ما عملت شئ في هذا المجال ، فالكودين السابقين يشتغلوا تمام :) )

 

 

جعفر

210.KmndeerNewMedLabDb - RowSource.accdb.7z

تم تعديل هذه المشاركة بواسطة jjafferr في 20 يوليو 2014 في 13:03

#25

عمل ممتاز جدا اخي جعفر واشكرك جزيل الشكر ......

 

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

مواضيع مشابهة