دورات هندسية

 

 

تمرين 3: Vba وأوتوكاد - أحداث أوتوكاد

صفحة 1 من 2 12 الأخيرةالأخيرة
النتائج 1 إلى 10 من 18
  1. [1]
    عبد الجواد
    عبد الجواد غير متواجد حالياً

    عضو متميز

    تاريخ التسجيل: Aug 2006
    المشاركات: 507
    Thumbs Up
    Received: 10
    Given: 0

    تمرين 3: Vba وأوتوكاد - أحداث أوتوكاد

    السلام عليكم:

    في هذا التمرين سنتحدث عن كيفية الاستفادة من بعض الأحداث (Events) التي يطلقها أوتوكاد عند القيام بأمر ما، وذلك عن طريق استعراض برنامج عملي.

    المهارات المطلوبة لفهم الموضوع:
    - معرفة بسيطة باستخدام برنامج أوتوكاد.
    - معرفة بالأوامر الأساسية للغة البرمجة Visual Basic.

    المستوى: متوسط

    مقدمة سريعة: ما هو الحدث (Event)؟

    الحدث هو عبارة عن برنامج جزئي (Sub) يتم تسميته بشكل محدد، وتقوم لغة VB بتنفيذ هذا البرنامج عند حصول طارئ ما.
    مثلاً: عند النقر على زر بواسطة الفأرة، يقوم هذا الزر بإصدار الحدث Click فإن كان هذا الزر اسمه Command1 تقوم VB بالبحث عن البرنامج الجزئي المسمى Command1_Click فتقوم بتنفيذه (في حال وجوده).
    كما هو موضح في المثال فإن اسم البرنامج الجزئي الذي يدل على الحدث يكون مؤلفاً من قسمين يفصل بينهما الرمز (_): الأول وهو اسم الكائن الذي يتبع له الحدث، والثاني هو اسم الحدث.
    بالنسبة لاسم الحدث فإن لكل كائن أحداثه الخاصة ويمكن معرفتها إما من ملف التعليمات الخاص بهذا الكائن أو كما سيتم توضيحه في المثال العملي أدناه.

    بعض الأحداث الخاصة بالكائن Document والتي سنحتاجها في هذا التمرين:
    الحدث BeginCommand: يحدث هذا الحدث بعد البدء بأمر جديد مثل Line أو Circle أو أي أمر آخر يتم تنفيذه من سطر أوامر أوتوكاد ويأخذ برنامجه الجزئي الشكل التالي:

    كود:
    Private Sub AcadDocument_BeginCommand(ByVal CommandName As String)
    
    End Sub
    نلاحظ أن هذا البرنامج اسمه AcadDocument_BeginCommand وهو مكون من قسمين: الأول وهو AcadDocument وهو يدل على اللوحة التي نرسم عليها والقسم الآخر وهو BeginCommand وهو اسم الحدث، كما أن البرنامج له بارامتر واحد اسمه CommandName وقيمته هي اسم الأمر الجاري تنفيذه في أوتوكاد، فإذا كتبنا الأمر L أو Line في أوتوكاد فإن هذا الحدث سيتم تفعيله وسيحمل المتحول CommandName القيمة "LINE"

    الحدث EndCommand: مثل السابق تماماً والفرق أنه يتم تفعيله بعد الانتهاء من تنفيذ الأمر بشكل كامل، ويأخذ برنامجه الجزئي الشكل التالي:

    كود:
    Private Sub AcadDocument_EndCommand(ByVal CommandName As String)
    
    End Sub
    الحدث ObjectAdded: يحدث هذا الحدث عند إضافة كائن ما إلى لوحة الرسم سواءً تم ذلك من قبل المستخدم أو من قبل أوتوكاد عندما يقوم بإضافة كائنات مؤقتة، ويأخذ برنامجه الشكل التالي:

    كود:
    Private Sub AcadDocument_ObjectAdded(ByVal Object As Object)
    
    End Sub
    نلاحظ أن هذا البرنامج له بارامتر واحد اسمه Object وهو يشير إلى الكائن الذي تمت إضافته، فإذا قمنا بإضافة خط (Line) فإن هذا المتحول سوف يؤشر إلى هذا الخط الجديد.

    والآن إلى التمرين:
    أستخدم غالباً في لوحات الأوتوكاد التي أرسمها عدة طبقات (وهذا أمر طبيعي!) وكذلك أستخدم عدة أنماط للأبعاد (DimStyles)
    لنفرض أنه لدي نمط أبعاد (DimStyle) اسمه Dim أستخدمه لرسم الأبعاد.
    ولدي نمط أبعاد آخر أستخدمه لكتابة أسماء الأعصاب اسمه RibName كما هو موضح في الشكل.



    عندما أكتب الأبعاد أضعها في طبقة ولتكن Dim وأستخدم النمط Dim، وعندما أكتب أسماء الأعصاب أضعها في طبقة أخرى ولتكن RibName وأستخدم النمط RibName.

    المشكلة:
    1- عندما أريد رسم بُعد ما، أو رسم اسم الأعصاب، أتذكر أن أغير الطبقة ولكن قد أنسى أن أغير نمط الأبعاد ليتوافق مع ما أريد رسمه، فيأخذ مني التعديل لاحقاً جهداً إضافياً.
    2- بعد رسم خط البعد الخاص باسم الأعصاب أقوم باختياره ثم تغيير الخاصية Text override إلى الاسم الذي أريده، وهذا يأخذ وقتاً إضافياً أيضاً.

    المطلوب لحل المشكلة:
    أريد برنامجاً يقوم بتغيير نمط البعد تلقائياً عندما أقوم بإضافة خط بعد بحسب الطبقة التي أقوم برسم البعد عليها، فإن كنت أرسم على الطبقة RibName أريد من البرنامج أن يختار نمط البعد RibName وإلا أن يختار نمط البعد Dim، ثم بعد الانتهاء من رسم خط البعد أن يسألني عن اسم الأعصاب إن كنت قد رسمت البُعد في الطبقة التي اسمها RibName، فيقوم تلقائياً بتغيير الخاصية Text override له إلى القيمة الجديدة.

    الحل:
    سأقوم بشرح الحل نظرياً ثم برمجياً، وسنلاحظ كيف أن جهداً برمجياً صغيراً يمكنه أن يجعل حياتنا أسهل، وأرجو أن أوفق في ذلك.
    عندما نبدأ أمراً جديداً وليكن Line يحدث الحدث BeginCommand للكائن ActiveDocument وهو الكائن الذي يشير إلى لوحة الرسم التي نرسم عليها، ويقوم أوتوكاد بتمرير اسم الأمر إلى البرنامج الجزئي الذي يقوم بمعالجة هذا الحدث، ويتم تخزين اسم الأمر في المتحول CommandName كما تم توضيحه أعلاه.
    ففي هذه الحالة (أي عند طلب أمر إضافة خط) ستكون قيمة المتحول CommandName تساوي LINE.
    أما عند إضافة خد بعد (من النوع Linear) (وهو الذي نريد استخدامه في مشروعنا) ستكون القيمة هي DIMLINEAR.
    لذلك سنختبر قيمة هذا المتحول فإن كانت تساوي DIMLINEAR نقوم باختبار اسم الطبقة الحالية، فإن كانت RibName سنقوم باختيار نمط البعد RibName وإلا سنختار نمط البعد Dim أياً كانت الطبقة.
    بعد الانتهاء من رسم خط البعد سيقوم أوتوكاد بتنشيط الحدث ObjectAdded والذي يدل على إضافة كائن جديد إلى اللوحة وسيقوم بتمرير هذا الكائن إلى البرنامج ضمن المتحول Object.
    لذلك سنختبر نوع هذا الكائن فإن كان بُعداً مرسوماً في الطبقة RibName سنقوم بتخزينه في متحول خاص بنا وليكن اسمه MyDim (لنتذكره لاحقاً من أجل تغيير الخاصية Text override) وإلا سنتجاهله.
    بعد هذا الحدث يقوم أوتوكاد بتنشيط الحدث EndCommand والذي يدل على الانتهاء بشكل كامل من آخر أمر فعال، وسنقوم عندها باختبار قيمة المتحول الذي قمنا بتخزينه، فإن كان لا يحوي قيمة فلا بأس، أما إن كان يحوي قيمة فهذا يعني أنه خط بعد في الطبقة RibName (طبعاً نحن قررنا ذلك في الخطوة السابقة) وسنسأل المستخدم عن الاسم الذي يريده ثم نقوم بتخزين هذا الاسم ضمن الخاصية Text override للكائن المضاف.
    هذا باختصار والآن إلى البرنامج.

    شرح البرنامج:
    افتح لوحة جديدة في أوتوكاد وأضف إليها الطبقة Dim والطبقة RibName، ثم أضف إليها نمطي بعد (Dim Style) أحدهما اسمه Dim والآخر RibName.

    ملاحظة: تقيد بحالات الأحرف كما كتبتها (أحرف صغيرة أو كبيرة) واجعل تمايزاً بين الطبقتين باللون وبين نمطي البعد بالشكل حتى تظهر نتائج البرنامج بشكل أوضح، أو يمكنك تحميل الملف الملحق Exercise03.dwg للتجريب عليه.

    قم بتشغيل VBA بالضغط على ALT+F11 في لوحة المفاتيح أو من القوائم Tools – Macro – Visual Basic Editor.
    بعد ظهور نافذة VBA انقر نقراً مزدوجاً على ThisDrawing فتظهر صفحة البرمجة الخاصة باللوحة الحالية كما هو موضح في الشكل:



    سنقوم أولاً بتعريف المتحول MyDim وهو من النوع AcadDimRotated وهو الذي سيشير إلى البعد المضاف كما يلي:

    كود:
    10 Dim MyDim As AcadDimRotated
    ملاحظة: الرقم في بداية السطر غير ضروري وقد استخدمته لتسهيل الشرح وقد تم توضيح ذلك في تمرين سابق.

    من قائمة الكائنات (راجع الشكل) اختر الكائن AcadDocument، ثم من قائمة الأحداث اختر الحدث BeginCommand فيقوم VBA بإضافة البرنامج الجزئي الذي تمت الإشارة إليه أعلاه، أي ستتم إضافة الأسطر التالية (بدون أرقام الأسطر):

    كود:
    20 Private Sub AcadDocument_BeginCommand(ByVal CommandName As String)
    
    100 End Sub
    أضف بين السطرين السابقين الأسطر التالية:

    كود:
    30 If CommandName = "DIMLINEAR" Then
    40 	If ThisDrawing.ActiveLayer.Name = "RibName" Then
    50 		ThisDrawing.ActiveDimStyle = DimStyles("RibName")
    60 	Else
    70 		ThisDrawing.ActiveDimStyle = DimStyles("Dim")
    80 	End If
    90 End If
    في السطر 30 نختبر قيمة المتحول CommandName فإن كانت DIMLINEAR فهي الحالة التي سنعالجها ضمن حلقة If وإلا فإن الأمر لا يهمنا وسينتقل عندها البرنامج إلى السطر 90.
    في حال كان الأمر هو DIMLINEAR أي أننا سنقوم بإضافة بُعد، لذلك سنختبر في السطر 40 اسم الطبقة الحالية فإن كان اسمها RibName سنقوم في السطر 50 بتغيير النمط الحالي للأبعاد إلى RibName فإن لم يكن اسمها كذلك (Else) سنقوم في السطر 70 بتفعيل نمط البعد Dim.
    حتى هذه اللحظة يمكننا اختبار البرنامج بالعودة إلى أوتوكاد وإضافة بعد من النوع (Linear)، وسنلاحظ كيف يتم اختيار نمط الأبعاد بحسب الطبقة التي نرسم عليها، وهكذا نكون قد حللنا المشكلة الأولى.

    ملاحظة: بالنسبة للسطر رقم 10 أعلاه لم نستخدمه حتى هذه اللحظة وهو خاص بالمشكلة الثانية.

    الآن أضف البرنامج الخاص بالحدث ObjectAdded بنفس الطريقة التي استخدمناها لإضافة الحدث السابق فيقوم VBA بإضافة الأسطر التالية (بدون أرقام للأسطر):

    كود:
    110 Private Sub AcadDocument_ObjectAdded(ByVal Object As Object)
    
    150 End Sub
    أضف الأسطر التالية بين السطرين السابقين:

    كود:
    120 If TypeOf Object Is AcadDimRotated And ThisDrawing.ActiveLayer.Name _
    = "RibName" Then
    130	Set MyDim = Object
    140 End If
    ملاحظة: الرمز _ (في نهاية السطر 120) يوضع في نهاية السطر لتجزئته إلى سطرين، ولكن VBA سيفهم هذين السطرين على أنهما سطر واحد، أي يمكننا كتابة السطر 120 والسطر الذي يليه (الذي ليس له رقم) يمكننا كتابتهما في سطر واحد بدون الرمز _

    في السطر 120 نقوم باختبار نوع الكائن Object والطبقة التي تحويه، فإن كان الكائن من النوع AcadDimRotated وكانت طبقته هي RibName فإن هذا الكائن يهمنا لأننا نريد تعديل الخاصية TextOverride له إلى اسم العصب لذلك سنقوم بجعل المتحول MyDim يشير إليه (أي سنتذكره) في السطر 130، أما إن كان الكائن المضاف ليس من النوع AcadDimRotated أو أنه كان على طبقة غير الطبقة RibName حتى لو كان خط بعد فإنه لا يهمنا ولن نقوم بتذكره.
    الآن أضف البرنامج الخاص بالحدث EndCommand كما تم شرحه أعلاه، أو يمكنك كتابته يدوياً:

    كود:
    160 Private Sub AcadDocument_EndCommand(ByVal CommandName As String)
    
    230 End Sub
    أضف بين السطرين السابقين:

    كود:
    170 If Not MyDim Is Nothing Then
    180 	Dim txt As String
    190 	txt = Trim(InputBox("Rib Name:"))
    200 	If txt <> "" Then MyDim.TextOverride = txt
    210 	Set MyDim = Nothing
    220 End If
    في السطر 170 نختبر المتحول MyDim فإن كان يشير إلى كائن ما فهذا يعني أنه يشير إلى كائن بعد تمت إضافته في الطبقة RibName لأنه لن يحمل قيمة إلا إذا تحقق هذا الشرط (راجع السطرين 120 و 130)
    إن كان هذا المتحول يشير إلى كائن ما سنقوم بالمعالجة في السطر 180 وحتى 210 وإلا فإن البرنامج سينتهي دون فعل شيء وهذا ما نريده.
    في السطر 180 نقوم بتعريف المتحول txt من النوع String وهو المتحول الذي سنقوم بتخزين اسم العصب فيه.
    في السطر 190 نظهر رسالة تسأل المستخدم عن اسم العصب عن طريق الأمر InputBox وهو أحد أوامر VBA، وبالنسبة للأمر Trim فهو يقوم بحذف المسافات من بداية ونهاية القيمة التي سيقوم المستخدم بإدخالها إن وجدت هذه المسافات، وسيتم تخزين القيمة المعادة من المستخدم في المتحول txt.
    في السطر 200 نقوم باختبار قيمة txt فإن كانت لا تساوي نصاً فارغاً فإننا سنقوم بتغيير الخاصة TextOverride للكائن MyDim إلى القيمة التي يحملها المتحول txt وإلا لن نقوم بتعديلها.
    في السطر 210 نقوم بتفريغ قيمة المتحول MyDim لأننا لن نحتاج إلى تذكره بعد هذا.
    السطر 220 هو نهاية حلقة If التي فتحناها في السطر 170.

    الآن بعد انتهاء البرنامج قم بتجربته بالذهاب إلى أوتوكاد وإضافة خط بعد في الطبقة RibName وستلاحظ بعد الانتهاء من إضافته سيقوم أوتوكاد بسؤالك عن اسم العصب، أدخل R1 مثلاً وسيقوم أوتوكاد بتعديل قيمة البعد إلى هذه القيمة الجديدة.

    أرجو أن أكون قد وفقت في إيصال الفكرة وأن لا تكون مجرد إضاعة وقت للقارئ، ومرفق هنا ملف أوتوكاد معرف فيه الطبقات وأنماط البعد الواردة في التمرين وكذلك أيضاً مرفق البرنامج الذي تم شرحه أعلاه واسمه Exercise03.dvb ويتم تحميله كما يلي:
    في أوتوكاد اختر الأمر Load Application من قائمة Tools، فتظهر نافذة Load/Unload Application.
    منها اختر الملف السابق ثم اضغط زر Load، عندها يصبح البرنامج جاهزاً للتنفيذ.
    نص البرنامج بالكامل:

    كود:
    Dim MyDim As AcadDimRotated
    
    Private Sub AcadDocument_BeginCommand(ByVal CommandName As String)
        If CommandName = "DIMLINEAR" Then
            If ThisDrawing.ActiveLayer.Name = "RibName" Then
                ThisDrawing.ActiveDimStyle = DimStyles("RibName")
            Else
                ThisDrawing.ActiveDimStyle = DimStyles("Dim")
            End If
        End If
    End Sub
    
    Private Sub AcadDocument_ObjectAdded(ByVal Object As Object)
        If TypeOf Object Is AcadDimRotated And ThisDrawing.ActiveLayer.Name _
    = "RibName" Then
            Set MyDim = Object
        End If
    End Sub
    
    Private Sub AcadDocument_EndCommand(ByVal CommandName As String)
        If Not MyDim Is Nothing Then
            Dim txt As String
            txt = Trim(InputBox("Rib Name:"))
            If txt <> "" Then MyDim.TextOverride = txt
            Set MyDim = Nothing
        End If
    End Sub
    وأخيراً أود أن أشير إلى أني سأقوم قريباً – إن شاء الله - بافتتاح قسم جديد في الموقع الخاص بسلسلة برامج جواد الإنشائية خاص بالبرمجة بلغة VBA مع أوتوكاد وإكسل، وهو عبارة عن تجميع لجميع الدروس والمقالات التي قمت بكتابتها في بعض المواقع ومنها هذا الموقع (ملتقى المهندسين العرب) وقد يحوي دروساً جديدة أيضاً، والغاية من هذا القسم تسهيل الوصول إلى هذه الدروس.

    روابط لتمارين سابقة:
    تمرين 1: استخدام vba وأوتوكاد
    تمرين 2 - vba وإكسل: إضافة تابع مخصص

  2. [2]
    خالد الأزهري
    خالد الأزهري غير متواجد حالياً
    مسلم
    الصورة الرمزية خالد الأزهري


    تاريخ التسجيل: Mar 2007
    المشاركات: 5,377

    وسام مشرف متميز

    Thumbs Up
    Received: 1,068
    Given: 724
    السلام عليكم ورحمة الله وبركاته
    بارك الله فيكم استاذنا عبد الجواد
    لنا عودة في وقت لاحق ان شاء الله...

    0 Not allowed!



  3. [3]
    شادي يس
    شادي يس غير متواجد حالياً
    عضو فعال جداً


    تاريخ التسجيل: Sep 2006
    المشاركات: 238
    Thumbs Up
    Received: 12
    Given: 44
    جزاك الله عنا كل خير يا استاذ عبد الجواد

    0 Not allowed!



  4. [4]

  5. [5]
    علي محمد يوسف
    علي محمد يوسف غير متواجد حالياً
    عضو تحرير المجلة


    تاريخ التسجيل: Aug 2007
    المشاركات: 3,006
    Thumbs Up
    Received: 478
    Given: 127
    السلام عليكم ورحمة الله وبركاته
    جزاكم الله خيرا وبارك الله فيكم تمنياتي لك ولجميع الأخوة دوام الصحة والتوفيق

    0 Not allowed!


    ربي اغفر لي ولوالدي وللمؤمنين والمؤمنات
    http://www.arab-eng.org/vb/showthread.php?t=68077

  6. [6]

  7. [7]
    hassan khalefa
    hassan khalefa غير متواجد حالياً
    عضو
    الصورة الرمزية hassan khalefa


    تاريخ التسجيل: Jun 2009
    المشاركات: 46
    Thumbs Up
    Received: 0
    Given: 0
    عفوا انا مش فاهم اي حاجة ممكن حد يبعتلي الاوتوكاد + شرحة؟

    0 Not allowed!



  8. [8]
    محمد العماد
    محمد العماد غير متواجد حالياً
    عضو


    تاريخ التسجيل: Dec 2007
    المشاركات: 11
    Thumbs Up
    Received: 0
    Given: 0
    الف شكر لك يا بشمهندس لطالما بحثت في هذا الموضوع وانابصراحة احب هذا الموضوع بشكل كبير
    على العموم لو سمحت اذا في عندك اي اضافات في هذا الموضوع الرجاء وضعه في المنتدى
    م / محمد العماد .

    0 Not allowed!



  9. [9]
    م.ابوالحسن عصام
    م.ابوالحسن عصام غير متواجد حالياً
    عضو فعال


    تاريخ التسجيل: Nov 2009
    المشاركات: 67
    Thumbs Up
    Received: 0
    Given: 0
    جزاكم الله خيرا والله اني اعتبر ها المنتدى جامعة اخرى بحياتي

    0 Not allowed!



  10. [10]
    عبد الجواد
    عبد الجواد غير متواجد حالياً
    عضو متميز


    تاريخ التسجيل: Aug 2006
    المشاركات: 507
    Thumbs Up
    Received: 10
    Given: 0
    السلام عليكم:

    شكراً لجميع الإخوة الذين تفاعلوا مع الموضوع.
    كنت قد وعدت أعلاه بافتتاح قسم لبرمجة vba في الموقع الخاص بسلسلة برامج جواد الإنشائية، وكان شبه جاهز ولكن تعرضت لظروف منعتني من ذلك، وقد قمت اليوم بعون الله بافتتاح هذا القسم.
    وهو عبارة عن تجميع لدروس ومقالات حول استخدام vba مع إكسل وأوتوكاد قمت بنشرها في مواقع متفرقة، (حتى الآن لم أضع جميع الدروس)، وأرجوا أن تجدوا فيها الفائدة.

    1 Not allowed!



  
صفحة 1 من 2 12 الأخيرةالأخيرة
الكلمات الدلالية لهذا الموضوع

عرض سحابة الكلمة الدلالية

RSS RSS 2.0 XML MAP HTML