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

للمبتدئين فى قواعد بيانات ADO

رائج
بدأه moh_190 في 16 ديسمبر 2004 · 26 رد · 23,041 مشاهدة · في قسم الدروس والمواضيع الهامة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

ADO

قد يتساءل البعض عن مكتبة ADO ما هي وما فائدتها وكيف يمكن استغلالها من خلال لغة الفيجوال بيسك 6.0 ؟؟ .

- ADO هي اختصار لMicrosoft ActiveX Data Object

- مكتبة ADO تعتبر الأسلوب الجديد ( قبل الأداة الجديدة ( ADO.NET للتعامل مع قاعد البيانات بعيدا عن

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

Access بدون الحاجة لوجود Access فهذه المكتبة توفر خدمة الاتصال والإجراءات المختلفة للتعامل معها .

- إما كيفية استغلالها فهذا ما سوف نتعرف علية في السطور القليلة القادمة .

أولا وقبل إن نبدأ بأي خطوة علينا توفير مكتبة ADO للمشروع . ولتوفيرها نتبع الخطوات التالية :

وبعد فتح مشروع جديد :

من خلال القائمة نختار Project ثم References … بعدها سوف تظهر نافذة معنونة بي References – Project1 وتحتوى هذه النافذة على مكتبات عديدة وما يهمنا منها هي مكتبة ADO وسوف نجدها باسم Microsoft ActiveX Data Objects 2.X Library .

وال X يعبر عن الإصدار المثبت على جهازك . وهناك إصدارات عديدة من هذه المكتبة وكلها تقريبا بالشكل التالي :

1- Microsoft ActiveX Data Objects 2.0 Library

2- Microsoft ActiveX Data Objects 2.1 Library

3- Microsoft ActiveX Data Objects 2.5 Library

4- Microsoft ActiveX Data Objects 2.6 Library

5- Microsoft ActiveX Data Objects 2.7 Library

بعد إن تختار أحدها سنكون بهذه الخطوة قد أمنا مكتبة ADO لمشروعنا .

وألان وبعد تأمين مكتبة الADO فيمكننا الشروع في العمل , وستكون خطة العمل كالتالي :

المستوى الأول

1- كيفية إجراء اتصال مع قواعد البيانات . 6- التصفية .( Filter )

2- كيفية فتح الجداول . 7- الفرز ( Sort ).

3- طريقة عرض السجلات . a. تصاعدي.

4- إدخال البيانات ، تحريها ، حذفها . b. تنازلي

5- عملية البحث ( Search )

.a بحث بحالة الأحرف

.b بحث شامل

كيفية إجراء اتصال مع قواعد البيانات :

لإجراء اتصال مع قاعد البيانات اكسيس تكون بالتالي :

نضع المتغير في قسم الجنرال General :

Dim db As New ADODB.Connection

ونضع الكود التالي في FORM_LOAD( )

Private Sub Form_Load( )

db.Provider = "Microsoft.JET.OLEDB.4.0؛"

db.Open App.Path & "\db1.mdb"

MsgBox "تم الاتصال بقاعدة البيانات"

End Sub

شرح الكود

db.Provider = "Microsoft.JET.OLEDB.4.0;"

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

هو ا لخاص بقواعد بيانات اكسيس . Microsoft.JET.OLEDB.4.0 فالمزود

db.Open App.Path & "\db1.mdb "

والغرض منه تحديد مسار قاعدة البيانات ... db1.mdb هو اسم قاعدة البيانات.

بالخطوات السابقة انتهينا من عملية الاتصال مع قواعد بيانات اكسيس.

كيفية فتح الجداول .

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

وهي كيفية فتح الجداول الموجودة في قاعدة البيانات .ولكي نفتح جدول في قاعدة البيانات يجب أولا تأمين اتصال مع

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

وهي كالتالي:

Dim db As New ADODB.Connection

Dim rs As New ADODB.Recordset

Private Sub Form_Load( )

db.Provider = "Microsoft.JET.OLEDB.4.0;"

db.Open App.Path & "\db1.mdb"

rs.Open "[Table1]", db, adOpenStatic, adLockReadOnly

End Sub

الشرح:

أنظر للمتغير rs حيث أسندنا إليه خصائص Recordset وهو الذي يُعنى بكل العمليات التي تجرئ على الجداول من

فتح وحذف وتعديل و ....الخ .

وأيضا لاحظ السطر

rs.Open "[Table1]", db, adOpenStatic, adLockReadOnly

حيث الجدول هنا هو Table1 و db تحدد الجدول الموجود في قاعدة البيانات .

طريقة عرض السجلات :

تعرفنا آنفا كيفية أجراء اتصال مع قواعد البيانات ومن ثم تعرضنا لطريقة فتح الجداول و ألان بمشيئة

الله سنتعلم كيفية عرض السجلات ، والإبحار ما بينها .وهنا سوف نحتاج إلى نشاء بعض الأدوات وتعريفها بالشكل المناسب كالصناديق النصوص Text Box وال label وبعض المفاتيح Command .

أسم قاعدة البيانات Db1.mdb وتحتوي على جدول واحد ويحمل اسم Table1 ويوجد في

الجدول ثلاثة سجلات :

السجل الأول : ID وهو يحوي بيانات رقمية ( المفتاح الأساسي )

السجل الثاني : CategoryName

السجل الثالث : Description

ألان سنقوم بإنشاء المشروع وكتابه الأكواد لعرض السجلات:

أولا ومثل ما نعرف نختار مشروع جديد New Project ثم Standard . بعد ظهور الفور ندرج ثلاثة Label فيه .

بالنسبة لترتيب ال Label فلا يهم رتبها بالشكل الذي تراه مناسب . وعنونها بالشكل التالي ، طبعا سنستخدم

خاصية Caption لعنونة ال Label .

الأول : ID

الثاني : Category Name

الثالث : Description

وبعد ذلك أيضا نضيف ثلاثة صناديق نصوص Text Box ونضعها أمام كل واحد مرتبة حسب وضع ال

Label فمثلا ال Label رقم واحد يكون أمامه ال Textbox رقم واحد . وهكذا بالنسبة للبقية .

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

عناوين ال Command تكون بالشكل التالي ومتسلسلة الأرقام .

Command رقم 1 يحمل اسم First Record:

Command رقم2 يحمل اسم : Previous Record

Command رقم3 يحمل اسم : Next Record

Command رقم4 يحمل اسم Last Record:

ولا تنسى إن تحفظ المشروع ولنسميه مثلا ViewRecord .

والآن وصلنا إلى دور كتابة الكود . ومثل ما عرفنا سابقا إن لإجراء إي اتصال مع إي قاعدة بيانات يجب تهيئة مكتبة

ADO وقد شرحنا سابقا طريقة تهيئتها وبشكل مبسط .

وهنا سنكمل الكود الذي تم فيه الاتصال مع الجدول / تذكير بالكود .

Dim db As New ADODB.Connection

Dim rs As New ADODB.Recordset

Private Sub Form_Load( )

db.Provider = "Microsoft.JET.OLEDB.4.0;"

db.Open App.Path & "\db1.mdb"

rs.Open "[Table1]", db, adOpenStatic, adLockReadOnly

End Sub

أولا نقوم بإنشاء Sub وسنسميه ViewRecord

والهدف منه هو عرض السجل الحالي الذي يتم استدعائه من قبل الضغط على ال Command الذي تم إنشائه سابقا .

وستتضح الرؤية بشكل افضل بعد إتمام الكود .

بالمناسبة توجد عدة طريق لعرض السجلات وقصد بعرض السجلات هو إظهار البيانات في صناديق النصوص TextBox

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

Sub ViewRecord( )

If Not rs.RecordCount = 0 Then

Text1.Text = “"

Text2.Text = ””

Text3.Text = “”

If Not IsNull(rs![iD]) Then Text1 = rs![iD]

If Not IsNull(rs![CategoryName]) Then Text2 = rs![CategoryName]

If Not IsNull(rs![Description]) Then Text3 = rs![Description]

End If

End Sub

الشرح:

الجملة الشرطية والتي هي :If Not rs.RecordCount = 0 Then

قبل إن اشرح ما فائدتها دعني أوضح فائدة الخاصية RecordCount وهذه الخاصية في الحقيقة ترجع عدد السجلات

الموجودة في الجدول ، فمثلا يوجد عندنا 10 سجلات مخزنة في الجدول فإن هذه الخاصية ترجع لنا العدد 10 ، فبها نستطيع

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

أتوقع بدأنا نفهم سبب استخدامها هنا .

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

الحقول ، وإلا سوف نقع في دائرة الأخطاء البرمجية .

أما السطور الثلاثة التي تلي الجملة الشرطية فهو تُعنى بإفراغ محتويات ال Textbox لكي يتم تجهيزها لاحتضان بيانات جديدة .

أما هذا الكود :

If Not IsNull(rs![iD]) Then Text1 = rs![iD]

If Not IsNull(rs![CategoryName]) Then Text2 = rs![CategoryName]

If Not IsNull(rs![Description]) Then Text3 = rs![Description]

إذ جئنا لنترجم الكود السابق لنص مقروء فالناتج يكون :

إذا كان الحقل الذي اسمهم ID فارغ ولا يحتوي على بيانات حينئذ تجاهل إسناد القيمة الفارغة إلى صندوق النصوص .

وهذه هي الترجمة الحقيقة للكود .

IsNull(rs![iD]) تتحقق من إن حقل ID لا يحوي قيمة فارغة .

Text1 = rs![iD] هنا نرجع قيمة الحقل إلى ال Textbox

وهكذا بالنسبة للبقية .

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

كود في قسم التحميل Form_Load وهذا الكود يقوم باستدعاء ال Sub الذي هو ViewRecord فلذلك نكتب الكود

التالي : Call ViewRecord

ويكون مكانه اسفل الكود الخاص بفتح الجدول . والآن تستطيع تشغيل البرنامج لترى ما تم إنجاز .

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

الحقل سوف نستخدم رقم الحقل أنظر الكود :

Sub ViewRecord( )

If Not rs.RecordCount = 0 Then

Text1.Text = ""

Text2.Text = ""

Text3.Text = ""

If Not IsNull(rs.Fields(0).Value) Then Text1 = rs.Fields(0).Value

If Not IsNull(rs.Fields(1).Value) Then Text2 = rs.Fields(1).Value

If Not IsNull(rs.Fields(2).Value) Then Text3 = rs.Fields(2).Value

End If

End Sub

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

انظر الكود :

Private Sub Form_Load( )

db.Provider = "Microsoft.JET.OLEDB.4.0;"

db.Open App.Path & "\db1.mdb"

rs.Open "[Table1]", db, adOpenStatic, adLockReadOnly

Set Text1.DataSource = rs

Set Text2.DataSource = rs

Set Text3.DataSource = rs

Text1.DataField = "ID"

Text2.DataField = "CategoryName"

Text3.DataField = "Description"

End Sub

وهكذا باب البرمجة والإبداع موجود ولكل شخص الطريقة التي يفضل استخدامها بغض النظر عن طول الكود أو قصره .

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

أو البيانات والانتقال ما بينها .

نبدأ بكتابة كود الانتقال إلى السجل الأول Record First وسنضع الكود في Command1 :

الكود :

If Not rs.BOF Then rs.MoveFirst

If rs.BOF And rs.RecordCount > 0 Then

Beep

Exit Sub

End If

Call ViewRecord

السطر الأول :

If Not rs.BOF Then rs.MoveFirst

ومعنى الكود السابق لفظيا هو إذا كان موقع السجل ليس بالأول فانتقل إلى السجل الأول . والخاصية BOF هي المسؤولة

عن إرجاع القيمة التي تشير إلى موقع السجل المعروض ، وMoveFirst هي المسؤولة عن تحقيق الانتقال

و في حالة عدم تحديد الجملة الشرطية سنقع في خطئ برمجي فادح .

إما باقي الكود :

If rs.BOF And rs.RecordCount > 0 Then

Beep

Exit Sub

End If

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

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

فيها تقريبا بنفس الفكرة ولكن سيختلف المضمون فعوضا عن استخدام MoveFirst سنستخدم مثلا

MovePrevious مع إضافات بسيطة . أما آخر سطر من الكود هو Call ViewRecord فالغاية منه هو إظهار

ما تم تنفيذه في الكود الذي سبقه .

والآن سأعرض باقي الأكواد ، واترك لكم فهم الكود :

كود التراجع أو الانتقال إلى السابق MovePrevious . ونضعه في Command2 :

Private Sub Command2_Click()

If Not rs.BOF Then rs.MovePrevious

If rs.BOF And rs.RecordCount > 0 Then

Beep

rs.MoveFirst

Exit Sub

End If

Call ViewRecord

End Sub

لعرض السجل التالي MoveNext نستخدم الكود الذي يلي ونضعه في Command3:

Private Sub Command3_Click()

If Not rs.EOF Then rs.MoveNext

If rs.EOF And rs.RecordCount > 0 Then

Beep

rs.MoveLast

End If

Call ViewRecord

End Sub

ولعرض السجل الأخير MoveLast والكود يسكون موضعه في Command4:

Private Sub Command4_Click()

If Not rs.EOF Then rs.MoveLast

If rs.EOF And rs.RecordCount > 0 Then

Beep

Exit Sub

End If

Call ViewRecord

End Sub

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

إدخال البيانات ، تحريها ، حذفها .

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

أخرها هو عرض السجلات وتصفحها . والآن سنأتي على ذكر العمليات أ و الإجراءات والتي تعتبر جزء

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

وسنبدأ بعملية الإضافة :

قد رأينا في قسم استعراض السجلات إن هناك عدة طرق للوصول إلى هدف معين في البرمجة ولكل

مبرمج طريقه أو أسلوبه المفضل. والبرمجة في الحقيقة هي طريق للإبداع.

طبعة للوصول إلى هذه النقطة نقطة إضافة البيانات يجب توفير :

- اتصال مع قواعد البيانات.

- فتح الجدول بالطريقة المعتادة ولكن مع إعطاء صلاحية الإضافة أو صلاحيات المعالجة .

والآن لتأمين اتصال يتيح لنا معالجة البيانات يجب إجراء تغيير طفيف في كود الاتصال مع الجدول :

Dim db As New ADODB.Connection

Dim rs As New ADODB.Recordset

Private Sub Form_Load()

db.Provider = "Microsoft.JET.OLEDB.4.0;"

db.Open App.Path & "\db1.mdb"

rs.Open "[Table1]", db, adOpenStatic, adLockPessimistic

End Sub

في الكود السابق قد أمنا اتصال مع الجدول في وضعية القراءة فقط ، ولكن عندما نريد إجراء عمليات المعالجة

يجب تأمين اتصال في وضعية الصلاحيات ( Pessimistic ) ، لهذا استبدلنا خاصية

adLockReadOnlyبالخاصية adLockPessimistic .

بعد إن تعرفنا على المسار الجديد والتغيير المحدث في فتح الجداول ، سنقوم بإضافة خمسة Commands .

Command5 سيحمل اسم Add .

Command6 سيحمل اسم Edit .

Command7 سيحمل اسم Delete .

Command8 سيحمل اسم Save .

Command9 سيحمل اسم Cancel .

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

إن المفاتيح الأخرى تكون غير متاحة أو ممكنة حيث لا يمكن إجراء عمليتين مع بعضهما البعض في نفس الوقت .

على العموم سوف تتضح فكرة ال Sub عند إكماله . والكود الذي سيحويه ال SUB هو :

Sub EnabledUnEnabled(n As Boolean)

Text1.Locked = True

Text2.Locked = n

Text3.Locked = n

Command1.Enabled = n

Command2.Enabled = n

Command3.Enabled = n

Command4.Enabled = n

Command5.Enabled = n

Command6.Enabled = n

Command7.Enabled = n

Command8.Enabled = Not n

Command9.Enabled = Not n

If rs.RecordCount = 0 Then

Command6.Enabled = False

Command7.Enabled = False

End If

End Sub

قد تلاحظ الحرف n الذي أضفناه إلى SUB من Boolean و ال Boolean هو متغير يرجع قيمة

True أو False . وسوف نستفيد منه في عملية الاستدعاء Calling .

فمثلا عندما نستدعي ال SUB السابق بهذا الشكل :

Call EnabledUnEnabled (True )

فسيكون الناتج هو إتاحة جميع المفاتيح ما عدى مفتاح Save وال Cancel أما البقية ستكون متاحة . والعكس صحيح .

أما السطور الثلاثة الأولى فمهمتها قفل ال Textbox ولا يمكن الكتابة فيه إلا بعد الضغط على مفتاح إضافة

سجل جديد Add وأما ما بعدها فهي مفهومة الغرض.

أما الجزء الأخير من الكود والذي هو :

If rs.RecordCount = 0 Then

Command6.Enabled = False

Command7.Enabled = False

End If

فهذا يتكفل بعملية إغلاق مفتاح Edit و Delete وهذا الإغلاق مشروط وهو إذا كان الجدول فارغ ولا يحتوي

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

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

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

من ال SUB وأتمنى إن تكون فكرة ال SUB مفهومة لدى الجميع .

وألان سننتقل إلى مفتاح الإضافة Add وكل الذي سيحويه هذا المفتاح هو التالي :

Private Sub Command5_Click( )

Text1.Text = “”

Text2.Text = “”

Text3.Text = “”

Call EnabledUnEnabled(False)

Text2.SetFocus

End Sub

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

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

من وجود البيانات قبل عملية الحفظ بخطوات .

وهذا الكود الذي سنضعه في مفتاح الحفظ Save وبعدها سنتناول الكود خطوة خطوه .

Private Sub Command8_Click( )

If Trim(Text2.Text) = "" Then

MsgBox "Connot contain a Null Value .", vbCritical, "Message"

Text2.SetFocus

Exit Sub

End If

With rs

.AddNew

![CategoryName] = Trim(Text2.Text)

If Not Trim(Text3.Text) = "" Then ![Description] = Trim(Text3.Text)

.Update

End With

rs.Requery

rs.MoveLast

Call EnabledUnEnabled(True)

Call ViewRecord

End Sub

الشرح:

If Trim(Text2.Text) = "" Then

MsgBox "Connot contain a Null Value .", vbCritical, "Message"

Text2.SetFocus

Exit Sub

End If

ونستفيد منه في عملية التحقق المذكورة سابقا وفي حالة لم يتم العثور على نص في Text Box رقم 2 فإنه سيقوم

بأخبارك إنه لا يمكن إسناد قيمة فارغة . وسيعيدك إلى ال Text Box الذي من المفترض تعبئته بالبيانات

ومن ثم يخرج من ال SUB ولا يتم تنفيذ ما بعده وهذا النوع من الأكواد أنا شخصيا أطلق عليه اسم ( صائد الأخطاء ) .

أما الكود الذي يليه :

With rs

.AddNew

![CategoryName] = Trim(Text2.Text)

If Not Trim(Text3.Text) = "" Then ![Description] = Trim(Text3.Text)

.Update

End With

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

وعلامة التعجب ! تفيد إن ما بعدها هو حقل وطبعا بعد تحديد الحقل سوف نسند له البيانات التي تم إدخالها .

وبالنسبة للحقول الضرورية أو المطلوبة فنكتفي بوضعها بهذا الشكل:

![CategoryName] = Trim(Text2.Text)

أما الحقول غير ضرورية والمتروكة كخيار للمستخدم يقوم بتعبئتها أو يتركها فارغة . فهذه الحقول يجب وضع

لها كود التحقق ويكون كتالي :

If Not Trim(Text3.Text) = "" Then ![Description] =Trim(Text3.Text)

والكود السابق يقوم بفحص ال Text Box وإذا كان فارغ فهو يتجاهل الحقل أما إذا كان ال Text Box يحوي

على بيانات فإنه سيسند القيمة إلى الحقل الصحيح .

أما الخاصية Update فهي المسؤولة عن حفظ القيم في السجل وبدونها يسكون ما سبق عقيما .

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

rs.Requery

ال Requery هي بمثابة Refresh في DAO حيث تقوم بتحديث للبيانات .

والكــود التالي:

rs.MoveLast

وال MoveLast الانتقال إلى السجل الأخير .. ولماذا نستخدمها هنا .. ببساطة لأنه السجل الجديد سيكون آخر سجل تم إضافته.

والكــــود :

Call EnabledUnEnabled (True)

ومثل ما عرفنا سابقا إن EnabledUnEnabled يقوم بعملية قفل أو فتح ال Text Box وال Commands

وهنا يجب أقفالها فعندما ننتهي من إي إجراء يجب قفل ما تم فتحة أو إتاحته .

والكـــــــود:

Call ViewRecord

وال ViewRecord يقوم بعرض السجل الجديد.

أنتهي .

بالنسبة لمفتاح إلغاء Cancel قم فقط بإضافة الكود التالي والكود مفهوم ولا يحتاج إلى توضيح :

Private Sub Command9_Click ( )

Call EnabledUnEnabled(True)

Call ViewRecord

End Sub

تحرير أو تعديل البيانات:

تحرير البيانات هي العملية التي يتم فيها استبدال البيانات السابقة ببيانات جديدة والفرق الأساسي ما بين عملية

إضافة سجل جديد وتعديله تكمن في خاصية AddNew حيث هذه الخاصية نستخدمها عند إضافة سجل جديد

إما في العملية الأخرى وهي التحرير فلا نستخدمها فالسطور القادمة بإذن الله تبين ما سبق .

نبدأ بإضافة المتغير الذي سوف يأتي ذكره والهدف منه هو تعريف البرنامج إن المستخدم الآن يقوم بعملية إضافة

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

مفتاح ليعمل على حفظ البيانات المعدلة .

نعرف متغير ونضعه في General:

Dim EditORAdd As Boolean

ثم نضيف المتغير إلى مفتاح إضافة سجل جديدAdd وجعل قيمته True ليكون الكود كاملا بالشكل التالي :

Private Sub Command5_Click()

Text1.Text = ""

Text2.Text = ""

Text3.Text = ""

Call EnabledUnEnabled(False)

Text2.SetFocus

EditORAdd = True

End Sub

والآن كلما نقرنا على مفتاح Add ستكون قيمة المتغير EditORAdd دائما True . ثم نضيف الكود التالي إلى مفتاح Edit .

الكــــود:

Private Sub Command6_Click()

Call EnabledUnEnabled(False)

Text2.SetFocus

EditORAdd = False

End Sub

وهنا نضع قيمة المتغير دائما تساوي False ، إذا مما سبق يتبين لنا إن المتغير إذا كانت قيمته تساوي False

فمعنا ذلك إن المستخدم يريد تحرير البيانات إما إذا كانت قيمة المتغير تساوي True فذلك يقودنا إلى إن المستخدم

بصدد إدخال بيانات جديدة .والآن سنضيف جملة شرطية إلى مفتاح الحفظ Save . وهي ستحل محل السطر

التالي من الكود الموجود في مفتاح الحفظ Save .

الكود الجديد :

If EditORAdd = True Then .AddNew

هل يمكنك ترجمة الكود السابق .؟؟؟! هو ببساطة إذا كانت قيمة المتغير EditORAdd تساوي True فسيتم

تنفيذ الخاصية AddNew إما إذا كانت قيمة المتغير EditORAdd لا تساوي True فإنه يتجاهل تنفيذها .

وأيضا سنضيف نفس الجملة الشرطية في آخر الكود من المفتاح Save . انظر الكود بعد آخر تعديل .

Private Sub Command8_Click()

If Trim(Text2.Text) = "" Then

MsgBox "Connot contain a Null Value .", vbCritical, "Message"

Text2.SetFocus

Exit Sub

End If

With rs

If EditORAdd = True Then .AddNew

![CategoryName] = Trim(Text2.Text)

If Not Trim(Text3.Text) = "" Then ![Description] = Trim(Text3.Text)

.Update

End With

If EditORAdd = True Then

rs.Requery

rs.MoveLast

End If

Call EnabledUnEnabled(True)

Call ViewRecord

End Sub

وبهذا قد انتهينا من عملية تعديل البيانات فمثل ما جاء آنفا إن الفرق الأساسي بين العمليتين

هي خاصية AddNew فحين تنفيذها سيتم إضافة سجل جديد أما حين تجاهلها فسيتم تعديل البيانات .

وأيضا قد استخدمنا المتغير لكي يتجاهل خاصية الإنعاش Requey وكذلك خاصية

الانتقال إلى السجل الأخير MoveLast .

حذف السجل

الخاصية Delete هي التي تقوم بحذف السجل المفرد أو السجل الحالي وطريقة بنائها بالشكل التالي : الكود كامل:

If MsgBox("Do you want to Delete a current record ?"), _

vbQuestion + vbYesNoCancel, "Message") = vbYes Then

rs.Delete adAffectCurrent

Text1.Text =""

Text2.Text = ""

Text3.Text = ""

Call EnabledUnEnabled(True)

Call Command3_Click

Call ViewRecord

End If

وكود الحذف هو rs.Delete adAffectCurrent أما باقي الأكواد فيه مسألة تنظيميه ونستغلها أيضا في

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

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

حينما يكون الجدول فارغ من السجلات .

البحث ( Search ):

ويمكننا البحث عن البيانات بطرقتين الأولى بالبحث بدلالة الكلمة والثاني البحث بدلالة حرف من كلمة أو جزء من نص .

يمكننا استخدام الإجراء Find للبحث عن ( نص ، رقم ، تاريخ ) أو إي بيان على اعتبار إن هذا البيان قد تم تحديده وإسناده

مسبقا إلى الإجراء Find . وقد تكون هذه البيانات موجودة في السجل الحالي أو في السجل التالي أو السابق أو في

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

البحث عن بيان موجود في السجل الأول ونحن في وسط السجلات بدون وضع معيار معين يتم بواسطة الرجوع إلى السجل الأول

ومن ثم تنفيذ عملية البحث . وطبعا يمكننا البحث عن السجلات في الجدول الحالي فقط أو الجدول النشط يعني لا يمكن البحث في

جدول غير نشط . وطريقة بناء الإجراء Find بالشكل التالي:

Find (Criteria, SkipRows, SearchDirection, Start)

Criteria

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

معرفة تصنيف البيان مع معرفة نوع البيانات التي يحتضنها الحقل من حيث إنها بيانات ( نصيه Text ، رقمية Numeric ،

تاريخ Date/Time ) وهذه في الحقيقة من الشروط التي يجب توفرها عند بناء جملة البحث أو إجراء البحث وهنا سأضع

مثال يوضح طريقة تكوين معيار صحيح مرتبط بنوع البيانات .

في حالة البحث عن بيانات نصية فتكون الطريقة بالشكل التالي على اعتبار المتغير rs قد أسند له خصائصRecordSet :

rs.Find "[CategoryName] = 'Produce' "

حيث CategoryName هو اسم الحقل و Produce هو البيان المطلوب البحث عنه وإيجاده .

وفي حالة البحث عن قيم رقمية أو بيانات رقمية نكون الإجراء بالشكل التالي :

Rs.Find " ID = 7 "

حيث ID هو اسم الحقل و 7 هي القيمة المطلوب إيجاده ، والآن أخي العزيز هل لاحظت الفرق ما بين كلا الحالتين .

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

لها الفاصلة .

وفي حالة البحث عن بيانات ذات قيم تاريخية فإننا نكون الإجراء بالشكل التالي :

Rs.Find =" FieldDate = #02/01/2004# "

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

صيغ تاريخية سنستخدم علامة # .

SkipRows

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

نقطة الانطلاقة لعملية البحث من الصف الحالي المتوقفين عنده (position ) .

SearchDirection

وهي تتمثل في اتجاه الانطلاقة لعملية البحث ويوجد اتجاهين :

الأول : adSearchBackward وهو البحث من النقطة الحالية للسجل إلى نقطة البداية أو إلى السجل الأول .

الثاني : adSearchForward وهو البحث من النقطة الحالية للسجل إلى أخر نقطة في السجل أو إلى السجل الأخير .

Start

وهي شبيه بالأولى حيث نحدد نقطة البداية من إي صف سيكون البحث (starting position for the search ) .

وبالنسبة للثلاث الوسائط فيه اختيارية الاستخدام يعني يمكننا استخدامها ويمكننا تجاهلها .

والآن سنتناول كتابة الكود الخاص بالإجراء Find . وهنا سوف لن نستخدم ( الوسائط ) سابقة الذكر : الكود :

Dim gFind As String, gBookMark As Variant

gFind = InputBox("Find What : ", "Search")

If Trim(gFind) = "" Then Exit Sub

gBookMark = rs.Bookmark

rs.Find "[CategoryName] = '" & Trim(gFind) & "'"

If rs.EOF Then

rs.Bookmark = gBookMark

Exit Sub

End If

Call ViewRecord

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

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

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

التحرك من النقطة الأولى ( أي السجل الأول ) إلى النقطة الثالثة ( أي السجل الثالث ) يعني سيكون التحرك نحوى الإمام .

والآن نريد إن نبحث عن بيان وهذا البيان موجود في السجل الثاني .

جرب الكود هل ستجد نتيجة . طبعا لا . لأن الكود

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

سجل في الجدول . حاول إن تتخيل العملية لأنها ستفيدنا في فيهم الكود وستساعدنا في استغلال ( الوسائط )

التي ممرنا عليها سابقا .

وباختصار الكود السابق يبحث عن البيانات في السجل الحالي إلى آخر سجل وإذا كنا في

السجل رقم 10 فلا يمكن لهذا الكود الرجوع إلى السجلات التي تليه باحثا فيها عن البيان المطلوب .

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

rs.Find "[CategoryName] = '" & Trim(gFind) & "'"

ونغير الكود ليصبح بهذا الشكل :

rs.Find "[CategoryName] = '" & Trim(gFind) & "'", 0, adSearchForward, 1

انظر للفرق بين الكودين من ناحية الشكل . الأول لم نستخدم ( الوسائط ) أما الكود الثاني فقد استخدمنا فيه الوسائط

ولكن ما الفرق بين الكودين السابقين في عملية التنفيذ .

الفرق بين الكود :

الأول مثل ما قلنا سابقا هو إنا منهجية البحث تكون بمسار واحد فقط وهو والبحث في السجل الحالي ومن ثم

الانتقال إلى السجلات ألاحقه .

والثاني بيدا عملية البحث من السجل رقم واحد مرور بجميع السجلات بغض النظر عن النقطة ( Position ) أو

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

أتوقع الآن وضح الفرق الأساسي بين الكودين . ولا تنسى أخي العزيز أن تجري بعض الاختبارات حول الإجراء

Find وجميع خواصها أو الوسائط التي تُتمم هذا الإجراء .

الطرق الأخرى للبحث :

1- عند البحث عن رقم سيكون الكود بهذا الشكل :

rs.Find "[iD] = " & Trim(gFind) & "", 0, adSearchForward, 1

2- البحث بدلالة حرف معين ، وهنا نستخدم الكلمة المحجوزة LIKE مع العلامة النسبة المئوية % .

حيث هذه العلامة تعني جميع الأحرف بعد هذا الحرف أو هذه الكلمة المدخلة:

rs.Find "[ CategoryName] LIKE '" & Trim(gFind) & "%'", 0, adSearchForward, 1

#2

هذا الدرس قد قراءتة فى موقع واردت ان يستفيد الجميع

#3

هذا الدرس من تأليف الأخ العزيز هيثم القلاف (Visitor_OM)

جزاه الله خيراً

والشكر موصول لناقل الموضوع الأخ moh_190

ani.gif
#4

جزاك الله خيرا لإشراكنا في المعلومات :)

