[TABLE='width:70%;'][CELL='filter:;']
محتوى الدرس:
كيفية تعريف مصفوفة ذات حجم متغير Dynamic Array.
حفظ محتويات الـDynamic Arrays عند إعادة تعريفيها.
جملة ReDim.
المصفوفات متغيرة الحجم Dynamic Array:
في بعض الأحيان، لا نعرف مسبقاً حجم المصفوفة التي سنستخدمها في البرنامج بالضبط، وقد نريد تغيير حجم المصفوفة أثناء تشغيل البرنامج، هنا سنحتاج إلى المصفوفات ذات الحجم المتغير Dynamic حيث يمكننا تغيير حجمها في أي وقت.
تعتبر المصفوفات متغيرة الحجم أحد مميزات الفيجيوال بيسك، وهي تساعد في تنظيم الذاكرة بكفاءة. فمثلاً، يمكن استخدام مصفوفة كبيرة لوقت قصير ثم إعادة تحجيمها لتحرير مساحة من الذاكرة عندما لا نحتاجها. وهذا من شأنه تسريع المعالجة.
ولصناعة Dynamic Array نتبع التالي:
نعلن عنها بأحد أوامر الإعلان الموضحة في الدرس السابق (Public or Private or Dim or Static) ونجعلها ديناميكية بعدم أي رقم في الأقواس كما يوضح المثال التالي:
Dim AnyArray( )
نعيد الإعلان عنها مع تحديد عدد العناصر باستخدام جملة ReDim كما في المثال التالي:
ReDim AnyArray( x+1 )
ملاحظات:
يمكن لجملة ReDim الظهور فقط في الـProcedure. وبعكس جملتي Dim, & Static فإن جملة ReDim قابلة للتنفيذ Executable.
تستخدم جملة ReDim نفس الصيغة Syntax المستخدم مع مصفوفات الحجم الثابت Fixed Array.
كل جملة من جمل ReDim يمكنها تغيير عدد العناصر بالإضافة إلى الحد الأعلى والحد الأدنى لكل بعد للمصفوفة، ومع ذلك فإن عدد الأبعاد في المصفوفة لا يمكن تغييره.
مثال:
لصناعة مصفوفة M كمصفوفة متغيرة الحجم، نعلن عنها أولاً في الـModule على النحو التالي:
Dim M( ) As Integer
ثم نعيد الإعلان عنها داخل الـProcedure على النحو التالي:
Sub ANY_NAME()
ReDim M(9, 15)
End Sub
حفظ محتويات المصفوفة متغيرة الحجم عند إعادة تعريفها:
لابد من التنويه إلى أنه تمحى جميع القيم المخزنة في المصفوفة كل مرة يعاد فيها تنفيذ جملة ReDim. ويجعل الفيجيوال بيسك القيم كالتالي:
Empty Value في حالة الــــ Variant Array
Zero في حالة الــــ Numeric Array
Zero-Length String في حالة الــــ String Array
Nothing في حالة الــــ Array of objects
وهذا مفيد عندما نريد تجهيز المصفوفة لبيانات جديدة أو عندما نريد اختزال حجم المصفوفة لتأخذ أقل مساحة ممكنة في الذاكرة. ولكن أحياناً نريد تغيير حجم المصفوفة دون فقد بياناتها!
يمكننا فعل ذلك باستخدام جملة ReDim مع كلمة Preserve وتعني "احفظ".
مثال:
الكود التالي يستخدم جملة ReDim لتخصيص، ثم إعادة تخصيص مساحة تخزينية لمصفوفة متغيرة الحجم، مع افتراض أن الـOption Base يساوي 1:
Dim MyArray ( ) As Integer 'declare Dynamic Array
ReDim MyArray( 5 ) 'allocate 5 elements
For I = 0 To 5 'loop 5 times
MyArray(I) = I 'initialize array elements
Next I
ReDim MyArray( 10 ) 'allocate 10 elements
For I = 0 To 10 'loop 10 times
MyArray(I) = I 'initialize array elements
Next I
الجملة التالية تغير حجم المصفوفة ولكنها لا تمحو العناصر الموجودة بها:
ReDim Preserve MyArray( 10 )
والآن يمكننا كتابة ملخص متكامل لجملة ReDim.
جملة ReDim:
تستخدم في مستوى الـProcedure لإعادة تخصيص allocates مساحة تخزينية storage space لمصفوفة متغيرة الحجم Dynamic array.
صيغتها Syntax:
ReDim [Preserve] varname(subscripts) [As type] [, varname (subscripts) [As type]]
حيث أن:
Preserve اختيارية، وتستخدم لحفظ البيانات الموجودة في المصفوفة عند تغيير حجم آخر بعد فيها.
varname اسم المتغير (اسم المصفوفة).
subscripts أبعاد المصفوفة (عددهم على الأكثر 60) وتستخدم الشكل التالي:
[lower To] upper [, [lower To] upper]
والقيمة الأدنى تحددها جملة Option Base وإذا لم توجد، يكون الحد الأدنى هو الافتراضي (صفر).
type اختيارية، وتحدد نوع بيان عناصر المصفوفة. وقد تكون أي من الأنواع التالية:
Byte, Boolean, Integer, Long, Single, Double, Currency, Decimal, Date, Object, String, Variant, User-defined.
[, varname (subscripts) [As type]] اختيارية، لإعادة تحجيم مصفوفة أخرى.
ملاحظات هامة:
جميع ما ذكر في الصيغة داخل قوسين مربعين [] يعتبر اختياري يمكن الاستغناء عنه حين عدم الحاجة إليه.
تستخدم جملة ReDim لتحجيم أو إعادة تحجيم مصفوفة متغيرة الحجم Dynamic Array والتي بالفعل قد أعلن عنها مسبقاً باستخدام أي من الجمل Dim, Private, Public مع أقواس فارغة (أي بدون ذكر الأبعاد).
يمكن تكرار استخدام جملة ReDim لتغيير عدد العناصر والأبعاد لمصفوفة، ومع ذلك لا يمكن الإعلان عن مصفوفة بنوع معين من البيانات ثم إعادة تعريفها لاحقاً مع تغيير نوع البيان لنوع آخر إلا إذا كانت المصفوفة محتواه في variant.
إذا كانت المصفوفة محتواه في variant فإن نوع بيان العناصر يمكن أن يتغير باستخدام المقطع As Type إلا إذا استخدمنا كلمة Preserve ففي هذه الحالة لا يسمح بتغييرات.
إذا استخدمنا كلمة Preserve يمكن فقط تحجيم البعد الأخير للمصفوفة ولا يمكن تغيير عدد الأبعاد على الإطلاق.
إذا كان للمصفوفة بعد واحد فيمكن إعادة تحجيم هذا البعد لأنه البعد الأخير والوحيد بالمصفوفة.
وإذا كان للمصفوفة بعدين أو أكثر فيمكن فقط تغيير حجم البعد الأخير مع الاحتفاظ بمحتويات المصفوفة.
عندما نستخدم Preserve يمكن تغيير حجم المصفوفة بتغيير الحد الأعلى بينما ينتج لدينا خطأ حين تغيير الحد الأدنى.
إذا صنعنا مصفوفة أصغر مما كانت فإن بيانات العناصر المخزنة سوف تفقد.
إذا مررنا pass مصفوفة إلى Procedure بالـRefrence فإنه لا يمكن تغيير أبعادها من داخل الـProcedure.
تحذير:
جملة ReDim ستعمل وكأنها جملة إعلان إذا كان المتغير (المصفوفة) التي تعلن عنه غير موجود على مستوى الـProcedure أو الـModule. وإذا كان هناك متغير آخر بنفس الاسم قد أنشئ بعد ذلك وحتى لو كان في النطاق ككل Scope؛ فإن ReDim سوف ترجع للمتغير الأخير ولن يتسبب عن ذلك خطأ في الترجمة Compilation error حتى ولو كانت جملة Option Explicit فعّالة. وبذلك لن يدرك المبرمج أنه هناك خطأ بالشيفرة code.
ولتفادي هذا التعارض لا ينبغي استخدام جملة ReDim كجملة إعلان بدلاً من Dim مثلاً، ولكن نستخدمها فقط لإعادة تعريف حجم المصفوفة.
مثال(1):
يبين المثال التالي كيف يمكن زيادة حجم البعد الأخير للمصفوفة متغيرة الحجم بدون محو البيانات الموجودة فيها:
ReDim X(10,10,10)
ReDim Preserve X(10,10,15)
مثال(2):
لإدخال قائمة من الأعداد غير معلومة العدد مسبقاً (أي وقت كتابة الشيفرة code) ويسأل عن عددها عند تشغيل الـcode:
Dim X() As Integer
N = InputBox("أدخل عدد العناصر من فضلك")
ReDim X(N)
For I = 1 To N
X(I) = InputBox("أدخل عنصر من القائمة")
Next I
مثال(3):
لإدخال قائمة من الأعداد غير معلومة العدد مسبقاً (أي وقت كتابة الشيفرة code)، ولا يسأل عن عددها عند تشغيل الـcode ولكن يقوم المستخدم بإدخال صفر (أو أي قيمة متقف عليها) عند الانتهاء من ادخال عناصر المصفوفة:
Dim X()
Do
prompt=" أدخل عنصراً من القائمة وفي النهاية أدخل صفر"
DummyVariable = InputBox(prompt)
IF DummyVariable <> 0 Then
UpperLimit = UpperLimit + 1
ReDim Preserve X(UpperLimit)
X(UpperLimit) = DummyVariable
Else
Exit Do
End IF
Loop
وإلى هنا نكون قد انتهينا من دروس المصفوفات وجميع ما يتعلق بها في الفيجيوال بيسك، أرجو من الله أخي الكريم أن تفيدك
منقول للأهمية
أم حيدر علي
[/CELL][/TABLE]كيفية تعريف مصفوفة ذات حجم متغير Dynamic Array.
حفظ محتويات الـDynamic Arrays عند إعادة تعريفيها.
جملة ReDim.
المصفوفات متغيرة الحجم Dynamic Array:
في بعض الأحيان، لا نعرف مسبقاً حجم المصفوفة التي سنستخدمها في البرنامج بالضبط، وقد نريد تغيير حجم المصفوفة أثناء تشغيل البرنامج، هنا سنحتاج إلى المصفوفات ذات الحجم المتغير Dynamic حيث يمكننا تغيير حجمها في أي وقت.
تعتبر المصفوفات متغيرة الحجم أحد مميزات الفيجيوال بيسك، وهي تساعد في تنظيم الذاكرة بكفاءة. فمثلاً، يمكن استخدام مصفوفة كبيرة لوقت قصير ثم إعادة تحجيمها لتحرير مساحة من الذاكرة عندما لا نحتاجها. وهذا من شأنه تسريع المعالجة.
ولصناعة Dynamic Array نتبع التالي:
نعلن عنها بأحد أوامر الإعلان الموضحة في الدرس السابق (Public or Private or Dim or Static) ونجعلها ديناميكية بعدم أي رقم في الأقواس كما يوضح المثال التالي:
Dim AnyArray( )
نعيد الإعلان عنها مع تحديد عدد العناصر باستخدام جملة ReDim كما في المثال التالي:
ReDim AnyArray( x+1 )
ملاحظات:
يمكن لجملة ReDim الظهور فقط في الـProcedure. وبعكس جملتي Dim, & Static فإن جملة ReDim قابلة للتنفيذ Executable.
تستخدم جملة ReDim نفس الصيغة Syntax المستخدم مع مصفوفات الحجم الثابت Fixed Array.
كل جملة من جمل ReDim يمكنها تغيير عدد العناصر بالإضافة إلى الحد الأعلى والحد الأدنى لكل بعد للمصفوفة، ومع ذلك فإن عدد الأبعاد في المصفوفة لا يمكن تغييره.
مثال:
لصناعة مصفوفة M كمصفوفة متغيرة الحجم، نعلن عنها أولاً في الـModule على النحو التالي:
Dim M( ) As Integer
ثم نعيد الإعلان عنها داخل الـProcedure على النحو التالي:
Sub ANY_NAME()
ReDim M(9, 15)
End Sub
حفظ محتويات المصفوفة متغيرة الحجم عند إعادة تعريفها:
لابد من التنويه إلى أنه تمحى جميع القيم المخزنة في المصفوفة كل مرة يعاد فيها تنفيذ جملة ReDim. ويجعل الفيجيوال بيسك القيم كالتالي:
Empty Value في حالة الــــ Variant Array
Zero في حالة الــــ Numeric Array
Zero-Length String في حالة الــــ String Array
Nothing في حالة الــــ Array of objects
وهذا مفيد عندما نريد تجهيز المصفوفة لبيانات جديدة أو عندما نريد اختزال حجم المصفوفة لتأخذ أقل مساحة ممكنة في الذاكرة. ولكن أحياناً نريد تغيير حجم المصفوفة دون فقد بياناتها!
يمكننا فعل ذلك باستخدام جملة ReDim مع كلمة Preserve وتعني "احفظ".
مثال:
الكود التالي يستخدم جملة ReDim لتخصيص، ثم إعادة تخصيص مساحة تخزينية لمصفوفة متغيرة الحجم، مع افتراض أن الـOption Base يساوي 1:
Dim MyArray ( ) As Integer 'declare Dynamic Array
ReDim MyArray( 5 ) 'allocate 5 elements
For I = 0 To 5 'loop 5 times
MyArray(I) = I 'initialize array elements
Next I
ReDim MyArray( 10 ) 'allocate 10 elements
For I = 0 To 10 'loop 10 times
MyArray(I) = I 'initialize array elements
Next I
الجملة التالية تغير حجم المصفوفة ولكنها لا تمحو العناصر الموجودة بها:
ReDim Preserve MyArray( 10 )
والآن يمكننا كتابة ملخص متكامل لجملة ReDim.
جملة ReDim:
تستخدم في مستوى الـProcedure لإعادة تخصيص allocates مساحة تخزينية storage space لمصفوفة متغيرة الحجم Dynamic array.
صيغتها Syntax:
ReDim [Preserve] varname(subscripts) [As type] [, varname (subscripts) [As type]]
حيث أن:
Preserve اختيارية، وتستخدم لحفظ البيانات الموجودة في المصفوفة عند تغيير حجم آخر بعد فيها.
varname اسم المتغير (اسم المصفوفة).
subscripts أبعاد المصفوفة (عددهم على الأكثر 60) وتستخدم الشكل التالي:
[lower To] upper [, [lower To] upper]
والقيمة الأدنى تحددها جملة Option Base وإذا لم توجد، يكون الحد الأدنى هو الافتراضي (صفر).
type اختيارية، وتحدد نوع بيان عناصر المصفوفة. وقد تكون أي من الأنواع التالية:
Byte, Boolean, Integer, Long, Single, Double, Currency, Decimal, Date, Object, String, Variant, User-defined.
[, varname (subscripts) [As type]] اختيارية، لإعادة تحجيم مصفوفة أخرى.
ملاحظات هامة:
جميع ما ذكر في الصيغة داخل قوسين مربعين [] يعتبر اختياري يمكن الاستغناء عنه حين عدم الحاجة إليه.
تستخدم جملة ReDim لتحجيم أو إعادة تحجيم مصفوفة متغيرة الحجم Dynamic Array والتي بالفعل قد أعلن عنها مسبقاً باستخدام أي من الجمل Dim, Private, Public مع أقواس فارغة (أي بدون ذكر الأبعاد).
يمكن تكرار استخدام جملة ReDim لتغيير عدد العناصر والأبعاد لمصفوفة، ومع ذلك لا يمكن الإعلان عن مصفوفة بنوع معين من البيانات ثم إعادة تعريفها لاحقاً مع تغيير نوع البيان لنوع آخر إلا إذا كانت المصفوفة محتواه في variant.
إذا كانت المصفوفة محتواه في variant فإن نوع بيان العناصر يمكن أن يتغير باستخدام المقطع As Type إلا إذا استخدمنا كلمة Preserve ففي هذه الحالة لا يسمح بتغييرات.
إذا استخدمنا كلمة Preserve يمكن فقط تحجيم البعد الأخير للمصفوفة ولا يمكن تغيير عدد الأبعاد على الإطلاق.
إذا كان للمصفوفة بعد واحد فيمكن إعادة تحجيم هذا البعد لأنه البعد الأخير والوحيد بالمصفوفة.
وإذا كان للمصفوفة بعدين أو أكثر فيمكن فقط تغيير حجم البعد الأخير مع الاحتفاظ بمحتويات المصفوفة.
عندما نستخدم Preserve يمكن تغيير حجم المصفوفة بتغيير الحد الأعلى بينما ينتج لدينا خطأ حين تغيير الحد الأدنى.
إذا صنعنا مصفوفة أصغر مما كانت فإن بيانات العناصر المخزنة سوف تفقد.
إذا مررنا pass مصفوفة إلى Procedure بالـRefrence فإنه لا يمكن تغيير أبعادها من داخل الـProcedure.
تحذير:
جملة ReDim ستعمل وكأنها جملة إعلان إذا كان المتغير (المصفوفة) التي تعلن عنه غير موجود على مستوى الـProcedure أو الـModule. وإذا كان هناك متغير آخر بنفس الاسم قد أنشئ بعد ذلك وحتى لو كان في النطاق ككل Scope؛ فإن ReDim سوف ترجع للمتغير الأخير ولن يتسبب عن ذلك خطأ في الترجمة Compilation error حتى ولو كانت جملة Option Explicit فعّالة. وبذلك لن يدرك المبرمج أنه هناك خطأ بالشيفرة code.
ولتفادي هذا التعارض لا ينبغي استخدام جملة ReDim كجملة إعلان بدلاً من Dim مثلاً، ولكن نستخدمها فقط لإعادة تعريف حجم المصفوفة.
مثال(1):
يبين المثال التالي كيف يمكن زيادة حجم البعد الأخير للمصفوفة متغيرة الحجم بدون محو البيانات الموجودة فيها:
ReDim X(10,10,10)
ReDim Preserve X(10,10,15)
مثال(2):
لإدخال قائمة من الأعداد غير معلومة العدد مسبقاً (أي وقت كتابة الشيفرة code) ويسأل عن عددها عند تشغيل الـcode:
Dim X() As Integer
N = InputBox("أدخل عدد العناصر من فضلك")
ReDim X(N)
For I = 1 To N
X(I) = InputBox("أدخل عنصر من القائمة")
Next I
مثال(3):
لإدخال قائمة من الأعداد غير معلومة العدد مسبقاً (أي وقت كتابة الشيفرة code)، ولا يسأل عن عددها عند تشغيل الـcode ولكن يقوم المستخدم بإدخال صفر (أو أي قيمة متقف عليها) عند الانتهاء من ادخال عناصر المصفوفة:
Dim X()
Do
prompt=" أدخل عنصراً من القائمة وفي النهاية أدخل صفر"
DummyVariable = InputBox(prompt)
IF DummyVariable <> 0 Then
UpperLimit = UpperLimit + 1
ReDim Preserve X(UpperLimit)
X(UpperLimit) = DummyVariable
Else
Exit Do
End IF
Loop
وإلى هنا نكون قد انتهينا من دروس المصفوفات وجميع ما يتعلق بها في الفيجيوال بيسك، أرجو من الله أخي الكريم أن تفيدك

منقول للأهمية
أم حيدر علي