JavaScript is not enabled!...Please enable javascript in your browser

جافا سكريبت غير ممكن! ... الرجاء تفعيل الجافا سكريبت في متصفحك.

-->
الصفحة الرئيسية

اكسيل VBA| اسرع واسهل كود بحث عن البيانات احترافى 100 %

اكسيل VBA| اسرع واسهل كود بحث عن البيانات احترافى 100 %

حل المشكلة: عندما يتكرر نفس الاسم في قائمة البحث 3 مرات!

هل سبق أن صممت أداة بحث في Excel باستخدام VBA ولاحظت أن اسم الطالب نفسه يظهر عدة مرات في ListBox لمجرد أنه مكرر في ورقة العمل؟
هذا المشهد محبط للمستخدم، ويجعل واجهة البرنامج تبدو غير احترافية.



مثال واقعي:

لديك جدول درجات يحتوي على 1000 صف، والطالب "أحمد محمد" مسجل في 3 مواد مختلفة (الرياضيات، العلوم، العربية).
عند كتابة حرف "أ" في مربع البحث، سيظهر اسم "أحمد محمد" ثلاث مرات متتالية في قائمة النتائج.
هذا التكرار يربك المستخدم ويجعله يظن أن هناك خطأ في قاعدة البيانات.


الحل: كائن Dictionary - الفلتر الذكي

ما هو Dictionary؟
Dictionary هو كائن برمجي موجود داخل نظام Windows (ليس حكراً على Excel). وظيفته الأساسية هي تخزين مفاتيح فريدة (Unique Keys). بمعنى أنك لا تستطيع إضافة نفس المفتاح مرتين.

تشبيه ذهبي:

تخيل أن الـ Dictionary هو "بواب حفلة". كل شخص يريد الدخول، البواب يسأله: "اسمك؟"
- إذا كان الاسم غير مسجل لديه، يكتبه في كشكه ويدخل الشخص.
- إذا حاول نفس الشخص الدخول مرة ثانية، يقول له البواب: "أنت دخلت قبل كده!".

هكذا يعمل Dictionary بالضبط مع أسماء الطلاب.

الكود قبل استخدام Dictionary (الخاطئ)


For i = 3 To lastRow
    currentName = ws.Cells(i, 2).Value
    If LCase(currentName) Like "*" & searchTerm & "*" Then
        ListBox1.AddItem currentName   ' سيضيف الاسم المكرر عدة مرات!
    End If
Next i

الكود بعد استخدام Dictionary (الصحيح)


Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")  ' استدعاء البواب

For i = 3 To lastRow
    currentName = Trim(ws.Cells(i, 2).Value)
    
    ' هل الاسم مسجل قبل كده في القاموس؟
    If Not dict.exists(currentName) Then
        dict.Add currentName, 1      ' سجله في القاموس
        ListBox1.AddItem currentName ' أضفه للقائمة مرة واحدة فقط
    End If
Next i

شرح كل سطر في الكود

  • Dim dict As Object: تعريف متغير باسم dict من نوع Object (لأن Dictionary ليس جزءاً أصلياً من VBA).
  • Set dict = CreateObject("Scripting.Dictionary"): إنشاء كائن Dictionary حقيقي في الذاكرة. هذه هي "قائمة البواب" الفارغة.
  • dict.exists(currentName): دالة تسأل: "هل الاسم currentName موجود بالفعل داخل القاموس؟" ترجع True إذا كان موجوداً، و False إذا لم يكن.
  • If Not dict.exists(...) Then: إذا كان الاسم غير موجود (Not موجود)، فعليك إضافته.
  • dict.Add currentName, 1: أضف الاسم كمفتاح (Key)، والقيمة العددية 1 (يمكن وضع أي قيمة، المهم هو المفتاح).

خطوة حاسمة: تنظيف القاموس قبل كل بحث

إذا لم تقم بمسح الـ Dictionary القديم، ستتراكم فيه أسماء من البحث السابق، ولن يتم إضافة أي أسماء جديدة (لأنها ستصبح "موجودة" من وجهة نظره).
لذلك، ضع هذين السطرين في بداية حدث البحث (مثل TextBox_Change):

Private Sub TextBox1_Change()
    ' 1- امسح القائمة المرئية أولاً
    ListBox1.Clear
    
    ' 2- أنشئ قاموساً جديداً فارغاً (أو امسح القديم)
    Set dict = CreateObject("Scripting.Dictionary")
    
    ' ... باقي كود البحث ...
End Sub

كود كامل وجاهز للاستخدام (نسخ-لصق)


Private Sub TextBox1_Change()
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim i As Long
    Dim currentName As String
    Dim searchTerm As String
    Dim dict As Object
    
    ' تنظيف الواجهة
    ListBox1.Clear
    Set dict = CreateObject("Scripting.Dictionary")
    
    ' تحديد ورقة العمل
    Set ws = ThisWorkbook.Sheets("Sheet1")
    lastRow = ws.Cells(ws.Rows.Count, 2).End(xlUp).Row
    
    ' البحث التزايدي من أول الحرف
    searchTerm = LCase(Trim(TextBox1.Text))
    If searchTerm = "" Then Exit Sub
    
    For i = 3 To lastRow
        currentName = Trim(ws.Cells(i, 2).Value)
        If currentName <> "" Then
            ' شرط البحث: يبدأ بالحروف المدخلة
            If LCase(Left(currentName, Len(searchTerm))) = searchTerm Then
                ' منع التكرار باستخدام Dictionary
                If Not dict.exists(currentName) Then
                    dict.Add currentName, 1
                    ListBox1.AddItem currentName
                End If
            End If
        End If
    Next i
End Sub

مقارنة الأداء: Dictionary vs الطرق التقليدية

الخاصية بدون Dictionary (حلقة مزدوجة) مع Dictionary سرعة البحث (1000 اسم) بطيء (0.5 ثانية) سريع جداً (0.05 ثانية) سرعة البحث (100,000 اسم) قد يتجمد Excel أقل من ثانية سهولة الكود معقد (حلقتان For) بسيط ونظيف

أسئلة متكررة

س: هل يعمل Dictionary على جميع إصدارات Excel؟
ج: نعم، من Excel 2000 حتى Excel 365، لأنه يعتمد على مكتبة موجودة في Windows نفسها.

س: ماذا يعني الرقم "1" في dict.Add currentName, 1 ؟
ج: Dictionary يخزن شيئين: مفتاح (Key) و قيمة (Value). نحن نحتاج المفتاح فقط لمنع التكرار، لذا نضع 1 كقيمة وهمية. يمكنك وضع أي شيء آخر.

س: كيف أمسح الـ Dictionary بدون إنشائه من جديد؟
ج: استخدم
dict.RemoveAll بدلاً من Set dict = CreateObject...

الخلاصة النهائية

✓ Dictionary = فلتر منع التكرار + أسرع 10 مرات من الحلول التقليدية

استخدمه في أي مشروع VBA يحتوي على:
- البحث عن أسماء طلاب
- البحث عن أرقام هواتف أو معرّفات فريدة
- أي قائمة قد تحتوي على بيانات مكررة في المصدر

📥 تحميل ملف مثال عملي

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