اذهب الي المحتوي
أوفيسنا

نجوم المشاركات

  1. محمد حجازي

    محمد حجازي

    المشرفين السابقين


    • نقاط

      12

    • Posts

      771


  2. Foksh

    Foksh

    الخبراء


    • نقاط

      10

    • Posts

      2,363


  3. دروب مبرمج

    دروب مبرمج

    الخبراء


    • نقاط

      7

    • Posts

      206


  4. أ / محمد صالح

    أ / محمد صالح

    أوفيسنا


    • نقاط

      3

    • Posts

      4,444


Popular Content

Showing content with the highest reputation on 28 سبت, 2023 in all areas

  1. اقتراحك جميل اخي @دروب مبرمج
    2 points
  2. تفضل هذا الاقتراح الفكرة هي كالتالي :- - يكن التعديل في جدول مشابه للجدول الرئيسي و مرتبط بالنموذج - في حال وجود تغييرات سيتم تحديث السجلات التي طرأ عليها تغيير bbb.accdb
    2 points
  3. لست بحاجة لها و في اعتقادي بأنها ليست مجدية و السبب انها بهذه الصورة لا تقوم بإعلامك عن مكان الخطأ في الكود او اثناء تنفيذ الكود و دائما افضل الطريقة التالية On Error GoTo errorhandle \\\\ هنا في تضع الأكواد التي تريد تنفيذها /// errorhandleexit: Exit Sub errorhandle: MsgBox Err.Description ' رسالة الاعلام عن الخطأ Resume errorhandleexit
    2 points
  4. هل تقصد هكذا ؟ Security - EDIT.mdb
    2 points
  5. انشئ مديول جديد و الصق فيه الشفرة التالية Public Function Translate(strInput As String, strFromSourceLanguage As String, strToTargetLanguage As String) As String On Error GoTo errorhandle Dim strURL As String Dim objHTTP As Object Dim objHTML As Object Dim objDivs As Object, objDiv As Object Dim strTranslated As String strURL = "https://translate.google.com/m?hl=" & strFromSourceLanguage & _ "&sl=" & strFromSourceLanguage & _ "&tl=" & strToTargetLanguage & _ "&ie=UTF-8&prev=_m&q=" & EncodeQP2(strInput) Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP") objHTTP.Open "GET", strURL, False objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" objHTTP.Send "" Set objHTML = CreateObject("htmlfile") With objHTML .Open .Write objHTTP.ResponseText .Close End With Set objDivs = objHTML.getElementsByTagName("div") For Each objDiv In objDivs If objDiv.className = "t0" Then strTranslated = objDiv.innerText Translate = strTranslated End If Next objDiv Set objHTML = Nothing Set objHTTP = Nothing errorhandleexit: Exit Function errorhandle: MsgBox Err.Description Resume errorhandleexit End Function Function EncodeQP2(s As String) As String Dim i As Long Dim p1 As Long Dim p2 As Long Dim r As String Dim n As Long For i = 1 To Len(s) n = AscW(Mid(s, i, 1)) If n < 128 Then r = r & "%" & Hex(n) ElseIf n < 2048 Then p1 = n \ 64 r = r & "%" & Hex(p1 + 192) p2 = n Mod 64 r = r & "%" & Hex(p2 + 128) Else End If Next i EncodeQP2 = r End Function و في حصل الاستعلام او النموذج او اي مكان ضع التالي Translate([TextBox1], "auto", "en")
    1 point
  6. في رايي المتواضع ..انها مفيدة في بعض المواضع البسيطة حينما يكون هناك تعارض بين امر ما واخر لكنها قد تسبب مشاكل كبيرة اذا اسيء استخدامها
    1 point
  7. نحترم فكرتك .. في الأصل أكسس لم تصنعه ميكروسوفت ليستفاد منه كتوزيع تجاري ، كما هو الحال في اللغات البرمجية الأخرى وتطبيقاتها وانما عملته لخدمات المكتب وتستفيد منه المؤسسات الصغيرة في اعمالها ، مثله مثل اكسل والوورد وبقية المجموعة ,, لاحظ ان معالج اكسس يصنع مشروعا كاملا بضغطة زر . فاذا ارتقينا الى قواعد سيكوال سيرفر فالافضل الارتقاء الى لغات برمجية ارقى وافضل ، والواجهات فيها لا تقارن بواجهات اكسس المحدودة . ما يميز اكسس سهولة ويسر العمل عليه وسرعة التنفيذ ... فما يتم تنفيذه على اكسس في يوم .. سيأخذ قرابة الشهر على اللغات الأخرى والسبب ان القوالب جاهزة في اكسس ولا تحتاج بناء من الصفر
    1 point
  8. وعليكم السلام ورحمة الله تعالى وبركاته Private Sub CommandButton5_Click() Dim ws As Worksheet: Set ws = Sheets("دراسة فندق") Me.Label171.Caption = Format(ws.[F6].Text, "0,#%") 'Me.Label171.Caption = ws.Range("F6").Text 'دخل الحج Me.Label167.Caption = ws.[G6].Text 'دخل الحج Me.Label163.Caption = ws.[H6].Text 'دخل الحج Me.Label187.Caption = ws.[I6].Text 'دخل الحج Me.Label183.Caption = ws.[J6].Text 'دخل الحج Me.Label179.Caption = ws.[K6].Text 'دخل الحج Me.Label199.Caption = ws.[L6].Text 'دخل الحج Me.Label195.Caption = ws.[M6].Text 'دخل الحج Me.Label191.Caption = ws.[N6].Text 'دخل الحج 'رمضان Me.Label169.Caption = Format(ws.[F7].Text, "0,#%") 'دخل رمضان Me.Label165.Caption = ws.[G7].Text 'دخل رمضان Me.Label161.Caption = ws.[H7].Text 'دخل رمضان Me.Label185.Caption = ws.[I7].Text 'دخل رمضان Me.Label181.Caption = ws.[J7].Text 'دخل رمضان Me.Label177.Caption = ws.[K7].Text 'دخل رمضان Me.Label197.Caption = ws.[L7].Text 'دخل رمضان Me.Label193.Caption = ws.[M7].Text 'دخل رمضان Me.Label189.Caption = ws.[N7].Text 'دخل رمضان 'مواسم رمضان Label170.Caption = Format(ws.[F8].Text, "0,#%") 'دخل مواسم رمضان Label166.Caption = ws.[G8].Text 'دخل مواسم رمضان Label162.Caption = ws.[H8].Text 'دخل مواسم رمضان Label186.Caption = ws.[I8].Text 'دخل مواسم رمضان Label182.Caption = ws.[J8].Text 'دخل مواسم رمضان Label178.Caption = ws.[K8].Text 'دخل مواسم رمضان Label198.Caption = ws.[L8].Text 'دخل مواسم رمضان Label194.Caption = ws.[M8].Text 'دخل مواسم رمضان Label190.Caption = ws.[N8].Text 'دخل مواسم رمضان End Sub برنامج دراسة فندق_2.xlsm
    1 point
  9. تفضل التعديل baset.zip ملاحظة في محلها فعلا يوجد تعارض لديه ارشيف صور غير مرتبط بجدول يريد اضافة الصورة لمربع النص في التقرير و لم يتم تحديد صورة معينة لكني جعلت آخر صورة تم اضافتها في المجلد هي الاساسية فعلا يجب على صاحب الموضوع التمعن جيدا في كلامك لأنه هو المنطق بعينه شكرا لك
    1 point
  10. @M.NHAKAMI ولكن لماذا كل هذه الاسطر وعدم تنظيم في ارقام الليبل ؟! اقترح عليك بجعل ارقام الليبل بشكل متتالي حتى تسهل الامر عليك ومن تم وضعها في حلقة تكرارية ووضع الخلايا في مصفوفه على اي حال في نهاية مدى كل خليه ضع كلمة TEXT هذا مثال Label163.Caption = Sheets("دراسة فندق").Range("h6").Text
    1 point
  11. تفضل أخي الكريم ,, أذا كان هو المطلوب ، فكلمة شكر تكفي ولتجنب تكرار هكذا مشاكل ، تجنب اللغة العربية في المسميات قدر المستطاع برنامج الأرشفة الالكترونية.accdb
    1 point
  12. أخي الكريم يجب أولا ضبط المدخلات بحيث أن كل جزء ج1 أو ج2 وهكذا يحتوي على 3 صفوف أعلاه ثم 12 صف أرقام ثم 3 صفوف أسفله وعليه يكون عدد صفوف الجزء 18 صفا ومعنى ضبط المدخلات أن تكون هذه الطريقة هي المتبعة في جميع الخلايا من ج1 حتى ج 9 ويمكنك استعمال هذه المعادلة في الخلية C8 ثم سحبها لأسفل =COUNTIFS(INDIRECT("'1'!C"&(B8-1)*18+1&":C"&B8*18),">"&0) وهذا ملفك بعد تنفيذ الفكرة على شيت 1 فقط بالتوفيق جمع عدد المستندات في القائمة حسب شروط.xlsm
    1 point
  13. ضع هذا كود الوظيفة هذا في الموديول Public Function SetFilePath(SetFileName As Variant, SetFolder As Variant) SetFilePath = CurrentProject.Path & "\" & "SysFiles" & "\" & SetFolder & "\" & SetFileName End Function و في التقرير في مصدر الصورة استدعي الوظيفة اعلاه =SetFilePath([Forms]![نموذج1]![List31];[Forms]![نموذج1]![ID]) تمام كذلك تفضل هذا التعديل baset.zip
    1 point
  14. اخي الكريم اعتقد انك بحاجة الى كود يعمل على مقارنة بيانات السجلات في الجدول ........ الخ الطريقة البرمجية قد تزعجك ، إلا أني جربت طريقة التفافية لولبية تفضل ،، bbb.accdb
    1 point
  15. اخي الكريم ، جرب هذه المحاولة البسيطة baset.zip
    1 point
  16. انار الله عقلك وقلبك كما انارت عقولنا بحلك الجميل المقدم من شخصكم الكبير انارت العقول بمصباح مفتاحه فى ايدينا جعلها الله صدقة جارية فى ميزان حسناتك وتقبلها منك ان شاء الله
    1 point
  17. وعليكم السلام ورحمة الله وبركاتة يمكنك كتابة الشرط والنتيجة المتوقعه لتسهيل فهم المطلوب !!!
    1 point
  18. احلى منسف بجميد كركى لعيونك احلى فوكش سلمت يمناك
    1 point
  19. اخي الكريم انا لم افعل شيئاً ، فقد نقلت الكود من أخونا @شايب الى مربع السرد فقط foksh.zip
    1 point
  20. عليكم السلام ورحمة الله وبركاته يمكنك استخدام هذه المعادلة في الخلية J9 =IF(F9=5,IF(COUNTIF($F$9:F9,5)/COUNTIF($F$9:$F$1000,5)<=0.5,"الفرح","الزهور"),"اشراقة") بالتوفيق
    1 point
  21. جرب أن تضع هذه المعادلة في الخلية B3 =IF(A3<=100,A3*1.5,IF(A3<=150,150+(A3-100)*2,IF(A3<=200,250+(A3-150)*5,500+(A3-200)*6))) على افتراض أن الأكثر من 200 ب 6 وطبعا ال 150 عبارة عن 100 في 1.5 وطبعا 250 عبارة عن 150 + ( 50 في 2) وطبعا ال 500 عبارة عن 250 + (50 في 5) بالتوفيق
    1 point
  22. اعتقد المشكلة في اوفيس 2013 جرب 2007 او 2010
    1 point
  23. هل تقصد كهذه الفكرة بعد الكتابة في القائمة المنسدلة ؛ اضغط Enter Database1(1).zip
    1 point
  24. السلام عليكم ورحمة الله وبركاتة اخي mahmoud nasr alhasany ان كان فهمي صحيح فهذا طلبك تفضل sum-listbox1 (1).xlsm
    1 point
  25. اخى الحبيب احمد عبدالحليم تم تجربة الملف ويعمل بالفعل بالكود بارك الله فيك وزادك من علمه أستاذى ومعلمى القدير أ / محمد صالح تم تنفيذ الخطوات بالفعل وتم تنفيذ المطلوب بالخطوات بدون أكواد ألف شكر لحضرتك وللأستاذ / أحمد عبد الحليم جعله الله فى ميزان حسناتكم
    1 point
  26. والله أعلى وأعلم على قدر معلوماتى للاسف PlaySound API الخاصة بتشغيل ملفات صوت ذات الامتداد WAV لا تدعم الإيقاف المؤقت/الاستئناف وننتظر من اساتذتنا أهل الخبرة مراجعتنا فى هذه النقطة إن أمكن وهذا تعديل بسيط علشان خاطر عيونك تدلل PlayAudio V0.2.zip
    1 point
  27. لم اجد تفاعل أو اى رد يدل على نجاح فاعلية التطبيق والتجربة وهذه القواعد للتجربة تم مراعاة عند كتابة الأكواد العمل على كل من النواتان 32x , 64x استاذى الجليل الاستاذ @Moosak اردت فقط الاطمئنان على المكتبة العامرة Moh3sam.zip
    1 point
  28. السلام عليكم ... سوف أحاول إن شاء الله في هذه السلسلة سرد بعض النصائح التي تمكنك من جعل الكود الموجود في لغة الـ VBA أكثر فاعلية بحيث تتمكن من إعداد مايكرو يستهلك وقتاً أقل في التنفيذ وقدراً أقل من الذاكرة. بعض هذه النصائح التي سوف أطرحها تتعلق بلغة الفيجوال بيسك بشكل عام وبعضها الآخر خاص بتطبيق الفيجوال على الاكسل . عملية طرح المشاركات لن تعتمد على جدول زمني محدد ، وإنما سيتم طرح المشاركات تبعاً لتوفر الوقت لدي. لقد اعتمدت في طرحي لهذه النصائح على مصدرين أساسيين: - البرمجة التفاعلية باستخدام الفيجوال بيسك و الاكسل : كتاب ورقي للمهندس شريف فتحي الشافعي. - مجموعة كتابات حصلت عليها من الويب للأخ المتميز تركي العسيري. أنا مبتدئ ولا أملك أي فكرة عن لغة الفيجوال: لا تقلق يا أخي ، يمكنك فهم و استيعاب الدروس إذا كنت تمتلك خلفية بسيطة عن لغة الـفيجوال وكيفية تطبيقها على الاكسل ، ولكن كيف يمكنك الحصول على هذه المعرفة البسيطة؟ كيف يمكنني أن أحصل على أساسيات الـ VBA؟ بصورة عامة فإنك تحتاج من أجل الولوج إلى عالم الـ VBA إلى معرفتين أساسيتين: 1. معرفة مبادئ الفيجوال الأساسية : - الأحداث وكيفية ربط السبب بالنتيجة (ربط الحدث بالإجراء) - المتغيرات و الثوابت و أنواعها - خصائص الكائنات - أداة الشرط IF و الحلقات التكرارية ويمكنك الحصول على هذه المعلومات بسهولة من دروس الفيجوال المنتشرة بكثرة في المواقع العربية. 2. معرفة الأهداف في الاكسل وتسلسلها الهرمي. في الروابط التالية دروس للأخ محمد طاهر عن لغة الـ VBA: http://www.officena.net/Tips/Excel1-intr.htm http://www.officena.net/Tips/Excel2-vbeditor.htm http://www.officena.net/Tips/Excel3-Invoice.htm http://www.officena.net/Tips/Excel4-Grades.htm ومن خلال تصفحي السريع لهذه الدروس فإنني أعتقد بأنها تمثل خير بداية لمن يريد الدخول لعالم الـ VBA الممتع . أنصحك الآن بقراءة هذه الدروس لكي تتمكن من متابعة سلسلة النصائح التي سنوردها. أنا لا أرى من ضرورة تدفعني لتعلم الـ VBA! بالنسبة لي فأنا أرى أن الـ VBA تعني الإبداع و السرعة و المرونة ، وسوف يمنحك تعلم الـ VBA الفرصة في انتقالك من مجرد مستخدم عادي للتطبيق إلى مطور له ، وسوف تتمكن من القيام بمهام ما كنت لتحلم بتنفيذها بواسطة استخدام الأدوات التقليدية في الاكسل ، ولا تعجب إذا أخبرتك بأنني أختصر عملاً قد يستغرق عدة ساعات بكتابة كود لا يتجاوز السبعة أسطر . أظن أنك قد اقتنعت بتعلم الـ VBA. :d هذا الموضوع مفتوح لمشاركات الجميع ونحن نرحب بأي مشاركة لأي أخ ، ولكن رجاء ممن يريد إضافة أي مشاركة التقيد بالترقيم الذي سوف ننتهجه في طرح النصائح.
    1 point
  29. السلام عليكم ... سوف أعرض هنا إن شاء الله بعض الخطوات البسيطة التي تمكنكم من إنشاء مخطط بياني فعال وبخطوات بسيطة . لا أخفيكم سراً أنني عانيت في الماضي من بعض المشاكل عندما كنت أتعامل مع المخططات البيانية ، وهذه المشاكل كان مردها الجهل بالمصطلحات التالية (متسلسلات البيانات Data Chains ، فئات البيانات Data Categories ، نقاط البيانات Data Points) ، و من وجهة نظري فإنك إذا فهمت و استوعبت هذه المصطلحات فإنك ستكون قد قطعت نصف الطريق لفهم و إنشاء المخططات المختلفة . ملاحظة : الكلام الآتي لا ينطبق على جميع المخططات البيانية الموجودة على الاكسل ، وذلك لأن بعض المخططات لها طبيعتها الخاصة بها. أمعن النظر بالصورة التالية و جاوبني عن هذه الأسئلة : 1- ما الهدف من المخطط البياني السابق . 2- ماذا ندرس في هذا المخطط . 3- ما الذي نرصد تغيره و بالنسبة لماذا . على ما يبدوا أن للأسئلة السابقة نفس الجواب ! ، وهو أننا نقوم بدراسة التقييم الذي حصل عليه الطلاب (أحمد ، محمد ، سعيد) وذلك بالنسبة (خلال) للأشهر (حزيران ، تموز ، آب ، أيلول) . لاحظ أخي أن الصندوق الموجود على أقصى اليسار (و الذي ندعوه بوسيلة الإيضاح) يحتوي على أسماء الطلاب و بجانبها نموذج للخط الخاص بكل طالب . ندعو كل من الخط الكحلي (الخاص بالطالب أحمد) و الخط الوردي (الخاص بالطالب محمد) و الخط الأخضر (الخاص بالطالب سعيد) بسلاسل البيانات Data Chains ، وهذه السلاسل هي التي نهدف لداستها . أي أننا نهدف من المخطط البياني السابق دراسة تقييم الطلاب (المتسلسلات البيانية) و ذلك عبر الأشهر المختلفة ، وبهذا فإننا يجب أن نحدد أولاً وقبل البدء بإنشاء أي تخطيط ما نريد دراسته وذلك لنعينه كمتسلسلات بيانات . نقاط البيانات Data Points هي عبارة عن القيم الموجودة على متسلسلات البيانات (و التي تشكل هذه المتسلسلات) ، وكل نقطة بيانات تقابل قيمة لخلية موجودة على الجدول الذي تم إنشاء التخطيط انطلاقا منه . فئات البيانات Data Categories هي عبارة عن مجموعة النقاط التي تنتمي لمجال أفقي معين ، فمثلاً النقاط التي تمثل القيم 7 ، 6 ، 4 تشكل بمجموعها فئة البيانات الخاصة بشهر آب. بعد تلك المقدمة ، هل تستطيع أن تخبرني ما هو التغيير الذي أجريته على المخطط السابق في الصورة التالية : ببساطة لقد جعلت مجموعة القيم الموجودة في كل شهر تشكل متسلسلة بيانات وجعلت مجموعة القيم الخاصة بكل طالب تشكل فئة بيانات (أي أنني جعلت المتسلسلات فئات و الفئات متسلسلات) لاحظ أخي أن المحور العامودي Y لا يمكن أن يكون سوى محور قيم ، و هذا المحور مهمته قياس قيم نقاط البيانات المختلفة . الآن و بعد أن استوعبنا المصطلحات السابقة ، هيا بنا لنقوم بإنشاء مخطط بياني (معتمدين بذلك على ما تعلمناه سابقاً) : لنقم أولاً برسم الجدول التالي : الجدول السابق يبين أرباح عدد من الشركات (المجد ، راما ، العالمي ، آفاق ، الكوثر) خلال أربعة أشهر (حزيران ، تموز ، آب ، أيلول) . بنظرة بسيطة على الجدول السابق نستنتج أن الذي نريد دراسته هو أرباح الشركات الخمس السابقة على مدى الأشهر الأربع . أي أن كل متسلسلة يجب أن تضم قيم الأرباح الخاصة بشركة معينة (واحدة فقط) ، و أن كل فئة يجب أن تضم قيم الأرباح المتحققة في شهر معين (واحد فقط) . لاحظ أخي أننا وضعنا أسماء فئات البيانات Data Categories في رؤوس أعمدة الجدول السابق ، و وضعنا أسماء متسلسلات البيانات Data Chains في رؤوس صفوف الجدول السابق ، بينما وضعنا قيم نقاط البيانات Data Points في الخلايا الموجودة داخل الجدول . لإدراج تخطيط بياني للبيانات الموجودة في الجدول السابق ما عليك سوى تحديد هذا الجدول و الضغط على F11 ليتم إدراج التخطيط في ورقة تخطيط مستقلة : قد تفاجئ عندما ترى أن الأكسل قد اعتبر (على خلاف ما تتوقع) أن القيم التابعة لكل شركة تشكل فئة بيانات و ليس متسلسلة بيانات ! ، و لكن لا تقلق يا أخي لأنه يمكننا حل هذه الإشكالية بسهولة فائقة . الاكسل يعتمد عند قيامه بعملية تحديد متسلسلات و فئات البيانات المختلفة على قاعدة بسيطة مفادها : أن متسلسلات البيانات يجب أن تكون أقل عدداً من فئات البيانات (و هذه قاعدة منطقية و غالبة و لكنها للأسف ليست صحيحة في مثالنا هذا) . لتغيير الافتراض السابق ما عليك سوى أن تخبر الاكسل بأن متسلسلات البيانات تتوضع (خلافاً لظنه) في صفوف الجدول ، و ذلك بإتباعك الخطوات التالية : نشط ورقة التخطيط المطلوبة (إذا كان التخطيط موجود على ورقة تخطيط مستقلة) أو حدد التخطيط المطلوب (إذا كان مضمنا في أحد أوراق العمل) ، ومن ثم اختر الخيار Source Data الموجود في القائمة Chart لتظهر لك نافذة : في التبويب Data Range و عند Series in غير التحديد من Column إلى Row و اضغط OK لتلاحظ النتيجة التالية : يمكنك إدراج بعض الإضافات على التخطيط السابق (كعنوان التخطيط و عناوين المحاور) و ذلك من خلال الخيار Chart Options الموجود في القائمة Chart . مرفق مثال لما كنا قد عملناه : يتبع .... CHART.rar
    1 point
  30. السلام عليكم ... من المفترض أنك استطعت في الدرس السابق امتلاك بعض الخبرات التي تمكنك من التعامل مع المخططات البيانية بصورة أكثر فاعلية ، و لكن و بالرغم من المعلومات السابقة فقد تواجهك بعض الحالات التي تشعر فيها بأن كليكما (أنت و الاكسل) لا يفهم الواحد منكما الآخر :) . سأورد في هذه المشاركة شرحاً عن بعض المشاكل الشائعة عند مستخدمي المخططات البيانية بواسطة الاكسل ، و التي تظهر عندما تكون عناوين الفئات أرقاماً . قلنا سابقاً بأن معظم مخططات الاكسل (ما عدا بعض المخططات التي تمتاز ببعض الخصوصية كالتخطيط الدائري و التخطيط س و ص المبعثر و ... الخ) تتألف من محورين : محور قيم عامودي يقيس قيم نقاط البيانات المختلفة ، و محور أفقي توجد فيه فئات البيانات التي تعامل كوحدات منفصلة بعيداً عن أي مقياس . و لكن ماذا نعنيه بأن محور الفئات لا يخضع لأي مقياس عند قيامه بتحديد مجالات الفئات ؟ لاحظ أخي الصورة التالية : لاحظ أخي أن فارق السنوات بين الفئات غير متساوي ، ومع ذلك ففد قام الاكسل برصف السنوات على فواصل متساوية (في نقاط متساوية البعد عن بعضها البعض) ، و مرد ذلك إلى أن الاكسل تعامل مع أرقام السنوات على أنها نصوص (مجردة من أي دلالة رقمية) تستخدم للإشارة إلى مجموعة من البيانات . ملاحظة1 : قد يسبب المخطط السابق ذو الفئات المرتبة بشكل غير متجانس في بعض المشاكل عند القراءة ، ومن المحتمل تسببه في تضليل المستخدم الغير متمكن . ملاحظة2 : يمكنك حل المشكلة السابقة باستخدام التخطيط س و ص المبعثر الذي يمتلك محوري قيم ، و تحديد الحد الأعلى و الأدنى لكل محور من أجل الحصول على أفضل قراءة للتخطيط السابق . هناك مشكلة أخرى تظهر عندما تكون عناوين الفئات أرقاماً وهي أن الاكسل لا يستطيع تميزها على أنها عناوين !!!. لفهم هذه المشكلة بشكل واضع نورد المثال التالي : البيانات السابقة هي بيانات افتراضية ... من الجدول السابق نستنتج أن عدد الإناث المتعلمات أكبر من عدد الذكور المتعلمين في جميع السنوات (هذا يدل على أنها بيانات خيالية ) و أن تغير عدد المتعلمين من الفئتين (ذكور و إناث) يكون في نفس الاتجاه . الآن قم بتحديد الجدول السابق و اضغط على المفتاح F11 ليقوم الاكسل بإدراج التخطيط الافتراضي : قد تفاجئ عندما تلاحظ أن الاكسل لم يستطع تحديد عناوين الفئات ، و أنه اعتبرها (عناوين الفئات التي هي بالحقيقة أرقام السنوات) متسلسلة جديدة . السبب في عدم قدرة الاكسل على تمييز البيانات الموجودة في المجال A2:A6 على أنها عناوين الفئات هو أن هذه العناوين موجودة على شكل أرقام . حسناً قد تقول لي أن حل هذه المشكلة بسيط ويكمن في التعامل مع البيانات السابقة كنصوص ، وذلك عن طريق تحديد المجال السابق والنقر على Ctrl+1 ومن ثم اختيار التصنيف Text من التبويب Number ، ولكن مهلاً يا أخي فإن هذه الطريقة لا تجدي نفعاً مع الاكسل ، و الحل يكمن بأحد الطرق التالية : 1. مسح محتوى الخلية A1 ، ومن ثم القيام بإدراج التخطيط . 2. وضع علامة التنصيص المفردة ' في بداية أرقام السنوات ، ومن ثم القيام بإدراج التخطيط . 3. حذف المتسلسلات الإضافية (متسلسلة العام) عن طريق الخيار Source Data الموجود في القائمة Chart ، أو بواسطة أي طريقة أخرى يتيحها لكل الاكسل (سنتحدث عن ذلك لاحقاً) . قد تتفهم السبب في عدم تمكن الاكسل من تحديد عناوين فئات البيانات ، و لكن ما هذه الأرقام التي وضعها الاكسل بدلاً من عناوين الفئات التي لم يستطع إيجادها ؟ . هذه الأرقام هي عبارة عن متوالية حسابية متزايدة تبدأ من الواحد (الحد الأول فيها هو العدد واحد) , و كل عنصر من عناصرها ينتج عن العنصر السابق له بإضافة العدد واحد (أساسها هو العدد واحد أيضاً) . لنقوم الآن بإدراج المخطط السابق عن طريق معالج إدراج التخطيط هذه المرة ، و لنرى ما يمكننا القيام به من أجل تحسين التخطيط الناتج ؛ و سيتم شرح كل ذلك إن شاء الله خطوة بخطوة : قم أولاً بتحديد الجدول السابق و انقر على زر التخطيط الموجود في شريط الأدوات القياسي ، أو قم باختيار الأمر Chart الموجود في القائمة Insert ليظهر لك معالج إضافة تخطيط جديد . هذا المعالج يتألف من أربع خطوات (أربع مربعات حوار) تنتهي بإتمام عملية إدراج التخطيط الجديد ، و البيانات الموجودة في هذه المربعات يمكن تعديلها بسهولة حتى بعد إدراج التخطيط الجديد ، وذلك لأنك ستجدها ضمن القائمة Chart في أي وقت تحتاجها فيه. يمكنك في المربع الأول اختيار نوع التخطيط الذي ترغب بإدراجه : مربع الحوار الثاني متخصص بالبيانات المصدر التي يستقي منها تخطيطك المفترض معلوماته : مربع الحوار هذا يتألف من تبويبين : الأول هو Data Range و قد تعرفنا عليه في الدرس السابق ، و الثاني هو Series : في هذا التبويب و ضمن Series ستجد متسلسلات البيانات الموجودة في تخطيطك المرتقب ، حدد متسلسلة "العام" و قم بحذفها عن طريق الزر Remove . يوجد أيضاً في هذا التبويب عدد من مربعات الإدخال يمكنك من خلالها التحكم ببيانات أي متسلسلة ، و ذلك عن طريق تحديد اسمها و مجال القيم الخاص بها و مجال عناوين الفئات التي تعتمد عليه و ... الخ ؛ و يجب التنويه أيضاً إلى أن عدد هذه المربعات و وظيفتها تتغير بتغير نوع التخطيط الذي تختاره في الخطوة السابقة . الآن و بعد حذف متسلسلة "العام" الزائدة سيظهر لك مربع الحوار السابق بالشكل التالي : الخطوة الثالثة تحتوي على مربع حوار يحتوي على العديد من التبويبات التي تتيح لك إجراء الكثير من التحسينات و الإضافات على تخطيطك . جربها فهي واضحة و مفيدة بشكل كبير : في الخطوة الرابعة يسألك الاكسل عن إذا ما كنت ترغب بإضافة تخطيطك في ورقة تخطيط منفصلة أو ككائن في ورقة عمل موجودة : الآن و بعد انتهائك من الخطوة الرابعة اضغط على مفتاح Finish ليتم إدراج التخطيط حسب المواصفات التي اعتمدتها في الخطوات السابقة : لاحظ أخي أن الفروق بين المتسلسلتين في التخطيط السابق لا تظهر بالشكل المطلوب الذي يمكننا من دراستها بصورة دقيقة ، ويرجع ذلك إلى أن مجال محور القيم كبير بالنسبة لمجال توضع البيانات فيه ، ولذلك فإنه لا مناص هنا من تضيق مجال محور القيم بإتباع ما يلي : حدد محور القيم (المحور العامودي) ومن ثم كليك يمين على هذا المحور و اختار Format Axis لتظهر لك نافذة . ضمن التبويب Scale ستجد الخيارات التالية : قم بإزالة التحديد (من أجل عدم تمكين الاكسل من تحديد قيم هاذين المربعين بشكل تلقائي) من جانب المربعين Minimum و Maximum و أدخل فيهما القيم الجديد كما هو موضع في الشكل السابق . بالإضافة للتعديل السابق ، قمت بإجراء بعض التعديلات الشكلية على عناصر التخطيط السابق و ذلك حتى يظهر بالصورة التالية : هل تشاطرني الرأي بأن هذا التخطيط هو أجمل و أسهل للفهم من التخطيط السابق ؟. (y) أرجو أن أكون قد وفقت في طرح شيء مفيد . مرفق مثال للتخطيط الناتج : تحياتي Chart2.rar
    1 point
  31. 6. طرق أخرى لتجنب الهدر الناتج عن إبقاء العديد من الجمل داخل الحلقات التكرارية : تحدثنا في المشاركة السابقة عن كيفية استخدام الجملة With من أجل التقليل من الاستدعاء المتكرر للأهداف و الأساليب داخل الحلقات التكرارية ، و بقي لدينا في هذا الدرس ذكر بعض الطرق الفنية الإضافية التي يمكننا من خلالها التقليل من استدعاء هذه الأهداف و الأساليب من داخل الحلقات التكرارية : قارن بين الكودين التاليين : Sub Test1() Dim i As Integer With Sheets("Sheet1") For i = 2 To 100 .Cells(i, 1).Value = .Cells(1, 1).Value * i Next i End With End Sub Sub Test2() Dim i As Integer Dim MyNumber As Double With Sheets("Sheet1") MyNumber = .Cells(1, 1).Value For i = 2 To 100 .Cells(i, 1).Value = MyNumber * i Next i End With End Sub لاحظ أخي أننا في الكود الأول قمنا باستدعاء القيمة الموجودة داخل الخلية A1 باستخدام الجملة التالية : .Cells(1, 1).Value و قد اضطررنا إلى استدعاء نفس الأسلوب السابق (و بالتالي نفس القيمة) 99 مرة في الكود الأول ، وهذا طبعاً سيقلل من سرعة هذا الكود. لحل المشكلة السابقة قمنا في الكود الثاني بتعريف المتغير MyNumber و تخصيص القيمة الموجودة في الخلية A1 بداخله ، وبهذا فإننا لم نضطر للتعامل مع الهدف A1 بصورة مباشرة سوى مرة واحدة فقط ، واستبدلنا ذلك بالتعامل مع القيمة المخزنة داخل المتغير MyNumber ، وهذا بالطبع سيزيد من سرعة الكود . هذه حالة أخرى أكثر تعقيداً ، يمكنك التعرف عليها بصورة أدق عن طريق مراجعة الشرح الموجود في الملف المرفق : الكود الأول : Sub Test3() With Sheets("Sheet2") For Each MyCell In .Range("B2:B11").Cells If MyCell.Value > 90000 Then .Cells(MyCell.Row, 3).Value = .Cells(2, 8).Value * 0.3 .Cells(MyCell.Row, 4).Value = .Cells(3, 8).Value * 0.7 .Cells(MyCell.Row, 5).Value = .Cells(4, 8).Value * 0.85 ElseIf MyCell.Value > 60000 Then .Cells(MyCell.Row, 3).Value = .Cells(2, 8).Value * 0.25 .Cells(MyCell.Row, 4).Value = .Cells(3, 8).Value * 0.4 .Cells(MyCell.Row, 5).Value = .Cells(4, 8).Value * 0.65 Else .Cells(MyCell.Row, 3).Value = .Cells(2, 8).Value * 0.2 .Cells(MyCell.Row, 4).Value = .Cells(3, 8).Value * 0.3 .Cells(MyCell.Row, 5).Value = .Cells(4, 8).Value * 0.5 End If Next MyCell End With End Sub الكود الثاني (المعدل) : Sub Test4() With Sheets("Sheet2") Group1 = Array(.Cells(2, 8).Value * 0.2, .Cells(3, 8).Value * 0.3, .Cells(4, 8).Value * 0.5) Group2 = Array(.Cells(2, 8).Value * 0.25, .Cells(3, 8).Value * 0.4, .Cells(4, 8).Value * 0.65) Group3 = Array(.Cells(2, 8).Value * 0.3, .Cells(3, 8).Value * 0.7, .Cells(4, 8).Value * 0.85) For Each MyCell In .Range("B2:B11").Cells If MyCell.Value > 90000 Then .Range(Cells(MyCell.Row, 3), Cells(MyCell.Row, 5)).Value = Group3 ElseIf MyCell.Value > 60000 Then .Range(Cells(MyCell.Row, 3), Cells(MyCell.Row, 5)).Value = Group2 Else .Range(Cells(MyCell.Row, 3), Cells(MyCell.Row, 5)).Value = Group1 End If Next MyCell End With End Sub بالتوفيق Loops.zip
    1 point
  32. 5. جعل الجملة With خارج الحلقات التكرارية : تحدثنا في المشاركة الثالثة عن كيفية استخدام الجملة With من اجل تقليل الحاجة لاستدعاء الأهداف المختلفة ، ولكن يجب على كل من يريد استخدام هذه الجملة الانتباه لوضعا خارج الحلقات التكرارية (وذلك من أجل زيادة كفاءة هذه الجملة أكثر و أكثر) ، لاحظ الأكواد التالية : Sub MyFunction1() Dim X As Byte For X = 1 To 10 Sheets("Sheet1").Cells(X + 1, 2).Value = 2 * X + 6 Sheets("Sheet1").Cells(X + 1, 3).Value = X ^ 2 - X + 7 Sheets("Sheet1").Cells(X + 1, 4).Value = 23 * X - 20 Sheets("Sheet1").Cells(X + 1, 5).Value = X ^ 3 + 55 * X ^ 2 + 6 Sheets("Sheet1").Cells(X + 1, 6).Value = 2 * X Next X End Sub Sub MyFunction2() Dim X As Byte For X = 1 To 10 With Sheets("Sheet1") .Cells(X + 1, 2).Value = 2 * X + 6 .Cells(X + 1, 3).Value = X ^ 2 - X + 7 .Cells(X + 1, 4).Value = 23 * X - 20 .Cells(X + 1, 5).Value = X ^ 3 + 55 * X ^ 2 + 6 .Cells(X + 1, 6).Value = 2 * X End With Next X End Sub Sub MyFunction3() Dim X As Byte With Sheets("Sheet1") For X = 1 To 10 .Cells(X + 1, 2).Value = 2 * X + 6 .Cells(X + 1, 3).Value = X ^ 2 - X + 7 .Cells(X + 1, 4).Value = 23 * X - 20 .Cells(X + 1, 5).Value = X ^ 3 + 55 * X ^ 2 + 6 .Cells(X + 1, 6).Value = 2 * X Next X End With End Sub الأكواد الثلاثة السابقة تقوم بنفس العمل (حساب قيمة المتغير التابع y لعدد من المعادلات عند قيم محددة للمتغير المستقل X "من 1 إلى 10"). نلاحظ أنه تم استدعاء الهدف : Sheets("Sheet1") 50 مرة في الكود الأول ، و 10 مرات في الكود الثاني ، ومرة واحدة في الكود الثالث . عملية الاستدعاء للهدف السابق تؤثر حتماً على سرعة الكود (الكود الثالث هو الأسرع يليه الثاني ثم الأول) ، لاحظ كيف أن عملية استدعاء الهدف السابق قد تقلصت بعد وضع الجملة With خارج الحلقة التكرارية For ... Next . (y) لا تقلق أخي إذا لم تشعر بتغير سرعة الكود وذلك لأن الفرق أقل من أي يدرك بسهولة ...... ولكن مهلاً أخي ، ستشعر بالفرق في حالة وجود عمليات كثيرة تجرى على بيانات كبيرة. هل انتهى الحديث ؟!!!!!! لا أعتقد ذلك : أثناء كتابتي للدرس تذكرت أحد الاستعمالات الغامضة للجملة With : إذا قررت (بعد أن ابيض شعرك) القيام بحفظ جدول الضرب و التخلص من هذه العقدة التي عانيت منها كثيراً :) . أول الخطوات ستكون إحضار الجدول ( ولكن من أين؟ :o ) . حسناً لديك عدة خيارات : استعارة دفتر ولدك الصغير ، طلب الجدول من المكتبة (من أجل ولدك طبعاً :d ) ، القيام بتصميم الجدول عن طريق الاكسل : أول ما سيخطر على بالك هو الكود التالي : Sub MultiplicationTable1() Dim i As Byte, ii As Byte For i = 1 To 10 For ii = 1 To 10 Sheets("Sheet2").Cells(i, ii) = i * ii Next ii Next i End Sub ولكن ، و بما أن وقتك غالي عليك و تريد استثمار كل ثانية منه لحفظ جدول الضرب ، فإنك ستفضل حتماً التعديل التالي في الكود السابق : Sub MultiplicationTable2() Dim i As Byte, ii As Byte With Sheets("Sheet2") For i = 1 To 10 For ii = 1 To 10 .Cells(i, ii) = i * ii Next ii Next i End With End Sub لاحظ أخي أن الهدف : Sheets("Sheet2") تم استدعائه 100 مرة في الكود الأول و مرة واحدة فقط في الكود الثاني. (y) مرفق ملف يتضمن الأكواد الموجودة في هذه المشاركة : بالتوفيق WithAndLoops.zip
    1 point
  33. 4. التعامل مع الأهداف بصورة مجمعة كلما أمكن ذلك : قد نطّر في كثير من الأحيان إلى استخدام نفس الأسلوب أو الخاصية بصورة متماثلة تماماً مع أكثر من هدف ، وفي هذه الحالات فإنه يفضل القيام بالعملية المطلوبة مرة واحدة فقط وذلك عن طريق التعامل مع الأهداف بصورة مجمعة بدلاً من التعامل معها بصورة منفردة واحدة تلو الأخرى. للأسلوب السابق مزايا عديدة ، من بينها: - الاستغناء عن التكرار الغير مبرر في الكود وما ينتج عنه من توفير في حجم الكود وسهولة في العمل نتيجة عدم الحاجة لتكرير نفس العبارات أكثر من مرة في الكود الواحد. - اكتساب الكود مزيداً من السرعة وذلك لأن الكود يقوم باستدعاء الأهداف كلها (مع الأساليب و الخصائص المرتبطة بها) مرة واحدة فقط وبصورة مجتمعة بدلاً من استدعاء كل هدف بصورة منفردة. و الآن سوف نناقش سوياً في الأسطر القادمة الطرق التي نستطيع من خلالها تطبيق هذه الطريقة على نوعين من الأهداف: أولاً : التعامل مع الهدف Range: الطرق المستخدمة في التعامل مع الهدف Range تتماثل إلى حد كبير في كل من صيغ الاكسل و أكواد الفيجوال ، لا حظ الكود التالي: Sub ClearMyCells() Worksheets("Sheet1").Range("A1:A5").ClearContents Worksheets("Sheet1").Range("C4").ClearContents Worksheets("Sheet1").Range("E22:E30").ClearContents End Sub الكود السابق يقوم بحذف محتويات الخلايا الموجودة في كل من المجالات A1:A5 وC4 و E22:E30. نلاحظ من الكود السابق كيف أننا قمنا باستدعاء الأهداف الثلاثة كل واحد بمفرده هذا فضلاً عن استدعاء الأسلوب ClearContents ثلاث مرات أيضاً !!! ، وفي هذه الحالة فإنني أعتقد أنك ستكون موالياً تماماً للكود التالي (المخصور :d ): Sub ClearMyCells() Worksheets("Sheet1").Range("A1:A5,C4,E22:E30").ClearContents End Sub الطريقة السابقة لا تقتصر فقط على تعليمة Range وإنما يمكن استخدامها أيضاً مع تعليمة Cells أيضاً ، لا حظ الكود التالي : Sub ClearMyCells() NumberRow = Application.InputBox(prompt:="أدخل رقم الصف", Title:="رقم الصف", Type:=1) Sheets("Sheet1").Cells(NumberRow, 1).ClearContents Sheets("Sheet1").Cells(NumberRow, 2).ClearContents Sheets("Sheet1").Cells(NumberRow, 3).ClearContents End Sub الكود السابق يقوم بمسح محتويات الخلايا الموجودة في الأعمدة A و B و C و الصف المدخل من قبل المستخدم. يمكننا دمج الأهداف الثلاثة السابقة عن طريق التناغم الذي يوفره لنا الاكسل بين التعليمتين Range و Cells ، لاحظ الكود: Sub ClearMyCells() NumberRow = Application.InputBox(prompt:="أدخل رقم الصف", Title:="رقم الصف", Type:=1) Sheets("Sheet1").Range(Cells(NumberRow, 1), Cells(NumberRow, 3)).ClearContents End Sub هناك أيضاً التعليمة Union التي يمكنها ربط مجموعة من النطاقات بهدف Range واحد ، وميزة هذه التعليمة في أنها توفر لك ربط الأهداف وقت الحاجة إليها فقط ، وبهذا فإنه يمكنك التعامل مع الأهداف بصورة مستقلة عندما تشاء و التعامل معها بصورة مجتمعة عندما تشاء أيضاً. لاحظ الكود التالي: Sub ClearMyCells() Set MyRange1 = Sheets("Sheet1").Range("A1:A5") Set MyRange2 = Sheets("Sheet1").Range("C1:C5") Union(MyRange1, MyRange2).ClearContents MyRange1.Font.Bold = True End Sub الكود السابق يقوم بمسح محتويات الخلايا الموجودة في المجالين A1:A5 و C1:C5 ومن ثم يقوم بتثقيل الخط في خلايا المجال A1:A5 فقط . ثانيا : التعامل مع الهدف Sheet : يمكننا دمج عدة أهداف من النوع Sheet باستخدام التعليمة Array . التعليمة Array تحول عدة بيانات مدخلة كنصوص تفصلها فاصلة إلى مصفوفة يكون ترتيب أول عنصر فيها هو صفر ، ولكن كيف يمكننا استخدام هذه التعليمة لدمج عدة أهداف من النوع Sheet؟ لاحظ أولاً الكود التالي: Sub DeleteSheets() Sheets("Sheet2").Delete Sheets("Sheet3").Delete Sheets("Sheet4").Delete End Sub الكود السابق يقوم بحذف الأوراق Sheet2 ، Sheet3 ، Sheet4 الواحدة تلو الأخرى. - الآن يمكننا استخدام التعليمة Array لإنشاء المصفوفة (في سطر منفصل) ، ومن ثم يتم استخدام المصفوفة المنشئة داخل التعليمة Sheets ، لاحظ الكود التالي: Sub DeleteSheets() MySheets = Array("Sheet2", "Sheet3", "Sheet4") Sheets(MySheets).Delete End Sub - أو يمكننا استخدام التعليمة Array بشكل مباشر داخل التعليمة Sheets ، لاحظ الكود التالي: Sub DeleteSheets() Sheets(Array("Sheet2", "Sheet3", "Sheet4")).Delete End Sub وهنا يجب التنويه أيضاً إلى أنه يمكننا استخدام التعليمة Array للإشارة إلى الأوراق باستخدام أسمائها (كما لاحظنا في الكود السابق) أو باستخدام ترتيبها ضمن مصنف العمل ، كما في الكود التالي: Sub DeleteSheets() Sheets(Array(2, 3, 4)).Delete End Sub الشيء المميز في هذه الخاصية هو أنه يمكننا استخدامها مع أي مصفوفة نقوم بإنشائها وبغض النظر عن طريقة إنشاءها (المهم أنها تحتوي بداخلها على مراجع الأوراق المطلوب تنفيذ الكود عليها) ، وهنا يمكننا الاستفادة بشكل كبير من خواص هذه المصفوفات أثناء كتابة الأكواد ويمكننا تطويع هذه المصفوفات في عملنا وذلك للقيام بمهام محددة وخاصة جداً ، لاحظ الكود التالي : Sub DeleteSheets() On Error GoTo OutOfRange Dim ReadyToDel() As String For Each MySheet In ActiveWorkbook.Worksheets If Not MySheet.Name = "Muhammad" And Not MySheet.Name = "Ahmad" Then ReDim Preserve ReadyToDel(UBound(ReadyToDel) + 1) ReadyToDel(UBound(ReadyToDel)) = MySheet.Name End If Next MySheet If UBound(ReadyToDel) > 0 Then Sheets(ReadyToDel).Delete Exit Sub OutOfRange: If Err = 9 Then ReDim ReadyToDel(0) Resume Next Else MsgBox Err.Description End If End Sub الكود السابق يقوم بالبحث ضمن أوراق العمل الموجودة في المصنف النشط ويقوم بحذف جميع الأوراق الموجودة ما عدا الورقتين Muhammad و Ahmad ، وهو (الكود) يعتمد على مصفوفة ديناميكية من أجل تخزين مراجع الأوراق المطلوب حذفها. أتمنى أن يكون شرحي واضحاً و وافياً
    1 point
  34. 3. استخدام الجملة With : قد نحتاج أحياناً إلى استخدام العديد من الخصائص و الأساليب التابعة لهدف معين في نفس الوقت ، وهنا فإنه يمكننا استخدام الجملة With من أجل التقليل بقدر الإمكان من الحاجة إلى الاستخدام المتكرر للأهداف المرجعية ، وبالتالي فإن هذه الجملة تتيح لنا تخفيض حجم الكود بالإضافة إلى المرونة التي توفرها في قراءة و فهم ومتابعة الكود . هناك ميزة أخرى توفرها لنا الجملة With ألا وهي السهولة في تعديل الكود ، حيث أننا لن نحتاج لتعديل الهدف مع كل خاصية أو أسلوب مرتبط به وإنما سيكون التعديل مرة واحدة من خلال الجملة With. في الكود التالي سنقوم بإظهار كل من أشرطة الأدوات : القياسي و التنسيق و النموذج: Sub ToolsList1() Application.CommandBars("Standard").Visible = True Application.CommandBars("Formatting").Visible = True Application.CommandBars("Forms").Visible = True End Sub يمكننا تعديل الكود السابق لتتم الإشارة إلى الهدف Application مرة واحدة فقط : Sub ToolsList2() With Application .CommandBars("Standard").Visible = True .CommandBars("Formatting").Visible = True .CommandBars("Forms").Visible = True End With End Sub كما يمكنك أيضاً الاستعانة بمجموعة من جمل With المتداخلة :o ، لاحظ الكود التالي : Sub FormatCells() With Sheets("Sheet1").Range("A1:D5") With .Font .ColorIndex = 3 .Bold = True .Size = 12 End With With .Borders() .LineStyle = xlDot .Weight = xlMedium End With End With End Sub وبهذا فإننا نلاحظ أن الدليل المرجعي المستخدم في الحلقة With الأولى (المجال A1:D5 الموجود في الورقة Sheet1) يمكن أن يكون دليلاً مرجعياً لمجموعات أخرى ( Borders، Font) و التي بدورها ستكون دليلاً مرجعياً لأساليب و خصائص مختلفة (ColorIndex ، LineStyle ، ... ، الخ) بالتوفيق
    1 point
  35. 2.استخدام متغيرات الهدف: قد نحتاج في كثير من الأحيان للإشارة إلى هدف معين عدد من المرات (قد تزيد على المئة مرة :d ) ، وفي هذه الحالة ولتقليص حجم الكود وسهولة قراءته و متابعته فإننا نقوم بتخصيص متغير ليحل محل الهدف الذي نتعامل معه ، حيث أنه يمكننا استبدال التعامل ليكون مع المتغير مباشرةً . انظر للكود التالي: Sub Report() MsgBox "المجموع " & Application.WorksheetFunction.Sum(Sheets(1).Range("A1:D5,E10,F5,G1:G4")) MsgBox "المعدل " & Application.WorksheetFunction.Average(Sheets(1).Range("A1:D5,E10,F5,G1:G4")) MsgBox "الحدالأعلى " & Application.WorksheetFunction.Max(Sheets(1).Range("A1:D5,E10,F5,G1:G4")) MsgBox "الحد الأدنى " & Application.WorksheetFunction.Min(Sheets(1).Range("A1:D5,E10,F5,G1:G4")) MsgBox "عدد الأرقام " & Application.WorksheetFunction.Count(Sheets(1).Range("A1:D5,E10,F5,G1:G4")) End Sub لاحظ كيف أننا أشرنا إلى الهدف التالي خمس مرات خلال الكود السابق: Sheets(1).Range("A1:D5,E10,F5,G1:G4") لنقوم الآن باستخدام متغير معين (المتغير MyRange مثلاً) للدلالة على الهدف السابق: Sub Report1() Dim MyRange As Range Set MyRange = Sheets(1).Range("A1:D5,E10,F5,G1:G4") MsgBox "المجموع " & Application.WorksheetFunction.Sum(MyRange) MsgBox "المعدل " & Application.WorksheetFunction.Average(MyRange) MsgBox "الحدالأعلى " & Application.WorksheetFunction.Max(MyRange) MsgBox "الحد الأدنى " & Application.WorksheetFunction.Min(MyRange) MsgBox "عدد الأرقام " & Application.WorksheetFunction.Count(MyRange) End Sub لاحظ أننا لم نحتاج لكتابة الهدف سوى مرة واحدة خلال الكود (y) تستطيع الآن أن تقدر (من خلال تقيمك للكودين السابقين) مدى التخفيض الذي نستطيع أن نحققه في حجم الأكواد باستخدام الطريقة السابقة.
    1 point
  36. 1. التقليل بقدر الإمكان من مرات اختيار وتنشيط الهدف: بدايتي وبداية أغلب مبرمجي الـ VBA كانت تعتمد على مسجل الماكرو ، و السبب الذي يبرر هذه البداية بسيط جداً ألا وهو جهل المبرمج المبتدأ بالخصائص و الأساليب المستخدمة في الفيجوال والخاصة بتطبيق الاكسل . الطريقة السهلة التي يُنصح بها للتغلب على هذا الجهل (الجهل بالخصائص و الأساليب الخاصة بتطبيق الاكسل) هو تسجيل ماكرو لما تريد أن تقوم به ومن ثم إجراء بعض التعديلات على المايكرو المسجل ، ولكن لماذا نجري تعديلات على المايكرو مادام ينفذ ما نريد بالضبط؟. من أهم الأسباب التي تجعل الكود المسجل غير فعال (والتي تدفعنا لتعديله لاحقاً) هو تنشيط الأهداف بصورة غير مبررة ، حيث أنه يمكننا في أغلب الأحيان كتابة كود يتعامل مع الأهداف بدون الحاجة لتنشيط أي منها ، ولكن مادام هذا هو الأسلوب الأنسب لماذا لا يعتمده مسجل المايكرو في عمله؟. إن مسجل المايكرو يقوم بمراقبة الحركات و الأفعال التي يقوم بها المستخدم ويعمل على تسجيلها بأمانة تامة ( يبدوا أن الأمانة الزائدة لمسجل المايكرو هي السبب في خلق هذه المشكلة :d ) لنقوم الآن بتسجيل مايكرو يقوم بمسح محتويات الخلية C5 الموجودة في الورقة Sheet2: اضغط على الخيار Record New Macro الموجود في القائمة Tools (القائمة الفرعية Macro) لتبدأ عملية تسجيل المايكرو. انتقل للورقة Sheet2 وانقر على الخلية C5 واضغط على الزر Delete ، ومن ثم أوقف تسجيل الماكرو من نفس الخيار السابق (لاحظ تغير اسمه إلى Stop Recording). الآن اضغط على Alt+Enter لتفتح لك نافذة محرر الفيجوال ، افتح الموديل المنشأ لترى فيه الكود الذي تم تسجيله مؤخراً: Sub Macro1() Sheets("Sheet2").Select Range("C5").Select Selection.ClearContents End Sub يمكننا تعديل الكود السابق ليتمتع بمزيد من البساطة و السرعة وفي نفس الوقت نحصل على نفس النتائج السابقة وذلك بدون الحاجة إلى تنشيط أو اختيار كل هدف قبل التعامل معه. الكود المعدل : Sub Macro1() Sheets("Sheet2").Range("C5").ClearContents End Sub لاحظ الفرق (y) هناك سبب آخر يدفعنا لتعديل الكود المسجل ، وهو تسجيل الحركات الزائدة التي قام بها المستخدم دون قصد منه (لاحظ أن مسجل المايكرو يمارس رقابة صارمة على جميع حركاتك). لاحظ الكود التالي: Sub Macro1() Sheets("Main").Select Application.CommandBars("Standard").Visible = False End Sub المستخدم كان يهدف من خلال تسجيله للمايكر إلى حذف شريط الأدوات القياسي ، ولكنه بشكل غير مقصود قام بتحديد الورقة Main ، وبما أن أشرطة الأدوات مرتبطة مباشرةً بالهدف Application فلا داعي هنا للسطر : Sheets("Main").Select أرجو أن أكون قد وفقت في إيصال المعلومة
    1 point
  37. السلام عليكم ... جرب المثال المرفق ، حيث وضعت كود يقوم بتصفية الأسماء الموجودة في ورقة أبجدي عن كل تغيير في الاسماء الموجودة في ورقة بيانات: jakord.zip
    1 point
  38. السلام عليكم ... أقدم لكم تجربتي الأولى مع الاكسل (أيام الدراسة) ، وهو برنامج يحسب اهتلاك الأصول الثابتة بعدة طرق. قمت بإضافة هذا البرنامج في أحد المنتديات وتذكرت أني لم أضعه في منتدى أوفيسنا ، ولذلك (ومن باب أولى) يتحتم علي تقديمه لأعضاء على هذا المنتدى الرائع. البرنامج مصمم على الأوفيس 97 وقد حدثت الملف ليتماشى مع نسخة 2003 ، وكما قلت لكم فإن هذا البرنامج يمثل أول تجربة لي في التعامل مع الاكسل (يوم كنا أولاد) لذلك أرجو عدم معاتبتي على الأخطاء التي قد تجدونها فيه. :d بالتوفيق Assets.zip
    1 point
  39. السلام عليكم ... ومن أجل حفظ الصفحة بدون ارتباطات مع الملف الأساسي إليك الكود التالي: Public NewWorkbok As Object Sub SaveSheet() Dim MyPath As String Dim NumberSheets() As Integer MyPath = Workbooks("MAH").Path & "\MAH_TEST" Set NewWorkbok = Workbooks.Add Workbooks("MAH").Sheets(1).Copy Before:=Workbooks(NewWorkbok.Name).Sheets(1) ReDim NumberSheets(2 To NewWorkbok.Worksheets.Count) For i = 2 To NewWorkbok.Worksheets.Count NumberSheets(i) = i Next i Application.DisplayAlerts = False With NewWorkbok .Sheets(NumberSheets).Delete .Sheets(1).Cells.Copy .Sheets(1).Cells.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False .Sheets(1).Cells(1, 1).Select .SaveAs Filename:=MyPath .Close End With Application.DisplayAlerts = True End Sub
    1 point
  40. مثلا أذاكان المطلوب متابعة الخلية A2 بحيث يظهر تاريخ أخر تعديل فى الخلية d2 نكتب فى D2 هذه المعادلة =ash(A2) ash.zip
    1 point
  41. السلام عليكم عندما نريد أن نكون معادلة في الـ VBA ومن ثم نستدعيها فعلينا أن نستخدم Function () ما تريد أن تعرفه End Function وذلك لكي يحتفظ الكود الذي كتبته بالقيمة المطلوبة التي تريد أن تصل إليها ولا نستخدم SUB لأنها تقوم بإجراء ماتريده ومن ثم ينتهي تأثيرها ولا تتنفذ مرة أخرى إلا إذا إستدعيتها من قائمة الماكرو أو عملت لها زر وربطتها بالماكرو ولكن Function تحتفظ بما تم تعريفة وبعد ذلك ستجد ما عرفته موجود في دوال الإكسل Function Paste وما قمت بتعريفه هو أنه في حال احتواء الخلية على أي نص والذي تم تعريفه مسبقاً ash1 As String فإنه سيتم استدعاء الدالة ash والتي تعطينا الوقت والتاريخ وذلك حسب التعريف ash = Date & Time إلى هنا ستعطينا الدالة نفس التأثير للمعادلة Now() فلهذا أضفت السطر application.screenupdating = false وذلك لكي يقوم بتعطيل خاصية التحديث التلقائي كلما حدث أي تغيير في البيانات آمل أن أكون قد حققت مطلبك يا سيد أنور والسلام
    1 point
  42. السلام عليكم الحمد لله لقد توصلت إلى الحل وهو كالآتي نعرف دالة جديدة عن طريق الـ VB والكود كالآتي Function ash(ash1 As String) If Application.WorksheetFunction.IsText(ash1) Then ash = Date & Time End If Application.ScreenUpdating = False End Function ومن داخل الإكسيل نستدعي الدالة وتحديد الخلية التي نريد أن نعرف متى تعدلت وعند تطبيق المعادلة سيعطينا وقت إدخال هذه المعادلة وسيتغير هذا الوقت فقط في حال التعديل أو الإلغاء وشكراً
    1 point
×
×
  • اضف...

Important Information