#5

شفى الله وعافى الاستاذ هيثم القلاف ... آمين يارب العالمين

#6
اقتباس
شفى الله وعافى الاستاذ هيثم القلاف ... آمين يارب العالمين

آمين .. آمين .. آمين ..

و لكن ما الذي حدث مع الاخ هيثم القلاف؟؟؟ هل لا زال موجود في منتدى الابداع ؟؟

لا اله الا الله .. محمد رسول الله

(* ربِ اجعلني مقيم الصلاة و من ذريتي ، ربنا و تقبل دعـاء *)

يا حيّ يا قيـوم ... برحمتك استغيث ... اصلح لي شأني كله و لا تكلني الى نفسي طرفة عين

#7
اقتباس
آمين .. آمين .. آمين ..

و لكن ما الذي حدث مع الاخ هيثم القلاف؟؟؟ هل لا زال موجود في منتدى الابداع ؟؟

في الحقيقة الاخ هيثم الان لديه ظروف قاهره ...

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

نسأل الله السلامة

#8

آمين يا رب العالمين ..

وإن شاء الله نراه من جديد .. سالماً غانماً بإذته تعالى ..

ani.gif
#9

السلام عليكم شباب

مشكور أخي على هالمعلومات القيمة ;) :)

و لكن عندي بعض الإستفسارات :

