You are on page 1of 58

‫الفصل الثالث‬

‫المتغيّرات‬

‫المتغيّرات ‪:Variables‬‬ ‫‪‬‬


‫المتغيرات؟‬
‫ّ‬ ‫ما هي‬

‫تعريف المتغيرات ‪:Declaring Variables‬‬ ‫‪‬‬


‫المتغيرات‪.‬‬
‫ّ‬ ‫صيغة تعريف‬

‫أنواع المتغيرات ‪:Types of Variables‬‬ ‫‪‬‬


‫وكيفية التعامل مع ك ّل منها‪.‬‬
‫ّ‬ ‫المتغيرات‪،‬‬
‫ّ‬ ‫نظرة شاملة ألنواع‬

‫تنسيق األرقام ‪:Formatting Numbers‬‬ ‫‪‬‬


‫معين قبل أو بعد الرقم‪...‬‬
‫العشرية أو وجود رمز ّ‬
‫ّ‬ ‫معين‪ ،‬كعدد الخانات‬
‫ق ّ‬ ‫النص بنس ٍ‬
‫ّ‬ ‫مربع‬
‫كيف تعرض الرقم في ّ‬
‫إلخ‪.‬‬

‫االختصارات المحدّدة لألنواع ‪:Data Type Identifiers‬‬ ‫‪‬‬


‫المتغير بدون كتابة اسم النوع‪.‬‬
‫ّ‬ ‫طريقة بديلة لتعريف‬

‫خيار "التعريف الصريح"‪: Option Explicit‬‬ ‫‪‬‬


‫المتغير قبل استخدامه!‬
‫ّ‬ ‫كيف تجبر نفسك على تعريف‪7‬‬

‫خيار "التحويل الدقيق" ‪:Option Strict‬‬ ‫‪‬‬


‫كيف تمنع اللغة عن التحويل التلقائي بين نوعين مختلفين من أنواع البيانات‪.‬‬

‫التحويل بين أنواع المتغيّرات ‪:Converting Variable Types‬‬ ‫‪‬‬


‫كيف تقوم أنت بالتحويل بين أنواع البيانات‪ ،‬في حالة تفعيل خيار التحويل الدقيق‪.‬‬

‫القيمة "ال شيء" ‪:Nothing‬‬ ‫‪‬‬


‫للكائنات فقط!‬
‫اختبار أنواع المتغيّرات ‪:Examining Variable Types‬‬ ‫‪‬‬
‫المتغير؟‬
‫ّ‬ ‫كيف تتأ ّكد من نوع البيانات الموجودة في‬

‫مجال المتغيّر ‪:Variable Scope‬‬ ‫‪‬‬


‫المتغير؟‬
‫ّ‬ ‫أي نطاق تستطيع استخدام‬
‫داخل ّ‬

‫عمر المتغيّر ‪:Variable Lifetime‬‬ ‫‪‬‬


‫المتغير محتفظا بقيمته؟‬
‫ّ‬ ‫إلى متّى يظ ّل‬

‫الثوابت ‪:Constants‬‬ ‫‪‬‬


‫تتغير قيمتها‪ 7‬أبدا؟‬
‫متغيرات ال ّ‬
‫هل هناك ّ‬

‫المصفوفات ‪:Arrays‬‬ ‫‪‬‬


‫كيف يمكن التعامل مع مجموعة كبيرة من البيانات ذات النوع المشترك‪.‬‬

‫يعرفها المستخدم ‪:User-Defined Data Types‬‬


‫األنواع التي ّ‬ ‫‪‬‬
‫التعرف على المرقّمات ‪ Enums‬والسجالت ‪.Structures‬‬
‫ّ‬

