لماذا تكون وحدات الماكرو في Excel لدي بطيئة عند تنشيط think-cell؟
تتمثل إحدى المشاكل الشائعة التي قد تؤثر بالسلب على الأداء في وحدات الماكرو بلغة VBA في استخدام الوظيفة .Select
. في كل مرة يتم فيها تحديد خلية في Excel، يتم إخطار كل وظيفة إضافية في Excel (بما في ذلك think-cell) بحدث تغيير التحديد هذا مما يؤدي إلى إبطاء وحدات الماكرو بدرجة كبيرة. تكون وحدات الماكرو التي يتم إنشاؤها باستخدام مسجل وحدات الماكرو عرضة لهذا النوع من المشكلات على وجه الخصوص.
- مدونة Office: "ما هي أسرع طريقة لفحص نطاق كبير في Excel?"
- MSDN: تحسين مستوى الأداء في Excel 2007: "كائنات Excel المرجعية مثل كائنات النطاق مباشرةً، دون تحديدها أو تنشيطها" (في القسم "وحدات ماكرو أسرع بلغة VBA").
مثال: كيفية تجنب استخدام العبارة .Select
لنلقِ نظرة على وحدة الماكرو البسيطة التالية AutoFillTable
:
Sub AutoFillTable()
Dim iRange As Excel.Range
Set iRange = Application.InputBox(prompt:="Enter range", Type:=8)
Dim nCount As Integer
nCount = iRange.Cells.Count
For i = 1 To nCount
Selection.Copy
If iRange.Cells.Item(i).Value = "" Then
iRange.Cells.Item(i).Range("A1").Select
ActiveSheet.Paste
Else
iRange.Cells.Item(i).Range("A1").Select
End If
Next
End Sub
تقوم هذه الوظيفة بفتح مربع إدخال يطالب المستخدم بتحديد نطاق خلايا. تنتقل الوظيفة عبر جميع الخلايا الموجودة في النطاق. وإذا عثرت على خلية غير فارغة، فإنها تقوم بنسخ محتوى الخلية إلى الحافظة. تقوم الوظيفة بلصق محتوى الحافظة في كل خلية فارغة تالية.
AutoFillTable
تستخدم الحافظة لنسخ محتوى الخلية. لذلك، تحتاج الوظيفة إلى تحديد جميع الخلايا التي تتم معالجتها بحيث يعرف Excel الخلية التي سيتم النسخ منها والخلية التي يجب اللصق فيها. الحل الموصى به موضح في الوظيفة التالية AutoFillTable2
:
Sub AutoFillTable2()
Dim iRange As Excel.Range
Set iRange = Application.InputBox(prompt:="Enter range", Type:=8)
Dim iCellMaster As Excel.Range
For Each iCell In iRange.Cells
If iCell.Value = "" Then
If Not iCellMaster Is Nothing Then
iCellMaster.Copy (iCell)
End If
Else
Set iCellMaster = iCell
End If
Next iCell
End Sub
AutoFillTable2
تختلف عن سابقتها في جانبين مهمين:
- الأهم من ذلك أنها لا تحتاج إلى تحديد أي خلية مجددًا. بدلاً من ذلك، عند العثور على خلية غير فارغة، يتم تخزين هذه الخلية في المتغير
iCellMaster
. بعد ذلك، عندما يتم العثور على خلية فارغة، يتم نسخ كل محتوىiCellMaster
إلىiCell
. - وهي تستخدم ميزة لغة Visual Basic
For Each … Next
لزيارة كل خلية في النطاق. وهذا يمثل تحسنًا فعليًا في الوضوح.