أنا إستخدمت أداة ado من component و ليس من الطريقة التي أشرت إليها

و قد طبقت طريقتك و لكن عندي سؤال لو كان لدي combodata و أريد أن أربطه مع ado بطريقتك كيف يكون ذلك ؟؟ مع العلم إن ال combodata مرتبطة مع جدول ثاني يعني نعمل لها rs1 as new adodb.recordset

أعرف إن ال combodata لها مجموعة من الخصائص هي :

1- boundcloumn

2-datasource

3-listfield

4-rowsource

لإنني استخدمت هذه الطريقة و لم يصعب علي إلا هذا الشيء :unsure: :wacko:

أرجو ألا أكون قد أثقلت عليك

جزاك الله عنا و عن الإسلام كل الخير :rolleyes:

و السلام

#10

السلام عليكم ورحمة الله وبركاته، والحمد الله على نعمة الصحة ..

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

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

اخي yaallah راجع الكود ادناه، وإن شاء الله تجد مطلوبك.

'
 Dim db As New ADODB.Connection
 Dim rs As New ADODB.Recordset
'
Private Sub Form_Load()
'
 db.CursorLocation = adUseClient
 db.Provider = "Microsoft.JET.OLEDB.4.0;"
 db.Open App.Path & "\YourDatabase.mdb"