‫المتغيّرات ‪:Variables‬‬
‫ألنك تستطيع تغيير‬ ‫متغي ٍ‬
‫رات‪ّ ،‬‬ ‫وطبعا ُس ّميت ّ‬ ‫المتغيرات بتخزين ِ‬
‫القيم أثناء تنفيذ البرنامج‪..‬‬ ‫أي لغة برمجة‪ ،‬تقوم‬
‫ً‬ ‫ّ‬ ‫كما في ّ‬
‫ٍ‬
‫لحظة أثناء تنفيذ البرنامج‪.‬‬ ‫أي‬
‫قيمها في ّ‬
‫والمتغير‪7‬‬
‫ّ‬ ‫المتغير‪" 7‬اسم المستخدم"‪ UserName 7‬يمكن أن تُوضع به القيمة "محمد"‪..‬‬
‫ّ‬ ‫اسم وقيمة‪ ..‬فمثال‪:‬‬
‫وللمتغير ٌ‬
‫ّ‬
‫"الخصم" ‪ Discount‬يمكن أن تُوضع به القيمة ‪.0.35‬‬
‫بين عالمتَ ْي تنصيص‪ ،‬بينما‬
‫تم وضعها َ‬ ‫أن القيمتين "محمد" و ‪ 0.35‬مختلفتان‪ ،‬فاألولى‪ 7‬نص ‪ String‬لهذا ّ‬
‫تالحظ هنا ّ‬
‫ُ‬
‫رقمية ‪.Numeric Value‬‬‫الثانية قيمة ّ‬
‫أسماء أو مخازن للقيم‪ّ ..‬إنها كذلك ِكيانات ّ‬
‫ذكيةٌ لتخزين‬ ‫ٍ‬ ‫مجرد‬
‫المتغيرات في ‪ VB.NET‬ليست ّ‬ ‫ّ‬ ‫فإن‬
‫وكما ذكرنا سابقا‪ّ ،‬‬
‫وإ جراء العمليات على القيم‪ ..‬باختصار‪ّ :‬إنها كائنات ‪ ،Objects‬لها وسائلها‪ 7‬وخصائصها الخاصة بها‪.‬‬
‫متغيرا (كائنا) من النوع "تاريخ" ‪:Date‬‬
‫ف ّ‬ ‫تعر ُ‬
‫فمثال‪ :‬هذه الجملة ّ‬
‫‪Dim Expiration As Date‬‬
‫ٍ‬
‫بجملة كالتالية‪:‬‬ ‫ويمكنك وضع تاريخ في هذا المتغير‬
‫‪Expiration = #1/1/2003#‬‬
‫المتغير مثل‪:‬‬
‫ّ‬ ‫بل ويمكنك‪ 7‬إجراء بعض العمليات على هذا‬
‫)‪Expiration.AddYears(3‬‬
‫األول‪ ..‬هذا التاريخ الجديد يمكن تخزينه‬ ‫ٍ‬
‫تاريخ جديد‪ ،‬يزيد بثالث سنوات عن التاريخ ّ‬
‫ٌ‬ ‫العملية‬
‫ّ‬ ‫سيكون ناتج هذه‬
‫ُ‬ ‫حيث‬
‫متغير آخر كالتالي‪:‬‬
‫أي ّ‬ ‫في ّ‬
‫‪Dim NewExpiration As Date‬‬
‫)‪NewExpiration = Expiration.AddYears(3‬‬
‫تتغير قيمته‪ ،‬بعد إجراء العملية التي تقع على يمينها‪..‬‬
‫أن المتغير الذي يقع على يسار عالمة "="‪ ،‬هو فقط الذي ّ‬
‫الحظ ّ‬
‫أي أن قيم المتغيرين ستكون كما بالجدول‪:‬‬

‫قيمته بعد تنفيذ العملية‬ ‫قيمته قبل تنفيذ العملية‬ ‫المتغير‬


‫ّ‬
‫‪#1/1/2003#‬‬ ‫‪#1/1/2003#‬‬ ‫‪Expiration‬‬
‫‪#1/1/2006#‬‬ ‫‪#AM #12:00:00‬‬ ‫‪NewExpiration‬‬

‫ٍ‬
‫جملة واحدة‪ ..‬مثال‪:‬‬ ‫المتغير وتغيير‪ 7‬قيمته في‬ ‫أن بإمكانك قراءة‬
‫ّ‬ ‫كما ّ‬
‫)‪Expiration = Expiration.AddYears(3‬‬
‫يخزن التاريخ الجديد‬
‫حيث يقرأ المترجم التاريخ الموجود في المتغير ‪ ،Expiration‬ويضيف عليه ثالث سنوات‪ ،‬ثم ّ‬
‫المتغير‪ ..‬بعد تنفيذ هذه العملية‪ ،‬ستصير‪ 7‬قيمة المتغير ‪ Expiration‬هي‪.#1/1/2006# :‬‬
‫ّ‬ ‫في نفس‬
‫أن معظم الوظائف‪ 7‬التي تحتاجها للتعامل مع التواريخ و األرقام والنصوص‪ ،‬تمنحها لك اللغة‬
‫الجمي ُل في األمر‪ ،‬هو ّ‬
‫جاهزةً‪ ،‬لتريحك من عناء كتابتها من البداية‪.‬‬

‫واآلن‪ ،‬وبمنتهى البساطة‪:‬‬


‫المتغيرات لتخزين القيم‪ ،‬فإذا احتجت لمعالجة هذه القيم‪ ،‬فاكتب اسم المتغير متبوعا بنقطة "‪ ،".‬وستظهر لك‬
‫ّ‬ ‫استخدم‪7‬‬
‫قائمة تعرض لك كل خصائصه‪ ،‬وكل الدوال الجاهزة التي يمكن تطبيقها عليه‪ ،‬وفي‪ 7‬معظم الحاالت ستجد أسماءها‬
‫مرة واحدة بالفأرة أو االنزالق إليه‬
‫أي منها في القائمة (بضغطه ّ‬
‫ألن مجرد تحديد ّ‬
‫معبرةً عن وظائفها‪ ،‬باإلضافة ّ‬
‫ّ‬
‫يؤدي إلى ظهور تلميح على الشاشة‪ ،‬يشرح لك وظيفة هذا العضو‪.‬‬‫باألسهم‪ 7‬من لوحة المفاتيح)‪ّ ،‬‬

‫تعريف المتغيرات ‪Declaring Variables‬‬

‫نعرف المتغيّر‪:‬‬
‫لماذا ّ‬ ‫‪‬‬
‫بعض االختالفات عن ‪ VB6‬في التعامل مع المتغيرات‪:‬‬ ‫‪‬‬
‫الشروط الواجب توافرها عند تعريف المتغيرات‪:‬‬ ‫‪‬‬

‫نعرف المتغيّر؟‪:‬‬
‫لماذا ّ‬

‫ملحوظة‪:‬‬
‫زرا‪ ،‬وانسخ الكود‬
‫أي كود موجود‪ 7‬في أمثلة هذا الفصل‪ ،‬فأنشئ‪ 7‬تطبيقا جديدا‪ ،‬وضع على النموذج ّ‬
‫لو أردت تجربة ّ‬
‫الزر‪.‬‬
‫إلى حدث ضغط هذا ّ‬
‫أيسر بالنسبة لمترجم‪ 7‬الكود‬ ‫ّ ِ‬ ‫ِ‬
‫األمر َ‬
‫إن هذا يجعل َ‬ ‫المتغيرات أوال قب َل استخدامها‪ّ ..‬‬ ‫تعريف‬
‫ُ‪7‬‬ ‫يجب‬
‫في معظم لغات البرمجة‪ُ ،‬‬
‫ٍ‬
‫العتبارات في تنظيم الذاكرة‪،‬‬ ‫متغيرا‪ ،‬عليه أن ُينشئه في الذاكرة‪ ،‬ونتيجة‬
‫مرة يصادف المترجم ّ‬ ‫‪ ،Compiler‬ففي ك ّل ّ‬
‫مما ُيبطئ‪ 7‬البرنامج‪ ..‬ولكن لو كان المترجم‪ 7‬يعرف كل متغيرات البرنامج‬ ‫فإن مثل هذه العملية تستهلك بعض الوقت‪ّ ،‬‬
‫سيتحسن األداء ألقصى درجة‪.‬‬
‫ّ‬ ‫وأنواعها سلفا قبل أن يبدأ ترجمة البرنامج‪ ،‬ففي هذه الحالة‬
‫لقد كانت من أشهر سمات ‪ ،VB‬عدم إرغامه للمبرمج على تعريف ك ّل المتغيرات‪ ..‬لقد صارت هذه السمة منتقدةً اآلن‬
‫المتغير ُيم ّكن المترجم من‬
‫ّ‬ ‫بشد ٍة‪ ،‬ليس فقط لألسباب المتعلّقة بسرعة الترجمة وكفاءة األداء‪ ،‬ولكن أيضا ألن تعريف‬
‫ّ‬
‫اصطياد أخطاء كثير ٍة‪ ،‬سواء في وقت التصميم ‪ Design Time‬أو وقت الترجمة ‪ ،Compile Time‬بدال من أن‬
‫ك في وقت التشغيل ‪.Runtime‬‬‫تُفاجئ َ‬
‫تعرف متغيرا من النوع "تاريخ" ‪ ،:Date</span‬ال يمكن أن يسمح لك المترجم بوضع عدد صحيح‬
‫فمثال‪ :‬عندما ّ‬
‫‪ Integer‬فيه‪ ..‬أيضا لن يسمح لك المترجم باستخدام‪ 7‬خاصية "شهر"‪ Month 7‬الخاصة بالمتغيرات‪ 7‬من النوع "تاريخ"‬
‫متغير من النوع "عدد صحيح" ‪.Integer‬‬ ‫‪ ،Date‬مع ّ‬
‫المتغيرات يم ّكن المترجم‪ 7‬من اصطياد‪ 7‬مثل هذين النوعين من األخطاء‪ ،‬أثناء كتابتك للكود‪ ،‬فال تكاد تترك‬
‫ّ‬ ‫إن تعريف‬
‫متعرجا‪ ،‬لو حلّقت فوقه بالفأرة‪ ،‬فسيظهر لك تلميح على الشاشة يصف‬
‫طا ّ‬ ‫السطر الذي كتبتها به‪ ،‬حتّى يضع تحته خ ً‬
‫الخطأ الذي ارتكبته‪.‬‬
‫التلقائي‪ ،‬لن يسمح لك باستخدام المتغيرات بدون تعريف‪،‬‬
‫ّ‬ ‫فإن المترجم‪ 7‬في ‪ VB.NET‬في الوضع‬
‫لكل تلك األسباب‪ّ ،‬‬
‫إال إذا طلبت أنت ذلك منه صراحةً ـ كما سنرى فيما بعد ـ وذلك على عكس الوضع الذي كان في ‪.VB6‬‬
‫المتغير‪ ..‬وللتسهيل‪ ،‬يمكنك استخدام رموز األنواع التراثية في لغة البيزيك‪ ،‬مثل ‪ $‬التي‬
‫ّ‬ ‫مطلوب منك أيضا‪ ،‬تحديد نوع‬
‫ترمز للنصوص‪ ..‬فمثال يمكنك كتابة‪:‬‬
‫‪Dim Note$‬‬
‫نص ّي‪ ..‬ولو حلّقت بالفأرة فوق‪ 7‬هذا السطر في بيئة التطوير‪ ،‬لظهر لك تلميح على‬
‫كمتغير ّ‬
‫ّ‬ ‫المتغير ‪Note‬‬
‫ّ‬ ‫لتعريف‬
‫الشاشة مكتوب فيه التالي‪:‬‬
‫‪Dim Note As String‬‬
‫تماما‪.‬‬
‫أن الجملتين متكافئتين ً‬
‫ّمما يعني ّ‬

‫بعض االختالفات عن ‪ VB6‬في التعامل مع المتغيرات‪:‬‬


‫‪ -1‬لم يعد مسموحا‪ 7‬باستخدام‪ 7‬الدوال التي تبدأ بالمقطع ‪ ،Def‬مثل ‪ DefInt‬و ‪ ،DefDbl‬لتحديد نوع المتغير الذي‬
‫معينة‪.‬‬
‫يبدأ بحروف‪ّ 7‬‬
‫متغير‪ ..‬ففي الجملة‪:‬‬
‫متغير من نفس النوع‪ ،‬بدون تكرار‪ 7‬اسم النوع بعد كل ّ‬
‫تعرف أكثر من ّ‬‫‪ -2‬يمكنك اآلن أن ّ‬
‫‪Dim Width, Depth, Height As Integer, Area, Volume As Double‬‬
‫ومتغيرين من نوع العدد المزدوج ‪.Double‬‬
‫ّ‬ ‫تم تعريف ثالثة متغيرات من نوع العدد الصحيح ‪،Integer‬‬
‫ّ‬
‫‪ -3‬يمكنك اآلن أن تضع قيما ابتدائية للمتغيرات‪ ،‬مباشرةً في جملة التعريف‪ ..‬مثال‪:‬‬
‫‪Dim Width As Integer = 9‬‬
‫‪Dim Distance As Integer = 100, Time As Single = 9.09‬‬
‫الرقمية‪ ،‬و‬
‫ّ‬ ‫افتراضية‪ ،‬كالصفر للمتغيرات‬
‫ّ‬ ‫ابتدائية‬
‫ّ‬ ‫المتغيرات قيما‬
‫ّ‬ ‫فإن ‪ VB‬يعطي‬
‫فإذا لم تضع هذه القيم‪ّ ،‬‬
‫ولكن ذلك ليس هو الوضع مع النصوص والحروف‪ ،‬فإذا لم تستخدم‪ 7‬معها كلمة‬ ‫ّ‬ ‫المنطقية‪..‬‬
‫ّ‬ ‫للمتغيرات‬
‫ّ‬ ‫‪False‬‬
‫فإن قيمتها تكون ‪.Nothing‬‬
‫أي قيمة‪ّ ،‬‬
‫‪ New‬أو إذا لم تضع بها ّ‬

‫الشروط الواجب توافرها عند تعريف المتغيرات‪:‬‬


‫إن‬
‫األساسية (تلك التي تراها باللون األزرق)‪ ..‬مثل ‪ Sub‬و‪ For‬و ‪ If‬وغيرها‪ّ ..‬‬
‫ّ‬ ‫‪ -‬أال يكون كلمة من كلمات اللغة‬
‫الجملة التالية غير مقبولة‪:‬‬
‫‪Dim Sub As Integer‬‬
‫مصرا‪ 7‬على مثل هذا األمر‪ ،‬فيمكنك‪ 7‬أن تضع االسم بين قوسين مضلعين []‪ ..‬هذه الجملة مقبولة‪:‬‬ ‫ّ‬ ‫ولكن لو كنت‬
‫‪Dim [Sub] As Integer‬‬
‫المتغير أن تحيطه بالقوسين المضلعين‪:‬‬
‫ّ‬ ‫لكن عليك في ك ّل موضع تستخدم‪ 7‬فيه‬
‫‪[Sub] = 5‬‬
‫‪ -‬أال يزيد عن ‪ 255‬حرفًا‪ ،‬وهو رقم كبير بالفعل بما يكفي‪.‬‬
‫‪ -‬أن يتكون من كلمة واحدة ال تتخللها المسافات‪ ..‬ويمكن استخدام‪ 7‬الشرطة المنخفضة "_" للفصل بين مقاطع الكلمة‬
‫بدال من المسافات‪.‬‬
‫ينتهي بها‪.‬‬ ‫‪ -‬ال يبدأ بأرقام‪ ،‬وإ ن كان من الممكن أن تتوسطه أرقام‪ ،‬أو‬
‫َ‬
‫أي من‪ :‬عالمات التنصيص أو األقواس أو النقطة "‪ ،".‬وال عالمات العمليات الحسابية أو عالمات‬‫‪ -‬ال يحتوي على ٍ‬
‫المقارنة الحسابية أو المنطقية‪ ،‬فكل هذه العالمات محجوزة لوظائف‪ 7‬أخرى‪.‬‬
‫متغيرين متماثلين في االسم داخل نفس‬
‫المتغير داخل نفس النطاق‪ ،‬فال يمكن تعريف‪ّ 7‬‬
‫ّ‬ ‫‪ -‬غير مسموح بتكرار‪ 7‬اسم‬
‫المتغير لكن في إجراءات مختلفة‪.‬‬
‫ّ‬ ‫اإلجراء‪ ،‬وإ ن كان من الممكن تكرار‪ 7‬نفس اسم‬
‫والمتغيرات في لغة البيزيك تتجاهل حالة األحرف ‪ ،Case-insensitive‬فاألسماء‪ myAge 7‬و ‪ myage‬و‬
‫المتغير‪ ..‬معنى هذا ّأنك ال تستطيع استخدام‪ 7‬هذه الكلمات لتعريف ثالثة‬
‫ّ‬ ‫‪ ،MYAGE‬كلّها متكافئة‪ ،‬وتشير‪ 7‬لنفس‬
‫متغيرات مختلفة‪ ،‬فكلّها تُعتبر اسما واحدا‪.‬‬

‫أنواع المتغيرات ‪Types of Variables‬‬

‫تنقسم أنواع المتغيرات إلى‪:‬‬


‫المتغيرات الرقميّة‪: Numeric Variables‬‬ ‫‪‬‬
‫المتغيرات المنطقية ‪:Boolean Variables‬‬ ‫‪‬‬
‫صيّة ‪:String Variables‬‬
‫المتغيّرات النّ ّ‬ ‫‪‬‬
‫المتغيّرات الحرفيّة ‪:Character Variables‬‬ ‫‪‬‬
‫المتغيرات الزمنيّة ‪:Date Variables‬‬ ‫‪‬‬
‫المتغيّرات الكائنات ‪:Object‬‬ ‫‪‬‬
‫المتغيرات الرقميّة ‪Numeric Variables‬‬

‫أنواع المتغيّرات الرقميّة‪:‬‬ ‫‪‬‬


‫المتغيّرات من النوع وحدة الذاكرة ‪Byte‬‬ ‫‪‬‬
‫العمليات على األرقام‪:‬‬
‫ّ‬ ‫‪‬‬
‫اختبار األعداد الصحيحة‪:‬‬ ‫‪‬‬
‫اختبار األعداد العشريّة‪:‬‬ ‫‪‬‬
‫المتغيرات العشريّة ‪:The Decimal Data Type‬‬ ‫‪‬‬
‫ما ال نهاية والقيم الشاذّة األخرى ‪:Infinity And Other Oddities‬‬ ‫‪‬‬

‫أنواع المتغيّرات الرقميّة‪:‬‬


‫واضعا‬
‫ً‬ ‫تحدد النوع الذي يناسبك‪،‬‬
‫العشرية‪ ..‬وعليك أنت أن ّ‬
‫ّ‬ ‫تبعا لحجم العدد ودقّته‬
‫أنواعا عديدة‪ً ،‬‬
‫ً‬ ‫الرقمية‬
‫ّ‬ ‫إن للمتغيرات‬
‫ّ‬
‫العشرية األكبر‪ ،‬تكون العمليات عليها أبطأ من األعداد الصحيحة واألعداد ذات الدقّة‬
‫ّ‬ ‫أن األعداد ذات الدقّة‬
‫في االعتبار ّ‬
‫العشرية األق ّل‪.‬‬
‫ّ‬
‫وفي هذا الجدول‪ ،‬األنواع التي تستطيع‪ 7‬استخدامها‪ 7‬لتخزين القيم الرقمية في ‪:VB‬‬

‫حجمه بوحدات‬
‫األعداد التي يقبلها‬ ‫النوع‬
‫الذاكرة ‪Bytes‬‬
‫من ‪ 0‬إلى ‪.255‬‬ ‫‪1‬‬ ‫وحدة ذاكرة ‪Byte‬‬
‫وحدة ذاكرة ذات‬
‫من ‪ 128-‬إلى ‪.127‬‬ ‫‪1‬‬
‫إشارة ‪SByte‬‬
‫قصير‪Short 7‬‬
‫من –‪ 32768‬إلى ‪32767‬‬ ‫‪2‬‬
‫‪Int16‬‬
‫صحيح ‪Integer‬‬
‫من ‪ 2147483648-‬إلى ‪2147483647‬‬ ‫‪4‬‬
‫‪Int32‬‬
‫طويل ‪Long‬‬
‫جدا‪.‬‬
‫يقبل أرقاما كبيرة ّ‬ ‫‪8‬‬
‫‪Int64‬‬
‫العادية‪ ..‬وهو يمثّل‬
‫ّ‬ ‫لألعداد ذات الدقّة العشرية‬ ‫‪4‬‬ ‫مفرد ‪Single‬‬
‫األعداد السالبة‪ :‬من –‪ 3.402823E38‬إلى –‬
‫‪ ، 1.401298E–45‬واألعداد الموجبة من‬
‫‪ 1.401298E–45‬إلى ‪.3.402823E38‬‬
‫وفي‪ 7‬هذا النوع‪ ،‬ال يمكن تمثيل الصفر بدقّة‪ ،‬فهو‬
‫جدا جدا‪ ،‬ولكنها أبدا ليست‬
‫يمثّل دائما بقيمة صغيرة ّ‬
‫صفرا!‬
‫لألعداد ذات الدقّة العشرية الفائقة‪ ،‬وهو يستخدم في‬
‫‪8‬‬ ‫مزدوج ‪Double‬‬
‫العلمية‪.‬‬
‫ّ‬ ‫الحسابات‬
‫والعشرية‪ ،‬حيث يم ّكنك من‬
‫ّ‬ ‫لتمثيل األعداد الصحيحة‬
‫العشرية التي تريد التعامل معها‪ ،‬من ‪0‬‬
‫ّ‬ ‫تحديد الدقّة‬ ‫‪16‬‬ ‫عشري ‪Decimal‬‬
‫عشرية‪.‬‬
‫ّ‬ ‫إلى ‪ 28‬خانة‬

‫ملحوظة‪:‬‬
‫أن هذا الرقم يساوي‪7:‬‬
‫الرمز ‪ E‬في عدد مثل ‪ E –45 1.401298‬هو طريقة الكمبيوتر لتمثيل األس العشري‪ ،‬أي ّ‬
‫‪.45 - 10 × 1.40129‬‬

‫المتغيرات من النوع "وحدة الذاكرة" ‪:The Byte Data Type‬‬


‫أن الوقت قد حان لكي نعرف ما هو الـ ‪Byte‬؟‬‫تظن ّ‬
‫أال ّ‬
‫ٍ‬
‫طريقة‬ ‫أن للجهاز ذاكرةً مؤقّتة ‪ ،RAM‬ال يمكنها أن تحتفظ بالبيانات‪ ،‬إال أثناء تشغيل الجهاز‪ ..‬وأبسط‬
‫طبعا ّ‬
‫تعرف ً‬
‫ُ‬
‫تتخيل بها تركيب هذه الذاكرة‪ ،‬هي ّأنها عبارة عن مجموعة هائلة من الخانات ‪ ،Bits‬كل خانة منها يمكن شحنها‬ ‫ّ‬
‫الكهربية منها (ونرمز لها بالرقم‪ ..)0 7‬المفروض‬
‫ّ‬ ‫كهربية (ونرمز لها في هذه الحالة بالرقم ‪ ،)1‬أو تفريغ الشحنة‬
‫ّ‬ ‫بشحنة‬
‫تتكون من آحاد وأصفار‪ ،‬حيث سيقوم‬
‫ثنائية ‪ّ ،Binary‬‬
‫تحوله إلى أعداد ّ‬‫نوع من البيانات‪ ،‬أن ّ‬
‫اآلن عندما تريد تخزين ٍ‬
‫كهربية وتخزينها‪ 7‬في الذاكرة‪.‬‬
‫ّ‬ ‫الكمبيوتر‪ 7‬بتحويلها إلى شحنات‬
‫أن تمثيل األعداد في النظام الثنائي يحتاج لخانات أكثر بكثير من تلك التي يحتاجها النظام العشري‪.‬‬‫وطبعا قد الحظت‪ّ ،‬‬
‫ً‬
‫ولكن كتابة كل تلك السيول من البيانات التي يتعامل معها الكمبيوتر‪ 7‬في ك ّل ثانية خانةً بخانة سيجعل العملية بطيئة‬
‫ضم الخانات في وحدات أكبر‪ ،‬سيوفّر‪ 7‬الوقت ويجعل الجهاز أسرع‪ ..‬ولقد ساد في فترة‬ ‫أن ّ‬
‫المصنعون ّ‬
‫ّ‬ ‫جدا‪ ..‬هنا وجد‬
‫ّ‬
‫مستمرا‪ 7‬حتّى اآلن‪ ،‬حتّى بعد‬
‫ًّ‬ ‫معا‪ ،‬وأُطلق‪ 7‬عليها اسم ‪ ..Byte‬ولقد ظ ّل هذا المصطلح‬
‫ما‪ ،‬جمع كل ‪ 8‬خانات ‪ً Bits 8‬‬
‫تطور‪ 7‬األمر إلى كتابة‬
‫ثم ّ‬‫ظهور تقنيات أخرى‪ ،‬م ّكنت الجهاز من أن يكتب ويقرأ كل ‪ 16‬خانة معا كوحدة واحدة‪ّ ،‬‬
‫مستمرا‪.‬‬
‫ّ‬ ‫التطور‪7‬‬
‫ّ‬ ‫وقراءة كل ‪ 32‬خانة معا (وهذا هو السبب في اقتران الرقم ‪ 32‬باسم الويندوز)‪ ،‬وما زال‬
‫يمكنك اآلن أن تدرك السبب في ترجمتنا لكلمة ‪ Byte‬بتعبير "وحدة الذاكرة"‪.‬‬
‫جميل‪ ..‬ولكن بماذا سيفيدنا كل هذا؟‬
‫ولكن هناك حاالت أخرى‪،‬‬
‫ّ‬ ‫خزن في أكثر من وحدة من وحدات الذاكرة ‪،Bytes‬‬ ‫أن كل األنواع السابقة تُ ّ‬
‫لقد رأينا ّ‬
‫الثنائية ‪ Binary files‬وملفات الصور‬
‫ّ‬ ‫نحتاج فيها للتعامل مع وحدات منفردة ‪ ،Byte 1‬مثل التعامل مع الملفات‬
‫متغيرات من النوع ‪،Byte‬‬
‫‪ Image files‬و ملفات الصوت ‪ ..Sound files‬في مثل هذه الحاالت يمكنك استخدام ّ‬
‫حيث يمكنها أن تحمل أعدادا صحيحة موجبة‪ ،‬من ‪ 0‬إلى ‪.255‬‬
‫مالحظة‪:‬‬
‫يتم تخزينها‪7‬‬
‫لم يعد بإمكانك استخدام وحدة ذاكرة واحدة لتحمل حرفا ‪ ،Character‬فالحروف‪ 7‬من النوع ‪ّ Unicode‬‬
‫في وحدتين ‪.Two Bytes‬‬

‫ولتعريف‪ 7‬متغير من هذا النوع استخدم جملةً كالتالية‪:‬‬


‫‪Dim Var As Byte = 15‬‬

‫العمليات على األرقام‪:‬‬


‫ّ‬
‫الحسابية‪..‬‬
‫ّ‬ ‫العمليات‬
‫ّ‬ ‫جري عليها بعض‬
‫متغيرات‪ ،‬دون أن تستطيع أن تُ َ‬
‫لن تكون هناك فائدة إذا كنت ستضع األرقام‪ 7‬في ّ‬
‫األساسية‪:‬‬
‫ّ‬ ‫الحسابية‬
‫ّ‬ ‫العمليات‬
‫ّ‬ ‫وفي الجدول التالي عالمات‬

‫عالمة الجمع‪.‬‬ ‫‪+‬‬


‫عالمة الطرح‪.‬‬ ‫‪-‬‬
‫عالمة الضرب‪.‬‬ ‫*‬
‫عشرية‪ ..‬فمثال‪:‬‬
‫ّ‬ ‫عالمة القسمة‪ ..‬ويمكن أن يكون الناتج عددا صحيحا‪ 7‬أو به أرقام‬ ‫‪/‬‬
‫‪X=7/2‬‬
‫ستعطي‪ 7‬الناتج ‪.3.5‬‬
‫ولكن الناتج هو العدد الصحيح فقط‪ ..‬فمثال‪:‬‬
‫ّ‬ ‫عالمة القسمة أيضا‪،‬‬ ‫\‬
‫‪X =7\2‬‬
‫ستعطي‪ 7‬الناتج ‪.3‬‬
‫العملية باستخدام الدالة ‪ ،Int‬لو شئت أال ترتبك بين عالمتي القسمة‬
‫ّ‬ ‫ويمكن أداء نفس‬
‫المتشابهتين‪ ،‬وذلك كالتالي‪:‬‬
‫)‪X = Int (7/2‬‬
‫ولكنها تعطي الباقي من القسمة فحسب‪ ..‬فمثال‪:‬‬
‫إحدى عالمات القسمة أيضا‪ّ ،‬‬
‫‪Mod‬‬
‫‪X = 7 Mod 2‬‬
‫سيعطي‪ 7‬الناتج ‪ ،1‬الذي هو عبارة عن باقي القسمة‪.‬‬
‫رياضيا بالصيغة ‪ ،32‬وتكتب في البرمجة كالتالي‪:‬‬
‫ّ‬ ‫األس‪ ..‬فمثال ‪ 2 × 2 × 2‬تُكتب‬
‫ّ‬ ‫^‬
‫‪2^3‬‬
‫لألس (‪ )3 ÷ 1‬كالتالي‪:‬‬
‫التكعيبي مثال‪ ،‬فارفع العدد ّ‬
‫ّ‬ ‫تعبر عن الجذر‬
‫ولو أردت أن ّ‬
‫)‪2 ^ (1/3‬‬

‫العملية‬
‫ّ‬ ‫صحة إجراء‬
‫العمليات المتداخلة‪ ،‬وذلك حتّى تضمن ّ‬
‫ّ‬ ‫أهمّية وضع األقواس في‬
‫ويجب أن ألفت انتباهك إلى ّ‬
‫الحسابية يسير تبعا للقواعد التالية‪:‬‬
‫ّ‬ ‫العمليات‬
‫ّ‬ ‫الطبيعي الذي يجرى به ‪VB‬‬
‫ّ‪7‬‬ ‫إن الترتيب‬
‫بالترتيب الذي تريدها به‪ّ ..‬‬
‫يتم تنفيذ ما بين األقواس أوال‪.‬‬
‫‪ّ -‬‬
‫يتم تنفيذ األسس أوال‪.‬‬
‫‪ -‬إذا لم تكن هناك أقواس ّ‬
‫يتم تنفيذ الضرب والقسمة‪.‬‬
‫ثم ّ‬‫‪ّ -‬‬
‫يتم تنفيذ الجمع والطرح‪.‬‬
‫ثم بعد ذلك ّ‬
‫‪ّ -‬‬
‫فإن الصيغة‪:‬‬
‫لهذا ّ‬
‫)‪8^(1/3‬‬
‫التكعيبي للعدد ‪ ..8‬ولكن لو أزلت األقواس‬
‫ّ‬ ‫العملية هي الجذر‬
‫ّ‬ ‫ألن القوس ينفّذ أوال‪ ،‬فتصبح‬
‫تعطي الناتج ‪ ،2‬وذلك ّ‬
‫كالتالي‪:‬‬
‫‪8^1/3‬‬
‫العملية كالتالي‪:‬‬
‫ّ‬ ‫ألن األس ينفّذ أوال‪ ،‬فتصبح‬
‫فإن الناتج سيكون ‪ ،2.666666‬وذلك ّ‬ ‫ّ‬
‫‪8/3‬‬
‫جيدا‪.‬‬
‫فانتبه لهذا ّ‬
‫متغير بمقدار ‪ 1‬مثال؟‬
‫هام‪ ..‬ماذا لو أردت أن نزيد قيمة ّ‬
‫شيء ّ‬
‫ٌ‬ ‫بقي‬
‫في هذه الحالة سنقوم‪ 7‬بالتالي‪:‬‬
‫‪X=5‬‬
‫‪Y=X+1‬‬
‫المتغير ‪X = Y ' 6‬‬
‫ّ‬ ‫صارت قيمة‬
‫المتغير‬
‫ّ‬ ‫ثم نقلنا قيمته إلى‬
‫األصلي مع الواحد‪ّ ،‬‬
‫ّ‬ ‫المتغير‬
‫ّ‬ ‫متغير وسيط‪ ،‬جعلنا قيمته هي ناتج جمع‬
‫حيث اعتمدنا على ّ‬
‫األصلي‪.‬‬
‫المتغيرات أو إنقاصها‪ ،‬أو ضربها في‬
‫ّ‬ ‫تتكرر مرارا في البرمجة‪ ،‬حيث تحتاج مرارا لزيادة قيم‬
‫العملية ّ‬
‫ّ‬ ‫ولكن مثل هذه‬
‫ّ‬
‫رقم‪ ...‬إلخ‪.‬‬
‫مرة‪ ،‬لصارت البرمجة جحيما ال ُيطاق!‬ ‫فلو كان على المبرمج أن يكتب هذه الخطوات في ك ّل ّ‬
‫العملية في سطر واحد مباشرةً كالتالي‪:‬‬
‫ّ‬ ‫ال تقلق‪ ..‬يمكنك أداء هذه‬
‫‪X=X+1‬‬
‫ٍ‬
‫وهلة ستبدو‪ 7‬لك الصيغة غريبة‪ ،‬ولكن حاول أن تقرأها كالتالي‪ :‬قيمة ‪ X‬الجديدة تساوي قيمته القديمة ‪.1 +‬‬ ‫ألول‬
‫ّ‬
‫العمليات أيضا مباحة‪:‬‬
‫ّ‬ ‫وال يشترط أن أجمع على المتغير الرقم‪ 1 7‬فحسب‪ ،‬فهذه‬
‫‪X = X + 13‬‬
‫‪X=X+X‬‬
‫‪Y=5‬‬
‫‪X=X+Y‬‬
‫الحسابية‪:‬‬
‫ّ‬ ‫العمليات‬
‫ّ‬ ‫يمتد إلى باقي‬
‫وال يقتصر األمر على الجمع فحسب‪ ،‬بل ّ‬
‫المتغير بمقدار ‪X = X – 4 '4‬‬
‫ّ‬ ‫إنقاص‬
‫المتغير في ‪X = X * 2 ' 2‬‬
‫ّ‬ ‫ضرب‬
‫المتغير على ‪X = X / 9 ' 9‬‬
‫ّ‬ ‫قسمة‬
‫المتغير لألس ‪X = X ^ 3 ' 3‬‬
‫ّ‬ ‫رفع‬
‫تقدمه لك ‪ ،VB.Net‬عن طريق استخدام الرموز‪7‬‬
‫إضافيا ّ‬
‫ّ‬ ‫ولكن هناك تسهيال‬
‫ّ‬ ‫كان هذا هو ما اعتاده مبرمجو ‪..VB6‬‬
‫كيفية استخدامها‪:‬‬
‫‪ =+‬و ‪ ..=^ ،=/ ،=* ، =-‬والجدول التالي يريك ّ‬
‫التقليدية‬
‫ّ‬ ‫الطريقة‬ ‫الطريقة المختصرة المكافئة‬
‫‪X=X+1‬‬ ‫‪X+=1‬‬
‫‪X=X+Y‬‬ ‫‪X += Y‬‬
‫‪X=X–4‬‬ ‫‪X -= 4‬‬
‫‪X=X*2‬‬ ‫‪X *= 2‬‬
‫‪X=X/9‬‬ ‫‪X /= 9‬‬
‫‪X=X^3‬‬ ‫‪X ^= 3‬‬

‫حر في اختيار الصيغة التي تريحك‪.‬‬


‫وأنت ّ‬

‫ملحوظة‪:‬‬
‫العملية في الغالب تُعيد‬
‫ّ‬ ‫ألن هذه‬
‫أن الناتج سيكون ‪ ،Double‬وذلك ّ‬
‫عملية‪ ،‬تعتبر اللغة ّ‬
‫أي ّ‬ ‫عند استخدام األس ^ في ّ‬
‫األدق أن تكتب الصيغ التي بها أسس كالتالي‪:‬‬
‫ّ‬ ‫فإن‬
‫أرقاما‪ 7‬كبيرة‪ ..‬لهذا ّ‬
‫‪Dim X As Integer = 3‬‬
‫)‪X = CInt (X^2‬‬
‫حيث استخدمنا دالة التحويل إلى عدد صحيح ‪ ،CInt‬وذلك حتّى ال يعترض ‪ VB‬إذا كان خيار التحويل الدقيق‬
‫للعملية في هذه الحالة!‬
‫ّ‬ ‫فعاال ‪ ..Option Strict On‬ولألسف ال توجد صيغة مختصرة‬

‫اختبار األعداد الصحيحة‪:‬‬


‫خاصية "أصغر قيمة" ‪ ،MinValue‬و"أكبر‬
‫ّ‬ ‫واآلن‪ ،‬استخدم الكود التالي الختبار أنواع المتغيرات‪ ..‬ستجد ّأننا نستخدم‬
‫قيمة" ‪ ،MaxValue‬لعرض نطاق كل نوع منها‪.‬‬
‫‪Dim ShortInt As Int16‬‬
‫‪Dim Int As Int32‬‬
‫‪Dim LongInt As Int64‬‬

‫)‪Console.WriteLine(ShortInt.MinValue‬‬
‫)‪Console.WriteLine(ShortInt.MaxValue‬‬
‫)‪Console.WriteLine(Int.MinValue‬‬
‫)‪Console.WriteLine(Int.MaxValue‬‬
‫)‪Console.WriteLine(LongInt.MinValue‬‬
‫)‪Console.WriteLine(LongInt.MaxValue‬‬
‫ستتسبب في خطإ تجاوز أقصى قيمة للمتغير '‬
‫ّ‬ ‫الجملة التالية‬
‫‪ٍShortInt = ShortInt.MaxValue + 1‬‬
‫تسبب أي خطأ '‬
‫لكن الجملة التالية لن ّ‬
‫‪Int = ShortInt.MaxValue + 1‬‬
‫للمتغير '‬
‫ّ‬ ‫ستتسبب في خطإ تجاوز الحد األدنى‬
‫ّ‬ ‫الجملة التالية‬
‫‪Int = Int.MinValue – 1‬‬
‫اختبار األعداد العشريّة‪:‬‬
‫العشرية للعدد المفرد ‪:Single‬‬
‫ّ‬ ‫استخدم هذا الكود الختبار‪ 7‬الدقّة‬
‫‪Dim A As Single‬‬
‫‪A=1/3‬‬
‫)‪Console.WriteLine(A‬‬
‫ستجد أن نافذة المخرجات ‪ Output window‬ستعرض لك النتيجة التالية‪ ،0.3333333 :‬حيث تالحظ وجود ‪7‬‬
‫عشرية‪.‬‬
‫ّ‬ ‫خانات‬
‫عدل الكود للتالي‪:‬‬
‫واآلن ّ‬
‫‪Dim A As Single‬‬
‫‪A = 100000/ 3‬‬
‫)‪Console.WriteLine(A‬‬
‫إن‬
‫مما ال يمنحك الدقّة التي تريدها‪ ،‬بل ّ‬
‫عشريتين فحسب‪ّ ،‬‬
‫ّ‬ ‫أن الناتج هو ‪ ،33333.34‬حيث يحتوي‪ 7‬على خانتين‬
‫ستجد ّ‬
‫يؤدى إلى‬
‫مقربا حتّى بطريقة صحيحة‪ ،‬فالمتوقّع‪ 7‬أن يكون الناتج ‪ ..!! 33333.33‬مثل هذا الخطإ يمكن أن ّ‬
‫الرقم ليس ّ‬
‫يسمى بتراكم الخطإ ‪ ،Error Propagation‬حيث قد تنشأ أخطاء ملموسة عند إجراء مجموعة من العمليات‬
‫ما ّ‬
‫المتتابعة على األعداد المفردة‪.‬‬
‫واآلن دعنا نقوم بنفس العمليتين السابقتين‪ ،‬ولكن مع استخدام المتغير المزدوج‪:Double 7‬‬
‫‪Dim B As Double‬‬
‫‪B=1/3‬‬
‫)‪Console.WriteLine(B‬‬
‫‪B = B * 100000‬‬
‫)‪Console.WriteLine(B‬‬
‫أن شاشة المخرجات ستعرض النتيجتين كما يلي‪:‬‬
‫ستجد ّ‬
‫‪0.333333333333333‬‬
‫‪33333.3333333333‬‬
‫أن النتيجتين أكثر دقّة‪.‬‬
‫واضح طبعا ّ‬
‫العشرية‪ ،‬بين النوعين المفرد والمزدوج‪:‬‬
‫ّ‬ ‫وإ ليك مثال آخر‪ ،‬لتوضيح الفرق في دقّة تمثيل األعداد‬
‫‪Dim A As Single, B As Double‬‬
‫‪A = 0.03007‬‬
‫‪B = 0.03007‬‬
‫)‪Console.WriteLine(A - B‬‬
‫ستفاجأ بأن الناتج لن يكون صفرا‪ ،‬وبدال من ذلك ستعرض نافذة المخرجات الرقم‪:‬‬
‫‪6.03199004634014E-10‬‬
‫ولكنه‬
‫الذي يكافئ ‪ .. 0.000000000603199004634014‬واضح ّأنه رقم صغير جدا‪ ،‬بما يكفي العتباره صفرا‪ّ ،‬‬
‫ليس صفرا!‬
‫مما يجعلهما غير متماثلين‪،‬‬
‫يتم بها تمثيل المفرد والمزدوج‪ 7‬في الذاكرة‪ّ ،‬‬
‫إن ذلك الخطأ يرجع الختالف الطريقة التي ّ‬‫ّ‬
‫حتّى ولو حمال نفس الرقم!‬
‫لهذا يجب أن تحتاط للتالي‪:‬‬
‫العشرية‪.‬‬
‫ّ‬ ‫متغيرين من نوعين مختلفين في الدقّة‬‫الحسابية على ّ‬
‫ّ‬ ‫‪ -‬ال تُ ِ‬
‫جر عملياتك‬
‫العشرية بجملة كالتالية‪:‬‬
‫ّ‬ ‫‪ -‬ال تحاول مقارنة عددين من نوعين مختلفين في الدقّة‬
‫‪If A = B Then‬‬
‫ألنك لن تضمن أداء البرنامج في هذه الحالة‪ ..‬واألفضل أن تستخدم جملةً كالتالية‪:‬‬
‫ّ‬
‫‪If (A - B) < 0.000001 Then‬‬
‫معين‪ ،‬يمكنك اختياره على حسب برنامجك‪ ،‬ففي هذه الحالة يمكن‬‫حد ّ‬ ‫فلو كان الفارق بين العددين أصغر من ّ‬
‫اعتبار العددين متساويين‪.‬‬

‫المتغيرات العشريّة ‪:Decimal Data Type‬‬


‫فإن ّأول خطوة‪ ،‬هي تحويلهما إلى عددين‬
‫لو أردت أن تضرب رقمين عشريين مثل‪ّ ،12.4051 × 328.558 :‬‬
‫تتحول إلى‪ ،124051 × 328558 :‬والتي ستعطي‪ 7‬النتاج‪:‬‬
‫أن العملية ّ‬
‫أي ّ‬
‫العشرية‪ّ ..‬‬
‫ّ‬ ‫صحيحين‪ ،‬مع تذ ّكر عدد الخانات‬
‫النهائي هو ‪.4075.7948458‬‬
‫ّ‬ ‫‪ ..40757948458‬بعد ذلك نضع العالمة العشرية بعد سبع خانات‪ ،‬فيكون الناتج‬
‫نجرب ذلك‪:‬‬
‫العشرية ‪ ..Decimal‬تعال ّ‬‫ّ‬ ‫هذه هي الطريقة التي يتعامل بها ‪ VB‬مع األعداد‬
‫‪Dim A As Decimal = 328.558‬‬
‫‪Dim B As Decimal = 12.4051‬‬
‫‪Dim C As Decimal‬‬
‫‪C=A*B‬‬
‫)‪Console.WriteLine(C‬‬
‫أي أخطاء في التقريب‪ ،‬بينما لو كنت استخدمت متغيرات مفردة‬
‫الحقيقي‪ ،‬بدون ّ‬
‫ّ‬ ‫ستجد ّأنك ستحصل على الناتج‬
‫عشرية صغيرة‪.‬‬
‫ّ‬ ‫مقرب ذو دقّة‬
‫‪ Single‬كنت ستحصل على الناتج ‪ ،4075.795‬وهو ناتج ّ‬
‫أما لو كنت‬
‫العلمية‪ّ ..‬‬
‫ّ‬ ‫العشرية‪ ،‬إال ّإنك يجب أن تستخدم األعداد المزدوجة في الحسابات‬
‫ّ‬ ‫ولكن بالرغم من دقّة األرقام‪7‬‬
‫وقرب‪ 7‬الناتج ألقرب خانتين عشريتين في النهاية‪.‬‬ ‫ٍ‬
‫العشرية‪ّ ،‬‬
‫ّ‬ ‫مالية‪ ،‬فاستخدم‪ 7‬األعداد‬
‫حسابات ّ‬ ‫تجري‬

‫ما ال نهاية والقيم الشاذّة األخرى ‪:Infinity And Other Oddities‬‬


‫رقما" ‪( NaN‬التي هي اختصار لتعبير ‪ ،)Not a Number‬و "ما ال‬ ‫الرقمية القيمتين "ليس ً‬
‫ّ‬ ‫يستخدم ‪ VB‬في الحسابات‬
‫التصرف‪ 7‬المناسب‪ ،‬بدال من أن‬
‫ّ‬ ‫تم في حساباتك‪ ،‬لتتّخذ‬
‫بأن شيئا ليس على ما يرام قد ّ‬
‫نهاية" ‪ ،Infinity‬وذلك إلعالمك ّ‬
‫يعرض لك ‪ VB‬رسالة خطإ كما كان يحدث في الماضي‪.‬‬

‫ما ال نهاية ‪:Infinity‬‬


‫نص"‬
‫"حول إلى ّ‬
‫الحسابية ـ كالقسمة على صفر ـ تعطي ما ال نهاية‪ ..‬ولو استدعيت الدالة ّ‬
‫ّ‬ ‫إن بعض العمليات‬
‫ّ‬
‫‪ ToString‬على هذه القيمة‪ ،‬لكان الناتج هو النص "‪ .."Infinity‬فْلَن َر هذا المثال‪:‬‬
‫‪Dim DblVar As Double = 999‬‬
‫‪Dim InfVar As Double‬‬
‫‪InfVar = DblVar / 0‬‬
‫)‪MsgBox(InfVar.ToString‬‬
‫النص "‪ "Infinity‬في الرسالة‪.‬‬
‫ّ‬ ‫سيظهر لك‬
‫المتغير‬
‫ّ‬ ‫سبب آخر للما ال نهاية‪ ،‬هو قسمة عدد كبير ًّ‬
‫جدا على عدد صغير‪ 7‬جدا جدا‪ ،‬لدرجة تجعل الناتج يتجاوز‪ 7‬حدود‪7‬‬ ‫ٌ‬
‫جرب هذا المثال‪:‬‬
‫المزدوج‪ّ ..‬‬
‫‪Dim LargeVar As Double = 1E299‬‬
‫‪Dim SmallVar As Double = 1E-299‬‬
‫‪Dim Result As Double‬‬
‫‪Result = LargeVar / SmallVar‬‬
‫)‪MsgBox(Result‬‬
‫النص "‪ "Infinity‬في الرسالة‪.‬‬
‫ّ‬ ‫أيضا سيظهر‪ 7‬لك‬
‫أن الناتج‬
‫العملية‪ ،‬بقسمة العدد الصغير جدا على العدد الكبير جدا‪ ،‬فسيكون الناتج صفرا‪ ..‬الواقع ّ‬
‫ّ‬ ‫وإ ذا ما عكست هذه‬
‫ولكن المتغير المزدوج ال يستطيع‪ 7‬التعامل مع مثل هذه األعداد القريبة جدا من‬
‫ّ‬ ‫سيكون عددا صغيرا‪ 7‬صغيرا جدا جدا‪،‬‬
‫الصفر‪.‬‬

‫ليس رقما ‪:NaN‬‬


‫معرفا‪ :‬ليس رقما‪ ،‬وال صفرا‪ ،‬وال حتّى ما ال نهاية‪.‬‬
‫عملية ما ليس ّ‬
‫توضح أن ناتج ّ‬‫ّ‬ ‫هذه القيمة‬
‫فمثال‪ ،‬ستنتج لك هذه القيمة‪ ،‬لو حاولت أن تحسب اللوغاريتم لعدد سالب‪ ،‬أو لو حاولت أن تقسم صفرا على صفر (‬
‫جرب هذا المثال‪:‬‬
‫رياضيا‪ 7،‬وليس لهما معني‪ّ ..‬‬
‫ّ‬ ‫معرفتان‬
‫عمليتان غير ّ‬
‫‪ ،)0/0‬فهما ّ‬
‫‪Dim Var1, Var2 As Double‬‬
‫‪Dim Result As Double‬‬
‫‪Var1 = 0‬‬
‫‪Var2 = 0‬‬
‫‪Result = Var1 / Var2‬‬
‫)‪MsgBox(Result‬‬
‫فإن الناتج‬
‫جدا مثل ‪ّ ،1E-299‬‬
‫ستظهر لك رسالة تعرض النص‪ .."NaN" :‬الحظ ّأنك لو جعلت قيمة ‪ Var2‬صغيرة ّ‬
‫جدا‪ ،‬فسيكون الناتج ما ال نهاية‪.‬‬
‫سيكون صفرا‪ ..‬ولو جعلت قيمة ‪ Var1‬صغيرة ّ‬
‫فإن الناتج سيكون أيضا ‪ ..NaN‬أضف هذا‬
‫أي عملية حسابية‪ّ ،‬‬
‫متغيرا يحمل القيمة ‪ ،NaN‬في ّ‬
‫وطبعا لو استخدمت ّ‬
‫الكود للمثال السابق‪:‬‬
‫‪Result = Result + Result‬‬
‫‪Result = 10 / Result‬‬
‫‪Result = Result + 1E299‬‬
‫)‪MsgBox(Result‬‬
‫سيكون الناتج هو الرسالة "‪ "NaN‬أيضا‪.‬‬

‫اختبار وجود "ما ال نهاية" و" ليس رقما" ‪:Testing For Infinity And NaN‬‬
‫و"إنها ما ال نهاية" ‪،IsInfinity‬‬
‫ّ‬ ‫"إنه ليس رقما" ‪IsNaN‬‬
‫األمر بسيط‪ :‬للتحقّق من هاتين القيمتين‪ ،‬استخدم الدالتين‪ّ :‬‬
‫اللتين تجدهما من أعضاء المتغيرات المفردة والمزدوجة‪.‬‬
‫ولمعرفة إشارة الما ال نهاية‪ ،‬استخدم الدالتين‪" :‬إنها ما ال نهاية سالبة"‪ IsNegativeInfinity‬و" إنها ما ال نهاية‬
‫موجبة" ‪.IsPositiveInfinity‬‬
‫توضيحي‪:‬‬
‫ّ‬ ‫وإ ليك مثال‬
‫‪Dim Var1, Var2 As Double‬‬
‫‪Dim Result As Double‬‬

‫‪Var1 = 0‬‬
‫‪Var2 = 0‬‬
‫‪Result = Var1 / Var2‬‬
‫‪If Result.IsInfinity(Result) Then‬‬
‫‪If Result.IsPositiveInfinity(Result) Then‬‬
‫)"هذا رقم كبير جدا‪ ..‬ال يمكن االستمرار"(‪MsgBox‬‬
‫ما ال نهاية سالبة ' ‪Else‬‬
‫)"هذا رقم صغير جدا‪ ..‬ال يمكن االستمرار"(‪MsgBox‬‬
‫‪End If‬‬
‫‪ElseIf Result.IsNaN(Result) Then‬‬
‫)"خطأ غير متوقع في الحسابات"(‪MsgBox‬‬
‫لم يحدث أي خطأ' ‪Else‬‬
‫)‪: " & Result.ToString‬النتيجة هي"(‪MsgBox‬‬
‫‪End If‬‬

‫غيرت قيمة ‪ Var1‬إلى ‪ ،1‬فستنتج ما ال نهاية موجبة‪ ،‬ولو‬


‫هذا الكود سيعرض الرسالة "ليس برقم" ‪ ..NaN‬ولكن لو ّ‬
‫غيرتها إلى ‪ ،1-‬فستنتج ما ال نهاية سالبة‪.‬‬

‫مالحظة‪:‬‬
‫رغم أن الدوال ‪ IsInfinity‬و ‪ IsPositiveInfinity‬و‪ IsNegativeInfinity‬و ‪ IsNaN‬هي من أعضاء‬
‫المتغير ‪ ،Result‬إال ّإنها ال تنطبق عليه‪ ،‬لهذا اضطررنا‪ 7‬إلرسال المتغير ‪ Result‬كمعامل لها‪ ،‬ليتم إجراء الدالة‬
‫ّ‬
‫منطقية للتعامل مع هذه الدوا ّل‪:‬‬
‫ّ‬ ‫أن الصيغة التالية هي األكثر‬
‫عليه‪ ..‬هذا األمر يقتضي ّ‬
‫)‪System.Double.IsInfinity (Result‬‬
‫للمتغير‪.‬‬
‫ّ‬ ‫األساسية ‪Base Class‬‬
‫ّ‬ ‫الخلية‬
‫أي من هذه الدوال من خالل ّ‬ ‫وذلك بالتعامل مع ّ‬
‫مطمئن‪ ،‬كالتالي‪:‬‬
‫ّ‬ ‫ولكن الصيغة السابقة قد تبدو طويلة‪ ..‬ال تقلق‪ ..‬يمكنك أن تكتبها مختصرة وأنت‬
‫)‪Double.IsInfinity (Result‬‬

‫تعريف‪:‬‬
‫طبق على الكائن الذي تنتمي إليه (بدون إرساله كمعامل بين قوسيها)‪ ،‬هي دوال مشتركة "‬
‫الدوال التي ال تُ ّ‬
‫األساسية ‪ ،Base Class‬وذلك ما فعلناه مع الدالة ‪.IsInfinity‬‬
‫ّ‬ ‫الخلية‬
‫‪ ،"Shared‬يمكن استخدامها‪ 7‬كذلك من ّ‬
‫المتغيرات المنطقية ‪:Boolean Variables‬‬
‫تخزن واحدةً فقط من القيمتين‪" :‬صواب" ‪ True‬و"خطأ"‪ ،False 7‬وهي في األساس أعداد صحيحة‪،‬‬
‫المنطقية ّ‬
‫ّ‬ ‫المتغيرات‬
‫فالقيمة "صواب"‪ 7‬تعادل ‪ ،1-‬والقيمة "خطأ" تعادل صفرا‪ ..‬وفي الواقع‪ ،‬أي قيمة غير صفرية‪ ،‬تعتبر ‪.True‬‬
‫ويمكنك تعريف المتغيرات من هذا النوع‪ ،‬بجملة كالتالية‪:‬‬
‫‪Dim Failure As Boolean‬‬
‫المبدئية ‪.False‬‬
‫ّ‬ ‫المتغير‬
‫ّ‬ ‫ابتدائية‪ ،‬فستكون قيمة‬
‫ّ‬ ‫تحدد قيمةً‬
‫ولو لم ّ‬
‫إن ك ّل التعبيرات التالية متاحة‪:‬‬
‫المتغير ‪Failure‬؟‪ّ ..‬‬
‫ّ‬ ‫ولكن كيف نضع القيم في‬
‫‪Dim Failure As Boolean = True‬‬
‫‪Failure = False‬‬
‫منطقية ' )(‪Failure = CheckFailure‬‬
‫ّ‬ ‫دالة تعيد قيمة‬
‫عملية مقارنة‪ ،‬كالتالي‪:‬‬
‫أي ّ‬ ‫المتغير ‪ Failure‬نتيجة ّ‬
‫ّ‬ ‫الحد‪ ،‬بل يمكن أن تضع في‬
‫وال يتوقّف‪ 7‬األمر عند هذا ّ‬
‫"" = ‪Failure = TextBox1.Text‬‬
‫مرة أخرى مع وضع قوسين‪ ،‬حتّى يسهل علينا فهمه‪:‬‬ ‫أن هذا التعبير قد يكون غريبا عليك‪ ..‬تعال نعيد كتابته ّ‬
‫أعرف ّ‬
‫)"" = ‪Failure = (TextBox1.Text‬‬
‫صحة العالقة الموجودة بين القوسين‪ ،‬فإذا كانت صحيحة‪ ،‬يضع القيمة‬‫اآلن سيفعل ‪ VB‬ما يأتي‪ :‬سيتحقّق أوال من ّ‬
‫المتغير ‪.Failure‬‬
‫ّ‬ ‫المتغير ‪ ،Failure‬وإ ن كانت خاطئة‪ ،‬يضع القيمة ‪ False‬في‬ ‫ّ‬ ‫‪ True‬في‬
‫التقليدية المكافئة لها‪:‬‬
‫ّ‬ ‫أهمّية هذه الصيغة‪ ،‬تعال نكتبها بالطريقة‬
‫ولكي تدرك مدى ّ‬
‫‪If TextBox1.Text = "" Then‬‬
‫‪Failure = True‬‬
‫‪Else‬‬
‫‪Failure = False‬‬
‫‪End If‬‬
‫أن الصيغة األولى تختصر خمسة أسطر في سطر واحد فقط!‬ ‫جدا ّ‬
‫واضح ّ‬
‫النص به كلمات أم فارغا‪،‬‬
‫ّ‬ ‫مربعات‬
‫تفعل أو تمنع تفعيل أحد األزرار‪ 7،‬تبعا لما إذا كان أحد ّ‬
‫وعلى هذا‪ ،‬لو أردت أن ّ‬
‫النص‪:‬‬
‫ّ‬ ‫مربع‬
‫تغير حروف ّ‬ ‫فاكتب السطر التالي في حدث ّ‬
‫_ ‪Private Sub TextBox1_TextChanged(ByVal sender As Object, ByVal‬‬
‫‪e As System.EventArgs) Handles TextBox1.TextChanged‬‬
‫"" >< ‪Button1.Enabled = TxtElem.Text‬‬
‫‪End Sub‬‬
‫المنطقية في اختبار الشروط‪ ،‬كالتالي‪:‬‬
‫ّ‬ ‫وتُستخدم‪ 7‬المتغيرات‬
‫العملية"(‪If Failure Then MsgBox‬‬
‫ّ‬ ‫)"ال يمكن إكمال‬
‫المنطقية "و" ‪" ،AND‬أو" ‪" ، OR‬ليس" ‪،NOT‬‬
‫ّ‬ ‫منطقيين أو أكثر‪ ،‬باستخدام‪ 7‬العمليات‬
‫ّ‬ ‫ويمكن تكوين عالقة بين متغيرين‬
‫الحصرية" ‪:XOR‬‬
‫ّ‬ ‫"أو‬
‫‪" Then Exit Sub‬تجاهل الخطأ" >< ‪If Failure = True And TextBox1.Text‬‬
‫الثنائية ‪Bit‬‬
‫ّ‬ ‫العمليات‬
‫ّ‬ ‫المنطقية فقط‪ ،‬بل تستخدم‪ 7‬كذلك في‬
‫ّ‬ ‫المتغيرات‬
‫ّ‬ ‫وال تستخدم المعامالت ‪ And‬و ‪ Or‬و ‪ Not‬مع‬
‫العد الثنائي ‪ ..Binary‬عليك بقراءته في ملحق ‪.2‬‬‫لتتعرف على نظام ّ‬‫بد لك من وقفة‪ّ ،‬‬
‫‪ ..Wise Operations‬هنا ال ّ‬
‫صيّة ‪String Variables‬‬
‫المتغيّرات النّ ّ‬

