محمد حجازي قام بنشر أبريل 24, 2005 مشاركة قام بنشر أبريل 24, 2005 السلام عليكم ... أعتذر أولاً عن هذا العنوان الغريب ، ولكن كان لا بد منه (لزوم التشويق :d ). عندما يخوض المرء في غمار الـ VBA فإنه يكتشف الكثير و الكثير من الثنائيات المميزة التي لا يجدها في كتب البرمجة التقليدية . هذه الثنائيات ترقى بالمبرمج إلى مستوى الاحتراف و تسهل عليه الكثير من الأمور. سوف أقوم إنشاء الله بعرض متتابع لهذه الثنائيات و ذلك على شكل مشاركات مرتبة و مرقمة في هذا الموضوع وذلك كلما خطرت على بالي واحدة منها ، وهذا الموضوع مفتوح للنقاش من كل الأعضاء ، ولكن رجائي لكل من يريد عرض تجاربه التقيد بالترقيم الموضح للمشاركات . وشكراً سلفاً على التفاعل 1 رابط هذا التعليق شارك More sharing options...
محمد حجازي قام بنشر أبريل 24, 2005 الكاتب مشاركة قام بنشر أبريل 24, 2005 1. الفرق بين Select و Activate : قد يتساءل المرء : ما الفرق بين تحديد الهدف Select وتنشيطه Activate : قد يكون من الصعوبة بمكان الإجابة عن هذا السؤال ببضع كلمات ، و لكن وكما تعودنا ، فإن الأمثلة هي خير طريقة لإيصال المعلومات ، لاحظ الكود التالي : Sub SelectAndActivate1() With Sheets("Sheet1") .Range("A1:E10").Select .Range("C5").Activate End With End Sub نلاحظ أننا قمنا بتحديد المجال A1:E10 و لكن الخلية النشطة في هذا المجال (الخلية الجاهزة لإستقبال البيانات) هي الخلية C5 . يمكننا تطبيق نفس الأسلوب السابق على أوراق العمل ، لاحظ الكود التالي : Sub SelectAndActivate2() Sheets(Array("Sheet1", "Sheet2", "Sheet3")).Select Sheets("Sheet2").Activate End Sub ولكن يجب عليك الانتباه إلى أن هذه الميزة متوفرة فقط في حال كون الهدف المنشط ينتمي إلى مجال الأهداف المحددة ، لفهم الموضوع بصورة أوضح راقب ما ينج عن هذه الأكواد : Sub SelectAndActivate3() With Sheets("Sheet1") .Range("A1:E10").Select .Range("H6").Activate End With End Sub Sub SelectAndActivate4() Sheets(Array("Sheet1", "Sheet2", "Sheet3")).Select Sheets("Sheet4").Activate End Sub لاحظ أن الهدف المحدد هو نفسه الهدف المنشط :p خذ هذا الأمر في الحسبان :pp: نفس الشيء يحصل عندما يكون الهدف المحدد هو هدف واحد ، في هذه الحالة فإن الهدف المحدد يكون منشطاً بصورة تلقائية ، وهنا لا فرق نستطيع استناجه بين هذين الكودين : Sub SelectAndActivate5() Sheets("Sheet1").Activate End Sub Sub SelectAndActivate6() Sheets("Sheet1").Select End Sub مرفق ملف يتضمن الحالات السابقة مع أكوادها : بالتوفيق Select_Activate.zip 1 رابط هذا التعليق شارك More sharing options...
محمد حجازي قام بنشر أبريل 24, 2005 الكاتب مشاركة قام بنشر أبريل 24, 2005 2. الفرق بين Sheets و Worksheets : الكلمة المحجوزة Worksheets تستخدم للإشارة إلى أوراق العمل فقط في المصنف ، أما الكلمة المحجوزة Sheets فتستخدم للإشارة إلى الأوراق بكافة أنواعها (أوراق العمل ، أوراق التخطيط ، ... ، الخ) في المصنف ، لاحظ الأكواد التالية : Sub WorksheetsAndSheets1() Sheets("Sheet1").Activate End Sub Sub WorksheetsAndSheets2() Sheets("Chart1").Activate End Sub Sub WorksheetsAndSheets3() Worksheets("Sheet1").Activate End Sub Sub WorksheetsAndSheets4() Worksheets("Chart1").Activate End Sub نلاحظ أن الكود الرابع يعطي الخطأ رقم 9 عند تشغيله :Subscript out of range و هذا ينطبق مع ما قلناه سابقاً ولكن ألم يخطر في بالك السؤال التالي: لماذا لا نستخدم الكلمة المحجوزة Sheets في جميع أكوادنا ؟!!!! هذا بالفعل ما أقوم به وذلك لأن الكلمة المحجوزة Sheets أسهل بالكتابة و أريح على الذهن :d ، ولكن مهلاً يمكننا الاستفادة من التفريق السابق في أكوادنا : بفرض أنه لدينا مصنف يحتوي على ثلاثة أوراق عمل Sheet1 ، Sheet2 ، Sheet3 و ورقة تخطيط واحدة Chart1 ، وبفرض أن ترتيب الأوراق كان كما يلي : Sheet1 ، Sheet2 ، Chart1 ، Sheet3 الآن لنقم بتطبيق الكود التالي : Sub WorksheetsAndSheets5() Worksheets(3).Activate End Sub نلاحظ أنه تم تنشيط الورقة Sheet3 ، هل تعرف لماذا؟ الكود السابق يقوم بتنشيط ورقة العمل الواقعة في الترتيب الثالث ، وبما أننا هنا نتعامل مع الكلمة المحجوزة Worksheets فإنه لم يتم أخذ الورقة Chart1 في الحسبان أثناء حساب ترتيب الأوراق. مرفق ملف يتضمن الحالات السابقة مع أكوادها : بالتوفيق Worksheets_Sheets.zip 1 رابط هذا التعليق شارك More sharing options...
smail_d قام بنشر أبريل 28, 2005 مشاركة قام بنشر أبريل 28, 2005 ألف شكر يأخينا الكريم مزيدا شكرا رابط هذا التعليق شارك More sharing options...
محمد حجازي قام بنشر مايو 10, 2005 الكاتب مشاركة قام بنشر مايو 10, 2005 3. الفرق بين Range و Cells : - يستخدم الأسلوب Range للإشارة إلى مجال الخلايا و ذلك عن طريق كتابة المجال باستخدام نظام الترميز A1 (تتم الإشارة إلى خلية ما بإدخال حرف العمود متبوعاً برقم الصف) ، لاحظ الأكواد التالية : Sub Test1() Sheets("Sheet1").Range("A1").ClearContents End Sub الكود السابق يقوم بمسح القيم الموجودة في الخلية A1 . Sub Test2() Sheets("Sheet1").Range("B2:C5").ClearContents End Sub الكود السابق يقوم بمسح القيم الموجودة في المجال B2:C5 . Sub Test3() Sheets("Sheet1").Range("A2:B3,D3,E5:G7,H11").ClearContents End Sub الكود السابق يقوم بمسح القيم الموجودة في المجالات A2:B3 ، D3 ، E5:G7 ، H11 . - أما الأسلوب Cells فيستخدم للإشارة إلى الخلايا المختلفة عن طريق كتابة رقم صف الخلية يليه رقم العامود ، لاحظ الكود التالي : Sub Test4() Sheets("Sheet1").Cells(2, 5).ClearContents End Sub الكود السابق يقوم بمسح القيم الموجودة في الخلية الواقعة في الصف الثاني و العامود الخامس من الورقة Sheet1 (أي الخلية E2). بالنسبة لقدرة الأسلوب Cells على الإشارة للمجالات المختلفة فهي محدودة ، ولا يستطيع ذلك إلى عن طريق الاستعانة بالأسلوب Range ، لاحظ الكود التالي : Sub Test5() Sheets("Sheet1").Range(Cells(2, 3), Cells(5, 7)).ClearContents End Sub الكود السابق يقوم بمسح القيم الموجودة في المجال C2:G5 الموجود في الورقة Sheet1 . مما سبق فإنه يبدو لنا أن التعامل مع الأسلوب Range هو أسهل بكثير من التعامل مع مثيلها Cells ، ولكن مهلاً ....... فالأسلوب Cells يمتلك مرونة عالية في التعامل مع الأهداف المتغيرة ، لاحظ الكود التالي : Sub MultiplicationTable1() Dim i As Byte, ii As Byte With Sheets("Sheet1") For i = 1 To 10 For ii = 1 To 10 .Cells(i, ii) = i * ii Next ii Next i End With End Sub الكود السابق هو كود مدرج في أحد مشاركاتنا السابقة ، ويقوم بإنشاء جدول الضرب في الورقة Sheet1 . لاحظ مقدار المرونة الذي يوفره لنا الأسلوب Cells ، و فكر بالصعوبات التي من المحتمل أن تواجهنا عند استخدام الأسلوب Range (و خصوصاً عند التعامل مع ترتيب الأعمدة) . مثال آخر يظهر مرونة الأسلوب Cells : بفرض أن لدينا جدول متوضع بين العامودين B و E ، ونريد إنشاء زر أمر لمسح قيم أي سجل بالاعتماد على رقمه . بالاعتماد على الأسلوب Cells فإننا نستطيع كتابة الكود التالي : Sub DeleteRecord1() Dim NumberRow As Long NumberRow = Application.InputBox(prompt:="ادخل رقم الصف", Title:="رقم الصف", Type:=1) If NumberRow = False Or NumberRow > 65536 Then Exit Sub Sheets("Sheet1").Range(Cells(NumberRow, 2), Cells(NumberRow, 5)).ClearContents End Sub الآن إذا أردنا الاعتماد على الأسلوب Range في الكود السابق عوضاً عن الأسلوب Cells ، فإننا سنحتاج لتعريف متغير إضافي MyRange من نوع نص و كتابة سطر إضافي لإنشاء المرجع المطلوب قبل استخدامه في الأسلوب Range ، لاحظ الكود التالي : Sub DeleteRecord2() Dim NumberRow As Long Dim MyRange As String NumberRow = Application.InputBox(prompt:="ادخل رقم الصف", Title:="رقم الصف", Type:=1) If NumberRow = False Or NumberRow > 65536 Then Exit Sub MyRange = "B" & NumberRow & ":E" & NumberRow Sheets("Sheet1").Range(MyRange).ClearContents End Sub بنظرة بسيطة نلاحظ أ الكود الأول هو أكثر كفاءة من الكود الثاني . لأخذ العلم ، فإن الطريقة السابقة أدرجت لتبيان الفرق بين الأسلوبين ، وذلك مع العلم بأنه يمكن حل المشكلة السابقة بطريقة أكثر بساطة و ذلك إذا ما اعتمدنا على الأسلوب Offset . ملاحظات هامة جداً عن الأسلوبين Cells و Range : 1. عندما تجري عملية مناقلة بين خلايا معينة ، فإنه لا يشترط استخدام نفس الأسلوب للإشارة إلى الخلايا أو النطاقات في كلتا المجموعتين : فمثلاً إذا أردنا لصق قيم المجال A1:A5 في المجال B1:B5 فإننا نستطيع عمل ذلك باستخدام أي طريقة من الطرق التالية : Sub Test6() With Sheets("Sheet1") Range("B1:B5").Value = Range("A1:A5").Value End With End Sub Sub Test7() With Sheets("Sheet1") Range(Cells(1, 2), Cells(5, 2)).Value = Range(Cells(1, 1), Cells(5, 1)).Value End With End Sub Sub Test8() With Sheets("Sheet1") Range(Cells(1, 2), Cells(5, 2)).Value = Range("A1:A5").Value End With End Sub Sub Test9() With Sheets("Sheet1") Range("B1:B5").Value = Range(Cells(1, 1), Cells(5, 1)).Value End With End Sub 2. قدرة كلا الأسلوبين Cells و Range على التكيف مع مجموعات الأهداف المختلفة : وهذه برأيي أهم ميزة يمتلكها هذين الأسلوبين ، وتقوم هذه الميزة على أن الأسلوب يشير للموضع النسبي للهدف المحتضن بالاعتماد على الهدف الحاضن له . لفهم هذه الميزة بشكل أوضح لاحظ الكودين التاليين : Sub Cells_Place1() Dim MyRange As Range Set MyRange = Sheets("Sheet1").Range("C5:H10") Sheets("Sheet1").Cells(1, 1).Value = "هذه الخلية الأولى من الورقة Sheet1" MyRange.Cells(1, 1).Value = "هذه الخلية الأولى من المجال MyRange" End Sub Sub Cells_Place2() Dim MyRange As Range Set MyRange = Sheets("Sheet1").Range("C5:H10") Sheets("Sheet1").Range("A1").Value = "هذه الخلية الأولى من الورقة Sheet1" MyRange.Range("A1").Value = "هذه الخلية الأولى من المجال MyRange" End Sub نلاحظ أن الأسلوبين Cells و Range قد اعتمدا على كل من الهدفين Sheet1 و MyRange ـ (C5:H10) من أجل تحديد الهدف الناتج (المحتضن) . بالنسبة لي ، فإنني أعتقد أن الأسلوب Cells أقدر على التعامل مع هذه الميزة بصورة أكثر كفاءة ، لاحظ الكود التالي : Sub Cell_Index() On Error GoTo NoRange Dim MyRange As Range Dim NumberRow As Long Dim NumberColumn As Long Set MyRange = Application.InputBox(prompt:="أدخل مجال الخلايا الذي تريده", Title:="مجال الخلايا", Type:=8) On Error GoTo 0 For NumberRow = 1 To MyRange.Rows.Count For NumberColumn = 1 To MyRange.Columns.Count MyRange.Cells(NumberRow, NumberColumn).Value = NumberRow & "×" & NumberColumn Next NumberColumn Next NumberRow Exit Sub NoRange: If Err = 424 Then Exit Sub Else MsgBox Err.Description End If End Sub الكود السابق يقوم بإدراج ترتيب كل خلية (رقم صفها و عامودها) وذلك بالنسبة للهدف الحاضن MyRange . لا تقلق أخي إذا لم تفهم هذه الميزة بصورة كاملة ، وذلك لأن لنا عودة معها عندما نقوم بشرح الأسلوبين CurrentRegion و UsedRange . تحياتي 1 رابط هذا التعليق شارك More sharing options...
الردود الموصى بها