'
 rs.Open "[YourTable]", db, adOpenStatic, adLockReadOnly
'
 Set DataCombo1.DataSource = rs
 Set DataCombo1.RowSource = rs
     DataCombo1.DataField = "YourField"
     DataCombo1.ListField = "YourField"
End Sub

وتقبلوا مني فائق الأحترام والتقدير.

#11

سلام

مشكور أخي على الرد و لكن

أنا راح أخبرك بالبرنامج و إن شاء الله تفهمني

البرنامج عبارة عن مكتبية منزلية قاعدة بياناتها عبارة عن 4 جداول جدول أساسي و 3 جداول فرعية في الجدول الأساسي حقول هي :

الإسم والمؤلف الناشر الطبعة و ملاحظات و كل هذه الحقول عبارة عن تكست

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

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

اسم الكتاب قران كريم نوعه سي دي محتواه ديني المؤلف صخر فتظهر المعلومات كما يلي :

كل ما في التكست صحيح و لكن ما في الكمبو يظهر كتاب النوع تعليمي المحتوى فكيف أجعل الإتساقية بين المعلومات المعروضة

( أتمنى أن تكون فهمت قصدي )

المشكلة الثانية عند الإضافة

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

أنا أضفت في شفرة الإضافة هذا الكود و لكن يظهر لي خطأ :