‫صيّة‪:‬‬
‫تعريف المتغيّرات النّ ّ‬ ‫‪‬‬
‫تشبيك النصوص ‪:Concatenation‬‬ ‫‪‬‬
‫مقارنة النصوص‪:‬‬ ‫‪‬‬

‫صيّة‪:‬‬
‫تعريف المتغيّرات النّ ّ‬
‫يتم تعريفها كالتالي‪:‬‬
‫‪Dim SomeText As String‬‬
‫نص‪ ،‬مها كانت مكوناته (حروف‪ ،‬رموز‪ 7،‬أرقام‪ ،‬عالمات تنسيق‪ ...‬إلخ)‪ ،‬ومهما كان‬
‫أي ّ‬‫اآلن يصبح بإمكانك أن تضع ّ‬
‫طوله (يمكن أن يصل إلى ‪ 2‬جيجا بايت‪ ،‬أي ‪ 2‬مليار حرف!)‪.‬‬
‫النص ّي‪:‬‬
‫ّ‬ ‫المتغير‪7‬‬
‫ّ‬ ‫وهذه الجمل تُريك كيف تستخدم‬
‫‪Dim AString As String‬‬
‫المتغير" = ‪AString‬‬
‫ّ‬ ‫"اكتب ما تريد في هذا‬
‫نصي فارغ ' "" = ‪AString‬‬ ‫متغير ّ‬
‫المتغير نصا جديدا أطول من القديم" = ‪AString‬‬
‫ّ‬ ‫"ولكن بإمكانك أن تكتب بهذا‬
‫رقمية‪ ،‬ويمكن استخدام دوال التحويل '‬
‫ّ‬ ‫هذا نص يحتوي على قيمة‬
‫للتعامل معها كرقم وليس كنص '‬
‫"‪AString = "25000‬‬
‫النص يوضع‪ 7‬بين عالمتي تنصيص‪ ..‬وهذا بالتأكيد سيدفعك للتساؤل‪ :‬ماذا لو أردت أن أضع عالمة‬
‫ّ‬ ‫أن‬
‫طبعا الحظت ّ‬
‫متغير؟‬
‫التنصيص نفسها في ّ‬
‫في هذه الحالة يجب أن تكتب أربع عالمات تنصيص كالتالي‪:‬‬
‫"""" = ‪Dim AString As String‬‬
‫وهناك ح ّل آخر‪ ،‬هو استخدام الدالة ‪ Chr‬للتعبير عن عالمة التنصيص كالتالي‪:‬‬
‫)‪Dim AString As String = Chr(34‬‬
‫سؤال آخر سيراودك‪ :‬ما الفارق بين التعبيرين التاليين‪:‬‬
‫‪Dim ANumber As Integer = 25000‬‬
‫"‪Dim AString As String = "25,000‬‬
‫إن كال المتغيرين يحمل قيمة مختلفة عن اآلخر‪:‬‬
‫النص ّي‪ AString‬يحتوي على ستة حروف‪ ،‬وهي "‪ "2‬و "‪ "5‬و "‪ ",‬و "‪ "0‬و "‪ "0‬و "‪ ،"0‬بينما العدد‬
‫ّ‬ ‫‪ -1‬فالمتغير‬
‫الصحيح ‪ ANumber‬يحتوي‪ 7‬على رقم‪ 7‬واحد هو ‪.25000‬‬
‫الستّة في ‪12‬‬
‫النص ّي يخزن حروفه ّ‬
‫ّ‬ ‫المتغير‬
‫ّ‬ ‫‪ -2‬بما أن كل حرف يتم تخزينه في وحدتي‪ 7‬ذاكرة ‪ ،Bytes 2‬فإن‬
‫يخزن العدد الصحيح العدد ‪ 25000‬في ‪ 4‬وحدات فقط‪.‬‬ ‫وحدة ذاكرة‪ ،‬بينما ّ‬
‫المتغير‬
‫ّ‬ ‫الحسابية‪ ،‬وتستخدم‪7‬‬
‫ّ‬ ‫النص ّي ‪ AString‬في العمليات‬
‫ّ‬ ‫المتغير‪7‬‬
‫ّ‬ ‫فإن بإمكانك أن تستخدم‬
‫ولكن برغم هذه الخالفات‪ّ ،‬‬
‫صّية‪ ،‬حيث يقوم ‪ VB‬بالعمليات الالزمة للتحويل بين النوعين (ما لم تمنعه من‬ ‫الن ّ‬
‫العمليات ّ‬
‫ّ‬ ‫الرقمي ‪ ANumber‬في‬
‫ّ‬
‫القيام بذلك‪ ،‬باستخدام‪ 7‬جملة ‪.)Option Strict On‬‬

‫ملحوظة لمبرمجي ‪:VB6‬‬


‫نص ّي ذي طول ثابت ‪.Fixed-length String‬‬
‫متغير ّ‬
‫لم يعد بإمكانك تعريف ّ‬

‫تشبيك النصوص ‪:Concatenation‬‬


‫نص جديد يجمع االثنين معا؟‬‫نصين‪ ،‬بحيث ينتج ّ‬
‫ماذا لو أردت أن تلحم ّ‬
‫الرقمية‪:‬‬
‫ّ‬ ‫المتغيرات‬
‫ّ‬ ‫بسيطة‪ ..‬استخدم عالمة الجمع "‪ "+‬كما اعتدت في استخدامها‪ 7‬بين‬
‫" محمد" = ‪Dim X As String‬‬
‫"حمدي" ‪X = X +‬‬
‫"غانم " = ‪Dim Y As String‬‬
‫أعد هذا الكتاب" = ‪Y‬‬
‫‪ّ "+X+Y‬‬
‫فإن بإمكانك استخدام الصيغة المختصرة التالية‪:‬‬
‫وحتّى ال تشعر النصوص بالغيرة من األرقام‪ّ ،‬‬
‫"حمدي" =‪X +‬‬
‫الحسابي وتشبيك النصوص‪ ،‬فاستخدم‪ 7‬العالمة & بدال من‬
‫ّ‬ ‫ولو كنت تخشى من االرتباك‪ 7‬في قراءة الكود بين الجمع‬
‫العالمة ‪:+‬‬
‫" محمد" = ‪Dim X As String‬‬
‫"حمدي" & ‪X = X‬‬
‫"غانم " = ‪Dim Y As String‬‬
‫‪Y=X&Y‬‬
‫أعد هذا الكتاب" = ‪Y‬‬
‫‪ّ "&X&Y‬‬
‫وأيضا هناك صيغة مختصرة تدخل فيها العالمة & كالتالي‪:‬‬
‫"حمدي" =& ‪X‬‬

‫مقارنة النصوص‪:‬‬
‫نصين عن طريق عالمة "=" كالتالي‪:‬‬
‫يمكنك مقارنة تساوي ّ‬
‫"محمد" = ‪", Y As String‬محمد" = ‪Dim X As String‬‬
‫‪If X = Y Then‬‬
‫)"النصان متساويان"( ‪MsgBox‬‬
‫ّ‬
‫‪End If‬‬
‫نصين‪،‬‬
‫كما يمكن استخدام عالمة عدم التساوي‪( "><" 7‬وهي عبارة عن عالمة < تليها عالمة >) للتأ ّكد من اختالف ّ‬
‫كالتالي‪:‬‬
‫"أحمد" = ‪Y‬‬
‫)"النصان مختلفان"( ‪If X <> Y Then MsgBox‬‬ ‫ّ‬
‫النصين باستخدام‪ 7‬عالمتى "<" و ">" وذلك لتعرف من منهما يسبق اآلخر في الترتيب‬
‫ّ‬ ‫والطريف‪ّ 7‬أنك تستطيع مقارنة‬
‫النص األصغر‪:‬‬
‫ّ‬ ‫الهجائي هو‬
‫ّ‬ ‫يكون األسبق منهما في الترتيب‬
‫ُ‬ ‫األبجدي‪ ،‬حيث‬
‫ّ‬
‫أبجديا"(‪If Y < X Then MsgBox‬‬
‫ّ‬ ‫)"أحمد يسبق محمد‬
‫معينة أم ال‪ ..‬انظر‬
‫النص يحتوي على صيغة ‪ّ Pattern‬‬
‫ّ‬ ‫كما يمكنك استخدام المعامل "يشبه" ‪ Like‬لمعرفة إذا ما كان‬
‫للمثال التالي‪:‬‬
‫نص للتجريب" = ‪Dim S As String‬‬ ‫"هذا ّ‬
‫)"الكلمة موجودة"( ‪*" Then MsgBox‬نص*" ‪If S Like‬‬
‫ِ‬
‫الحروف مهما كانت هذه الحروف‪ ،‬ومهما كان عددها‬ ‫أي عدد من‬
‫الحظ استخدامنا للعالمة "*"‪ ،‬وهي تقوم بديال عن ّ‬
‫(يمكن أن يكون هذا العدد صفرا!)‪.‬‬
‫ٍ‬
‫واحد فقط مهما كان هذا الحرف‪ ،‬والعالمة ‪ #‬كبديل‬ ‫ٍ‬
‫لحرف‬ ‫اإلنجليزية "?" كبديل‬
‫ّ‬ ‫ويمكن استخدام عالمة االستفهام‬
‫لألرقام (من ‪ 0‬إلى ‪.)9‬‬
‫انظر لألمثلة التالية‪:‬‬
‫نص للتجريب" = ‪Dim S As String‬‬ ‫"هذا ّ‬
‫عملية التساوي '‬
‫ّ‬ ‫خاصة يكافئ‬
‫ّ‬ ‫عدم وجود عالمات‬
‫لن تظهر الرسالة ' )"الكلمة موجودة"( ‪" Then MsgBox‬هذا" ‪If S Like‬‬
‫الص '‬
‫هل كلمة "هذا" تبدأ من الحرف الثاني في ّ‬
‫لن تظهر الرسالة ' )"الكلمة موجودة"( ‪" Then MsgBox‬هذا!" ‪If S Like‬‬
‫النص '‬
‫ّ‬ ‫هل كلمة هذا هي آخر كلمة في‬
‫لن تظهر الرسالة ' )"الكلمة موجودة"( ‪" Then MsgBox‬هذا*" ‪If S Like‬‬
‫النص بكلمة هذا وينتهي بكلم للتجريب '‬
‫ّ‬ ‫هل يبدأ‬
‫ستظهر الرسالة ' )"الكلمة موجودة"( ‪" Then MsgBox‬هذا*للتجريب" ‪If S Like‬‬
‫مشدد '‬
‫حرف ّ‬
‫ٌ‬ ‫النص على حرف نون يليه‬‫ّ‬ ‫هل يحتوى‬
‫ستظهر الرسالة ' )"الكلمة موجودة"( ‪!ّ*" Then MsgBox‬ن*" ‪If S Like‬‬
‫إما‬ ‫ٍ‬
‫لنعبر عن حرف واحد من الحروف‪ 7‬الموجودة بين القوسين‪ ..‬هذه الحروف‪ّ 7‬‬
‫كما يمكن استخدام قوسين مضلّعين [ ] ّ‬
‫تعبر هذه الصيغة عن الحروف‬
‫أن تكتب متتالية مثل [‪ ،]ACdF‬وإ ّما أن تكتب على صورة مجال‪ ،‬مثل [‪ ]g-y‬حيث ّ‬
‫النص يبدأ بحرف الهاء‪ ،‬وهي محصورة بين حرفي الميم والياء‪:‬‬
‫ّ‬ ‫ألن‬
‫من ‪ g‬إلى ‪ ..y‬فمثال المقارنة التالية صحيحة‪ّ ،‬‬
‫ستظهر الرسالة ' )"الكلمة موجودة"( ‪]*" Then MsgBox‬م‪-‬ي[" ‪If S Like‬‬
‫أي حرف من تلك الموجودة بين القوسين‪ ،‬فضع في بداية القوسين عالمة‬‫النص ال يحتوي‪ 7‬على ّ‬
‫ّ‬ ‫أن‬
‫ولو أردت أن تتأ ّكد ّ‬
‫النص يبدأ بحرف الهاء‪ ،‬وهي محصورة بين حرفي الميم والياء‪،‬‬
‫ّ‬ ‫ألن‬
‫! ‪ ..‬وفي المثال التالي ستكون المقارنة خاطئة‪ّ ،‬‬
‫وهو عكس المطلوب‪:‬‬
‫لن تظهر الرسالة ' )"الكلمة موجودة"( ‪]*" Then MsgBox‬م‪-‬ي![" ‪If S Like‬‬

‫ملحوظة‪:‬‬
‫النص‪ ،‬فضعها بين قوسين مضلّعين‪،‬‬
‫ّ‬ ‫الخاصة بالمعامل ‪ Like‬في‬
‫ّ‬ ‫أي عالمة من العالمات‬
‫إذا أردت البحث عن ّ‬
‫النص‪.‬‬
‫ّ‬ ‫أي موضع من‬
‫مثل استخدام الصيغة '*[?]*' للبحث عن عالمة االستفهام اإلنجليزية في ّ‬

‫المتغيّرات الحرفيّة ‪:Character Variables‬‬


‫ألن الكمبيوتر‪ 7‬ال يعرف شيئا‬
‫تخزن فيها حرفا واحدا‪ ..‬ونظرا ّ‬ ‫متغيرات طولها وحدتا ذاكرة ‪ ،Bytes 2‬يمكن أن ّ‬ ‫هي ّ‬
‫يتم تمثيله بأرقام تد ّل عليه‪ ،‬فإن الكمبيوتر يمثّل الحروف‪ 7‬بأرقام‪ 7‬من النوع‬
‫غير األرقام‪ 7،‬وأي شيء ُيحفظ به يجب أن ّ‬
‫"عدد قصير بدون إشارة" )‪ ..Unsigned Short Integers (UInt16‬فمثال الحرف "‪ "a‬يمثّله الرقم‪.65 7‬‬
‫فإن بإمكانك تحويل األعداد الصحيحة إلى حروف‪ ،‬باستخدام‪ 7‬الدالة ‪ ،)(Chr‬وتحويل الحروف إلى أرقام‪ ،‬باستخدام‬
‫لهذا ّ‬
‫جرب ما يلي‪:‬‬
‫الدالة ‪ّ ..)(CInt‬‬
‫))"‪Console.WriteLine(CInt("a‬‬
‫ستجد أن نافذة المخرجات تعرض الرقم‪.65 7‬‬
‫حرفية‪:‬‬
‫ّ‬ ‫ويمكنك استخدام جملة كالتالية لتعريف‪ 7‬متغيرات‬
‫‪Dim Char1, Char2 As Char‬‬

‫مالحظة‪:‬‬
‫ال تستطيع مقارنة حرف بعدد مباشرة‪ ..‬فجملة كالتالية هي جملة مرفوضة‪:‬‬
‫‪If Char1 = 5 Then Char1 = 40‬‬
‫والصحيح أن تستخدم الجملة التالية‪:‬‬
‫)‪If Char1 = Chr(5) Then Char1 = Chr(40‬‬

‫نصا (في الحالة األخيرة سيتم‬


‫الحرفي عند تعريفه‪ ،‬سواء أكانت حرفا أم ّ‬
‫ّ‪7‬‬ ‫المتغير‬
‫ّ‬ ‫ابتدائيةً في‬
‫ّ‬ ‫وبإمكانك أن تضع قيمةً‬
‫جرب ما يلي‪:‬‬‫المتغير)‪ّ ..‬‬
‫ّ‬ ‫وضع أول حرف فقط في‬
‫"‪Dim Char1 As Char = "a", Char2 As Char = "ABC‬‬
‫)‪Console.WriteLine(Char1‬‬
‫)‪Console.WriteLine(Char2‬‬
‫ستجد أن شاشة المخرجات ستعرض ما يلي‪:‬‬
‫‪a‬‬
‫‪A‬‬
‫ولكن الطريقة السابقة لن تعمل إذا كان اختيار "التحويل الدقيق"‪ 7‬فعاال ‪ ،Option Strict On‬لهذا يجب استخدام الطريقة‬
‫اآلتية للتعبير عن الحروف‪:‬‬
‫‪Dim Char1 As Char = "a"c‬‬
‫بين‬
‫أن ما بين عالمتي التنصيص حرف وليس نصا‪ ..‬وفي‪ 7‬هذه الحالة يجب أن يكون ما َ‬ ‫حيث يخبر الحرف ‪ّ c، VB‬‬
‫عالمتي التنصيص حرف واحد بالضبط‪ 7،‬حيث لن يقبل ‪ VB‬جملةً كالتالية‪:‬‬
‫‪Dim Char1 As Char = "abc"c‬‬
‫أي موضع‬
‫إن وضع حرف ‪ c‬بجوار عالمتي التنصيص هو طريقة ‪ VB‬لكي يرمز للحروف‪ ،‬ويمكن استخدامها‪ 7‬في ّ‬
‫كالتالي‪:‬‬
‫‪Dim Char1 As Char = "a"c‬‬
‫‪If Char1 = "b"c Then exit sub‬‬
‫و"إنه عالمة ترقيم"‪7‬‬
‫و"إنه رقم"‪ّ IsDigit 7‬‬
‫"إنه حرف" ‪ّ IsLetter‬‬
‫الشيقة‪ ،‬مثل ّ‬
‫الحرفي يمتلك بعض الوسائل ّ‬
‫ّ‬ ‫والمتغير‬
‫ّ‬
‫‪ ...IsPunctuation‬إلخ‪.‬‬
‫جربت الجملة التالية‪:‬‬
‫فلو ّ‬
‫))"‪Console.WriteLine(Char.IsDigit("2‬‬
‫لظهر لك في نافذة المخرجات كلمة "‪."True‬‬
‫جرب أيضا ما يلي‪:‬‬
‫ّ‬
‫"‪Dim A As Char = "2‬‬
‫))‪Console.WriteLine(A.IsDigit(a‬‬
‫ستحصل على نفس النتيجة‪ ..‬طبعا يمكنك أن تالحظ أن الدالة ‪ IsDigit‬هي دالة مشتركة ‪ ،Shared‬يمكن استخدامها‬
‫األساسية ‪ ..Char Class‬بل حتّى يمكن استخدامها‪ 7‬من ّأية دالة ناتجها حرف‪..‬‬
‫ّ‬ ‫خلية النوع‬
‫من المتغير الحرفي‪ 7،‬أو من ّ‬
‫جرب المثال التالي‪:‬‬
‫ّ‬
‫"‪Dim X As String = "M2f‬‬
‫))‪Console.WriteLine(X.Chars(1).IsDigit(X, 1‬‬
‫ستحصل على نفس النتيجة‪ ،‬وهي ‪ ..True‬ولكننا نحتاج لبعض اإليضاح‪:‬‬
‫فالدالة "حروف"‪ Chars 7‬تأخذ رقم‪ 7‬الحرف الذي تريد معرفته في النص‪ ،‬وتُرجع‪ 7‬لك هذا الحرف‪ ..‬هذا مع مالحظة أن‬
‫الحرف األول في النص يوجد في الموضع رقم ‪ ..0‬إلى هنا يمكن التوقّف‪ ،‬حيث يمكن استخدام جملة كالتالية‪:‬‬
‫))‪Console.WriteLine(X.Chars(1‬‬
‫حيث سيظهر‪ 7‬لك في نافذة المخرجات ما يلي‪:‬‬
‫‪2‬‬
‫النص‪.‬‬
‫ّ‬ ‫إن "‪ "2‬هو الحرف الموجود‪ 7‬في الموضع ‪( 1‬الحرف الثاني) في‬ ‫حيث ّ‬
‫أن الدالة ‪ )(Chars‬تُرجع حرفا‪ ،‬إذن فيمكن تطبيق وسائل الحروف‪ 7‬عليها‪ ،‬كالتالي‪:‬‬ ‫ولكن بما ّ‬
‫))‪Console.WriteLine(X.Chars(1).IsDigit(X, 1‬‬
‫النص ّي ‪ ،X‬وموضع‬
‫ّ‬ ‫المتغير‬
‫ّ‬ ‫"إنه رقم" ‪ IsDigit‬كما فعلنا من قبل‪ ،‬ولكن أرسلنا لها‬
‫وتالحظ ّأننا لم نرسل حرفا‪ 7‬لدالة ّ‬
‫الحرف فيه‪ ،‬الذي نريد اختبار كونه رقما أم ال‪ ..‬وال بأس في هذا‪ ،‬فالدالة ‪ IsDigit‬لها تعريفان‪ ،‬يختلفان فقط في‬
‫نوعية المعامالت التي تقبلها الدالة‪ :‬أحدهما يمكن أن ترسل فيه معامال واحدا للدالة‪ ،‬هو الحرف الذي تريد اختباره‪،‬‬
‫واآلخر ترسل فيه معاملين للدالة‪ :‬أحد النصوص وموضع‪ 7‬الحرف المراد اختباره فيه‪.‬‬
‫مالحظة‪:‬‬
‫القدرة على تعريف أكثر من صورة للدالة تختلف في المعامالت (إما في عدد المعامالت أو في نوعها أو في‬
‫تسمى "زيادة التحميل" ‪ ،Overloading‬وسنترجمها‪ 7‬بعد ذلك "تعدد التعريفات"‪.‬‬
‫كليهما) ّ‬

‫أي ّأننا يمكن أن نكتب صيغة أخرى للجملة السابقة كالتالي‪:‬‬


‫)))‪Console.WriteLine(X.Chars(1).IsDigit(X.Chars(1‬‬
‫حيث أرسلنا الحرف للدالة‪ ..‬هذا الحرف لم نرسله مباشرة‪ ،‬بل حصلنا عليه من الدالة ‪ ..Chars‬طبعا ستبدو لك الجملة‬
‫غبية‪ ،‬لتكرار الدالة ‪ Chars‬مرتين‪ ،‬وهو ما ال ينصح به‪ ..‬معك حق‪ ،‬واألفضل أن تستخدم‪ 7‬الجملة التالية‪:‬‬
‫السابقة ّ‬
‫)))‪Console.WriteLine(Char.IsDigit(X.Chars(1‬‬
‫الحرفية‬
‫ّ‬ ‫المتغيرات‬
‫ّ‬ ‫الحرفي من أماكن أخرى غير‬
‫ّ‬ ‫المتغير‬
‫ّ‬ ‫ولكننا فقط كنا نريد توضيح قدرتك‪ 7‬على استخدام‪ 7‬وسائل‬
‫نفسها‪.‬‬

‫هامة‪:‬‬
‫قاعدة ّ‬
‫منطقي أو كائن من‬
‫ّ‬ ‫حرفي أو‬
‫ّ‬ ‫نص ّي أو‬
‫رقمي أو ّ‬
‫ّ‪7‬‬ ‫كل دالة لها قيمة معادة ‪ ،Return Value‬هذه القيمة لها نوع ما‪،‬‬
‫أي نوع‪ ..‬أبشر إذن‪ :‬بمجرد كتابة نقطة بعد قوس الدالة‪ ،‬سيظهر لك قائمة بكل خصائص ووسائل نوع القيمة‬
‫متغير‬
‫جدا‪ ،‬فلو لديك ّ‬
‫المعادة‪ ،‬حيث يمكنك استخدامها‪ 7‬مباشرة‪ ..‬مثل هذه الطريقة تم ّكنك من كتابة جمل معقّدة ّ‬
‫نص ّي مثال‪ ،‬يمكنك استدعاء إحدى دواله‪ ،‬ولتكن قيمتها‪ 7‬المعادة حرفا‪ ،‬حيث يمكنك استدعاء إحدى دوال الحروف‬
‫ّ‬
‫المنطقية‬
‫ّ‬ ‫منطقية (صواب أو خطأ)‪ ،‬حيث يمكنك استدعاء إحدى دوال المتغيرات‬
‫ّ‬ ‫منها‪ ،‬ولتكن قيمتها المعادة‬
‫منها‪ .... ،‬وهكذا‪..‬‬

‫انظر إلى الجملة التالية‪:‬‬


‫_ ‪Console.WriteLine(X.Chars(1).IsDigit(X, 0).‬‬
‫))""(‪ToString.Chars(1).IsDigit‬‬
‫تلك الجملة المكلكعة متاحة اآلن في ‪ ،VB‬وهي تطبع كلمة "‪ "False‬في شاشة المخرجات‪ ..‬هل تريد أن تفهمها؟‪ ..‬أنت‬
‫الجاني على نفسك!‬
‫النص (وهو "‬
‫ّ‬ ‫النصي ‪ ،X‬للحصول على الحرف الثاني في‬‫ّ‬ ‫بالمتغير‬
‫ّ‬ ‫في البداية نستدعي دالة "حروف"‪ Chars 7‬الخاصة‬
‫رقمي" ‪ ،IsDigit‬حيث ستنتج عنها القيمة "صواب"‪ ،True 7‬التي سنستدعي‬
‫ّ‬ ‫"إنه‬
‫‪ ..)"2‬هذا الحرف سنستدعى منه الدالة ّ‬
‫النص سنستدعي منه الدالة "حروف"‬
‫ّ‬ ‫النص "‪ .."True‬هذا‬
‫ّ‬ ‫نص" ‪ ،ToString‬لتحويلها إلى‬
‫"حول إلى ّ‬
‫منها الدالة ّ‬
‫رقمي" ‪ ،IsDigit‬حيث‬
‫ّ‬ ‫"إنه‬
‫‪ ،Chars‬لنحصل على الحرف الثاني (وهو "‪ ..)"r‬هذا الحرف سنستدعي منه الدالة ّ‬
‫سنختبر بها هل النص الفارغ "" هو رقم أم ال‪ ..‬طبعا ال‪ ..‬لهذا سيكون الناتج "خطأ" ‪!False‬‬
‫أما‬
‫يوضح اإلمكانيات الجديدة للغة‪ّ ..‬‬
‫ّ‬ ‫عبث‬
‫ولكنه ٌ‬
‫طبعا هذا نوع من العبث على غرار "من أين تصل ألذنك يا جحا؟"‪ّ ،‬‬
‫فإن كل الكلكعة السابقة يمكن اختصارها‪ 7‬إلى الجملة التالية‪:‬‬
‫الجد‪ّ ،‬‬
‫لو شئت ّ‬
‫))""(‪Console.WriteLine(Char.IsDigit‬‬
‫الدقّة‪ ..‬ومن أقصر الطرق للوصول‪ 7‬إلى أذن جحا!‬ ‫ستؤدي‪ 7‬نفس وظيفة الجملة المكلكعة السابقة بمنتهى‪ّ 7‬‬
‫ّ‬ ‫والتي‬
‫المتغيرات الزمنيّة ‪:Date Variables‬‬
‫متغيرات التاريخ والوقت بتنسيق خاص كأعداد مزدوجة‪ ،‬بحيث يمثّل العدد الصحيح التاريخ‪ ،‬ويمثّل الجزء‬
‫يتم تخزين ّ‬
‫العشري الزمن‪.‬‬
‫ّ‬
‫المتغيرات والكتابة فيه بطرق‪ 7‬كالتالية‪:‬‬
‫ّ‬ ‫ويتم تعريف‪ 7‬هذا النوع من‬
‫‪Dim Expiration As Date‬‬
‫‪Expiration = #01/01/2004#‬‬
‫‪Expiration = #8/27/2001 6:29:11 PM#‬‬
‫"‪Expiration = "July 2, 2002‬‬
‫الحاليين ' )(‪Expiration = Now‬‬
‫ّ‬ ‫‪.‬دالة "اآلن" تعطيك التاريخ والوقت‬
‫نص ّي مكتوب بين عالمتي‬
‫رقمي مكتوب بين عالمتي ‪ ،##‬أو كتاريخ ّ‬ ‫ّ‪7‬‬ ‫تالحظ ّأننا نكتب التاريخ بطريقتين‪ :‬إما كتاريخ‬
‫ضمنيا‪ 7‬في الحالة األخيرة‪ ،‬إلى تنسيق التاريخ والوقت‪ 7‬المناسب‪.‬‬
‫ّ‬ ‫تنصيص ""‪ ،‬حيث سيتم تحويله‬
‫ولتجعل األمر في غاية السهولة‪ ،‬استخدم األعضاء الخاصة بمتغيرات التاريخ والوقت‪ ،‬والتي سنناقشها في الفصل رقم‪7‬‬
‫‪ 8‬إن شاء اهلل‪.‬‬
‫أن بإمكانك استخدام‪ 7‬الدوال الجاهزة التي يمنحها لك ‪ VB‬للتعامل مع التاريخ والوقت‪ ..‬فمثال‪ :‬يمكنك استخدام الدالة‬
‫كما ّ‬
‫الزمنية التي تختارها (أيام‪،‬‬
‫ّ‬ ‫"فرق التاريخ" ‪ ،)(DateDIff‬لحساب الفرق بين تاريخين مختلفين‪ ،‬وبالوحدة‬
‫األلفية‪:‬‬
‫ّ‬ ‫األيام التي عشناها في هذه‬
‫ساعات‪ ..)... ،‬إليك هذا المثال‪ ،‬لحساب عدد ّ‬
‫‪Dim Days As Long‬‬
‫))(‪Days = DateDIff(DateInterval.Day, #12/31/2000#, Now‬‬

‫ملحوظة لمبرمجي ‪:VB6‬‬


‫الحسابية‬
‫ّ‬ ‫لم يعد باإلمكان التعامل مع متغيرات التاريخ والوقت كأرقام‪ ،‬ولم يعد ممكنا أن تستخدمها‪ 7‬في العمليات‬
‫الزمنية في المقابل‪.‬‬
‫ّ‬ ‫كالطرح والجمع‪ ،‬كما كان في الماضي‪ ،‬ولكن بإمكانك استخدام الدوال‬

‫المتغيّرات الكائنات ‪:Object‬‬


‫تعرفه‬
‫أي كائن آخر ّ‬
‫نوع من البيانات‪ ،‬سواء من األنواع السابقة‪ ،‬أو من ّ‬
‫أي ٍ‬‫الطريف في هذا النوع‪ّ ،‬أنه يستطيع تخزين ّ‬
‫تعرفه أنت‪.‬‬
‫اللغة‪ ،‬أو ّ‬
‫أي نوع من‬
‫حيث يمكنني أن أضع فيه ّ‬
‫العام‪ُ ،‬‬
‫المتغيرات إذن من هذا النوع ّ‬
‫ّ‬ ‫فألعرف كل‬
‫ّ‬ ‫ستتهلّل فرحا‪ ،‬وتهتف‪ :‬رائع‪..‬‬
‫البيانات دونما قلق!‬
‫المتغير الكائن‪،‬‬
‫ّ‬ ‫سيئة‪ ،‬فقبل أن يستخدم ‪ VB‬هذا‬‫جانبية ّ‬
‫ّ‬ ‫لألسف‪ :‬ال تبدو األمور بهذه البساطة‪ ،‬ففع ُل ذلك سيكون له آثار‬
‫ال بد له أن ِ‬
‫يعرف نوع البيانات التي به أوال‪ ،‬ليقوم بعمليات التحويل المناسبة‪ ،‬للتعامل مع هذا النوع من البيانات‪..‬‬
‫بنص آخر‪ ..‬مثل هذه‬
‫نص قبل لصقه ّ‬
‫يحوله إلى ّ‬
‫المتغير الكائن يحتوي على عدد صحيح‪ ،‬فعلى ‪ VB‬أن ّ‬ ‫ّ‬ ‫فمثال‪ ،‬لو كان‬
‫المتغير الكائن ‪ Object‬في حاالت الضرورة فحسب‪.‬‬
‫ّ‬ ‫التحويالت تمثّل عبئا على سرعة البرنامج‪ ..‬لذا فعليك استخدام‬
‫تنسيق األرقام ‪:Formatting Numbers‬‬
‫النصّية ‪ String‬بالطبع‪،‬وهي‬
‫ّ‬ ‫نص" ‪ ToString‬هي إحدى وسائل كل أنواع البيانات‪ ،‬ما عدا البيانات‬
‫"حول إلى ّ‬‫الدالة ّ‬
‫بأي تنسيق‪ 7‬تريده‪.‬‬
‫تقوم بتحويل األرقام إلى نصوص‪ّ ،‬‬
‫وكما رأيت سابقا‪ ،‬يمكنك استدعاء هذه الدالة بدون أي معامالت‪ ،‬لتحويل العدد إلى نص كما هو بدون تنسيق‪.‬‬
‫نسق العدد على شاكلتها‪.‬‬
‫تبين به الصيغة التي يجب أن ُي ّ‬
‫ولكن بإمكانك‪ 7‬أيضا أن ترسل لهذه الدالة معامال‪ّ ،‬‬
‫ّ‬
‫وفي الجدول التالي‪ ،‬ستجد كل الرموز‪ 7‬الجاهزة التي يمكن أن تستخدمها‪ 7‬في التنسيق‪:‬‬

‫الناتج‬ ‫مثال‬ ‫المعنى‬ ‫الرمز‬


‫سيتوقف الناتج على‬ ‫‪ToString("C").12345.67‬‬ ‫عملة ‪Currency‬‬ ‫‪ C‬أو ‪c‬‬
‫لغة نسخة الويندوز‪7‬‬
‫والمنطقة التي‬
‫ضبطت عمله عليها‪،‬‬
‫فلو كانت أمريكا‪،‬‬
‫فسيكون‪ 7‬الناتج ‪$‬‬
‫أما لو‬
‫‪ّ ،12,345.67‬‬
‫كانت مصر‪ ،‬فسيكون‬
‫الناتج ‪12.345,67‬‬
‫ج‪.‬م‪.‬‬
‫‪1.234567E+004‬‬ ‫علمي ‪ToString("E").12345.67 Scientific‬‬ ‫‪ E‬أو ‪e‬‬
‫‪12345.672‬‬ ‫‪.12345.6715‬‬ ‫مقربة ألقرب ‪3‬‬ ‫‪ F‬أو ‪f‬‬
‫)"‪ToString("F‬‬ ‫عشرية‬
‫ّ‬ ‫عالمات‬
‫‪Fixed-point‬‬
‫عام ‪،General‬‬
‫ّ‬ ‫‪ G‬أو ‪g‬‬
‫وهي ترجع الرقم‬
‫إما مقربا ألقرب‬
‫ّ‬
‫ثالث عالمات‬
‫عشرية‪ ،‬أو في‬
‫محدد‪.‬‬
‫تنسيق‪ّ 7‬‬
‫‪12,345.67‬‬ ‫‪ToString("N").12345.67‬‬ ‫تنسيق‪ 7‬رقم‬ ‫‪ N‬أو ‪n‬‬
‫‪Number‬‬
‫‪FA‬‬ ‫‪ToString("X").250‬‬ ‫عدد سداسي عشر‬ ‫‪ X‬أو ‪x‬‬
‫‪HexaDecimal‬‬
‫مالحظتان‪:‬‬
‫المنسق‪ ،‬فالتعبير‪.5596 7‬‬
‫ّ‬ ‫النص‬
‫ّ‬ ‫العشرية في‬
‫ّ‬ ‫‪ -1‬يمكن أن ُيتبع رمز التنسيق برقم‪ ،‬ليدل على عدد الخانات‬
‫أما التعبير‪ ToString("c3").5596.4499‬فسوف ينتج‬ ‫)"‪ ToString("c‬سوف ينتج عنه"‪ّ ،"5,596.00$‬‬
‫عنه "‪ ،"5,596.450$‬والتعبير‪ ToString("f3").)134.5( 7‬سينتج عنه "‪."134.500‬‬
‫‪ -2‬ليست كل التنسيقات قابلة للتطبيق على كل أنواع األعداد‪ ،‬فمثال‪ ،‬ال يمكن تنسيق عدد بتنسيق‪ 7‬سداسي عشري‬
‫إال إذا كان عددا صحيحا‪.‬‬

‫ولكنك قد ال تجد التنسيق الذي تريده في الرموز السابقة‪ ،‬فماذا تفعل؟‬


‫ّ‬
‫في هذه الحالة يمكنك تكوين صيغة عامة للتنسيق‪ 7‬الذي تريده‪ ،‬باستخدام الرموز التالية‪:‬‬

‫معناه‬ ‫الرمز‬
‫عشرية في هذا الموضع‪ ،‬فإذا كانت غير موجودة‪ ،‬يتم وضع صفر مكانها‪ ،‬وأنت‬ ‫ّ‬ ‫خانة‬
‫العشرية ال يؤثّر في قيمة العدد‪ ،‬فالعدد‪ 0.1 7‬هو‬
‫ّ‬ ‫أن الصفر على أقصى يمين العالمة‬
‫تعرف ّ‬ ‫‪0‬‬
‫نفسه العدد ‪.0.10‬‬
‫رقم يؤثّر‪ 7‬في قيمة العدد في هذا الموضع (مثل الجزء الصحيح من العدد)‪.‬‬ ‫‪#‬‬
‫عالمة عشرية في هذا الموضع‪.‬‬ ‫‪.‬‬
‫فاصلة في هذا الموضع‪.‬‬ ‫‪,‬‬
‫مئوية في هذا الموضع‪.‬‬
‫عالمة ّ‬ ‫‪%‬‬
‫‪E+0‬‬
‫أن العدد ‪ 12 10 × 233‬يمثّله الكمبيوتر‪7‬‬
‫ّ‬ ‫سابقا‬ ‫ذكرنا‬ ‫ولقد‬ ‫ة‪..‬‬ ‫ي‬‫أس‬
‫ّّ‬ ‫صيغة‬ ‫في‬ ‫‪7‬‬
‫م‬ ‫الرق‬ ‫لتنسيق‬ ‫‪E-0‬‬
‫‪ e+0‬كالتالي‪.233E+12 :‬‬
‫‪e-0‬‬
‫أن الجزء التالي من النص سيعرض في سطر جديد‪.‬‬
‫سطر جديد‪ ،‬بمعني ّ‬ ‫\‪n‬‬
‫لعرض نص بين عالمتي تنصيص‪.‬‬ ‫""‬

‫مثال‪:‬‬
‫))"‪MsgBox (123.4890.ToString("#.00‬‬
‫ستعرض الرسالة الرقم مقربا إلى أقرب خانتين عشريتين‪' 123.49 :‬‬
‫وسيوضحها لك األمثلة التالية‪ ،‬حيث وضعنا الناتج‬
‫ّ‬ ‫هامة‪ ،‬هي الرموز‪ 7‬المستخدمة لتنسيق‪ 7‬التواريخ‪،‬‬
‫ما زالت لدينا نقطة ّ‬
‫كتعليق بجوار‪ 7‬كل جملة‪:‬‬
‫))"‪Console.WriteLine(birthDate.ToString("d‬‬
‫‪'1/1/2000‬‬
‫))"‪Console.WriteLine(birthDate.ToString("D‬‬
‫‪'Saturday, January 01, 2000‬‬
‫))"‪Console.WriteLine(birthDate.ToString("f‬‬
‫‪'Saturday, January 01, 2000 12:00 AM‬‬
‫))"‪Console.WriteLine(birthDate.ToString("s‬‬
‫‪'2000-01-01T00:00:00‬‬
‫))"‪Console.WriteLine(birthDate.ToString("U‬‬
‫‪'Saturday, January 01, 2000 12:00:00 AM‬‬

‫ملحوظة‪:1‬‬
‫المنسق‪ ،‬يمكنك استخدام الوسيلة ‪ ،Parse‬التي تمتلكها ك ّل أنواع البيانات‬
‫ّ‬ ‫النص‬
‫ّ‬ ‫األصلي من‬
‫ّ‬ ‫الستعادة الرقم‬
‫الرقمية‪.‬‬
‫ّ‬

‫ملحوظة‪:2‬‬
‫الخاصة بـ ‪ VB6‬ما زال بإمكانك استخدامها‪ 7‬حتّى اآلن‪ ..‬هذه الدوا ّل هي‪:‬‬
‫ّ‬ ‫هناك مجموعة من دوال التنسيق‪7‬‬
‫تنسيق ‪ Format‬ـ تنسيق العملة ‪ FormatCurrency‬ـ تنسيق التاريخ والوقت‪ FormatDateTime 7‬ـ تنسيق‬
‫مهمة استكشاف هذه الدوا ّل‪ ،‬وإ ن‬
‫مئوي ‪ ..FormatPercent‬وسأترك لك ّ‬
‫ّ‬ ‫األرقام ‪ FormatNumber‬ـ تنسيق‬
‫كنت ال أرى ّأنك ستحتاج إليها أصال!‬

‫االختصارات المحدّدة لألنواع ‪:Data Type Identifiers‬‬


‫المتغير‪ ،‬إذا لصقت الرمز الخاص به في نهاية اسمه‪ ،‬مثل‪:‬‬
‫ّ‬ ‫كما ذكرنا من قبل‪ ،‬يمكنك أال تذكر نوع‬
‫‪Dim MyText$‬‬
‫المتغير‪ 7‬بعالمة الدوالر‪ $MyText 7‬أو‬
‫ّ‬ ‫نص ّي ‪ ..String‬ويمكنك بعد ذلك أن تستخدم‬
‫متغير ّ‬
‫فعالمة الدوالر ‪ $‬تدل على ّ‬
‫بدونها ‪ ،MyText‬عند كتابة الكود‪.‬‬
‫يوضح االختصارات المستخدمة مع كل نوع من المتغيرات‪:‬‬
‫ّ‬ ‫والجدول التالي‬

‫‪$‬‬ ‫نص ‪String‬‬


‫‪%‬‬ ‫عدد صحيح )‪Integer (Int32‬‬
‫&‬ ‫عدد طويل )‪Long (Int64‬‬
‫!‬ ‫عدد مفرد ‪Single‬‬
‫‪#‬‬ ‫عدد مزدوج ‪Double‬‬
‫@‬ ‫عدد عشري ‪Decimal‬‬

‫أن هناك دافعا حقيقيا يدفعك الستخدام مثل هذه االختصارات‪ ،‬إال إذا كنت من هواة إرباك نفسك!!‬
‫وال أرى ّ‬

‫الخيار "التعريف الصريح"‪: Option Explicit‬‬


‫الخلية أو قالب الكود ‪:Module‬‬
‫يمكنك أن تكتب الجملة التالية في بداية أي ملف‪ ،‬قبل تعريف النموذج أو ّ‬
‫‪Option Explicit Off‬‬
‫الملف‪ ،‬بدون أن تحتاج لتعريفها أوال‪ ..‬في هذه الحالة‬
‫ّ‬ ‫المتغيرات في هذا‬
‫ّ‬ ‫وذلك إلخبار مترجم الكود ّأنك ستستخدم‬
‫المتغيرات يمكنها أن تستوعب أي نوع من أنواع البيانات‪ ،‬لهذا سيعتبرها‪ 7‬من النوع "كائن"‬
‫ّ‬ ‫أن هذه‬
‫سيفترض المترجم ّ‬
‫تخزنها‪ 7‬فيه‪.‬‬
‫متغير‪ 7‬فيما بعد‪ ،‬تبعا لنوع البيانات التي ّ‬
‫‪ ،Object‬حيث سيقوم بتعديل نوع كل ّ‬

‫ملحوظة لمبرمجي ‪:VB6‬‬


‫"متنوع" ‪ ،Variant‬وفي المقابل يمكنك استخدام‪ 7‬المتغير من النوع‬
‫لم يعد باإلمكان استخدام المتغيرات من النوع ّ‬
‫نوع من أنواع البيانات والكائنات‪.‬‬
‫"كائن" ‪ Object‬لتخزين أي ٍ‬

‫الخيار "التحويل الدقيق" ‪:Option Strict‬‬


‫التلقائي‪ ،‬ليسمح للغة بنقل البيانات بين أنواع مختلفة دون استخدام دوال التحويل‪ ،‬ففي هذه‬
‫ّ‬ ‫هذا الخيار مغلق في الوضع‬
‫تلقائيا‪.‬‬
‫ّ‬ ‫الحالة‪ ،‬تقوم اللغة بإجراء التحويالت المناسبة‬
‫انظر هذا المثال‪:‬‬
‫"‪Dim A As String = "25000‬‬
‫عملية القسمة '‬
‫ّ‬ ‫النصي في‬
‫ّ‬ ‫انظر كيف سنستخدم المتغير‬
‫)‪Console.WriteLine(A / 2‬‬
‫وانظر أيضا هذا المثال‪ ،‬لترى كيف نجمع نصا على رقم‪:‬‬
‫‪Dim A As Double = 31.03‬‬
‫"‪A = A + "1‬‬
‫فسيوضح لك األمر تماما‪:‬‬
‫ّ‬ ‫أما هذا المثال‬
‫ّ‬
‫‪Dim I As Integer, S As String‬‬
‫‪I = 10‬‬
‫"‪S = "11‬‬
‫ستظهر القيمة ‪ 21‬في شاشة المخرجات (جمع حسابي) ' )‪Console.WriteLine(I + S‬‬
‫نصي) ' )‪Console.WriteLine(I & S‬‬
‫ستظهر القيمة ‪ 1011‬في شاشة المخرجات (جمع ّ‬

‫الملف‪:‬‬
‫ّ‬ ‫الخاصّية‪ ،‬بكتابة الجملة التالية في بداية‬
‫ّ‬ ‫ويمكنك أن توقف هذه‬
‫‪Option Strict On‬‬
‫أن خطوطا‪ 7‬متعرجة قد ظهرت ‪ ،‬لتدل على وجود خطإ كالتالي‪:‬‬
‫وبهذا لن يمكنك تنفيذ المثالين السابقين‪ ،‬حيث ستجد ّ‬
‫"خيار التحويل الدقيق يمنع التحويل التلقائي من نص إلى مزدوج" ‪Option strict disallows implicit‬‬
‫‪.conversions from String To Double‬‬
‫الرقمية‬
‫ّ‬ ‫الضمنية ستصير‪ 7‬مستحيلة‪ ،‬فما زال التحويل بين أنواع المتغيرات‬
‫ّ‬ ‫أن كل أنواع التحويالت‬‫ولكن هذا ال يعني ّ‬
‫المتغير األكبر‪ ،‬كأن تضع "عددا صحيحا"‪Integer‬‬
‫ّ‬ ‫آليا‪ ،‬ولكن في اتجاه واحد فقط‪ :‬حينما تضع المتغير األصغر‪ 7‬في‬
‫يتم ّ‬
‫في "عدد مزدوج" ‪ ..Double‬ولكن العكس ليس مسموحا به‪ ،‬كأن تحاول وضع "عدد مزدوج" ‪Double‬في "عدد‬
‫ألن هناك احتماال كبيرا أال يستوعب العدد الصحيح قيمة العدد المزدوج‪.‬‬
‫صحيح" ‪ّ ،Integer‬‬
‫المتأخر"‪ ..Late-bind 7‬أتذكر عندما كنا نبرمج أزرار‬
‫ّ‬ ‫وهناك شيء آخر سيمنعه خيار التحويل الدقيق‪ ،‬ذلك هو "الربط‬
‫األرقام في تطبيق اآللة الحاسبة في الفصل السابق؟‪ ..‬لقد كان تعريف اإلجراء المستجيب لضغط الحدث كالتالي‪:‬‬
‫_ ‪Private Sub Digit_Click(ByVal sender As System.Object,‬‬
‫_ ‪ByVal e As System.EventArgs) HAndles Bt1.Click, Bt2.Click,‬‬
‫_ ‪Bt3.Click, Bt4.Click, Bt5.Click, Bt6.Click,‬‬
‫‪Bt7.Click, Bt8.Click, Bt9.Click, Bt0.Click‬‬
‫‪End Sub‬‬
‫المتغير ‪ sender‬هو متغير عام من النوع "كائن" ‪ ،Object‬يمكن أن يستقبل أي نوع من أنواع البيانات أو‬
‫ّ‬ ‫إن‬
‫وقلنا ّ‬
‫ألننا نعرف ّأنه سيستقبل الزر المضغوط‪ ،‬فيمكننا‪ 7‬كتابة جملة من نوع‪:‬‬
‫الكائنات‪ ..‬ونظرا‪ّ 7‬‬
‫"‪sender.Text = "1‬‬
‫الخاصية ‪ ،Text‬ال يستطيع مترجم‬
‫ّ‬ ‫المتغير ‪ sender‬على ّأنه زر‪ ،‬وله‬
‫ّ‬ ‫المتأخر"‪ ،‬فبينما‪ 7‬تعامل أنت‬
‫ّ‬ ‫هذا هو "الربط‪7‬‬
‫ألن المترجم ال يقرأ الغيب‪ ،‬وال‬
‫الكود أن يستوعب هذه المعلومة إال عند محاولة تنفيذ هذه الجملة عند تشغيل البرنامج‪ّ ،‬‬
‫المتغير الذي سيستقبله المتغير العام ‪ sender‬قبل أن يستقبله بالفعل!‬
‫ّ‬ ‫يعرف ما نوع الكائن أو‬
‫لهذا عندما تكتب ‪ ،.sender‬وتظهر لك قائمة األعضاء‪ ،‬لن تجد فيها خاصية ‪ ..Text‬بل لن تجد فيها إال دالة واحدة‬
‫ألن المترجم لن‬
‫خطيرا‪ّ ،‬‬
‫ً‬ ‫استخداما‬
‫ً‬ ‫هي "اقرأ نوع الكائن" ‪ ..GetType‬لهذا فإن استخدام التعبير ‪ sender.Text‬يعتبر‬
‫يهدد بحدوث أخطاء أثناء تشغيل‬
‫مما ّ‬
‫يستطيع أن يتحقّق من قدرة الكائن على تنفيذ الجملة التي كتبتها‪ ،‬إال أثناء تنفيذها‪ّ ،‬‬
‫البرنامج وإ نهاء تشغيله‪.‬‬
‫لهذا فإن استخدام‪ 7‬خيار "التحويل الدقيق" لن يسمح بمثل هذا االستخدام‪ ،‬ويجب عليك ساعتها أن تستخدم "الربط المب ّكر"‪7‬‬
‫‪ ،Early-bind‬بتحويل نوع الكائن ‪ sender‬إلى زر‪ ،‬كالتالي‪:‬‬
‫"‪CType(sender, Button).Text = "1‬‬
‫صحة الكود قبل تشغيل البرنامج‪.‬‬
‫أي شيء يتعامل‪ ،‬ويمكنه أن يتحقّق من ّ‬
‫ففي هذه الحالة يعرف المترجم مع ّ‬

‫ملحوظة‪:‬‬
‫قلنا إن كتابة الخيارين‪:‬‬
‫‪Option Explicit Off‬‬
‫‪Option Strict On‬‬
‫تؤثّر‪ 7‬على كل ملفات‬
‫الملف‪ ..‬فماذا لو أردت أن ّ‬
‫ّ‬ ‫أي ملف من ملفات المشروع‪ 7،‬يؤثّر فقط على هذا‬
‫في بداية ّ‬
‫المشروع؟‪7‬‬
‫في هذه الحالة‪ ،‬يمكنك أن تختار هذين الخيارين من صفحات الخواص للمشروع الحالي‪ ،‬وذلك بضغط زر الفأرة‬
‫األيمن على اسم المشروع‪ 7‬في متصفّح المشاريع ‪ ،Solution Explorer‬وضغط‪" 7‬خصائص"‪ Properties 7‬من‬
‫عامة لكل المشروع‪.‬‬
‫الموضعية‪ ..‬وفي‪ 7‬هذه الحالة‪ ،‬ستكون اإلعدادات التي تختارها لهما ّ‬
‫ّ‬ ‫القائمة‬
‫التحويل بين أنواع المتغيّرات ‪:Converting Variable Types‬‬
‫متغير آلخر‪:‬‬
‫في الجدول التالي‪ ،‬ستجد الدوال التي تسمح لك بالتحويل من نوع ّ‬

‫تحول إلى‬
‫ّ‬ ‫الدالة‬
‫منطقي ‪Boolean‬‬ ‫‪CBool‬‬
‫وحدة ذاكرة ‪Byte‬‬ ‫‪CByte‬‬
‫حرف ‪Unicode character‬‬ ‫‪CChar‬‬
‫تاريخ ‪Date‬‬ ‫‪CDate‬‬
‫عدد مزدوج ‪Double‬‬ ‫‪CDbl‬‬
‫عدد عشري ‪Decimal‬‬ ‫‪CDec‬‬
‫عدد صحيح )‪Integer (Int32‬‬ ‫‪CInt‬‬
‫عدد طويل )‪Long (Int64‬‬ ‫‪CLng‬‬
‫كائن ‪Object‬‬ ‫‪CObj‬‬
‫عدد قصير‪Short (Int16) 7‬‬ ‫‪CShort‬‬
‫عدد مفرد ‪Single‬‬ ‫‪CSng‬‬
‫نص ‪String‬‬
‫ّ‬ ‫‪CStr‬‬

‫مثال‪:‬‬
‫جرب ما يلي‪:‬‬
‫لتحويل عدد صحيح إلى عدد مزدوج‪ّ ،‬‬
‫‪Dim A As Integer‬‬
‫‪Dim B As Double‬‬
‫)‪B = CDbl(A‬‬
‫فيم نحتاج ذلك؟‬
‫ولكن َ‬
‫عرفت عددين صحيحين كالتالي‪:‬‬
‫افترض ّأنك ّ‬
‫‪Dim A As Integer, B As Integer‬‬
‫‪A = 23‬‬
‫‪B=7‬‬
‫ٍ‬
‫جملة كالتالية‪:‬‬ ‫لو حاولت قسمة العددين ‪ ،23/7‬فسيكون الناتج عددا مزدوجا‪ ..‬هنا سينتج خطأ عن‬
‫‪A=A/B‬‬
‫ولكن استخدام‪ 7‬دالة التحويل‪ ،‬يمكن أن ُيخلصك من هذا الخطإ‪:‬‬
‫)‪A = CInt(A / B‬‬
‫الدقّة العشرية للناتج‪ ،‬ولو لم تكن تريد ذلك‪ ،‬فعليك أن تعرف متغيرا مزدوجا‪ 7‬تستقبل فيه‬
‫وإ ن كان الثمن هو ّأنك ستفقد ّ‬
‫الناتج‪:‬‬
‫‪Dim C As Double‬‬
‫‪C=A/B‬‬
‫تحدده لها‪ ..‬إليك هذا المثال‪:‬‬
‫العامة "تحويل النوع" ‪ ،CType‬للتحويل إلى أي نوع ّ‬
‫كما أن بإمكانك استخدام‪ 7‬الدالة ّ‬
‫"‪Dim A As String = "34.56‬‬
‫‪Dim B As Double‬‬
‫‪B = CType(A, Double) / 1.14‬‬
‫إجباري فقط في حالة عمل الخيار "التحويل‪ 7‬الدقيق"‪Option 7‬‬
‫ّ‬ ‫فإن استخدام التحويل الصريح‬
‫وكما أوضحنا‪ 7‬من قبل‪ّ ،‬‬
‫الضمني قد ُيفسد‬
‫ّ‬ ‫ألن التحويل‬
‫ولكن األفضل دائما أن تراعي دقّة التحويل أثناء كتابتك للكود‪ ،‬وذلك ّ‬
‫ّ‬ ‫‪، Strict On‬‬
‫بعض البيانات‪ ،‬مثل ما يحدث عندما تحاول وضع عدد مزدوج في عدد صحيح‪ ،‬ففي هذه الحالة ستخسر الجزء‬
‫العشري من الرقم‪ ،‬وهو ما قد ال تريده‪.‬‬
‫ّ‬

‫القيمة "ال شيء" ‪:The Nothing Value‬‬


‫المتغير ما زال فارغا لم يرتبط بكائن ما‬
‫ّ‬ ‫أن‬
‫لتوضح ّ‬
‫ّ‬ ‫تستخدم هذه القيمة مع المتغيرات من النوع "كائن" ‪،Object‬‬
‫متغير بكائن‪ ،‬فضع فيه هذه القيمة‪:‬‬
‫تدمر ارتباط‪ّ 7‬‬
‫بالفعل‪ ..‬فإذا أردت أن ّ‬
‫‪Dim B As New Button‬‬
‫}بعض الكود الذي يستخدم الزر{‬
‫‪B = Nothing‬‬

‫ملحوظة لمبرمجي ‪:VB6‬‬


‫لم يعد مطلوبا استخدام كلمة ‪ Set‬لوضع القيم في الكائنات‪ ،‬ففي الماضي كان حتميا أن تكتب‪:‬‬
‫‪Set B = Nothing‬‬
‫العادية‪:‬‬
‫ّ‬ ‫العادية‪ ،‬ويمكن وضع القيم بها باستخدام عملية التساوي‬
‫ّ‬ ‫ولكن اآلن يتم معاملة الكائنات كالمتغيرات‬
‫‪B = Nothing‬‬

‫ولو أردت أن تعرف إذا ما كان المتغير‪ 7‬مرتبطا بكائن أم ال‪ ،‬استخدم جملةً كالتالية‪:‬‬
‫‪If B Is Nothing Then Exit Sub‬‬
‫مرة أخرى‪ ،‬فاستخدم جملة كالتالية‪:‬‬ ‫المتغير بنسخة جديدة من الكائن ّ‬
‫ّ‬ ‫ولو أردت إعادة ربط هذا‬
‫‪B = New Button‬‬
‫ملحوظة‪:‬‬
‫الرقمية (العدد الصحيح ‪ ،Integer‬والمفرد‬
‫ّ‬ ‫األساسية ذات القيمة‬
‫ّ‬ ‫أي نوع من أنواع البيانات‬
‫عند تعريف متغير‪ 7‬من ّ‬
‫االفتراضية (صفر لألرقام و‬
‫ّ‬ ‫‪ ،Single‬والمزدوج ‪ ،Double‬والقيم المنطقية ‪ ..Boolean‬إلخ) فإنه يأخذ القيمة‬
‫الحرفية ‪ ،Char‬فهي‬
‫ّ‬ ‫والمتغيرات‪7‬‬
‫ّ‬ ‫النصّية ‪،String‬‬
‫ّ‬ ‫المتغيرات‬
‫ّ‬ ‫ولكن هذا ال ينطبق على‬
‫ّ‬ ‫المنطقية)‪..‬‬
‫ّ‬ ‫‪ False‬للقيمة‬
‫مما‬
‫االبتدائية ‪ّ ،Nothing‬‬
‫ّ‬ ‫فإنها تأخذ القيمة‬
‫مرجعية ‪ ،Reference Type‬لهذا ّ‬
‫ّ‬ ‫ولكنها أنواع‬
‫رقمية‪ّ ،‬‬
‫ليس أنواعا ّ‬
‫ولتنجب‬
‫ألي دالة‪ّ ..‬‬
‫أي وسيلة من وسائلها أو عند محاولة إرسالها كمعامل ّ‬‫يهدد بحدوث خطإ عند محاولة استخدام‪ّ 7‬‬
‫ّ‬
‫أي أخطاء محتملة استخدم واحدا من الحلول التالية‪:‬‬
‫ّ‬
‫نصا فارغا ""‪:‬‬
‫أي قيمة‪ ،‬حتّى لو كانت ّ‬
‫النصي أو الحرفي ضع فيه ّ‬
‫ّ‬ ‫المتغير‬
‫ّ‬ ‫‪ -‬بعد تعريف‪7‬‬
‫‪Dim X As String‬‬
‫"" = ‪X‬‬
‫ابتدائية في سطر‪ 7‬تعريفه‪:‬‬
‫ّ‬ ‫للمتغير قيمة‬
‫ّ‬ ‫‪ -‬أو ضع‬
‫"" = ‪Dim X As String‬‬
‫المتغير بنسخة جديدة بعد تعريفه‪:‬‬
‫ّ‬ ‫‪ -‬أو اربط‬
‫‪Dim X As Char‬‬
‫‪X = New Char‬‬
‫المتغير فارغة القيمة ""‪:‬‬
‫ّ‬ ‫المتغير منذ البداية‪ ،‬حتّى يرتبط بنسخة جديدة من‬
‫ّ‬ ‫‪ -‬أو استخدم كلمة ‪ New‬في تعريف‪7‬‬
‫‪Dim X As New Char‬‬

‫اختبار أنواع المتغيّرات ‪:Examining Variable Types‬‬


‫متغير وسيلتين تخبرانك بنوعه‪:‬‬
‫يمتلك ك ّل ّ‬
‫‪" -‬اقرأ النوع" ‪:)(GetType‬‬
‫المتغير‪.‬‬
‫ّ‬ ‫وهي تُرجع نوعا ‪ Type‬عبارة عن كائن يمثّل نوع‬
‫‪" -‬اقرأ كود النوع" ‪:)(GetTypeCode‬‬
‫وهي تُرجع قيمةً ترمز‪ 7‬للنوع‪ ..‬فالعدد المزدوج‪ 7‬مثال رقمه ‪.14‬‬
‫انظر للمثال التالي‪:‬‬
‫‪Dim Var As Double‬‬
‫المتغير هو"(‪Console.WriteLine‬‬
‫ّ‬ ‫)‪ " & Var.GetType.ToString‬نوع‬
‫‪If Var.GetType() Is GetType(Double) Then Exit Sub‬‬
‫المتغير‪ ،‬كما في المثال التالي‪:‬‬
‫ّ‬ ‫ويمكنك كذلك استخدام التعبير ‪ ،TypeOf ….. IS‬لمعرفة نوع‬
‫"" = ‪Dim Var As String‬‬
‫نص"(‪If TypeOf Var Is String Then MsgBox‬‬ ‫)"نوع المتغير ّ‬

‫ملحوظة‪:‬‬
‫الرقمية‪ ،‬مثل األعداد الصحيحة والمفردة‬
‫ّ‬ ‫المتغيرات‬
‫ّ‬ ‫ال يمكن استخدام‪ 7‬التعبير ‪ TypeOf ….. IS‬مع أنواع‬
‫المرجعية ‪ Reference Type‬مثل النصوص‬‫ّ‬ ‫المنطقية‪ ..‬يمكن استخدامها فقط مع األنواع‬
‫ّ‬ ‫والمزدوجة والقيم‬
‫يجب‬
‫ب من هذا االختالف‪ُ ،‬‬‫تتعج َ‬
‫والحروف والكائنات ‪ Objects‬واألنواع المشتقّة من الخاليا ‪ ..Classes‬وقب َل أن ّ‬
‫الرقمية ـ على خالف الحروف والنصوص ـ ليست في الواقع خاليا‪ ،‬بل هي عبارة عن‬‫ّ‬ ‫المتغيرات‬
‫ّ‬ ‫أن‬
‫أخبرك ّ‬
‫أن َ‬
‫سنتعرف عليها في نهاية هذا الفصل‪.‬‬
‫ّ‬ ‫يهمّنك‪..‬‬
‫تعرف ما هي السجالت؟‪ ..‬ال ّ‬
‫ُ‪7‬‬ ‫سجالت ‪ ..Structures‬ماذا؟‪ ..‬ال‬

‫نصا يمثّل اسم النوع الذي‬


‫المتغير‪ ،‬فيمكنك‪ 7‬أن تستخدم الدالة ‪ ،TypeName‬التي تُعيد ّ‬
‫ّ‬ ‫ولو أردت أن تعرف اسم نوع‬
‫المتغير‪ ..‬انظر للجمل التالية‪:‬‬
‫ّ‬ ‫ينتمي إليه‬
‫‪Dim name As Integer‬‬
‫‪Dim a As Object‬‬
‫‪Console.WriteLine(TypeName(name)) ' Integer‬‬
‫‪Console.WriteLine(TypeName(a)) ' Nothing‬‬
‫"نص ما" = ‪a‬‬
‫ّ‬
‫‪Console.WriteLine(TypeName(a)) ' String‬‬
‫وإ ذا كان التعامل مع اسم النوع ال يعجبك‪ ،‬فيمكنك التعامل معك من خالل المرقّم‪ ،VariantType 7‬وذلك عن طريق‪7‬‬
‫استخدام الدالّة ‪ ..VarType‬انظر للمثال التالي‪:‬‬
‫‪Dim X As Object‬‬
‫"‪If VarType(X) = VariantType.Empty Then X = "111‬‬
‫نصّية ‪ ...‬إلخ‪ ..‬انظر للجدول التالي‪:‬‬
‫رقمية أم ّ‬
‫نوعية البيانات‪ :‬هل هي ّ‬
‫ّ‬ ‫نوعية أخرى من الدوال‪ ،‬لمعرفة‬
‫ّ‬ ‫أن لديك‬
‫كما ّ‬

‫نصا‬
‫أي نوع‪ ،‬حتّى لو كان ّ‬
‫تُرجع "صواب" ‪ ،True‬إذا كان معاملها رقما من ّ‬ ‫رقمي"‬
‫ّ‬ ‫"إنه‬
‫ّ‬
‫يحتوي على رقم‪.‬‬ ‫‪)(IsNumeric‬‬
‫تُرجع "صواب" ‪ ،True‬إذا كان معاملها تاريخا أو وقتا‪.‬‬ ‫ّإنه تاريخ"‬
‫‪)(IsDate‬‬
‫بأي كائن‪.‬‬ ‫إنّه ال شيء"‬
‫تُرجع "صواب" ‪ ،True‬إذا كان معاملها غير مرتبط‪ّ 7‬‬
‫‪IsNothing‬‬
‫بأي كائن‪ ..‬وهذه الدالة مماثلة‬
‫تُرجع "صواب" ‪ ،True‬إذا كان معاملها غير مرتبط‪ّ 7‬‬ ‫"إنه فارغ"‬
‫ّ‬
‫"إنه فارغ"‪.)(IsNull 7‬‬
‫لدالة ‪ّ VB6‬‬ ‫‪)(IsDBNull‬‬
‫"إنه كائن"‬
‫تُرجع "صواب" ‪ ،True‬إذا كان معاملها كائنا‪ ،‬وهي مماثلة لدالة ‪ّ VB6‬‬ ‫"إنه مرجع"‬
‫ّ‬
‫‪.)(IsObject )(IsReference‬‬
‫وسنتعرف‪ 7‬على المصفوفات‪7‬‬
‫ّ‬ ‫تُرجع "صواب" ‪ ،True‬إذا كان معاملها مصفوفة‪..‬‬ ‫‪IsArray‬‬
‫الحقا في هذا الفصل‪.‬‬
‫مجال المتغيّر ‪:Variable Scope‬‬
‫المتغير واستخدامه‪.‬‬
‫ّ‬ ‫المتغير هو مقطع الكود الذي يمكن خاللَه رؤيةُ‬
‫ّ‬ ‫مجال‬
‫المتغير‪ ،‬من المقاطع التالية‪:‬‬
‫ّ‬ ‫وهذا المجال ببساطة‪ ،‬هو أصغر مقطع يوجد فيه‬
‫‪.Sub.. End Sub -‬‬
‫‪.Function.. End Function -‬‬
‫‪.If.. End If -‬‬
‫‪.For.. Next -‬‬
‫‪.Do.. Loop -‬‬
‫‪.While.. End While -‬‬
‫متغير يتم تعريفه في أحد هذه المقاطع‪ ،‬ال يمكن التعامل معه إال داخل هذا المقطع‪ ،‬هو وما ينتمي‬
‫أي ّ‬ ‫أن ّ‬
‫وهذا يعني ّ‬
‫فرعية‪ ..‬وبهذا يمكن أن يحتوى البرنامج على عشرات المتغيرات بنفس االسم (مثل المتغير ‪sender‬‬ ‫ّ‬ ‫إليه من مقاطع‬
‫ولكنها معزولة عن بعضها‪ ،‬كل في نطاقه ومجاله‪ ،‬بحيث‬
‫الذي تجده في معامل كل اإلجراءات المستجيبة لألحداث)‪ّ ،‬‬
‫تكون لك ّل منهما قيمته المستقلّة‪.‬‬
‫المتغير‬
‫ّ‬ ‫يسمى‬
‫موضعيا‪ ،Local Variable 7‬بينما ّ‬
‫ّ‬ ‫متغيرا‬
‫المعرف على مستوى‪ 7‬اإلجراء أو الدالة ّ‬
‫ّ‬ ‫المتغير‬
‫ّ‬ ‫سمى‪7‬‬
‫وي ّ‬
‫هذا‪ُ ،‬‬
‫الخلية أو‬
‫المعرفة على مستوى‪ّ 7‬‬
‫ّ‬ ‫المتغيرات‬
‫ّ‬ ‫أما‬
‫نعرفه داخل أحد المقاطع متغيرا‪ 7‬مقطعيا ‪ّ ..Block Variable‬‬
‫الذي ّ‬
‫فتسمى متغيرات مستوى القالب ‪.Module-level Variables‬‬
‫القالب‪ّ ،‬‬
‫متغير‪ 7‬يحمل االسم ‪:X‬‬
‫انظر لهذا المثال‪ ،‬والحظ كم لدينا من ّ‬
‫)(‪Sub VarDomain‬‬
‫متغير خاص بهذا اإلجراء فقط' ‪Dim I As Integer‬‬

‫‪If I = 3 Then‬‬
‫متغير خاص بجملة الشرط فقط ' ‪Dim X As Integer = 3‬‬

‫‪End If‬‬
‫‪For I = 1 To 3‬‬
‫متغير خاص بجملة التكرار "من إلى" فقط ' ‪Dim X As String‬‬

‫‪Next I‬‬
‫‪Do While I < 5‬‬
‫متغير خاص بجملة التكرار ‪:‬نفذ بينما" فقط ' ‪Dim X As Long‬‬

‫‪Loop‬‬
‫‪End Sub‬‬
‫ألن ‪I‬‬
‫متغير اسمه ‪ I‬داخل أي مقطع من مقاطع اإلجراء السابق‪ّ ،‬‬
‫أن ‪ VB‬لن يسمح لك بتعريف ّ‬ ‫ورغم هذه المرونة‪ ،‬إال ّ‬
‫المتغير الذي يحمل نفس‬
‫ّ‬ ‫موضعي سبق تعريفه على مستوى اإلجراء كلّه‪ ،‬مما سيمنعك من استخدامه مع‬
‫ّ‪7‬‬ ‫متغير‬
‫هو ّ‬
‫المتغير‬
‫ّ‬ ‫المتغير األصغر‪ 7‬يحجب‬
‫ّ‬ ‫أن‬
‫تسمى هذا األمر "التظليل" ‪ ،Shadowing‬بمعنى ّ‬
‫اسمه داخل نفس المقطع‪ّ ..‬‬
‫ألنهما يحمالن نفس االسم‪ ،‬فال يمكن استخدام‪ 7‬أكثر من واحد منهما في نفس المقطع‪.‬‬
‫األكبر‪ّ ،‬‬
‫المتغيرين الحاملين لنفس االسم قد تم تعريفه على مستوى‪ 7‬النموذج‪ ،‬واآلخر‬
‫ّ‬ ‫ولكن حدوث هذا مقبول عندما يكون أحد‬‫ّ‬
‫على مستوى‪ 7‬اإلجراء‪ ،‬ففي هذه الحالة يمكن التفريق بينهما كما في المثال التالي‪:‬‬
‫‪Public Class Form1‬‬
‫‪Inherits System.Windows.Forms.Form‬‬
‫‪Dim I As Int16 = 3‬‬

‫_ ‪Private Sub Button1_Click(ByVal sender As System.Object, ByVal e‬‬


‫‪As System.EventArgs) Handles Button1.Click‬‬
‫‪Dim I As Int16 = 5‬‬
‫هذه هي طريقة استخدام متغير مستوى النموذج'‬
‫الناتج ‪MsgBox(Me.I) ' 3‬‬
‫هذه هي طريقة استخدام متغير مستوى اإلجراء'‬
‫الناتج ‪MsgBox(I) ' 5‬‬
‫‪End Sub‬‬
‫‪End Class‬‬
‫يدمر وتزول قيمته عند‬‫يدمر فور‪ 7‬مغادرة المقطع‪ ،‬ولكن ّ‬
‫المقطعي ال ُيرى إال في مقطعه‪ ،‬إال ّإنه ال ّ‬
‫ّ‬ ‫المتغير‬
‫ّ‬ ‫أن‬
‫وبرغم ّ‬
‫المقطعي نفس‬
‫ّ‬ ‫للمتغير‬
‫ّ‬ ‫مغادرة اإلجراء الذي يحتويه‪ ،‬لهذا عند دخول المقطع مرة أخرى (قبل مغادرة اإلجراء)‪ ،‬ستكون‬
‫مرة‪ ..‬لهذا يجب مراعاة ذلك‪ ،‬حتّى ال تنتج نتائج غير متوقّعة‪.‬‬‫قيمته التي يحتفظ بها منذ مغادرة المقطع آخر ّ‬
‫المعرفة على مستوى‪ 7‬القالب‪ ،‬يمكن التعامل معها من جميع اإلجراءات والدوال المنتمية لهذا القالب‪ ،‬وهو‬
‫ّ‬ ‫والمتغيرات‬
‫ألنها ترفع قابلية الخطإ في البرنامج‪ ،‬نظرا‬
‫المتغيرات بقدر اإلمكان‪ّ ،‬‬
‫ّ‬ ‫ما يوجب عليك أن تقلّل من تعريف‪ 7‬مثل هذه‬
‫لتعدد األماكن التي يتم تغييرها فيها‪.‬‬
‫المتغيرات‪ ،‬ذلك هو مجال المشروع‪ 7‬ككل‪ ،‬حيث يمكن تعريف‪ 7‬بعض المتغيرات على‬
‫ّ‬ ‫ما زال هناك نوع من مجال‬
‫عامة ‪ Public‬لكل المشروع‪:‬‬
‫مستوى القالب أو النموذج على ّأنها ّ‬
‫‪Public GlobalVar As Integer‬‬

‫مالحظة‪:‬‬
‫ال يمكن تعريف‪ 7‬مثل هذا النوع من المتغيرات على مستوى المقطع وال على مستوى اإلجراء أو الدالة‪.‬‬

‫تمتد كذلك لألدوات‪ ،‬فلو لديك أداة على نموذج‪ ،‬وتريد التعامل معها من‬
‫وال تقتصر كلمة ‪ Public‬على المتغيرات‪ ،‬بل ّ‬
‫الخاصة بهذه األداة إلى "عام" ‪.Public‬‬
‫ّ‬ ‫خاصّية "المجال" ‪Modifier‬‬
‫ّ‬ ‫نموذج آخر‪ ،‬فيمكنك تعديل‬
‫ولكن هناك مشكلة‪ :‬استخدام المجال العام للمتغيرات‪ ،‬يجعلها قابلة لالستخدام‪ 7‬من خارج المشروع‪ 7‬نفسه‪ ،‬من أي‬
‫ّ‬
‫مشروع آخر ُيضيف مرجعا لمشروعك‪ ..‬فماذا لو لم تكن تريد حدوث ذلك؟‬
‫مرئيا في كل أجزاء المشروع‪،‬‬
‫المتغير ّ‬
‫ّ‬ ‫في هذه الحالة استخدم‪ 7‬كلمة "صديق" ‪ Friend‬بدال من ‪ ،Public‬فهي تجعل‬
‫ولكن ال يمكن استخدامه من خارجه من أي مشروع آخر‪:‬‬
‫‪Friend Var As Integer‬‬
‫عمر المتغيّر ‪:The Lifetime of a Variable‬‬
‫المتغير هو الفترة التي يحتفظ خاللها بقيمته‪.‬‬
‫ّ‬ ‫عمر‬
‫المعرفة على مستوى‪ 7‬المشروع‪ 7‬تحتفظ بقيمتها طوال تشغيل البرنامج‪.‬‬
‫ّ‬ ‫‪ -‬المتغيرات‬
‫المعرفة على مستوى النموذج‪ ،‬توجد عند تحميل النموذج ‪ ،Load‬ولو حاولت استخدامها قبل تحميل‬
‫ّ‬ ‫‪ -‬والمتغيرات‪7‬‬
‫النموذج‪ ،‬فسيتم‪ 7‬تحميل النموذج أوال‪ ..‬وعند إنهاء تحميل النموذج ‪ ،UnLoad‬تنتهي هذه المتغيرات‪ ،‬فلو أعيد‬
‫كأنما أعيد حجزها في الذاكرة من جديد‪.‬‬
‫تحميل النموذج‪ ،‬توضع بها قيمها االبتدائيّة ّ‬
‫المعرفة داخل اإلجراءات‪ ،‬تحتفظ بقيمتها إلى أن ينتهي اإلجراء‪ ،‬حيث يتم تحرير الذاكرة منها‪ ،‬فإذا‬
‫ّ‬ ‫والمتغيرات‪7‬‬
‫ّ‬ ‫‪-‬‬
‫عاد البرنامج إلى اإلجراء من جديد‪ ،‬يتم حجزها من جديد‪ ،‬ومنحها قيمها االبتدائية‪.‬‬

‫مالحظة‪:‬‬
‫ينتهي اإلجراء بإحدى ثالث جمل‪:‬‬
‫‪ :End Sub -1‬وهي النهاية الطبيعية لإلجراء‪.‬‬
‫‪ Exit Sub -2‬أو ‪ :Return‬وهي نهاية طارئة‪ ،‬تنهي اإلجراء عند حدوث سبب من األسباب‪.‬‬
‫‪ :End -3‬وهي تنهي البرنامج كلّه‪.‬‬
‫ولكن من الممكن أن يغادر ‪ VB‬اإلجراء مؤقّتا‪ ،‬نتيجة استدعاء إجراء آخر من داخله‪ ..‬في هذه الحالة يتم االحتفاظ‬
‫طبيعية‪.‬‬
‫ّ‬ ‫األول بطريقة‬
‫الفرعي‪ ،‬ويعود‪ VB 7‬لتنفيذ اإلجراء ّ‬
‫ّ‬ ‫بقيم جميع المتغيرات كما هي‪ ،‬حتّى ينتهي اإلجراء‬

‫سيدور بيننا هذا الحوار‪:‬‬


‫المتغير بعد انتهاء اإلجراء؟‬
‫ّ‬ ‫‪ -‬ولكن ماذا لو أردت أن أحتفظ بقيمة‬
‫تعرفه خارج اإلجراء‪.‬‬
‫‪ -‬يمكنك أن ّ‬
‫المتغير بمجال أكبر من المطلوب‪،‬‬
‫ّ‬ ‫المتغير إال في هذا اإلجراء‪ ،‬وأنت ح ّذرتني‪ 7‬من تعريف‪7‬‬
‫ّ‬ ‫ولكنني‪ 7‬لن أستخدم‬
‫‪ّ -‬‬
‫يتسبب في أخطاء غير متوقّعة‪.‬‬
‫حتّى ال ّ‬
‫‪ -‬آه‪ :‬عندي لك ح ّل مناسب‪.‬‬
‫‪ -‬أسعفني به‪.‬‬
‫المتغير‪ 7‬على ّأنه "ثابت القيمة" ‪ ،Static‬وبهذا سيحتفظ بقيمته حتّى بعد انتهاء اإلجراء‪،‬‬
‫ّ‬ ‫تعرف‬
‫إن بإمكانك أن ّ‬ ‫‪ّ -‬‬
‫موضعيا‪ ،‬ال يمكن التعامل معه من خارج اإلجراء‪.‬‬
‫ّ‬ ‫رغم ّأنه ما زال‬
‫‪ -‬يا بن اإليه!‬
‫‪ -‬هذه هي صيغة التعريف‪:‬‬
‫‪Static X As Integer = 3‬‬
‫يدمر قيمته القديمة؟‬
‫مما ّ‬
‫يتم فيها استدعاء اإلجراء‪ّ ،‬‬
‫مرة ّ‬
‫االبتدائية ‪ ،3‬في ك ّل ّ‬
‫ّ‬ ‫‪ -‬ولكن‪ :‬ألن توضع به القيمة‬
‫مرة يتم تعريفه فيها فقط‪ ،‬بعد ذلك سيحتفظ بقيمته‬
‫المتغير‪ ،‬إال في ّأول ّ‬
‫ّ‬ ‫االبتدائية ال توضع في‬
‫ّ‬ ‫‪ -‬ال‪ ،‬فهذه القيمة‬
‫مرة أخرى‪.‬‬
‫التي كانت به قبل مغادرة اإلجراء‪ ،‬ليمكنك استخدامها عندما تعود لإلجراء ّ‬
‫االبتدائية من جديد‪ ،‬لسبب أو آخر؟‬
‫ّ‬ ‫‪ -‬جميل‪ ..‬ولكن ماذا لو أردت أن أجعله يعود لقيمته‬
‫‪ -‬سؤا ٌل وجيه‪ ..‬لألسف‪ ..‬ال توجد وسيلة مباشرةٌ لفعل هذا من خارج اإلجراء‪ ..‬ولكن يمكن التحايل على ذلك‪،‬‬
‫األصلية‪ ..‬انظر‬
‫ّ‬ ‫المتغيرات ثابتة القيمة ‪ Static‬إلى قيمها‬
‫ّ‬ ‫مهمته إخبار اإلجراء بإعادة‬
‫بتعريف‪ 7‬معامل لإلجراء‪ّ ،‬‬
‫لخلية النموذج‪ ،‬قبل جملة ‪ End Class‬مباشرةً‪:‬‬
‫لهذا المثال‪ ..‬أضف اإلجراء التالي ّ‬
‫)‪Sub ShowMessage(InitializeStatics As Boolean‬‬
‫" رقم" = ‪Static X As Integer = 3, Y As String‬‬
‫‪If InitializeStatics = True Then‬‬
‫‪X=3‬‬
‫"علي" = ‪Y‬‬
‫‪End If‬‬
‫‪X+=1‬‬
‫)‪Y += Str(I‬‬
‫)‪MsgBox(Y‬‬
‫‪End Sub‬‬
‫زرا على النموذج واكتب فيه ما يلي‪:‬‬
‫واآلن ضع ّ‬
‫"ستظهر الرسالة "رقم ‪ShowMessage (False) ' 1‬‬
‫"ستظهر الرسالة "رقم ‪ShowMessage (False) ' 12‬‬
‫"ستظهر الرسالة "رقم ‪ShowMessage (False) ' 123‬‬
‫"ستظهر الرسالة "رقم ‪ShowMessage (False) ' 1234‬‬
‫يتم زيادتها في ك ّل استدعاء‪ ..‬ولكن لو‬
‫المتغيرين يحتفظ بقيمته‪ ،‬التي ّ‬
‫ّ‬ ‫ألن كال من‬
‫تالحظ تصاعد رقم الرسالة‪ ،‬وذلك ّ‬
‫جربت االستدعاءات التالية بعد االستدعاءات السابقة‪:‬‬
‫ّ‬
‫"ستظهر الرسالة "رقم ‪ShowMessage (True) ' 1‬‬
‫ستظهر الرسالة "رقم ‪ "1‬أيضا ' )‪ShowMessage (True‬‬
‫ستظهر الرسالة "رقم ‪ "1‬أيضا ' )‪ShowMessage (True‬‬
‫المتغيرين ثابتي القيمة إلى قيمتيهما‬
‫ّ‬ ‫مرة نطلب من اإلجراء إعادة‬
‫ألننا في ك ّل ّ‬
‫فستالحظ ثبات نتيجة الرسالة‪ ،‬وذلك ّ‬
‫االبتدائية‪.‬‬
‫ّ‬
‫وستجد المزيد التفاصيل حول تعريف اإلجراءات ومعامالتها‪ ،‬في للفصل التالي‪.‬‬

‫الثوابت ‪:Constants‬‬
‫عرف الثوابت؟‬
‫ون ّ‬
‫ف ُ‬ ‫المتغيرات‪ ،‬فلماذا ال ِ‬
‫نعر ُ‬ ‫ّ‬ ‫وعرفنا‬
‫عرفنا ّ‬ ‫َ‬
‫ولكن هذه القيمة ال‬
‫ّ‬ ‫كالمتغيرات‪،‬‬
‫ّ‬ ‫سيقال هنا‪ :‬هذا نوع من مخازن الذاكرة‪ ،‬توضع فيه قيمة‪ ،‬تماما‬ ‫يبدو ّأنك قد فهمت ما ُ‬
‫فهمت بالضبط‪ 7‬ما هي الثوابت!‬
‫َ‬ ‫يمكن تغييرها‪ 7‬بعد ذلك‪ ،‬وستظ ّ‪7‬ل ثابتة طوال البرنامج‪ ..‬مرحى‪ :‬لقد‬
‫وهذه طريق‪ 7‬تعريفها‪:‬‬
‫‪Const MyValue = 10‬‬
‫نعرف‪ 7‬مثل هذه الثوابت؟‬
‫ولكن لماذا ّ‬
‫بمجرد‬
‫ّ‬ ‫فإنها تم ّكنك من تغيير الكثير من الحسابات‬
‫المتغيرات‪ّ ،‬‬
‫ّ‬ ‫أهمّية كبيرة‪ ..‬فبخالف ّأنها تُنفّذ أسرع من‬
‫إن لذلك ّ‬
‫ّ‬
‫متفرقة من‬
‫حسابية في مواضع ّ‬‫ّ‬ ‫عملية‬
‫المتغير ‪ MyValue‬في ثالثين ّ‬ ‫ّ‬ ‫تغيير جملة واحدة‪ ..‬افترض ّأنك تستخدم‬
‫أن القيمة ‪ 10‬غير مناسبة‪ ،‬فكل ما عليك هو تغييرها‪ 7‬في جملة التعريف‪ ،‬ليتم تعديل كل‬
‫التطبيق‪ ..‬اآلن لو اكتشفت ّ‬
‫الحسابية الثالثين دفعة واحدة‪:‬‬
‫ّ‬ ‫العمليات‬
‫‪Const MyValue = 15‬‬
‫تتخيل حجم المأساة‪ ،‬لو كنت تستخدم العدد ‪ 10‬مباشرةً في حسابات العمليات الثالثين!!‪ ..‬في هذه الحالة‬
‫ولكن حاول أن ّ‬
‫عملية شاقّة!‬
‫كلّما اكتشفت حاجتك لتغيير هذه القيمة‪ ،‬فعليك البحث عن هذه الجمل واستبدالها‪ ..‬يا لها من ّ‬
‫تحدد نوع الثابت لمترجم الكود‪ ،‬كما يلي‪:‬‬
‫ويمكن أن ّ‬
‫"اسمي هو محمد" = ‪Const MyValue As String‬‬
‫تحدد مجال الثابت‪ ،‬بكلمة من الكلمات‪ Public :‬أو ‪ Private‬أو ‪:Friend‬‬ ‫كما يمكن أن ّ‬
‫‪Public Const MyValue As Integer = 15‬‬
‫ومسموح لك باستخدام‪ 7‬الثوابت في تعريف ثوابت أخرى‪ ،‬فمثال‪ :‬يمكن استخدام التعبير التالي لتعريف‪ 7‬ثابت يحتوي على‬
‫التقريبية "ط"‪:‬‬
‫ّ‬ ‫النسبة‬
‫‪Const Pi = Math.Pi‬‬
‫‪Const Pi2 = 2 * Pi‬‬
‫ولكن ليس مسموحا‪ 7‬لك باستخدام الدوال في تعريف الثوابت‪ ،‬فمثال‪ :‬التعريف‪ 7‬التالي غير مسموح به‪:‬‬
‫)‪Const Pi = Math.Log(Math.Pi‬‬
‫ملحوظة‪:‬‬
‫الدائرية‪ Circular Declaration‬عند تعريف ثوابت بثوابت أخرى‪ ..‬فمثال عند‬
‫ّ‬ ‫حاول أال تقع في التعريفات‬
‫تعريف‪:‬‬
‫‪Const Pi = Pi2 / 2‬‬
‫‪Const Pi2 = 2 * Pi‬‬
‫فأي منهما لن تكون له قيمة بدون اآلخر‪،‬‬
‫ستجد أن كال من التعريفين معتمد على اآلخر‪ ،‬بطريقة ليس لها معنى‪ّ ،‬‬
‫مما سيجعل المترجم‪ 7‬يعرض رسالة خطإ‪.‬‬ ‫ّ‬

‫المصفوفات ‪Arrays‬‬

‫ما هي المصفوفة‪:‬‬ ‫‪o‬‬


‫وضع القيم االبتدائيّة للمصفوفات ‪:Initializing Arrays‬‬ ‫‪o‬‬
‫حدود المصفوفة ‪:Array Limits‬‬ ‫‪o‬‬
‫المصفوفة متعدّدة األبعاد ‪:Multidimensional Arrays‬‬ ‫‪o‬‬
‫المصفوفات المرنة ‪:Dynamic Arrays‬‬ ‫‪o‬‬
‫مصفوفة المصفوفات ‪:Arrays of Arrays‬‬ ‫‪o‬‬
‫مشروع المصفوفات‪:‬‬ ‫‪o‬‬
‫ما هي المصفوفة‪:‬‬
‫المتكررة آلالف أو ماليين‬
‫ّ‬ ‫صنع الكمبيوتر‪ 7‬أساسا‪ ،‬ليقوم بالعمليات الرتيبة‬
‫الحقيقية تبدأ من هذه النقطة‪ ،‬فلقد ُ‬
‫ّ‬ ‫البرمجة‬
‫ٍ‬
‫بسرعة وبدون ملل‪.‬‬ ‫المرات‪،‬‬
‫ّ‬
‫متغيرا وتجمعها‬
‫تعرف خمسين ّ‬ ‫افترض مثال ّأنك تريد حساب متوسط‪ 7‬العمر لخمسين طالبا‪ّ ..‬أول ما ستف ّكر فيه‪ ،‬هو أن ّ‬
‫إن مثل هذه الطريقة ستستهلك منك شهرا على األق ّل لكتابتها‪ ،‬وهي كفيلة بجعلك تكره‬
‫معا وتقسم الناتج على ‪ّ ..50‬‬
‫البرمجة على بكرة أبيها!‬
‫تخيل!‬
‫مع ّأنك تستطيع أن تكتب هذا البرنامج في خمس سطور‪ 7‬ال غير‪ّ ..‬‬
‫آلية رتيبة‬
‫والفكرة كلّها تعتمد على تخزين أعمار الطلبة في "تركيب ما"‪ ،‬يمكن للكمبيوتر‪ 7‬أن يتعامل معه بطريقة ّ‬
‫العمليات التي نريدها‪.‬‬
‫ّ‬ ‫متكررة‪ ،‬لينفّذ عليه‬
‫ّ‬
‫معينة‪ ،‬بحيث‬
‫تتكون من مجموعة من الخانات‪ ،‬كل خانة منها تحتفظ بقيمة ّ‬
‫هذا التركيب هو المصفوفة ‪ ،Array‬التي ّ‬
‫يمكن الوصول‪ 7‬لهذه القيمة عن طريق رقم خانتها ‪.Index‬‬
‫أال يبدو لك هذا الكالم مألوفا؟‪7‬‬
‫أي حرف‬
‫النص هو عبارة عن مصفوفة من الحروف‪ 7،‬ولقد استخدمنا بالفعل الدالة "حروف" ‪ Chars‬للحصول على ّ‬
‫ّ‬ ‫إن‬
‫ّ‬
‫النص‪:‬‬
‫ّ‬ ‫أي موضع في مصفوفة‬
‫من ّ‬
‫"أنا مصفوفة حروف" = ‪Dim X As String‬‬
‫ستعرض الرسالة الحرف ا ' ))‪MsgBox ( X.Chars(2‬‬
‫نعرف المصفوفة؟‬‫ولكن كيف ّ‬
‫سنتبع اسمه بقوسين يحتويان على عدد خانات المصفوفة‪:‬‬
‫ولكننا ُ‬
‫العادي‪ّ ،‬‬
‫ّ‬ ‫المتغير‬
‫ّ‬ ‫تعرف‬
‫تماما كما ّ‬
‫‪Dim StudentAge(49) As Integer‬‬
‫متغير من النوع "عدد صحيح"‪.‬‬
‫بهذا صار لدينا مصفوفة تحتوي على ‪ 50‬خانة (من ‪ 0‬إلى ‪ ،)49‬كل خانة منها هي ّ‬

‫ملحوظة لمبرمجي ‪:VB6‬‬


‫لم يعد بإمكانك استخدام جملة ‪ Option Base 1‬لجعل ترقيم خانات المصفوفة يبدأ من ‪ 1‬بدال من ‪ ..0‬أنت مجبر‬
‫على أن تتعامل مع مصفوفات‪ 7‬تبدأ بالخانة رقم صفر‪ ،‬سواء أعجبك هذا أم ال!‬
‫ليس هذا فحسب‪ ،‬بل لم يعد بإمكانك تحديد بداية ونهاية الترقيم‪ 7‬بجملة كالتالية‪:‬‬
‫‪Dim StudentAge(20 To 70) As Integer‬‬
‫فمثل هذه الجملة مرفوضةٌ اآلن تماما‪.‬‬

‫ولكن كيف نتعامل مع المصفوفة؟‬


‫عادي تماما‪:‬‬
‫ّ‬ ‫متغير‪7‬‬
‫كأنك تتعامل مع ّ‬ ‫تتخيل‪ ،‬فبمجرد‪ 7‬كتابة رقم الخانة التي تريدها‪ ،‬يبدو األمر ّ‬
‫مما ّ‬‫األمر أبسيط ّ‬
‫‪StudentAge(0) = 10‬‬
‫)‪MsgBox (StudentAge(0).ToString‬‬
‫تقليدي من النوع عدد‬
‫ّ‬ ‫أن الجزء (‪ )0‬غير موجود في الجملتين السابقتين‪ ،‬فستجد ّأنك تتعامل مع متغير‬‫فلو اعتبرت ّ‬
‫الخاصة به‪.‬‬
‫ّ‬ ‫صحيح‪ ،‬حتّى ّإنك تستخدم‪ 7‬الدالة ‪ToString‬‬
‫سيدور بيننا هذا الحوار‪ ..‬ستبادرني‪ 7‬قائال‪:‬‬
‫‪ -‬جميل‪ ..‬هذه هي المصفوفة‪ ،‬ولكنني‪ 7‬ما زلت ال أفهم كيف ستساعدنا في تبسيط الحسابات‪.‬‬
‫‪ -‬ف ّكر قليال في فائدة وجود‪ 7‬رقم الخانة ‪.Index‬‬
‫متغيرا‪ ،‬اللهم إال ّإننا اختصرنا‪7‬‬
‫العملية تشبه طريقة التعامل مع خمسين ّ‬
‫ّ‬ ‫‪ -‬ال أرى فيه ما يلفت النظر‪ ..‬ما زالت‬
‫جمل تعريفهم في جملة واحدة واسم واحد!‬
‫متغير؟‬
‫‪ -‬حتّى لو قلت لك ّإنك تستطيع‪ 7‬كتابة رقم الخانة بطريقة غير مباشرة‪ ،‬بوضعه في ّ‬
‫‪ -‬كيف هذا؟‬
‫‪ -‬كالتالي‪:‬‬
‫‪Dim StudentAge(49) As Integer‬‬
‫‪Dim I As Integer = 3‬‬
‫‪StudentAge (I) = 10‬‬
‫المتغير = ‪I‬‬
‫ّ‬ ‫ألن‬
‫فأنت في الجملة الثالثة تضع القيمة ‪ 10‬في الخانة الرابعة (الخانة رقم ‪ )3‬من المصفوفة‪ ،‬نظرا ّ‬
‫‪.3‬‬
‫ولكني ما زلت ال أفهم كيف سنستفيد منه!‬‫‪ -‬يبدو هذا مثيرا‪ّ ..‬‬
‫عملية ما على المصفوفة‪ ،‬على الخانة رقم ‪،I‬‬
‫‪ -‬ف ّكر كالتالي‪ :‬هل هناك طريقة أخبر بها اللغة‪ّ ،‬أنني أريد أن أنفّذ ّ‬
‫العملية؟‬
‫ّ‬ ‫مرة‪ ،‬لتصبح ‪ ،1‬ثم ‪ ،2‬ثم ‪ ،... ،3‬حتّى تصل إلى ‪ ،49‬حيث تتوقّف‬ ‫حيث ‪ I‬تبدأ من ‪ ،0‬ثم تزيد في كل ّ‬
‫مية؟‬
‫الجهن ّ‬
‫ّ‬ ‫‪ -‬إم‪ ..‬تبدو فكرةً ج ّذابة‪ ..‬ولكن هل هناك حقًّا ما يفعل مثل هذه األالعيب‬
‫‪ -‬امتلئ بهجة‪ ،‬فلدينا‪ 7‬هذه الطريقة بالفعل!‬
‫‪ -‬أسعفني بها أرجوك‪.‬‬
‫كل ما نحتاجه‪ ،‬هو مقطع التكرار "من إلى" ‪ ،For Loop‬كالتالي‪:‬‬
‫‪For I = 0 To 49 Step 1‬‬
‫}أي عمليات على الخانة )‪' { StudentAge (I‬‬
‫‪Next‬‬
‫أن هذا المقطع واضح‪ ،‬فهو يقول ببساطة‪ :‬من (‪ )I‬تساوي‪ 0 7‬إلى أن تصبح (‪ )I‬تساوي ‪ ،49‬بزيادة ‪ 1‬في كل‬
‫وأعتقد ّ‬
‫دورة‪ ،‬نفّذ المقطع‪.‬‬
‫يتم زيادة ‪1‬‬
‫التكرارية‪ ،‬وكلّما وصل التنفيذ إلى كلمة "التالي" ‪ّ ،Next‬‬
‫ّ‬ ‫أن ‪ I‬ستساوي‪ 7‬صفرا في بداية الجملة‬‫معنى هذا ّ‬
‫يتم التأ ّكد هل ما زال لم يتجاوز‪ 7‬الرقم ‪:49‬‬
‫المتغير (‪ ،)I‬حيث ّ‬
‫ّ‬ ‫على قيمة‬
‫للمتغير ‪.I‬‬
‫ّ‬ ‫مرة أأخرى‪ ،‬لكن بالقيمة الجديدة‬
‫يتم تنفيذ المقطع ّ‬
‫‪ -‬فإن كان كذلك‪ّ ،‬‬
‫‪ -‬وإ ن كان ‪ I‬أكبر من ‪ ،49‬ينتهي التكرار‪ ،‬وينتقل التنفيذ إلى السطر التالي لكلمة ‪ ..Next‬معنى هذا أن قيمة (‪)I‬‬
‫ستكون ‪ 50‬بعد انتهاء تنفيذ التكرار‪.‬‬
‫متوسط أعمار الطلبة‪ ،‬هو جمع كل أعمار الطالب (كل خانات المصفوفة) داخل مقطع‬‫ّ‬ ‫اآلن‪ ،‬ك ّل ما نريد فعله لحساب‬
‫التكرار‪ ،‬وبعد انتهائنا من ذلك‪ ،‬نقسم الناتج على ‪ ..50‬هذا هو البرنامج‪:‬‬
‫‪Dim StudentAge(49) As Integer, I As Integer, Sum As Integer‬‬
‫}بعض الكود لكتابة أعمار الطالب في المصفوفة{'‬
‫‪For I = 0 To 49 Step 1‬‬
‫الحالية على المجموع السابق' )‪Sum += AstudentAge (I‬‬
‫ّ‬ ‫جمع محتوى الخانة‬
‫‪Next‬‬
‫)‪MsgBox ( Sum / 50‬‬
‫نخزن بها ثالثة ألوان‪:‬‬
‫مخصصة لألرقام‪ ،‬انظر إلى المصفوفة التالية‪ ،‬والتي ّ‬
‫ّ‬ ‫تظن أن المصفوفة‬
‫وحتّى ال ّ‬
‫‪Dim Colors(2) As Color‬‬
‫‪Colors (0) = Color.Red‬‬
‫‪Colors (1) = Color.Blue‬‬
‫‪Colors (2) = Color.Green‬‬
‫إن كائن األلوان ‪ ،Color‬يمنحك من بين خصائصه‪ ،‬أسماء ‪ 128‬لونا‪ ،‬يمكنك اختيار ما تشاء منها‪.‬‬
‫ّ‬

‫ملحوظة‪:‬‬
‫عرفت مصفوفة من النوع "كائن" ‪ ،Object‬فيمكنك أن تضع في كل‬
‫كل خانات المصفوفة لها نفس النوع‪ ،‬ولكن لو ّ‬
‫خانة قيمة مختلفة في النوع عن األخرى‪.‬‬

‫وضع القيم االبتدائيّة للمصفوفات ‪:Initializing Arrays‬‬


‫االبتدائية للمصفوفة في نفس جملة التعريف بالصيغة التالية‪:‬‬
‫ّ‬ ‫يمكنك أن تضع القيم‬
‫نوع_البيانات = {قيمة_‪ ,0‬قيمة_‪ … ,1‬قيمة_ن} ‪() As‬اسم_المصفوفة ‪Dim‬‬
‫وكمثال‪:‬‬
‫"حسان"{ = ‪Dim Names() As String‬‬
‫}"فكري"‪ّ ,‬‬
‫وهو نفس ما يمكن أن تفعله بالجمل الثالث التالية‪:‬‬
‫‪Dim Names(1) As String‬‬
‫" فكري " = )‪Names(0‬‬
‫"حسان" = )‪Names(1‬‬
‫ّ‬
‫أو بالجملتين التاليتين‪:‬‬
‫‪Dim Names() As String‬‬
‫"حسان"{ )(‪Names = New String‬‬
‫}"فكري"‪ّ ,‬‬
‫أن اللغة لن تقبل منك جملة كالتالية‪:‬‬
‫ما يجب أن تعرفه هنا‪ ،‬هو ّ‬
‫"حسان"{ = ‪Dim Names(1) As String‬‬ ‫}"فكري"‪ّ ,‬‬
‫ابتدائية لمصفوفة تم تحديد عدد الخانات لها!!‬
‫ّ‬ ‫ألنك ارتكبت خطأ قاتال‪ ،‬وحاولت أن تضع قيما‬
‫ّ‬
‫أال يبدو لك هذا غباء من اللغة؟!‬
‫نواحي عديدة‪ ..‬فمثال يمكنك أن تمأل خانات المصفوفة بطريقة‬ ‫يحدث هذا بينما تبدو اللغة في منتهى المرونة في‬
‫َ‬
‫أخرى‪ ،‬بوضع مصفوفة أخرى فيها مباشرة‪:‬‬
‫‪Dim X(2) As Integer‬‬
‫}‪Dim Y() As Integer = {1,3,4,5‬‬
‫‪X=Y‬‬
‫ستعرض الرسالة الرقم ‪MsgBox X(3) ' 5‬‬
‫بمجرد كتابة ‪ ،X = Y‬قد صارت المصفوفة ‪ X‬نسخة طبق األصل من المصفوفة ‪ ،Y‬لدرجة أن عدد‬ ‫ّ‬ ‫تالحظّ ّأنه‬
‫أن هذه الخانات قد صارت تحتوي على قيم خانات المصفوفة‬
‫عرفناه سابقا‪ ،‬باإلضافة إلى ّ‬
‫عما ّ‬
‫خانات ‪ X‬قد زاد بواحد‪ّ 7‬‬
‫‪ ..Y‬منتهى المرونة والسهولة‪.‬‬
‫قيد واحد فقط هو المفروض عليك في هذه الحالة‪ :‬أن تكون المصفوفتان من نفس النوع‪ :‬لهما نفس عدد األبعاد‪ ،‬ولهما‬
‫أحادية البعد‪ ،‬أو كانت إحداهما‬
‫ّ‬ ‫نفس نوع البيانات‪ ..‬فمثال‪ ،‬سيحدث خطأ لو كانت إحداهما ثنائية البعد بينما األخرى‬
‫رقمية‪ ،‬أو حتّى كانت إحداهما تستوعب أعدادا صحيحة ‪ ،Integers‬واألخرى تستوعب أعدادا‬ ‫نصّية واألخرى ّ‬ ‫ّ‬
‫مزدوجة ‪.Double‬‬

‫حدود المصفوفة ‪:Array Limits‬‬


‫"الحد األعلى" ‪ ،)(UBound‬التي جاء اسمها‬
‫ّ‬ ‫يمكنك أن تعرف رقم الخانة األخيرة في المصفوفة‪ ،‬باستخدام الدالة‬
‫اختصارا لتعبير ‪ ،Upper Bound‬وهي تأخذ اسم المصفوفة كمعامل‪ ،‬وتُرجع رقم آخر خانة بها‪ ..‬ويمكنك‪ 7‬أن تحصل‬
‫الحد األعلى" ‪ ،GetUpperBound‬التي تنتمي لوسائل المصفوفة‪ ..‬طبعا لم‬‫على نفس النتيجة‪ ،‬باستخدام الدالة "اقرإ ّ‬
‫يدهشك األمر‪ :‬نعم‪ ..‬حتّى المصفوفة هي نوع من الكائنات‪ ،‬ولها خصائصها‪ 7‬ووسائلها‪:‬‬
‫‪Dim MyArray(19) As Integer‬‬
‫ستعرض الرسالة الرقم ‪MsgBox (UBound(MyArray)) ' 19‬‬
‫ستعرض الرسالة الرقم ‪MsgBox (MyArray.GetUpperBound(0)) ' 19‬‬
‫ألنها‬
‫إن هذه الوسيلة ال تحتاج السم المصفوفة‪ّ ،‬‬
‫تالحظ ّأننا أرسلنا الرقم‪ 7‬صفر كمعامل للوسيلة ‪ّ ..GetUpperBound‬‬
‫ولكنها في المقابل تحتاج لرقم‪ 7‬البعد ‪ Dimension‬الذي ستحسب خانته األخيرة‪..‬‬
‫تُنفّ ُذ على المصفوفة التي تنتمي إليها‪ّ ،‬‬
‫ما هو البعد؟‪ ..‬أسمعك تتساءل‪ ..‬حسنا‪ :‬سنشرح ذلك بعد ٍ‬
‫قليل فاصبر!‬
‫رقميا يمكنك استخدام‬
‫التكرارية‪ ،‬فبدال من تحديد رقم الخانة األخيرة ّ‬
‫ّ‬ ‫الهامة الستخدام‪ 7‬هذه الدالة‪ ،‬الجمل‬
‫ومن المواضع‪ّ 7‬‬
‫كود كالتالي‪:‬‬
‫‪Dim I As Integer, MyArray(19) As Integer‬‬
‫)‪For I = 0 To MyArray.GetUpperBound(0‬‬
‫‪MyArray(I) = I * 1000‬‬
‫‪Next‬‬
‫الخاصية "طول" ‪ Length‬لمعرفة طول المصفوفة‪:‬‬ ‫ّ‬ ‫ويمكنك استخدام‬
‫)‪Console.WriteLine(MyArray.Length‬‬
‫أيضا‪ّ ،‬أنك تستطيع‪ 7‬استخدام الوسائل الخاصة بنوع خانات المصفوفة‪ ،‬فلو كانت المصفوفة من النوع عدد‬ ‫الطريف ً‬
‫صحيح‪ Integer‬مثال‪ ،‬يمكن استخدام وسائل األعداد الصحيحة لكل خانة‪ ،‬كالتالي‪:‬‬
‫‪MyArray(0) = 3‬‬
‫‪I = MyArray(0).MinValue‬‬
‫)‪MsgBox (MyArray(0).ToString‬‬
‫زمنية‬
‫نصّية ‪ ،String‬يمكن استخدام وسائل النصوص لكل خانة‪ ،‬ولو كانت المصفوفة ّ‬
‫وبالمثل‪ ،‬لو كانت المصفوفة ّ‬
‫‪ ،Date‬يمكن استخدام وسائل النصوص لكل خانة‪ ....‬وهكذا‪.‬‬
‫المصفوفة متعدّدة األبعاد ‪:Multidimensional Arrays‬‬
‫ولكنك كثيرا ما ستحتاج الستخدام‪7‬‬
‫أحادية البعد‪ّ ..‬‬
‫ّ‬ ‫كل ما تعاملنا مع من المصفوفات‪ 7‬حتّى اآلن‪ ،‬هو المصفوفات‬
‫وثالثية وأكثر‪.‬‬
‫ّ‬ ‫ثنائية‬
‫متعددة البعد‪ّ ،‬‬
‫مصفوفات ّ‬

‫ثنائية البعد تمثّل‬


‫إن المصفوفة ّ‬ ‫ثنائية لتمثيل عشرة مدن ودرجات حرارتها في أسبوع‪ّ ..‬‬
‫فمثال‪ ،‬ستحتاج لمصفوفة ّ‬
‫جدوال‪ :‬صفوفا وأعمدة‪ ..‬وفي حالتنا هذه‪ ،‬سيكون الصف هو رقم المدينة‪ ،‬والعمود هو رقم اليوم في األسبوع‪.‬‬
‫الثنائية تحتاج لرقمين للوصول ألي خانة‪ :‬رقم‪ 7‬الصف ورقم العمود‪.‬‬
‫ّ‬ ‫طبعا يمكنك أن تستنتج أن المصفوفة‬
‫عشر مدن × سبع أيام ' ‪Dim City(9, 6) As Integer‬‬
‫األول ‪ 23‬درجة ' ‪City(0,0) = 23‬‬
‫درجة حرارة المدينة األولى في اليوم ّ‬
‫الصف‪ ،‬والخانة الثانية تمثّل العمود‪.‬‬
‫ّ‬ ‫كما تالحظ‪ ،‬الخانة األولى تمثّل‬
‫ثالثية‪ ،‬مثل‪:‬‬
‫يمكن أيضا أن تكون لديك مصفوفة ّ‬
‫‪Dim City(9, 6, 3) As Integer‬‬
‫رياضية إليضاح‬
‫ّ‬ ‫الرباعية ‪ ...‬إلخ‪ ..‬ال تحاول‪ّ ..‬إنها طرق‬
‫ّ‬ ‫ثم‬
‫الثالثية ّ‬
‫ّ‬ ‫تخيل األبعاد‬
‫طبعا سترهق ذهنك في محاولة ّ‬
‫األول ‪ 10‬مدن‪ ،‬والثاني ‪7‬‬
‫معينة من المعامالت والبيانات‪ ..‬ففي المثال السابق‪ ،‬يمكن أن يمثّل البعد ّ‬
‫ارتباط مجموعة ّ‬
‫أيام‪ ،‬والثالث ‪ 3‬قراءات في اليوم (في الفجر = ‪ ،0‬في الظهيرة = ‪ ،1‬في الغروب = ‪.)2‬‬
‫األول = ‪ )1‬في اليوم الثالث (اإلحداثي الثاني = ‪ )2‬في وقت‬
‫تحدد أن درجة الحرارة في المدينة الثانية (اإلحداثي ّ‬
‫فلكي ّ‬
‫الظهيرة (اإلحداثي الثالث = ‪ )1‬كانت ‪ 40‬درجة (قيمة الخانة = ‪ ،)40‬يمكنك أن تكتب‪:‬‬
‫‪City(1,2,1) = 40‬‬
‫متعددة البعد‪ ..‬انظر لما يلي‪:‬‬
‫االبتدائية في المصفوفات‪ّ 7‬‬
‫ّ‬ ‫أن هناك وسيلة ما لوضع القيم‬‫ولك أن تتوقّع‪ّ ،‬‬

‫} }‪Dim A(,) As Integer = { {10, 20, 30}, {11, 21, 31}, {12, 22, 32‬‬
‫الناتج ‪Console.WriteLine(A(0, 1)) ' 20‬‬
‫الناتج ‪Console.WriteLine(A(2, 2)) ' 32‬‬
‫ألن المصفوفة ‪ 3‬صفوف × ‪ 3‬أعمدة‪.‬‬ ‫الحظ أن أكبر خانة في المصفوفة السابقة هي (‪ّ ،)2،2‬‬
‫خاصّية "الرتبة" ‪ ،Rank‬التي يمكنك استخدامها لمعرفة عدد‬
‫ّ‬ ‫خواص المصفوفة‪ ،‬هي‬
‫ّ‬ ‫هامة من‬
‫لخاصية ّ‬
‫ّ‬ ‫هنا ستحتاج‬
‫أبعاد المصفوفة‪:‬‬
‫‪Dim Salaries(1,99) As Object‬‬
‫ستعرض الرسالة ‪MsgBox(Salaries.Rank) ' 2‬‬
‫فإن الناتج‬
‫خاصّية "الطول" ‪ Length‬في مصفوفة متعددة األبعاد‪ّ ،‬‬
‫ّ‬ ‫وأحب أن ألفت نظرك إلى شيء‪ :‬عندما تستخدم‪7‬‬
‫سيكون هو الطول الكلّ ّي للمصفوفة‪ ،‬الناتج من ضرب أطوال كل أبعادها‪:‬‬
‫ستعرض الرسالة "‪MsgBox (Salaries.Length) ' )100×2( "200‬‬
‫ولكن ماذا لو أحببت أن تعرف طول بعد بعينه؟‪ ..‬في هذه الحالة استخدم‪ 7‬الدالة "اقرإ الطول" ‪ ،GetLength‬وابعث لها‬
‫البعد الذي تقصده كمعامل‪:‬‬
‫الناتج ‪Console.WriteLine(Salaries.GetLength(0)) ' 2‬‬

‫المصفوفات المرنة ‪:Dynamic Arrays‬‬


‫كثيرا ما تجد نفسك عاجزا عن أن تعرف بالضبط حجم مصفوفتك قبل تشغيل التطبيق‪ ،‬أو قد يحتاج المستخدم‪ 7‬ألن‬
‫مما يجعلك في حاجة لزيادة طول المصفوفة‪ ..‬في هذه الحالة تحتاج إلى مصفوفة مرنة‪،‬‬‫قيما جديدة باستمرار‪ّ ،‬‬
‫ُيدخل ً‬
‫أي وقت‪ ،‬لتتالءم مع عدد الخانات التي لديك‪.‬‬
‫قابلة لزيادة حجمها أو إنقاصه في ّ‬
‫معينا‪:‬‬
‫تحدد لها طوال ّ‬
‫ولفعل ذلك‪ ،‬ابدأ بتعريف المصفوفة بقوسين فارغين‪ ،‬بمعنى أال ّ‬
‫‪Dim DynArray() As Integer‬‬
‫ويمكن وضع القوسين الفارغين بعد نوع البيانات‪:‬‬
‫)(‪Dim DynArray As Integer‬‬

‫ملحوظة‪:‬‬
‫وأنها تتشابه مع صيغة تعريف الكائنات (باستخدام كلمة‬
‫خاصة ّ‬ ‫ّ‬ ‫قد يصيبك‪ 7‬بعض االرتباك من الصيغة األخيرة‪،‬‬
‫تعرف عددا صحيحا منفردا‪:‬‬ ‫إن الجملة التالية ّ‬
‫‪ّ ..)New‬‬
‫)(‪Dim StudentAge As New Integer‬‬
‫جيدا‪ ،‬وال‬
‫فستؤدي‪ 7‬الجملة لتعريف‪ 7‬مصفوفة أعداد صحيحة‪ ..‬انتبه لهذا ّ‬
‫ّ‬ ‫بينما لو أزلت كلمة ‪ New‬وتركت القوسين‬
‫تنس أن تحذف القوسين عند حذف كلمة ‪ New‬حتّى ال يختلف معنى الجملة عن الذي تريده‪.‬‬ ‫َ‬
‫الجدير بالذكر‪ّ ،‬أنك ال تستطيع‪ 7‬استخدام كلمة ‪ New‬في تعريف مصفوفة كائنات‪ ..‬فالجملة التالية مرفوضة تماما‪:‬‬
‫)(‪Dim X() As New Form1‬‬
‫فماذا تفعل لو أردت أن تنشئ نسخة جديدة من ك ّل كائن في خانات المصفوفة؟‬
‫في هذه الحالة استخدم هذه الصيغة‪:‬‬
‫})(‪Dim X() As Form1 = {New Form1‬‬
‫أي كائن تريده)‪.‬‬
‫وبهذا تحصل على مصفوفة‪ ،‬تحتوي‪ 7‬ك ّل خانة منها على نسخة جديدة من النموذج (أو ّ‬

‫ثم حينما تجد نفسك أثناء البرنامج محتاجا لحجز عدد من الخانات‪ ،‬استخدم‪ 7‬تعبير"أعد تعريف" ‪ ReDim‬كالتالي‪:‬‬
‫)‪ReDim DynArray(UserCount‬‬
‫رقمي‪ ،‬يحتوي على عدد أدخله المستخدم‪ ،‬وليكن ‪.20‬‬
‫ّ‬ ‫متغير‬
‫حيث ‪ UserCount‬هو ّ‬
‫خاصّية‪ ،‬فهي ليست مثل ‪ ،Dim‬وال تظهر أبدا‬
‫ّ‬ ‫وجملة "أعد تعريف"‪ ReDim 7‬ال تُستخدم فقط إال في إجراء أو دالة أو‬
‫على مستوى‪ 7‬النموذج‪.‬‬
‫كما يمكن تحديد أبعاد المصفوفة بجملة ‪:ReDim‬‬
‫‪Dim Matrix( , , ) As Double‬‬
‫)‪ReDim Matrix(9, 9, 9‬‬
‫ولكن ال يمكنك تغيير عدد هذه األبعاد فيما بعد‪ ،‬فجملة كالتالية لن تكون مقبولة‪:‬‬
‫)‪ReDim Matrix(9, 9‬‬
‫وإ ن كان من الممكن تغيير طول أي بعد من األبعاد‪:‬‬
‫)‪ReDim Matrix(9, 2, 3‬‬

‫مالحظات‪:‬‬
‫‪ -1‬ال يمكن تغيير نوع المصفوفة بجملة ‪ ..ReDim‬هذا هو السبب في غياب الجزء الخاص بتعبير ‪ As‬منها‪.‬‬
‫‪ -2‬يمكن استخدام‪ 7‬جملة ‪ ReDim‬لتغيير حجم المصفوفات ثابتة الحجم كذلك!‪ ..‬انظر المثال التالي‪:‬‬
‫‪Dim X(3) As Integer‬‬
‫)‪ReDim X(4‬‬
‫إن اللغة تتعامل مع ك ّل المصفوفات على ّأنها مرنة‪ ،‬لدرجة‬
‫إن المالحظة السابقة تقو ُل بوضوح‪ّ :‬‬
‫‪ -3‬في الواقع‪ّ ،‬‬
‫ّأنك صرت تستطيع كتابة شيء كان ممنوعا في النسخ السابقة وفي‪ 7‬باقي لغات البرمجة‪ ،‬أال وهو تعريف عدد‬
‫بمتغير‪ ،‬شريطةَ أن يكون قد تم تعريفه في أي سطر يسبق تعريف‪ 7‬المصفوفة‪ ،‬وذلك حتّى‬
‫ّ‬ ‫خانات المصفوفة‬
‫ابتدائية تضعها فيه أثناء تعريفه‪ ،‬أو أي قيمة‬
‫ّ‬ ‫االفتراضية ‪ ،0‬أو أي قيمة‬
‫ّ‬ ‫مبدئية‪ ،‬سواء القيمة‬
‫ّ‬ ‫تكون له قيمة‬
‫إن كل الجمل التالية‬
‫أخرى تضعها فيه بعد أن تتلقاها من مربع نص أو أي وسيلة إدخال يستخدمها‪ 7‬المستخدم‪ّ ..‬‬
‫مباحة‪:‬‬
‫‪ Dim I As Integer‬‬
‫‪Dim X(I) As Integer ' I = 0‬‬
‫‪ Dim I As Integer = 3‬‬
‫‪Dim X(I) As Integer‬‬
‫‪ Dim I As Integer‬‬
‫)‪I = Val( Text1.Text‬‬
‫‪Dim X(I) As Integer‬‬

‫ولكنك ما زلت قلقا‪ ،‬تقضم أظافرك‪ 7‬وتتساءل‪:‬‬


‫ّ‬
‫‪ -‬ولكن ماذا عن البيانات الموجودة في المصفوفة؟‪ ..‬ماذا سيحدث لها بعد تغيير حجم المصفوفة؟‬
‫‪ -‬ستُمحى تماما ونهائيًّا!‬
‫ولكنني أريد االحتفاظ بالبيانات السابقة‪ ..‬هذا سيجعل هذه الوسيلة عقيمة بالنسبة لي!‬
‫‪ -‬ماذا؟!!‪ّ ..‬‬
‫‪ -‬ليس في ك ّل األحوال‪ ،‬فهذه الطريقة نافعة جدا حينما تريد حجز مصفوفة فارغة بالحجم الذي تتطلّبه بيانات‬
‫تتغير من فصل لفصل‪.‬‬
‫المستخدم‪ ،‬كعدد الطلبة في فصل مثال‪ ،‬وهي ّ‬
‫الحالية دون أن‬
‫ّ‬ ‫األهم‪ ،‬هي عندما أريد زيادة حجم المصفوفة الستيعاب بيانات جديدة على البيانات‬
‫ّ‬ ‫ولكن الحالة‬
‫ّ‬ ‫‪-‬‬
‫أفقدها‪.‬‬
‫‪ -‬حسنا حسنا‪ ..‬ال تبتئس هكذا‪ ..‬هناك حل!‬
‫إلي به‪.‬‬ ‫ًّ‬
‫‪ -‬حقّا؟!‪ّ ..‬‬
‫‪ -‬يمكنك استخدام كلمة "احتفاظ"‪ ،Preserve 7‬لالحتفاظ بالبيانات السابقة في المصفوفة‪ ..‬فلو أزدت عدد الخانات‪،‬‬
‫تصاف‪ 7‬إلى المصفوفة خانات جديدة مع االحتفاظ بقيم خاناتها‪ 7‬القديمة‪ ،‬ولو أنقصت عدد الخانات‪ ،‬ضاعت البيانات‬
‫الموجودة في الخانات التي نقصت فقط‪ ،‬واحتفظت ببيانات باقي الخانات‪.‬‬
‫انظر لهذا المثال‪:‬‬
‫)‪ReDim Preserve DynArray(UBound(DynArray) + 1‬‬
‫حدها األعلى‪ ..‬هذا مع عدم ضياع القيم القديمة من المصفوفة‪.‬‬
‫لقد أضفنا خانة جديدة للمصفوفة‪ ،‬بزيادة ‪ 1‬على ّ‬
‫وهناك طريقة أخرى لتغيير حجم المصفوفة المرنة‪ ،‬ولكن دون حفظ محتوياتها السابقة‪ ،‬وذلك باستخدام‪ 7‬كلمة ‪New‬‬
‫كالتالي‪:‬‬
‫}{ )‪DynArray = New Integer(30‬‬
‫فإن بإمكانك أن تستخدمهما‪ 7‬في وضع القيم‬
‫تظن ّأنهما بال فائدة‪ّ ،‬‬
‫المتعرجين‪ ..‬وحتّى ال ّ‬
‫ّ‬ ‫حتمية وجود القوسين‬
‫ّ‬ ‫الحظ‬
‫االبتدائية للمصفوفة‪:‬‬
‫ّ‬
‫}‪DynArray = New Integer(3) {1,2,4,5‬‬
‫عكسية لحجز المصفوفة‪ ،‬هي محوها‪ ،‬وذلك إذا أردت أن تمحو ك ّل خانات المصفوفة‪ ،‬لتوفير‪ 7‬مساحة‬
‫ّ‬ ‫عملية‬
‫وهناك ّ‬
‫الذاكرة بعد االنتهاء من استخدامها‪ ..‬واألمر بسيط‪ ..‬ك ّل ما عليك هو أن تستخدم جملة المحو ‪ Erase‬كالتالي‪:‬‬
‫‪Erase DynArray‬‬
‫ويمكنك أن تمحو بجملة واحدة أكثر من مصفوفة‪ ،‬وذلك بوضع فواصل‪ 7‬بين أسمائها‪:‬‬
‫‪Erase DynArray1, DynArray2, DynArray3‬‬

‫مصفوفة المصفوفات ‪:Arrays of Arrays‬‬


‫أي شيء‪ ،‬حتّى لو كان مصفوفة!‪..‬‬ ‫عرفت مصفوفة من النوع "كائن" ‪ ،Object‬فإن بإمكانك أن تضع في خاناتها‪ّ 7‬‬
‫لو ّ‬
‫عادية‪ ..‬انظر لهذا المثال‪:‬‬
‫تساو ّ‬‫نعم‪ :‬يمكنك أن تضع مصفوفة في خانة من مصفوفة من النوع "كائن" بعملية ٍ‪7‬‬
‫‪Dim X(2) As Object, Y(2) As Object, Z(3) As Int16‬‬
‫‪Z(0) = 1‬‬
‫‪Y(0) = Z‬‬
‫كأنه هو‬
‫لقد وضعنا‪ 7‬المصفوفة ‪ Z‬بكاملها في الخانة األولى من المصفوفة ‪ ..Y‬اآلن يمكن استخدام التعبير )‪ّ Y(0‬‬
‫المصفوفة ‪:Z‬‬
‫))‪MsgBox(Y(0)(0‬‬
‫العملية أكثر‪ ..‬سنضع المصفوفة ‪ Y‬في‬
‫ّ‬ ‫ألن )‪ Y(0)(0‬هو تعبير مكافئ لـ )‪ ..Z(0‬تعال نعقّد‬ ‫هذه الرسالة ستعرض ‪ّ ،1‬‬
‫إحدى خاناتها هي نفسها!!‬
‫‪Y(1) = 2‬‬
‫‪Y(2) = Y‬‬
‫اآلن يصير التعبير )‪ Y(2‬مكافئا‪ 7‬للمصفوفة ‪ Y‬نفسها‪ ،‬وبالتالي‪ 7‬يصير‪ 7‬التعبير )‪ Y(2)(0‬مكافئا‪ 7‬للتعبير )‪ ،Y(0‬الذي‬
‫يكافئ بدوره المصفوفة ‪:Z‬‬
‫))‪MsgBox(Y(2)(0)(0) + Y(2)(1‬‬
‫سيكون الناتج هو ‪ ،3‬نتيجة لجمع الخانة األولى من المصفوفة ‪ Z‬مع الخانة الثانية من المصفوفة ‪ ..Y‬ويمكنك تعقيد‬
‫ألي درجة تريدها‪:‬‬
‫العملية ّ‬
‫ّ‬
‫‪X(0) = Z‬‬
‫‪X(1) = Y‬‬
‫الناتج ‪MsgBox(X(1)(2)(0)(0)) ' 1‬‬
‫‪X(2) = X‬‬
‫الناتج ‪MsgBox(X(2)(1)(2)(0)(0)) ' 1‬‬

‫مالحظة‪:‬‬
‫المتأخر‪Late 7‬‬
‫ّ‬ ‫ألنه نوع من الربط‬
‫لن تعمل هذه الطريقة في حالة اختيار‪" 7‬التحويل الدقيق" ‪ّ ،Option Strict On‬‬
‫‪ ،Binding‬فالكود الذي تكتبه يشير‪ 7‬إلى أن إحدى خانات المصفوفة تحتوي على مصفوفة أخرى‪ ،‬وهو ما ال يمكن‬
‫صحته‪ ،‬إال عند تنفيذ البرنامج بالفعل‪.‬‬
‫لمترجم‪ 7‬الكود أن يتحقّق من ّ‬

‫تعرف مصفوفة مصفوفات مباشرةً كالتالي‪:‬‬


‫تلك كانت طريقة غير مباشرة‪ ،‬ولكن بإمكانك أن ّ‬
‫‪Dim X() () As Integer‬‬
‫والتعامل معها سيبدو‪ 7‬معقّدا قليال‪ ،‬لهذا لن نناقشها هنا‪.‬‬

‫مشروع المصفوفات‪:‬‬
‫المتغيرات والمصفوفات‪ ..‬وسنفعل ذلك عن طريق‬
‫ّ‬ ‫نتدرب على استخدام بعض ما تعلّمناه حتّى اآلن عن‬
‫آن األوان لكي ّ‬
‫نص‪ ،‬ويضعها في مصفوفة‪ ،‬مانحا للمستخدم‪ 7‬القدرة على عكس‬
‫مربع ّ‬‫إنشاء تطبيق يأخذ القيم التي يدخلها المستخدم‪ 7‬في ّ‬
‫أن ‪ VB.Net‬تمنحك اآلن وسائل جاهزة عكس المصفوفة وترتيبها‪7‬‬ ‫هذه المصفوفة أو ترتيبها‪ 7‬أو البحث فيها‪ ..‬ورغم ّ‬
‫(سنتعرف‪ 7‬عليها بالتفصيل في فصل المجموعات ‪ ،)Collections‬إال ّإنه سيكون تدريبا مفيدا أن نبني هذه‬
‫ّ‬ ‫والبحث فيها‬
‫األساسية‪ ..‬ستجد هذا التطبيق في مجلّد هذا الفصل باسم‬
‫ّ‬ ‫البرمجية‬
‫ّ‬ ‫نتعرف‪ 7‬على بعض المهارات‬
‫الوسائل بأنفسنا‪ ،‬حتّى ّ‬
‫‪.Arrays‬‬
‫ابدأ بتصميم واجهة التطبيق‪ 7‬كما في الصورة التالية‪:‬‬
‫"متعدد‪ 7‬األسطر"‪MultiLine 7‬‬
‫ّ‬ ‫خاصية‬
‫ّ‬ ‫تغير‬
‫تنس أن ّ‬
‫النص‪ ،‬ال َ‬
‫ّ‬ ‫مربع‬
‫وحتّى يستطيع‪ 7‬المستخدم كتابة أكثر من سطر في ّ‬
‫إلى صواب ‪.True‬‬

‫قراءة المدخالت‪:‬‬
‫الخاصية‬
‫ّ‬ ‫النص في خانة في مصفوفة‪ ..‬أبسط طريقة لفعل هذا هو استخدام‪7‬‬
‫ّ‬ ‫مربع‬
‫نخزن ك ّل سطر في ّ‬ ‫نريد اآلن أن ّ‬
‫نصية‪ ،‬تحتوي ك ّل خانة منها على سطر من سطور‬ ‫الخاصية تعيد لك مصفوفة ّ‬
‫ّ‬ ‫النص‪ ..‬هذه‬
‫ّ‬ ‫بمربع‬
‫الخاصة ّ‬
‫ّ‬ ‫‪Lines‬‬
‫النص‪ ..‬إذن فك ّل ما نحتاجه هو السطران التاليان‪:‬‬
‫ّ‬ ‫مربع‬
‫ّ‬
‫‪Dim Arr() As String‬‬
‫‪Arr = TextBox1.Lines‬‬
‫النص‪ ،‬حتّى ال‬
‫ّ‬ ‫مربع‬
‫أن المستخدم قد أدخل بعض العناصر‪ 7‬في ّ‬‫ولكن قبل أن نفعل ذلك‪ ،‬يجب علينا أوال أن نتأ ّكد من ّ‬
‫نص فارغ‪.‬‬
‫مربع ّ‬
‫أي خطأ غير متوقّع نتيجةً للتعامل مع ّ‬ ‫يحدث ّ‬
‫لهذا سنتستخدم‪ 7‬الكود التالي‪:‬‬
‫‪If TextBox1.Text = "" Then‬‬
‫النص أوال"(‪MsgBox‬‬
‫ّ‬ ‫مربع‬
‫نص في ّ‬‫أي ّ‬
‫)"ال تحاول التذاكي علينا‪ ..‬أدخل ّ‬
‫النص' )(‪TextBox1.Focus‬‬
‫ّ‬ ‫مربع‬
‫شر الكتابة في ّ‬
‫ضع مؤ ّ‬
‫العملية ' ‪Exit Sub‬‬
‫ّ‬ ‫عدم إكمال‬
‫‪End If‬‬

‫البحث في المصفوفة‪:‬‬
‫أبسط طريقة يمكن أن نستخدمها‪ 7‬للبحث في المصفوفة هي في نفس الوقت أسوأ وأبطأ‪ 7‬طريقة‪ ،‬وذلك بالمرور عبر ك ّل‬
‫بنص الخانة‪.‬‬
‫نص البحث ّ‬ ‫خانات المصفوفة خانة خانة‪ ،‬ومقارنة ّ‬
‫يعد أسرع بكثير من الطريقة األولى‪.‬‬
‫وتوجد طرق أفضل للبحث‪ ،‬مثل البحث الثنائي ‪ ،Binary Search‬الذي ّ‬
‫جيدةً بالبرمجة‬
‫الثنائي يتطلّب معرفة ّ‬
‫ّ‬ ‫ألن البحث‬
‫نظرا ّ‬
‫ول ّكنا سنقتصر‪ 7‬على كتابة الطريقة األولى في هذا الفصل‪ً ،‬‬
‫وسنتعرف‪ 7‬عليها بالتفصيل في الفصل القادم بإذن اهلل‪.‬‬
‫ّ‬ ‫االرتدادية ‪،Recursive Programming‬‬
‫ّ‬
‫التقليدي‪:‬‬
‫ّ‬ ‫البحث‬
‫َ‬ ‫تعا َل َنر‬
‫النص الذي يريد البحث عنه‪:‬‬
‫ّ‬ ‫في البداية يجب أن نطلب من المستخدم‪ 7‬أن ُيدخل‬
‫)""(‪Dim S As String = InputBox‬‬
‫مربع اإلدخال فارغا‪ ،‬فعلينا أال نقوم بالبحث‪:‬‬
‫فإذا ترك المستخدم‪ّ 7‬‬
‫‪If S = "" Then‬‬
‫)"!نص البحث فارغ‪ ..‬ال تحاول التذاكي علينا"( ‪MsgBox‬‬
‫ّ‬
‫‪Exit Sub‬‬
‫‪End If‬‬
‫نص بحث‪ ،‬فهذا هو الكود الذي يبحث عنه‪:‬‬ ‫فإذا كان هناك ّ‬
‫‪Dim Found As Boolean, I As Integer‬‬
‫)‪For I = 0 To Arr.GetUpperBound(0‬‬
‫‪If S = Arr(I) Then‬‬
‫نص البحث موجود في السطر رقم"(‪MsgBox‬‬ ‫))‪ّ " + Str(I + 1‬‬
‫‪Found = True‬‬
‫يمكنك استخدام هذه الجملة لو أردت االكتفاء بالعثور على ّأول نسخة من النص '‬
‫‪' Exit For‬‬
‫ستستمر جملة التكرار لنهاية المصفوفة '‬
‫ّ‬ ‫‪،‬ومن دونها‬
‫مرة '‬
‫النص أكثر من ّ‬
‫ّ‬ ‫وقد تعثر على نفس‬
‫‪End If‬‬
‫‪Next‬‬
‫النص فيجب أن نخبر المستخدم‪ x‬بهذا '‬
‫ّ‬ ‫لو لم نجد‬
‫نص البحث"(‪If Found = False Then MsgBox‬‬ ‫يتم العثور على ّ‬
‫)"لم ّ‬

‫عكس خانات المصفوفة‪:‬‬


‫ٍ‬
‫بصوت مسموع‪:‬‬ ‫تعا َل نف ّكر معا‬
‫كيف نعكس خانات المصفوفة؟‬
‫سنضع في الخانة األولي محتويات الخانة األخيرة‪ ،‬ونضع في الخانة األخيرة محتويات األولى‪.‬‬
‫ثم سنفعل المثل في الخانتين الثانية وقبل األخيرة‪.‬‬‫ّ‬
‫ثم الخانة الثالثة وقبل قبل األخيرة (الثالثة من آخر المصفوفة)‪.‬‬
‫ّ‬
‫وهكذا‪. ...‬‬
‫فكأننا وضعنا مرآةً عند منتصف‪ 7‬المصفوفة‪ ،‬لنعكس ك ّل خانة مع صورتها في المرآة‪.‬‬
‫ّ‬
‫ولكن كيف تعرف صورة الخانة في هذه المرآة؟‬
‫الحظ ما يلي‪:‬‬
‫الخانة رقم ‪ .‬تقابلها الخانة األخيرة‪.‬‬
‫والخانة رقم ‪ 1‬تقابلها تلك التي تسبق األخيرة بـ ‪.1‬‬
‫والخانة رقم ‪ 2‬تقابلها تلك التي تسبق األخيرة بـ ‪.2‬‬
‫والخانة رقم ‪ I‬تقابلها تلك التي تسبق األخيرة بـ ‪.I‬‬
‫فإن رقم صورتها في المرآة هو ‪ ،J‬حيث‪:‬‬
‫الحالية ‪ّ ،I‬‬
‫ّ‬ ‫إذن‪ ،‬لو كان رقم الخانة‬
‫‪J = Arr.GetUperBound(0) – I‬‬
‫وأنت بالطبع تعلم أن )‪ Arr.GetUperBound(0‬هو رقم الخانة األخيرة في المصفوفة‪.‬‬
‫العملية؟‬
‫ّ‬ ‫ولكن متى تتوقّف هذه‬
‫تتوقّف‪ 7‬بالطبع عند الوصول إلى منتصف‪ 7‬المصفوفة (المرآة)‪ ،‬ففي هذه الحالة سيكون النصف األيمن قد انتقل للنصف‬
‫األيسر والعكس‪.‬‬
‫أعتقد اآلن ّأنك تستطيع فهم هذا الكود‪ ،‬الذي يقوم بعكس المصفوفة‪:‬‬
‫‪Dim Temp As String, I As Integer, J As Integer‬‬
‫)‪Dim Up As Integer = Arr.GetUpperBound(0‬‬
‫‪If CheckTextBox() = False Then Exit Sub‬‬
‫‪For I = 0 To Up \ 2‬‬
‫‪J = Up - I‬‬
‫تبادل قيمتي الخانتين ‪' Swap‬‬
‫متغير احتياطي '‬
‫الحالية في ّ‬
‫ّ‬ ‫‪،‬يجب حفظ قيمة الخانة‬
‫قبل الكتابة في هذه الخانة‪ ،‬وذلك أل ّننا نحتاجها لكي توضع في الخانة المناظرة '‬
‫)‪Temp = Arr(I‬‬
‫الحالية '‬
‫ّ‬ ‫نقل قيمة الخانة المناظرة إلى الخانة‬
‫)‪Arr(I) = Arr(J‬‬
‫المتغير االحتياطي إلى الخانة المناظرة '‬
‫ّ‬ ‫نقل قيمة الخانة األولى من‬
‫‪Arr(J) = Temp‬‬
‫‪Next‬‬
‫تتبق إذن إال خطوةٌ واحدة‪ ،‬هي وضع‬
‫النص‪ ..‬لم ّ‬
‫ّ‬ ‫مربع‬
‫اآلن تحتوي المصفوفة ‪ Arr‬على نسخة معكوسة من سطور ّ‬
‫النص‪ ،‬ليرى المستخدم التغيير الذي حدث‪:‬‬
‫ّ‬ ‫مربع‬
‫المصفوفة المعكوسة في مصفوفة سطور‪ّ 7‬‬
‫‪TextBox1.Lines = Arr‬‬

‫ترتيب المصفوفة‪:‬‬
‫هناك طرق عديدة لترتيب المصفوفات‪ ،‬سنكتفي هنا بشرح إحداها‪ ،‬وهي طريقة الفقّاعة ‪ ،Bubble Sort‬وسنحيل‪7‬‬
‫الطريقة األخرى‪ 7‬األفضل واألسرع ـ وهي طريقة الترتيب السريع ‪ Quick Sort‬ـ إلى الفصل القادم إن شاء اهلل‪.‬‬
‫أعرف ّأنك ستسألني‪ 7‬في لماضة‪:‬‬
‫ظفات؟‬
‫‪ -‬ما هو ترتيب الفقاقيع هذا؟‪ ..‬وهل لهذا عالقة بالصابون والمن ّ‬
‫األخف يطفو!‬
‫ّ‬ ‫نظرية‪:‬‬
‫ّ‬ ‫حق!‪ ..‬فهذه الطريقة في الترتيب تستخدم‬
‫‪ -‬يبدو ّأنك على ّ‬
‫ِ‬
‫بالماء!‪ ..‬هل يبدو لك ّأنك أضفت لي جديدا؟‬ ‫الع ِ‬
‫سر‬ ‫بعد ُ‬
‫الماء َ‬
‫َ‬ ‫فسر‬
‫‪ -‬كمن ّ‬
‫‪ -‬اصبر قليال وستفهم‪.‬‬
‫سيدي!‬
‫تفضل يا ّ‬
‫اللهم الروح‪ّ ..‬‬ ‫‪ -‬أطل ّ‬
‫يتم تبادل‬
‫‪ -‬الحكايةُ وما فيها ّأننا سنقارن قيمة ك ّل خانة في الصفوفة بما يليها‪ ،‬فإذا كانت الخانة التالية أصغر‪ّ ،‬‬
‫إن هذا في النهاية سيجعل العناصر‪ 7‬األصغر‪ 7‬تطفو إلى بداية المصفوفة‪ ..‬تماما كما‬ ‫الحالية‪ّ ..‬‬
‫ّ‬ ‫قيمتها‪ 7‬مع الخانة‬
‫تفعل الفقاقيع حينما تتصاعد إلى سطح الماء‪.‬‬
‫ٍ‬
‫حاجة لبعض اإليضاح‪.‬‬ ‫ولكنني‪ 7‬ما زلت في‬
‫‪ -‬أعتقد ّأنني فهمت‪ّ ،‬‬
‫عمليا‪.‬‬
‫‪ -‬إذن فلنأخذ مثاال ّ‬
‫أن لدينا المصفوفة التالية‪:‬‬
‫افترض ّ‬

‫‪5‬‬
‫‪2‬‬
‫‪6‬‬
‫‪4‬‬
‫‪3‬‬
‫بد من مبادلتهما‪:‬‬
‫أن بها الرقم ‪ 5‬وهو أكبر من الرقم‪ ..2 7‬إذن فال ّ‬
‫سنبدأ بمقارنة الخانة األولى بما يليها‪ ..‬سنكتشف‪ّ 7‬‬

‫‪2‬‬
‫‪5‬‬
‫‪6‬‬
‫‪4‬‬
‫‪3‬‬

‫وكأن شيئا لم يكن‪ ..‬الفارق الوحيد ّأنها صارت تحتوي على الرقم‬
‫ّ‬ ‫سنستمر في مقارنة الخانة األولى بما يليها‬
‫ّ‬ ‫الحظ ّأننا‬
‫‪ ..2‬لحسن الحظّ ّأنه أصغر من الرقم‪ 6 7‬والرقم ‪ 4‬والرقم ‪.3‬‬
‫بد من "تعويم" الرقم ‪4‬‬
‫ولكنه أكبر من الرقم ‪ ..4‬إذن فال ّ‬
‫ننتقل اآلن للخانة الثانية‪ ..‬سنجد أن الرقم ‪ 5‬أق ّل من الرقم ‪ّ ،6‬‬
‫إلى أعلى‪:‬‬

‫‪2‬‬
‫‪4‬‬
‫‪6‬‬
‫‪5‬‬
‫‪3‬‬

‫أن الخانة الثانية صارت تحتوي على الرقم ‪..4‬‬


‫عملية المقارنة‪ ،‬ولكن باألخذ في االعتبار ّ‬
‫وكما اعتدنا سنواصل باقي ّ‬
‫حتمية مبادلتهما‪:‬‬
‫ّ‬ ‫مما يعني‬
‫هنا سنجد ّأنه أكبر من الرقم‪ّ ،3 7‬‬

‫‪2‬‬
‫‪3‬‬
‫‪6‬‬
‫‪5‬‬
‫‪4‬‬

‫المرة الثانية التي نقارن‬


‫أن هذه هي ّ‬ ‫اآلن نصل للخانة الثالثة‪ ،‬وفيها‪ 7‬الرقم‪ ..6 7‬لألسف سنجده أكبر من الرقم ‪( 5‬الحظ ّ‬
‫إن هذا من عيوب هذه الطريقة‪ ،‬حيث يكون عدد المقارنات كبيرا)‪ ..‬اآلن سنبادلهما‪:‬‬ ‫فيها هذين الرقمين‪ّ ..‬‬

‫‪2‬‬
‫‪3‬‬
‫‪5‬‬
‫‪6‬‬
‫‪4‬‬

‫وسنواصل‪ 7‬المقارنة على الخانة الثالثة وفيها الرقم ‪ ..5‬سنجد ّأنه أق ّل من الرقم ‪ ..4‬فلنقُم بعمل الالزم‪:‬‬

‫‪2‬‬
‫‪3‬‬
‫‪4‬‬
‫‪6‬‬
‫‪5‬‬

‫المرة الثالثة التي نقارنه فيها بالرقم‪7‬‬


‫نصل اآلن لمقارنة الخانة الرابعة بما يليها‪ ..‬سنجد فيها الرقم ‪ ..6‬آه‪ ..‬هذه هي ّ‬
‫‪ ..!!5‬أليس شيئا ممال؟‬
‫طبعا يجب تعويم الرقم‪.5 7‬‬

‫‪2‬‬
‫‪3‬‬
‫‪4‬‬
‫‪5‬‬
‫‪6‬‬

‫العملية‪ ..‬وطبعا‪ 7‬المصفوفة اآلن مرتّبة!‪ ..‬الحظ‬


‫ّ‬ ‫نصل اآلن للخانة األخيرة‪ ..‬لم يعد هناك ما نقارنها به‪ ..‬إذن فقد انتهت‬
‫أي خانات بعدها!!‬‫ألنها بالفعل بال فائدة‪ ،‬فال توجد ّ‬
‫ّأننا نستطيع االستغناء عن مقارنة الخانة األخيرة مع بعدها‪ّ ،‬‬
‫علما بأن كتابة الكود لهذه الطريقة‬
‫أي اعتراض على هذه الطريقة وما بها من عيوب‪ ،‬يجب أن أُحيطك ً‬
‫تطلق ّ‬
‫َ‬ ‫وقب َل أن‬
‫يعد أسهل ما يمكن‪ ،‬وهي الميزة الوحيدة في الموضوع!!‬
‫ُ‬
‫تعال َنر هذا الكود‪:‬‬
‫‪Dim Temp As String, I, J As Integer‬‬
‫)‪Dim Up As Integer = Arr.GetUpperBound(0‬‬
‫تكرارية لك ّل خانة من خانات المصفوفة ' ‪For I = 0 To Up -1‬‬
‫ّ‬ ‫جملة‬
‫الحالية ' ‪For J = I + 1 To Up‬‬
‫ّ‬ ‫تكرارية لك ّل الخانات التالية للخانة‬
‫ّ‬ ‫جملة‬
‫‪If Arr(I) > Arr(J) Then‬‬
‫تبادل قيمتي الخانتين ‪' Swap‬‬
‫)‪Temp = Arr(I‬‬
‫)‪Arr(I) = Arr(J‬‬
‫‪Arr(J) = Temp‬‬
‫‪End If‬‬
‫‪Next‬‬
‫‪Next‬‬
‫النص مجموعة من األرقام‬
‫ّ‬ ‫مربع‬
‫نصيةّ‪ ..‬فماذا لو أردنا أن نكتب في ّ‬
‫هجائي‪ ،‬فالمصفوفة ّ‬
‫ّ‬ ‫أن هذا ترتيب‬
‫الحظ ّ‬
‫ونرتّبها؟‬
‫أن ‪ 11‬ستوضع قبل ‪ 2‬و ‪ 34‬ستوضع‪ 7‬قبل ‪!!5‬‬ ‫هجائيا‪ ،‬بمعنى ّ‬
‫ّ‬ ‫سيتم ترتيبها‬
‫في هذه الحالة ّ‬
‫رقمي؟‪7‬‬
‫ّ‬ ‫فهل هناك طريقة إلجراء ترتيب‬
‫جدا‪ ..‬ك ّل ما سنفعله هو تغيير‪ 7‬سطر مقارنة خانتي المصفوفة في اإلجراء السابق إلى السطر التالي‪:‬‬
‫بسيطة ّ‬
‫‪If Val(Arr(I)) > Val(Arr(J)) Then‬‬
‫سيتم‬
‫معبرا عن رقم)‪ ..‬وبهذا ّ‬
‫نصا ّ‬‫رقمية ـ إذا كان قابال للتحويل (إذا كان ّ‬
‫النص إلى قيمة ّ‬
‫ّ‬ ‫تحول‬
‫إن دالة القيمة ‪ّ )(Val‬‬
‫ّ‬
‫المرة ال نصوصا‪.‬‬
‫إجراء الترتيب بين األرقام‪ 7‬الموجودة في المصفوفة باعتبارها أرقاما هذه ّ‬
‫وستجد الكود الكامل لهذا التطبيق في مجلّد برامج هذا الفصل‪.‬‬
‫عرفها المستخدم ‪User-Defined Data Types‬‬
‫األنواع التي يُ ّ‬

‫المرقََّمات ‪:Enumerators‬‬
‫ُ‬ ‫‪o‬‬
‫السجالت ‪:Structures‬‬ ‫‪o‬‬

‫المرقََّمات ‪Enumerators‬‬
‫ُ‬
‫المرقََّمات‪:‬‬
‫تعريف ُ‬ ‫‪‬‬
‫المرقّمات كمؤشّرات ‪:Flags‬‬ ‫‪‬‬
‫بعض وسائل خليّة المرقّم ‪:Enum Class‬‬ ‫‪‬‬

‫المرقََّمات‪:‬‬
‫تعريف ُ‬
‫المرقَّمات‪ :‬وهي أنواع تحتوى على تعبيرات ّ‬
‫نصّية مناظرة لمجموعة من األرقام‪،‬‬ ‫من األنواع التي تستطيع‪ 7‬تعريفها‪ُ ،‬‬
‫الستخدامها بدال من هذه األرقام‪ 7‬عند كتابة الكود‪ ،‬ليصبح أكثر سهولة ووضوحا عند قراءته‪.‬‬
‫المرقَّمات في بداية النموذج أو القالب أو ّ‬
‫الخلية كالتالي‪:‬‬ ‫عرف ُ‬ ‫وتُ ّ‬
‫اسم_المرقم ‪Private Enum‬‬
‫تعبير‪ = 1‬قيمة‪1‬‬
‫‪…….‬‬
‫تعبير_ن = قيمة_ن‬
‫‪End Enum‬‬
‫عام ‪ Public‬أو "صديق"‪ Friend 7‬للمرقّم‪ 7‬بدال من ‪.Private‬‬
‫إمكانية استخدام مجال ّ‬
‫ّ‬ ‫هذا مع‬
‫مثال‪ :‬مرقّم‪ 7‬أيام األسبوع‪:‬‬
‫‪Private Enum WeekDays‬‬
‫السبت = ‪0‬‬
‫‪Saturday = 0‬‬
‫األحد = ‪1‬‬
‫‪Sunday = 1‬‬
‫االثنين = ‪2‬‬
‫‪Monday = 2‬‬
‫الثالثاء = ‪3‬‬
‫‪Tuesday = 3‬‬
‫األربعاء = ‪4‬‬
‫‪Wednesday = 4‬‬
‫الخميس = ‪5‬‬
‫‪Thursday = 5‬‬
‫الجمعة = ‪6‬‬
‫‪Friday = 6‬‬
‫‪End Enum‬‬
‫واإلنجليزية‪ ،‬ومنحنا‪ 7‬اسمي نفس اليوم في اللغتين نفس الرقم‪ ،‬حتّى يمكن استخدام‬
‫ّ‬ ‫بالعربية‬
‫ّ‬ ‫األيام‬
‫طبعا تالحظ ّأننا أسمينا ّ‬
‫دت فعل هذا حتّى أريك أن المرقّم يمكن أن يحتوي‪ 7‬على أكثر من اسم لنفس‬‫تعم ُ‬
‫أحدهما مكان اآلخر بدون قيود‪ ..‬لقد ّ‬
‫الرقمية بدون مشاكل‪.‬‬
‫ّ‬ ‫القيمة‬
‫واآلن تعال نستخدم‪ 7‬هذا النوع‪:‬‬
‫‪Dim X As WeekDays‬‬
‫السبت‪X = WeekDays.‬‬
‫)"القيمتان متكافئتان"( ‪If X = WeekDays.Saturday Then MsgBox‬‬
‫الرقمي مباشرة‪ ..‬فمثال الكود التالي مماثل تماما لذلك الذي في‬
‫ّ‪7‬‬ ‫وال يوجد ما يمنعك من استخدام الرقم المناظر للتعبير‬
‫المثال السابق‪:‬‬
‫‪Dim X As WeekDays‬‬
‫‪X=0‬‬
‫)"القيمتان متكافئتان"( ‪If X = WeekDays.Saturday Then MsgBox‬‬
‫ويمكن تعريف المرقّم على الصيغة المختصرة التالية‪:‬‬
‫‪Private Enum DigitNames‬‬
‫‪Zero‬‬
‫‪One‬‬
‫‪Two‬‬
‫‪Three‬‬
‫‪Four‬‬
‫‪Five‬‬
‫‪Six‬‬
‫‪Seven‬‬
‫‪Eight‬‬
‫‪Nine‬‬
‫‪End Enum‬‬
‫أن التعريف السابق هو‬
‫أي ّ‬
‫سيعتبر ّأول عضو هو القيمة صفر‪ ،‬والثاني‪ 7‬هو القيمة ‪ ..،1‬وهكذا‪ّ ..‬‬
‫حيث في هذه الحالة ُ‬
‫اختصار لهذا التعريف‪:‬‬
‫‪Private Enum DigitNames‬‬
‫‪Zero = 0‬‬
‫‪One = 1‬‬
‫‪Two = 2‬‬
‫‪Three = 3‬‬
‫‪Four = 4‬‬
‫‪Five = 5‬‬
‫‪Six = 6‬‬
‫‪Seven = 7‬‬
‫‪Eight = 8‬‬
‫‪Nine = 9‬‬
‫‪End Enum‬‬

‫كما يمكن تحديد نوع قيم المرقّم‪ ..‬انظر للمثال التالي‪:‬‬


‫‪Private Enum DigitNames As Byte‬‬
‫‪Zero‬‬
‫‪One‬‬
‫‪Two‬‬
‫‪Three‬‬
‫‪Four‬‬
‫‪Five‬‬
‫‪Six‬‬
‫‪Seven‬‬
‫‪Eight‬‬
‫‪Nine‬‬
‫‪End Enum‬‬

‫ملحوظة لمبرمجي ‪:VB6‬‬


‫عرفه أنت‪ ،‬فإن هناك احتماال‬
‫المعرفة في اللغة‪ ،‬باإلضافة لما يمكن أن تُ ّ‬
‫ّ‬ ‫نظرا للكم الهائل من التعبيرات الرقمية‬
‫ً‬
‫نقيض‬
‫ُ‬ ‫كبيرا في حدوث تشابه بين أسمائها‪ ،‬وهو ما ترفضه قواعد اللغة‪ ،‬هذا باإلضافة لصعوبة حفظك لها‪ ،‬وهو‬
‫الم َرقّم‪ 7‬الذي‬
‫للهدف الذي ُوضعت من أجله‪ ..‬لهذا كان من األفضل عزل كل مجموعة من التعبيرات الرقمية داخل ُ‬
‫قيما مختلفة‪ ،‬ما دام لكل منها مدى‬
‫تنتمي إليه‪ ،‬وبهذا‪ 7‬يمكن السماح بتكرار‪ 7‬أسماء التعبيرات الرقمية ومنحها‪ً 7‬‬
‫‪ Domain‬مختلف‪ ..‬هذا هو السبب في أن التعبيرات الرقمية أصبحت تكتب كالتالي‪:‬‬
‫‪X = WeekDays.Saturday‬‬
‫الرقمي‪ 7،‬على خالف ما كنت تكتبه في النسخ السابقة‪ ،‬حيث كانت التعبيرات الرقمية‬
‫ّ‬ ‫بكتابة اسم المرقّم‪ 7‬قبل التعبير‬
‫تستخدم‪ 7‬مباشرة كالتالي‪:‬‬
‫‪X = Saturday‬‬
‫أن مرقَّما‪ 7‬اسمه ‪ Enum1‬يمكن أن يحتوي على التعبير ‪ Value1‬وقيمته ‪ ،1‬في نفس اللحظة التي‬
‫معنى هذا ّ‬
‫ألن مترجم الكود ‪ Compiler‬لن يرتبك‬
‫يحتوى‪ 7‬فيها مرقم‪ 7‬اسمه ‪ Enum2‬على التعبير ‪ Value1‬وقيمته ‪ّ ،2‬‬
‫بينهما‪ ،‬فنحن نستخدمهما‪ 7‬كالتالي‪:‬‬
‫‪X = Enum1.Value1‬‬
‫'بعد تنفيذ هذه الجملة‪ ،‬ستصبح قيمة ‪ X‬تساوي ‪1‬‬
‫‪X = Enum2.Value1‬‬
‫'بعد تنفيذ هذه الجملة‪ ،‬ستصبح قيمة ‪ X‬تساوي ‪2‬‬

‫المرقّمات كمؤشّرات ‪:Flags‬‬


‫متغير قيمتين أو أكثر معا؟‬
‫ماذا لو أردت أن تضع في ّ‬
‫ولكنها ستتّضح بالتأكيد في المرقّم التالي‪:‬‬
‫أهمّية ذلك ال تتّضح في مرقّم ّأيام األسبوع‪ّ ،‬‬
‫إن ّ‬‫ّ‬
‫‪Enum FileAttribute‬‬
‫عادي‬
‫للقراءة_فقط‬
‫خفي‬
‫ّ‬
‫مضغوط‬
‫‪End Enum‬‬
‫الملف يمكن أن يمتلك أكثر من سمة في نفس الوقت‪ ،‬إذ يمكن أن‬
‫ّ‬ ‫أن‬
‫الملف‪ ..‬المشكلة ّ‬
‫ّ‬ ‫يعبر عن سمات‬‫هذا المرقّم‪ّ 7‬‬
‫نعرفه من هذا المرقّم‪7‬‬
‫متغير ّ‬
‫أي ّ‬ ‫إن ّ‬
‫وخفيا وللقراءة فقط‪ّ ..‬‬
‫ّ‬ ‫وخفيا‪ ..‬أو مضغوطا‪7‬‬
‫ّ‬ ‫خفيا وللقراءة فقط‪ ..‬أو مضغوطا‪7‬‬
‫يكون ّ‬
‫نعبر إذن عن مثل هذه الحاالت؟‬
‫لن يحمل أكثر من قيمة‪ ،‬فكيف‪ 7‬يمكن أن ّ‬
‫تعرف‪ 7‬هذا المرقّم ليصبح كالتالي‪:‬‬
‫بسيطة‪ ..‬أعد ّ‬
‫‪<Flags()> Enum FileAttribute‬‬
‫عادي = ‪1‬‬
‫للقراءة_فقط = ‪2‬‬
‫خفي = ‪4‬‬
‫ّ‬
‫مضغوط = ‪8‬‬
‫‪End Enum‬‬
‫أساسيتين‪:‬‬
‫ّ‬ ‫حيث قمنا بخطوتين‬
‫‪ -‬استخدمنا السمة <‪ >)(Flags‬في تعريف‪ 7‬المرقّم‪.‬‬
‫أي رقمين أو أكثر ينتج عنه‬‫أن جمع ّ‬
‫ثنائية (‪ ،) 2 ، 2 ، 2 ، 2‬وذلك حتّى نضمن ّ‬
‫‪3‬‬ ‫‪2‬‬ ‫‪1‬‬ ‫‪0‬‬
‫‪ -‬كما رقّمنا التعبيرات بأرقام‪ّ 7‬‬
‫أن الرقم ‪ 6‬مثال‪ ،‬ال يمكن أن ينتج إال من جمع ‪ ،4 + 2‬وبهذا فهو يد ّل‬ ‫عدد متفرد غير ٍ‬
‫قابل للتكرار‪ ..‬بمعنى ّ‬ ‫ّ‬
‫وخفي‪.‬‬
‫ّ‬ ‫ملف للقراءة فقط‬
‫على ّ‬
‫جرب ما يلي‪:‬‬
‫ّ‬
‫‪Dim MyFileAttr As FileAttribute‬‬
‫خفي‪ Or FileAttribute.‬للقراءة_فقط‪MyFileAttr = FileAttribute.‬‬
‫ّ‬
‫)‪MsgBox(MyFileAttr.ToString‬‬
‫خفي"‪.‬‬
‫ستظهر الرسالة تحمل العبارة التالية‪" :‬للقراءة_فقط‪ّ ،‬‬
‫معينة‪ ،‬فعليك استخدام‬
‫أما لو شئت التحقّق من وجود سمة ّ‬
‫الحظ ّأننا استخدمنا المعامل ‪ Or‬لدمج أكثر من سمة‪ّ ..‬‬
‫المعامل ‪ And‬كالتالي‪:‬‬
‫…… ‪ Then‬للقراءة_فقط‪If MyFileAttr And FileAttribute.‬‬
‫ٍ‬
‫ولمزيد من التفاصيل‪ ،‬اقرأ موضوع‪ 7‬األقنعة ‪ Masks‬في ملحق رقم ‪.2‬‬

‫بعض وسائل خليّة المرقّم ‪:Enum Class‬‬


‫أهمها‪:‬‬
‫تعرفه ـ بعض الوسائل‪ ،‬سنذكر هنا ّ‬
‫أي مرقّم ّ‬
‫خلية المرقّم‪ 7‬ـ التي يرثها‪ّ 7‬‬
‫تمنحك ّ‬

‫اقرإ االسم ‪:GetName‬‬


‫معينا في أحد المرقّمات‪ ..‬فمثال‪ ،‬الجملة التالية تعرض رسالة‬
‫استخدم هذه الوسيلة لمعرفة االسم الذي يمثّل رقما ّ‬
‫"للقراة_فقط"‪:‬‬
‫))‪MsgBox([Enum].GetName(GetType(FileAttribute), 2‬‬
‫أساسية ولن يسمح لك ‪ VB‬باستخدامها‪7‬‬
‫ّ‬ ‫ألن هذه كلمة‬
‫الخلية ‪ Enum‬بين قوسين مضلّعين‪ ،‬وذلك ّ‬ ‫الحظ وضعنا السم ّ‬
‫األساسية‪ ،‬مثل [‬
‫ّ‬ ‫إن بإمكانك أن تفعل هذا مع باقي الخاليا‬
‫الخلية‪ ،‬إال بوضعها‪ 7‬بين هذين القوسين‪ّ ..‬‬
‫لتشير السم ّ‬
‫‪ ،]Integer‬و [‪ ....]String‬إلخ‪.‬‬
‫األول للوسيلة ال يقبل اسم المرقّم مباشرة‪ ،‬بل يقبل نوعه‪ ..‬ويمكن الحصول على هذا النوع‬
‫أن المعامل ّ‬
‫الحظ كذلك ّ‬
‫باستخدام الدالة ‪.GetType‬‬

‫اقرإ األسماء ‪:GetName‬‬


‫معين‪ ..‬انظر للمثال التالي‪:‬‬
‫يعرفها‪ 7‬مرقّم ّ‬
‫استخدم هذه الوسيلة للحصول على مصفوفة بها ك ّل األسماء التي ّ‬
‫)))‪Dim N() As String = ([Enum].GetNames(GetType(FileAttribute‬‬

‫اقرإ القيم ‪:GetValues‬‬


‫المعرفة في المرقّم‪7.‬‬ ‫ِ‬
‫للوسيلة السابقة‪ ،‬إال ّإنها تعيد مصفوفة تحتوي‪ 7‬على القيم‬ ‫مماثلةٌ‬
‫ّ‬

‫معرفة ‪:IsDefined‬‬‫إ ّنها ّ‬


‫األول‪.‬‬
‫معرفة في المرقّم المرسل في المعامل ّ‬
‫تعيد هذه الوسيلة ‪ ،True‬إذا كانت القيمة المرسلة في المعامل الثاني ّ‬

‫السجالت ‪:Structures‬‬
‫كثيرا ما ستحتاج للتعامل مع مجموعات من المتغيرات مختلفة األنواع‪ ،‬لتخزين سج ّل واحد من البيانات‪ ،‬كأن تريد‬
‫تخزين سجالت عن الطلبة‪ ،‬كل سجل يحتوي على اسم الطالب ورقمه وفصله‪ ...‬إلخ‪.‬‬
‫عرف مثل هذا السج ّل ‪ Structure‬كالتالي‪:‬‬
‫ويمكنك أن تُ ّ‬
‫‪Structure Student‬‬
‫‪Dim Name As String‬‬
‫‪Dim ID As Integer‬‬
‫‪Dim StudentClass As Integer‬‬
‫‪End Structure‬‬
‫إي إجراء أو دالة‪ ،‬وإ نما على مستوى النموذج أو القالب‪.‬‬
‫يكون داخل ّ‬
‫َ‬ ‫هذا التعريف‪ 7‬ال يمكن أن‬

‫هامة‪:‬‬
‫ملحوظة ّ‬
‫فكأن‬
‫موضعيا ‪ Local‬للمقطع الذي يوجد به‪ّ ،‬‬
‫ّ‬ ‫المعرف باستخدام كلمة ‪Dim‬‬
‫ّ‬ ‫المتغير‬
‫ّ‬ ‫أي موضع في اللغة‪ ،‬يكون‬
‫في ّ‬
‫كلمة ‪ Dim‬مناظرة لكلمة ‪ ..Private‬إال في مقطع السج ّل‪ ،‬حيث تكون كلمة ‪ Dim‬مناظرة لكلمة ‪ ،Public‬وبذلك‬
‫خاصا‪ ،‬ال‬
‫ّ‬ ‫المتغير‬
‫ّ‬ ‫أما لو شئت أن تجعل‬
‫عاما قابال لالستخدام‪ 7‬عبر اسم السج ّل في باقي البرنامج‪ّ ..‬‬
‫المتغير ّ‬
‫ّ‬ ‫يكون‬
‫فعرفه باستخدام‪ 7‬كلمة‬
‫يمكن استخدامه إال داخل مقطع السج ّل فقط‪ ،‬وال يظهر اسمه في قائمة أعضاء السج ّل‪ّ ،‬‬
‫‪.Private‬‬

‫المتغيرات‪ ،‬يمكنك استخدامه في برنامجك‪ ،‬كالتالي‪:‬‬


‫ّ‬ ‫اآلن قد صار لديك نوع جديد من أنواع‬
‫‪Dim Ahmad As Student‬‬
‫"أحمد شاكر" =‪Ahmad.Name‬‬
‫‪Ahmad.StudentClass = 5‬‬
‫‪Ahmad.ID = 40‬‬
‫ستالحظ أن قائمة األعضاء ستظهر لك بعد كتابة نقطة "‪ ".‬بعد اسم المتغير ‪ ،Ahmad‬تحتوي‪ 7‬على العناصر‪ 7‬التي‬
‫عرفتها في السج ّل‪ ،‬باإلضافة لبعض الدوال الجاهزة التي يمنحها لك ‪ ،VB‬مثل "يساوي" ‪ ،Equals‬و"اقرإ النوع"‪7‬‬
‫ّ‬
‫نتعرف على الدالة "يساوي" ‪.Equals‬‬
‫نص" ‪ ..ToString‬وسيكون من المفيد هنا أن ّ‬ ‫"حول إلى ّ‬‫‪ GetType‬و ّ‬
‫ألنك‬
‫ضح في األنواع البسيطة‪ ،‬كاألرقام‪ 7‬والنصوص‪ّ ،‬‬ ‫ولكن أهميتها ال تتّ ُ‬
‫ّ‬ ‫إن هذه الدالة موجودة في ك ّل أنواع البيانات‪،‬‬
‫ّ‬
‫أما في األنواع المعقّدة كالسجالت‪ ،‬التي‬
‫تستطيع التحقّق من تساوي قيمتين‪ ،‬باستخدام‪ 7‬عالمة التساوي‪ "=" 7‬مباشرة‪ّ ..‬‬
‫(متغير) في أحد السجالت‪ ،‬مع الحقل‬
‫ّ‬ ‫فإنك تحتاج للتأ ّكد من تساوي كل حقل‬
‫الداخلية‪ّ ،‬‬
‫ّ‬ ‫تحتوي على العديد من الحقول‬
‫أهمّية دالة التساوي ‪ ،Equals‬فهي تقوم بمقارنة كل‬
‫عملية شاقّة‪ ..‬هنا تبرز ّ‬
‫مما يجعلها ّ‬‫الذي يناظره في السج ّل اآلخر‪ّ ،‬‬
‫حقول السجلين‪ ،‬فإن تطابق السجالن فهما متساويان‪ ،‬وإ ن اختلف أحد الحقول عن مناظره‪ ،‬فالسجالن غير متساويين‪..‬‬
‫انظر هذا المثال‪:‬‬
‫‪Dim S1, S2 As Student‬‬
‫} امأل حقول السجلين ببعض البيانات {‬
‫‪If S1.Equals(S2) Then‬‬
‫"السجالن متماثالن" ‪MsgBox‬‬
‫‪Else‬‬
‫"السجالن مختلفان" ‪MsgBox‬‬
‫‪End If‬‬
‫التقليدية العقيمة التالية‪:‬‬
‫ّ‬ ‫وهو البديل السهل‪ ،‬للطريقة‬
‫‪Dim S1, S2 As Student‬‬
‫} امأل حقول السجلين ببعض البيانات {‬
‫_ ‪If S1.Name = S2.Name AND S1.ID = S2.ID AND‬‬
‫‪S1.StudentClass = S2. StudentClass Then‬‬
‫"السجالن متماثالن" ‪MsgBox‬‬
‫‪Else‬‬
‫"السجالن مختلفان" ‪MsgBox‬‬
‫‪End If‬‬
‫مما‬
‫فإذا كان لدينا هنا ‪ 3‬حقول في سجل الطالب‪ ،‬فيمكن أن يكون لديك في سجل آخر ‪ 10‬حقول أو ‪ 20‬حقال أو أكثر‪ّ ،‬‬
‫ومضيعة للوقت والجهد‪.‬‬
‫ّ‬ ‫عملية مملّة‬
‫سيجعل المقارنة حقال بحقل ّ‬
‫أي سج ّل‪:‬‬
‫تعرف مصفوفة ‪ Array‬من ّ‬ ‫متغير آخر‪ ،‬يمكنك أن ّ‬
‫وكأي ّ‬
‫ّ‬
‫‪Dim Students(10) As Student‬‬
‫"‪Students(0).Name ="Ahmad‬‬
‫‪Students(1).ID = 5‬‬
‫‪If Students(3).Equals(Students(4)) Then Exit Sub‬‬
‫بل يمكن أن يكون أحد حقول السج ّل نفسه مصفوفة‪ ،‬كما يلي‪:‬‬
‫‪Structure Person‬‬
‫‪Dim First As String‬‬
‫‪Dim Last As String‬‬
‫‪Dim Address As String‬‬
‫‪Dim Phone As String‬‬
‫‪Dim EMail(10) As String‬‬
‫‪End Structure‬‬
‫تخزن ‪ 11‬عنوانا‬
‫تالحظ أننا نحاول أن نجعل الحقل ‪ EMail‬مصفوفة من ‪ 11‬خانة (من ‪ 0‬إلى ‪ ،)10‬بحيث يمكنك أن ّ‬
‫بريديا لكل شخص‪ ..‬لألسف لن تنجح هذه المحاولة‪ ،‬فسيظهر‪ 7‬لك خط متعرج تحت هذا السطر‪ ،‬ولو حلّقت فوقه‬
‫ابتدائيا‪ ..‬لهذا‬
‫ّ‬ ‫بالفأرة‪ ،‬لظهر لك تلميح على الشاشة‪ ،‬يخبرك أن المصفوفة التي تنتمي للسج ّل ال يمكن منحها حجما‬
‫سنعدل التعريف إلى‪:‬‬
‫ّ‬
‫‪Structure Person‬‬
‫‪Dim First As String‬‬
‫‪Dim Last As String‬‬
‫‪Dim Address As String‬‬
‫‪Dim Phone As String‬‬
‫‪Dim EMail() As String‬‬
‫‪End Structure‬‬

‫والستخدام‪ 7‬هذا الحقل في الكود‪ ،‬إليك هذا المثال‪:‬‬


‫‪Dim APerson As Person‬‬
‫)‪ReDim APerson.EMail(10‬‬
‫"‪APerson.EMail(0) = "JDoe@tex.com‬‬
‫تعرف مصفوفة من هذا السج ّل‪ ،‬ثابتة أو مرنة‪ ،‬كالتالي‪:‬‬
‫وطبعا يمكنك أن ّ‬
‫‪Dim AllPeople(1000) As Person‬‬
‫)‪ReDim AllPeople(3).EMail(2‬‬
‫)‪ReDim AllPeople(4).EMail(5‬‬
‫‪If AllPeople(3).EMail(0) = AllPeople(4).EMail(1) Then Exit Sub‬‬
‫وإ ن كانت المشكلة التي ستواجهك هي حاجتك إلعادة تعريف أطوال المصفوفة ‪ Email‬لك ّل عنصر في من عناصر‪7‬‬
‫التكرارية التالية‪:‬‬
‫ّ‬ ‫المصفوفة ‪ ..!AllPeople‬ال مشكلة‪ ..‬استخدم الجملة‬
‫‪Dim C As Integer‬‬
‫‪For C = 0 To 1000‬‬
‫)‪ReDim AllPeople(C).EMail(10‬‬
‫‪Next‬‬
‫السجالت بالدوا ّل‪.‬‬
‫نتعرف على عالقة ّ‬
‫سنتعرف‪ 7‬عليه في الفصل القادم‪ ،‬عندما ّ‬
‫ّ‬ ‫السجالت‪،‬‬
‫مما يقال عن ّ‬
‫وهناك المزيد ّ‬

‫ولكن موضعها‪ 7‬ليس هنا‪ ،‬فهي‬


‫ّ‬ ‫عرفها‪ 7،‬وهي الخاليا ‪،Classes‬‬
‫جدا من أنواع المتغيرات التي يمكنك أن تُ ّ‬ ‫هام‬
‫بقي نوع ّ‬
‫مستق ّل بذاته‪.‬‬ ‫ٍ‬
‫لفصل‬ ‫تحتاج‬

You might also like