rs.requrey

rs.ddnew

rs.fields("name")=text1.(i don't now what i must choose )

و هكذا بالنسبة للتكست

ما هو الخطأ في هذا الكود

أرجو الإجابة و آسفة على الإطالة :rolleyes:

و السلام

#12

بخصوص إظهار البيانات في ComboData بشكل يوازي البيانات في باقي ال TextBox فالكود التالي يحل المشكلة إن شاء الله :

ComboData1.Text=rs![YourField]

ال rs هو RecordSet وال YourField هو اسم الحقل .

اما السؤال الثاني فالمشكلة غير واضحة بالنسبة لي، افضل إن ترفقي البرنامج لك اتمكن من أجراء التعديل علية .. .

بالتوفيق.

#13

السلام عليكم

مشكور أخي و لكن عفوا أخي كيف أرفق المبرنامج في صورة ملف مضغوط

#14

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

والخيار لك .

#15

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

الحقيقة يشكر الأخ على هذا الشرح المميز والموفق وأسأل الله أن يجزيه خيرا على ذلك ..

سؤالي يا جماعة حول ربط هذه الأداة بأراكل كيف يكون

فقد ذكر الأخ الكريم أنه لعمل اتصال باكسيس نكتب

db.Provider = "Microsoft.Jet.OLEDB.4.0;"

db.Open App.Path & "\db1.mdb"

rs.Open "[Table1]", db, adOpenStatic, adLockPessimistic

فكيف يكون الحال مع أواركل

وشكرا ..

#16

للرفع

#17

معذرة اخي Baihan لم أرى مشاركتك إلا هذه اللحظة ... عموما تجد الحل على هذا الرابط

وبالتوفيق.

#18

مشكور علي هذا الموضوع الرائع

واريد ان اعرف adUseClient

الناس انواع

رجل يعلم ويعلم انه يعلم فهذا عالم فوقروه

رجل يعلم ولا يعلم انه يعلم فهذا غافل فإيقزوه

رجل لا يعلم ويعلم انه لا يعلم فهذا جاهل فعلموه

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

#19

مشكور moh_190 علي هذا الموضوع الرائع ونشكر كل من شارك بالرد

الناس انواع

رجل يعلم ويعلم انه يعلم فهذا عالم فوقروه

رجل يعلم ولا يعلم انه يعلم فهذا غافل فإيقزوه

رجل لا يعلم ويعلم انه لا يعلم فهذا جاهل فعلموه

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

#20

مجهود ممتاز

ربنا معانا ;)

Mimo

040.gif

#21

استخدم ADO مع VB6

على برنامج يقوم بالاتصال بACCESS & SQLserver2000

عند الاستعلام عند عدد السجلات فى ACCESS يعمل ولا يعمل SQLserver2000

db2.ConnectionString = "Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=Medical;Data Source=M_HUSSEIN"

RSCOURSET.Open "select* from tb_Direction ", db2, adOpenStatic, adLockOptimistic

if RSCOURSET.RecordCount >0

يظهر عدد السجلات -1 اما فى Access يظهر الرقم الحقيقى

البريد m_hussein2001@hotmail.com

#22

رائع جدا جدا جدا وشكرا على الافاده

#23

معي مشكله في ADO في كيفية استخراج استعلام مثلا حسب التاريخ حيث اني مستخدم طريقة التعامل مع قاعدة البيانات DSN وجزاكم الله خير

#24

جزاك الله خير درس رائع

#25

الف شكر لك اخوي عالموضوع الرائع

الف شكر لك اخوي عالموضوع الرائع

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