في بي إيه: كيفية الحصول على اسم الشهر من التاريخ

دليل أكاديمي شامل يشرح كيفية استخراج اسم الشهر من التاريخ في إكسيل باستخدام لغة البرمجة في بي إيه (VBA) ودالة MonthName بالتفصيل والتطبيق العملي.

Mohammed looti أكاديمي وباحث متخصص في علم النفس
تاريخ النشر
تمت المراجعة العلمية · د. مروة عبد العظيم · 22 أكتوبر، 2026
مراجعة وتدقيق علمي معتمد تاريخ التدقيق: 22 أكتوبر، 2026
د. مروة عبد العظيم دكتوراه في علم النفس
عضو هيئة التدريس • جامعة كربلاء
معايير التدقيق والاعتماد السريري

يخضع هذا المحتوى لمعايير ضبط الجودة والتدقيق العلمي والأكاديمي الصارمة في شبكة علم النفس العربي، لضمان صحة المعلومات ودقتها السريرية ومطابقتها لأحدث الأدلة والبراهين الصادرة عن الجمعيات النفسية والطبية المعتمدة (APA / WHO).

تمثل معالجة البيانات الزمنية في البيئات المكتبية المؤتمتة حجر الزاوية لتطوير النظم الإدارية والتحليلية الحديثة، حيث يُعد تطبيق مايكروسوفت إكسيل، المدعوم ببيئة التطوير فيجوال بيسك للتطبيقات (Visual Basic for Applications – VBA)، المنصة الأكثر انتشاراً في قطاعات الأعمال والمؤسسات الأكاديمية لإدارة البيانات وجدولتها. ورغم البساطة الظاهرة التي تبدو عليها التواريخ في واجهات المستخدم الرسومية، فإن التعامل البرمجي مع هذه القيم ينطوي على تعقيدات بنيوية ترتبط بكيفية تمثيل الزمن رقمياً، والفصل المعماري بين القيمة التخزينية المجردة والمظهر النصي الدلالي الذي يتطلبه صانع القرار ومحلل البيانات.

تكتسب مسألة تحويل التواريخ التقويمية إلى أسماء شهور واضحة ومقروءة أهمية بالغة عند بناء لوحات المؤشرات (Dashboards)، وإعداد التقارير المالية الدورية، وتأسيس قواعد بيانات مرنة وقابلة للتوسع. يهدف هذا المقال إلى تقديم دراسة تأصيلية وتطبيقية شاملة لكيفية استخلاص أسماء الشهور من التواريخ باستخدام لغة البرمجة VBA، مسلطاً الضوء على البنية التركيبية والدلالية للدوال المتخصصة، وعلى رأسها دالة MonthName ودالة Format، مع استعراض استراتيجيات الحوسبة المتقدمة لتحسين الأداء البرمجي، وضمان التوافق الإقليمي واللغوي، وإدارة الاستثناءات والأخطاء التشغيلية باحترافية كاملة.

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

1. مقدمة تأصيلية للتعامل مع البيانات الزمنية في لغة في بي إيه (VBA)

1.1 مفهوم المتغيرات الزمنية والتواريخ في بيئة إكسيل البرمجية

يعتمد محرك مايكروسوفت إكسيل في تمثيله الداخلي للتواريخ على نظام رقمي تسلسلي صارم؛ حيث يُخزن التاريخ كعدد حقيقي موجب (Serial Number) يبدأ من نقطة مرجعية موحدة تاريخياً تُعرف بنقطة الأساس التقويمي. في هذا النظام، يمثل الرقم الصحيح عدد الأيام المنقضية منذ الأول من يناير عام 1900، بينما يمثل الجزء الكسري العشري الوقت المنقضي من اليوم بالساعات والدقائق والثواني. هذا التجريد الرياضي هو الذي يتيح إجراء العمليات الحسابية الزمنية، مثل طرح تاريخين لتحديد الفارق بالأيام، أو إضافة عدد صحيح إلى تاريخ معين للانتقال المستقبلي.

وعلى مستوى لغة البرمجة Visual Basic for Applications، التي ظهرت لأول مرة عام 1993 مع إصدار إكسيل 5.0 لتحل محل لغة الماكرو الكلاسيكية XLM، يُخصص للتواريخ نوع بيانات فريد هو Date. يشغل هذا النوع 8 بايتات في الذاكرة العشوائية ويتم التعامل معه داخلياً كعدد حقيقي بنظام الفاصلة العائمة ذي الدقة المزدوجة (Double-precision floating-point). يمتد النطاق الزمني لنوع البيانات Date من 1 يناير عام 100 ميلادية حتى 31 ديسمبر عام 9999 ميلادية، مما يمنحه مرونة فائقة لمعالجة البيانات التاريخية والمستقبلية على حد سواء.

تكمن الصعوبة في كثير من بيئات العمل البرمجية في التمييز المفاهيمي بين القيمة المخزنة والعرض النصي. فالقيمة المخزنة داخل الخلية قد تكون الرقم التسلسلي 45222، ولكن المستخدم يتوقع رؤيتها بتنسيق وصفي مقروء مثل “أكتوبر 2023” أو “تشرين الأول”. إن تحويل هذا الرقم التسلسلي المجرد إلى نص يمثل اسم الشهر ليس مجرد خطوة تجميلية للواجهة، بل هو عملية تحويل بنيوية تنقل البيانات من فضاء العمليات الحسابية الكمية إلى فضاء التصنيف الكيفي والتجميع الإحصائي، مما يعزز دقة النظم الحاسوبية وملاءمتها للمستخدمين البشريين كما هو مؤصل في أبحاث هندسة النظم الرقمية (da Silva et al., 2022).

1.2 الحاجة التحليلية لاستخلاص أسماء الشهور في معالجة البيانات

في بيئات الأعمال المعاصرة، تشكل البيانات الزمنية غير المهيكلة عائقاً أمام إعداد التقارير الموجزة ذات الكفاءة العالية. عند التعامل مع ملايين السجلات المالية أو الإدارية التي تتضمن طوابع زمنية تفصيلية، يحتاج المحلل المالي أو الإداري إلى تجميع هذه المعاملات ضمن فترات دورية متسقة. يوفر استخلاص اسم الشهر وسيلة قياسية لإنشاء جداول المحاور (Pivot Tables) ومخططات الاتجاه الزمني (Trend Analysis)، حيث يمكن تجميع كافة حركات التدفق النقدي أو مبيعات المنتجات التي تمت في شهر محدد تحت مسمى وصفي موحد بدلاً من تشتيتها عبر مئات التواريخ المنفصلة.

إلى جانب التجميع والتلخيص، يلعب استخراج أسماء الشهور دوراً محورياً في الحد من الأخطاء التفسيرية الناتجة عن التباين الثقافي والإقليمي لتنسيقات التواريخ. فالتاريخ المكتوب بصيغة أرقام مجردة مثل “05/06/2024” يثير التباساً كبيراً في الفرق متعددة الجنسيات؛ إذ يقرأه مستخدم النظام الأمريكي كـ “الخامس من يونيو”، بينما يفسره مستخدم النظام البريطاني أو الأوروبي كـ “السادس من مايو”. يؤدي تحويل رقم الشهر فورياً إلى اسمه النصي الكامل أو المختصر برمجياً إلى إزالة هذا اللبس تماماً، مما يضمن تدفقاً معلوماتياً آمناً وقرارات قائمة على قراءة موحدة للواقع التشغيلي.

علاوة على ذلك، يسهل توليد أسماء الشهور كنصوص منفصلة عمليات الأتمتة المتقدمة في بيئة إكسيل، مثل تقسيم المصنفات تلقائياً إلى أوراق عمل مخصصة لكل شهر، أو تسمية ملفات التصدير بصيغ PDF وفق أسماء الشهور تلقائياً، والقيام بعمليات الفرز والتصفية المبرمجة دون تعديل الخلايا الحاوية على الأرقام التسلسلية الأصلية، مما يحافظ على تكامل البيانات ويحمي السجلات المصدرية من التلف الحسابي.

2. البنية التركيبية والدلالية لدالة MonthName في لغة في بي إيه

2.1 التعريف النظري ومعاملات دالة MonthName

تُعد دالة MonthName دالة نصية قياسية مدمجة في مكتبة لغة Visual Basic for Applications الأساسية، وصُممت خصيصاً لإرجاع سلسلة نصية (String) تمثل اسم الشهر التقويمي المقابل لعدد صحيح محدد. تتميز هذه الدالة ببنيتها الصريحة واستقلاليتها الوظيفية، وصيغتها العامة المعتمدة في بيئة التطوير هي:

MonthName(Month, [Abbreviate])

تتضمن الدالة معاملين رئيسيين يحددان سلوكها التنفيذي بدقة:

  • المعامل الأول (Month): وهو معامل إلزامي (Required) يأخذ قيمة عددية صحيحة من نوع Long تتراوح حصراً بين 1 و12، حيث يشير الرقم 1 إلى شهر يناير (أو كانون الثاني/محرم بحسب الإعدادات الإقليمية)، بينما يشير الرقم 12 إلى شهر ديسمبر. إذا تم تمرير قيمة خارج هذا النطاق المغلق [1, 12]، يتوقف محرك التنفيذ فورياً ويطلق خطأ وقت التشغيل رقم 5 (Runtime Error 5: Invalid procedure call or argument).
  • المعامل الثاني (Abbreviate): وهو معامل اختياري (Optional) يأخذ قيمة منطقية (Boolean). القيمة الافتراضية لهذا المعامل عند إهماله هي False، مما يعني أن الدالة ستُرجع الاسم الكامل للشهر دون اقتطاع. أما إذا حُدد هذا المعامل بالقيمة True، فإن الدالة تُرجع صيغة مختصرة لاسم الشهر تتكون عادة من ثلاثة أحرف في اللغات اللاتينية، أو صيغة مختصرة متوافقة محلياً.

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

2.2 الفروق بين دوال التواريخ القياسية ودالة MonthName المخصصة

يقع كثير من مطوري برمجيات إكسيل المبتدئين في خطأ الخلط بين الدوال التي تستخرج مكونات التاريخ وتلك التي تشكل النصوص الوصفية. دالة Month القياسية، على سبيل المثال، هي دالة حسابية وظيفتها الوحيدة استخلاص الترتيب العددي للشهر من تاريخ كامل، مخرجة عدداً صحيحاً من 1 إلى 12، ولكنها عاجزة تماماً عن تقديم أي تمثيل نصي وصفي. في المقابل، صُممت دالة MonthName حصرياً لتكون جسراً لغوياً يحول هذا الترتيب العددي إلى مسمى معجمي.

قبل إدراج دالة MonthName في البيئة القياسية لـ VBA، كان المبرمجون يلجؤون إلى حلول برمجية غير فعالة، مثل بناء جمل شرطية متفرعة طويلة باستخدام Select Case تتألف من اثنتي عشرة حالة، أو مصفوفات يدوية مسبقة التعريف. هذا الأسلوب القديم لم يكن يستهلك وقتاً أطول في الكتابة فحسب، بل كان يستهلك مساحة إضافية في الذاكرة ويتطلب صيانة برمجية مستمرة إذا تغيرت متطلبات العرض اللغوي.

إن الاعتماد على الدوال الأصلية المضمنة في النواة البرمجية مثل MonthName يقلل من العبء الحسابي (Overhead)؛ حيث تُنفذ الدالة عبر تعليمات برمجية مجمعة مسبقاً (Compiled native code) تتفاعل مباشرة مع مكتبات الربط الديناميكي لنظام التشغيل، مما يمنحها سرعة فائقة في التنفيذ وتكيفاً سلساً مع واجهات المستخدم مقارنة بالمنطق الشرطي المصمم يدوياً.

3. استخراج الرقم التسلسلي للشهر كخطوة وسيطة محورية

3.1 دور دالة Month في تفكيك عناصر التاريخ

لا تمتلك دالة MonthName بمفردها القدرة على قراءة كائن التاريخ الكامل مباشرة؛ إذ لا يمكن تمرير تاريخ مثل “2026-10-22” كمعامل أول لها، وإلا سيحدث خطأ تحويل في الأنواع (Type Mismatch) أو تفسير خاطئ للرقم التسلسلي كقيمة شهر تجاوزت الحد المسموح به. هنا تبرز دالة Month كأداة وظيفية وسيطة لا غنى عنها في بنية المعالجة.

تعمل دالة Month(Date) كأداة تفكيك لمصفوفة التاريخ المخزن؛ حيث تقبل أي تعبير تاريخي صالح أو رقم تسلسلي، وتجري حساباً رياضياً سريعاً لعزل القيمة المقابلة للشهر فقط كعدد صحيح مجرد. تتميز الدالة بمرونة فائقة في التعامل مع المدخلات المتنوعة، سواء كانت متغيرات مصرحاً عنها صراحة كنوع Date، أو نصوصاً تقبل التحويل المنطقي إلى تاريخ وفق الإعدادات المحلية للمستخدم.

ومع ذلك، ينطوي التعامل مع دالة Month على محاذير يجب التنبه لها؛ فعند تمرير خلية فارغة إليها، قد يعامل إكسيل القيمة الفارغة كرقم صفري (0)، والذي يناظر في تقويم إكسيل تاريخ 30 ديسمبر 1899، مما يجعل الدالة تُرجع الرقم 12 بدلاً من إشعار المستخدم بالفراغ، الأمر الذي يؤكد ضرورة عزل خطوة الاستخراج والتأكد من منطقية المدخل الزمني قبل استخدامه في مراحل المعالجة اللاحقة.

3.2 الربط المنطقي بين دالتي Month وMonthName في تعبير برمجي واحد

لتحقيق الكفاءة البرمجية واختصار عدد الأسطر، يلجأ المطورون المحترفون إلى تطبيق مبدأ “الدوال المتداخلة” (Nested Functions)؛ حيث يُدمج استدعاء دالة Month كمعامل داخلي مباشر يُمرر إلى دالة MonthName الخارجية. يتيح هذا النمط المعماري إنجاز عملية التحويل المعقدة في تعبير برمجي موحد وأنيق.

يتضح هذا التدفق المنطقي من خلال المثال الرياضي والبرمجي التالي: لنفترض أن الخلية A2 تحتوي على التاريخ 22 أكتوبر 2026. في البداية، تقرأ بيئة التنفيذ الجزء الداخلي للتعبير، فتستدعي دالة Month(Range("A2").Value) التي تحلل التاريخ وتستخرج منه القيمة العددية 10. بعد إتمام هذه الخطوة، يُمرر الناتج العددي تلقائياً إلى الدالة المحيطة لتصبح الصيغة مكافئة لـ MonthName(10)، والتي تُرجع بدورها السلسلة النصية “October”.

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

4. التطبيق العملي: كتابة ماكرو استخراج اسم الشهر خطوة بخطوة

4.1 تهيئة بيئة التطوير (VBE) وبناء الإجراء الفرعي

لبدء كتابة الشفرة البرمجية العملية، يجب أولاً تهيئة بيئة التطوير المرئية المتكاملة في إكسيل (Visual Basic Editor – VBE). يتم ذلك عبر فتح مصنف إكسيل والضغط على مفتاحي Alt + F11 من لوحة المفاتيح. من شريط الأدوات العلوي في نافذة المحرر، يتم النقر على قائمة Insert ثم اختيار Module لإنشاء وحدة نمطية قياسية جديدة تماماً.

تتمثل الخطوة الاحترافية الأولى قبل كتابة أي سطر إجرائي في إضافة التعليمة الصريحة Option Explicit في أعلى الوحدة النمطية. تلزم هذه التعليمة المطور بالتصريح الصريح عن كافة المتغيرات المستخدمة في الإجراءات، مما يحمي الشفرة من الأخطاء الإملائية الشائعة في تسمية المتغيرات التي قد تهدر ساعات في تصحيح الأخطاء التشغيلية الخفية.

عقب ذلك، يتم إنشاء الإجراء الفرعي باستخدام الكلمة المفتاحية Sub متبوعة باسم وصفي معبر يخضع لقواعد التسمية القياسية في لغة في بي إيه، مثل عدم بدء الاسم برقم وخلوه من المسافات والرموز الخاصة، كالتالي: Sub ExtractMonthNames(). بعد ذلك، يتم حجز المتغير الرقمي المخصص لإدارة حلقة التكرار باستخدام تعليمة التصريح Dim i As Long، ويُفضل استخدام نوع Long بدلاً من Integer لتجنب أخطاء تجاوز السعة (Overflow) في حال امتدت صفوف البيانات لأكثر من 32,767 صفاً.

4.2 شرح السطور البرمجية للشفرة المرجعية

يتناول هذا الجزء بناء الإجراء الميداني الذي يقرأ التواريخ من العمود A ابتداءً من الصف الثاني لتخطي صف العناوين، ويطبع أسماء الشهور المقابلة في العمود C. يمكن كتابة الإجراء المعياري عبر التكوين التالي:

تبدأ الحلقة التكرارية بالصيغة: For i = 2 To 11، وتحدد هذه العبارة النطاق الإجرائي للصفوف المستهدفة بالتنفيذ، من الصف الثاني وحتى الصف الحادي عشر. داخل جسم الحلقة، يُنفذ سطر الإسناد الجوهري التالي:

Range("C" & i).Value = MonthName(Month(Range("A" & i).Value))

في هذا السطر الحاسم، يدمج المشغل النصي & الحرف “C” مع رقم الفهرس الحالي i لتحديد كائن الخلية المستهدفة ديناميكياً في كل دورة. يتم استدعاء خاصية Value للخلية المقابلة في العمود A، وتمريرها فورياً إلى دالة Month، ومن ثم تمرير الناتج الرقمي إلى دالة MonthName، لتستقر السلسلة النصية الناتجة داخل الخلية المحددة في العمود C. بعد إتمام الإسناد، تأتي التعليمة Next i لزيادة قيمة العداد بمقدار واحد والانتقال آلياً إلى الصف التالي حتى استيفاء المدى الحسابي للحلقة بالكامل.

4.3 تحليل مخرجات التنفيذ والتحقق من صحة النتائج

بمجرد النقر على زر التشغيل Run Sub (F5)، يبدأ المحرك البرمجي بمعالجة الخلايا بدقة وتسلسل متناهيين. عند تدقيق المخرجات في العمود C، يظهر النجاح التشغيلي للخوارزمية عبر التوافق التام بين تواريخ الإدخال وأسماء الشهور الناتجة. فإذا كانت الخلية A2 تحتوي على “15/01/2025″، فإن الخلية C2 تستقبل القيمة النصية “January” (أو يناير بحسب بيئة النظام)، وبالمثل تُترجم تواريخ شهر فبراير ومارس وبقية شهور السنة بدقة بالغة.

تثبت هذه الشفرة استقراراً تاماً بغض النظر عن تفاوت أطوال الأيام في الشهور؛ فالشهور ذات الثمانية وعشرين يوماً مثل فبراير تُعالج بذات الموثوقية التي تُعالج بها الشهور ذات الثلاثين أو الإحدى وثلاثين يوماً، نظراً لأن تركيز دالة Month ينصب حصرياً على المؤشر التقويمي المضمن داخل التمثيل الرقمي للخلية دون التأثر بتغيرات نهاية الشهر. ومع استكمال الحلقة للصف الأخير، يخرج الإجراء بهدوء وأمان دون توليد أي أخطاء في وقت التشغيل، مما يؤكد سلامة المنطق البرمجي وصحة تطبيق المبادئ التركيبية للدوال.

5. استراتيجيات تكرار الحلقات لمعالجة النطاقات الديناميكية المتغيرة

5.1 تجاوز الحدود الثابتة وتحديد الصف الأخير برمجياً

على الرغم من بساطة تحديد حدود الحلقة مسبقاً (Hardcoding) كما في التعبير For i = 2 To 11، إلا أن هذا الأسلوب يمثل ممارسة برمجية هشة في بيئات الإنتاج الفعلية؛ فالبيانات المالية والإدارية تتسم بالديناميكية والتغير المستمر، وإضافة صفوف جديدة تستلزم تحديث الكود يدوياً في كل مرة، وهو أمر غير عملي ويفتح الباب واسعاً أمام الأخطاء التشغيلية وتجاهل السجلات المضافة حديثاً.

للتغلب على هذا القصور المعماري، يُستخدم النمط البرمجي المعتمد على الخاصية End(xlUp) لحساب رقم آخر صف مستخدم في ورقة العمل برمجياً قبل بدء الحلقة. يُصاغ هذا الحل عبر السطر التالي:

Dim LastRow As Long
LastRow = Cells(Rows.Count, "A").End(xlUp).Row

يقوم هذا التعبير بمحاكاة سلوك المستخدم البشري عندما ينتقل إلى الخلية الأخيرة في أقصى قاع ورقة العمل بالعمود A (الصف رقم 1,048,576 في مصنفات إكسيل الحديثة)، ثم يضغط على اختصار لوحة المفاتيح Ctrl + Up Arrow ليصعد رأسياً ويستقر تلقائياً على آخر خلية فعلية تحتوي على بيانات. بعد احتساب هذه القيمة، تصبح صياغة الحلقة مرنة وشاملة تماماً: For i = 2 To LastRow، مما يضمن معالجة كافة السجلات بدقة متناهية ودون إهدار للموارد الحاسوبية في تكرار الحلقات داخل خلايا فارغة تقع أسفل الجدول.

5.2 مقارنة الحلقات التكرارية: For…Next مقابل For Each…Next

توفر لغة VBA آليات متعددة للمرور عبر نطاقات الخلايا، وتعد المقارنة بين حلقة الفهرسة الرقمية For...Next وحلقة استعراض الكائنات For Each...Next من الموضوعات المحورية في تحسين كفاءة المعالجة. يوضح الجدول والتحليل التالي الفروق الهيكلية والأدائية بين الأسلوبين:

  • حلقة For…Next القياسية: تعتمد على عداد رقمي صحيح يشير إلى مؤشرات الصفوف. ميزتها الأساسية تكمن في انخفاض استهلاك الذاكرة وسهولة تتبع الموقع النسبي للبيانات، مما يجعلها مثالية للتعامل مع الأعمدة المتجاورة، مثل القراءة من العمود A والكتابة المتزامنة في العمود C بنفس رقم الفهرس.
  • حلقة For Each…Next الكائنية: تعتمد على تخصيص متغير من نوع كائن Range للمرور المباشر على كل خلية ضمن نطاق محدد مسبقاً، كأن نصرح: Dim cell As Range متبوعة بـ For Each cell In Range("A2:A" & LastRow).

من الناحية المعمارية، تُعد حلقة For Each أكثر أناقة وقراءة عند الرغبة في فحص الخلايا دون الحاجة لحساب المؤشرات الرقمية، إلا أن لكل دورة فيها تكلفة طفيفة في استهلاك الذاكرة ناتجة عن تحديث مؤشر كائن الخلية عبر واجهة البرمجة المشتركة COM. لذلك، في الجداول الطويلة التي تتضمن عشرات الآلاف من الصفوف، تتفوق حلقة الفهرسة الرقمية For...Next في سرعة الاستجابة واستقرار الموارد، خصوصاً إذا اقترنت بتقنيات تقليل التفاعل المباشر مع واجهة إكسيل كما سيتم تفصيله لاحقاً.

6. التحكم في تنسيقات الإخراج: الأسماء الكاملة والمختصرة للشهور

6.1 استخدام معامل الاختصار (Abbreviate Parameter)

يوفر المعامل الثاني في دالة MonthName مرونة فائقة لمصممي النظم في مواءمة المخرجات النصية مع القيود المكانية لواجهات العرض وجداول التقارير الموجزة. في كثير من السيناريوهات التحليلية، تكون أعمدة البيانات مكدسة أو مخصصة لمخططات إحصائية ضيقة المساحة لا تتسع لطباعة أسماء الشهور الطويلة مثل “September” أو “سبتمبر”، مما يجعل الصيغة المختصرة المكونة من ثلاثة أحرف مطلباً تصميمياً رئيسياً.

يتحقق هذا الاختصار عبر التمرير الصريح للقيمة المنطقية True كمعامل ثانٍ للدالة، كما في التعبير الآتي:
Range("D" & i).Value = MonthName(Month(Range("A" & i).Value), True)

عند تفعيل هذا الخيار، تعود الدالة بالاسم المختصر للشهر؛ فالتاريخ العائد لشهر يناير يُعرض كنص “Jan”، وتاريخ شهر أغسطس يُعرض كـ “Aug”. وتجدر الإشارة إلى أن إهمال هذا المعامل أو ضبطه على False يُبقي على الخيار الافتراضي الذي يعرض الاسم الكامل دون اقتطاع (“January”، “August”). يمنح هذا التمييز البرمجي صانع القرار إمكانية إنشاء مخرجات مزدوجة تدعم متطلبات العرض المالي الصارم والعرض البصري المضغوط في آن واحد.

6.2 توحيد التنسيق النصي وحالة الأحرف للغات اللاتينية

في الأنظمة الإدارية التي تعتمد اللغة الإنجليزية أو اللغات اللاتينية في تدوين بياناتها، تكتسب مسألة توحيد حالة الأحرف (Case Sensitivity) أهمية قصوى لضمان اتساق قواعد البيانات وتسهيل عمليات الفرز والاستعلام اللاحقة عبر استعلامات SQL أو دوال المطابقة مثل VLOOKUP وXLOOKUP. تُرجع دالة MonthName افتراضياً أسماء الشهور بنمط العنوان (Title Case)، حيث يبدأ الاسم بحرف كبير يليه حروف صغيرة (مثل “March”).

لإخضاع المخرجات النصية لمعايير تنسيق صارمة، يمكن دمج دالة MonthName مع دوال معالجة النصوص القياسية في VBA:

  • لتحويل اسم الشهر بالكامل إلى أحرف كبيرة: يتم تطويق التعبير بدالة UCase، ليصبح التعبير: UCase(MonthName(Month(dt)))، فتكون النتيجة “MARCH”.
  • لتحويله إلى أحرف صغيرة تماماً: تُستخدم دالة LCase لتكون النتيجة “march”.
  • لتأكيد نمط الحرف الاستهلالي الكبير مع باقي الحروف الصغيرة بطريقة معيارية مطلقة: يمكن الاستعانة بدالة التحويل النصي الشاملة StrConv مع الثابت البرمجي vbProperCase عبر الصياغة: StrConv(MonthName(Month(dt)), vbProperCase).

إن هذا الضبط الدقيق لحالة الأحرف والنصوص يضمن نظافة البيانات (Data Cleansing)، ويمنع حدوث أي تشوهات بصرية في التقارير النهائية الموجهة للإدارة العليا، فضلاً عن رفع موثوقية الأنظمة عند تصدير البيانات إلى مستودعات البيانات الخارجية (Data Warehouses).

7. التدويل، الإعدادات الإقليمية، وتعدد اللغات لأسماء الشهور

7.1 اعتماد دالة MonthName على الإعدادات الإقليمية للنظام

من المسائل الهندسية الدقيقة التي تغيب عن أذهان كثير من المطورين هي أن دالة MonthName في لغة VBA ليست دالة معزولة لغوياً، بل هي دالة تعتمد اعتماداً كلياً على الإعدادات الإقليمية (Regional Settings) ومعرف اللغة المحلي (Locale ID – LCID) المعتمد في نظام تشغيل ويندوز المثبت على جهاز المستخدم. تستدعي الدالة واجهات برمجة التطبيقات الخاصة بالدعم اللغوي القومي لنظام ويندوز (Win32 NLS APIs) لترجمة رقم الشهر إلى مقابله النصي.

يترتب على هذه الطبيعة المعمارية تحدٍ تقني بالغ الحساسية في بيئات العمل الدولية المشتركة؛ فإذا كُتب الماكرو ونُفذ على جهاز مضبوط وفق البيئة الإقليمية العربية (مثلاً: الإعدادات الإقليمية لمصر أو السعودية)، ستُرجع دالة MonthName(1) النص “يناير” أو “محرم” بحسب نوع التقويم النشط. وإذا تم نقل نفس ملف الإكسيل وتشغيله على جهاز زميل عمل في المملكة المتحدة مضبوط على الإنجليزية، فستُرجع الدالة ذاتها النص “January”، دون أي تغيير في الكود المكتوب.

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

7.2 تخصيص لغة إخراج أسماء الشهور برمجياً

لتحييد تأثير الإعدادات الإقليمية لنظام التشغيل وفرض لغة إخراج نصية محددة بدقة مطلقة، يتجه المطورون نحو استراتيجيتين معماريتين متقدمتين:

الاستراتيجية الأولى: استدعاء دالة التنسيق مع وسيط لغوي صريح:
يمكن توظيف دالة WorksheetFunction.Text بالتكامل مع أكواد التنسيق المسبوقة بمحدد اللغة الإقليمي المعتمد في إكسيل (LCID Hex Codes). على سبيل المثال، لفرض كتابة اسم الشهر باللغة الإنجليزية بغض النظر عن نظام التشغيل، يمكن تمرير البادئة [$-0409] (التي ترمز للإنجليزية الأمريكية) بالشكل التالي:
WorksheetFunction.Text(dt, "[$-0409]mmmm")

الاستراتيجية الثانية: بناء مصفوفة نصوص مخصصة (Custom String Array):
تعد هذه الطريقة الأكثر صلابة واستقراراً على الإطلاق لعزل الكود عن أي عوامل خارجية. يقوم المطور بإنشاء مصفوفة تحتوي على أسماء الشهور باللغة المطلوبة حصراً، وربطها برقم الشهر كمعامل فهرسة:

Dim ArabicMonths As Variant
ArabicMonths = Array("يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر")
Range("C" & i).Value = ArabicMonths(Month(Range("A" & i).Value) - 1)

نظراً لأن مصفوفات VBA التي تُنشأ بواسطة الدالة Array تبدأ بفهرس صفري (0-based) افتراضياً، يتم طرح 1 من ناتج دالة Month لمطابقة الترتيب الصحيح. يضمن هذا النهج ظهور الأسماء باللغة العربية حصراً حتى لو شُغّل المصنف على نظام تشغيل ياباني أو أمريكي، مما يوفر تحكماً برمجياً كاملاً في واجهة العرض.

8. التحقق من صحة البيانات الزمنية ومعالجة الأخطاء الاستثنائية

8.1 فحص طبيعة البيانات قبل التنفيذ باستخدام دالة IsDate

تتعرض البرمجيات المؤسسية للفشل والانهيار المفاجئ في أغلب الأحيان نتيجة إدخال بيانات غير متوقعة أو رديئة الجودة داخل جداول البيانات. فوجود خلية نصية تحتوي على عبارة مثل “Pending”، أو كتابة تاريخ بصيغة خاطئة نحو “31/02/2024″، أو وجود خلايا فارغة بين السجلات، سيؤدي حتماً إلى توقف الماكرو وإطلاق خطأ وقت التشغيل 13 (Type Mismatch) عند محاولة تمرير هذه القيمة إلى دالة Month.

لتجنب هذا السلوك الكارثي، يجب ترسيخ مبدأ “البرمجة الدفاعية” (Defensive Programming) عبر فحص صلاحية مدخلات الخلية منطقياً قبل الشروع في معالجتها. تبرز دالة IsDate كخط الدفاع الأول في هذا السياق؛ إذ تقبل أي تعبير برمجي وتُرجع القيمة المنطقية True فقط إذا كان بالإمكان تفسير القيمة كتاريخ تقويمي صالح، وتُرجع False في خلاف ذلك.

يتم تطبيق هذا الفحص الوقائي عبر هيكل شرطي يحيط بعملية التحويل داخل الحلقة التكرارية:

If Not IsEmpty(Range("A" & i).Value) And IsDate(Range("A" & i).Value) Then
    Range("C" & i).Value = MonthName(Month(Range("A" & i).Value))
Else
    Range("C" & i).Value = "تاريخ غير صالح"
End If

يضمن هذا الهيكل الشرطي عزل السجلات الشاذة والمشوهة بأمان، ووضع وسوم تحذيرية واضحة أمامها في عمود الإخراج، مما يسمح للماكرو بمتابعة مهامه حتى النهاية دون توقف، ويتيح لفرق التدقيق لاحقاً مراجعة الخلايا غير الصالحة وتصحيحها.

8.2 تطبيق آليات إدارة الأخطاء (Error Handling) في في بي إيه

بجانب التحقق الاستباقي من صحة البيانات، تتطلب المعايير المهنية لتطوير البرمجيات بناء شبكة أمان لاقتناص أي أخطاء استثنائية غير متوقعة قد تطرأ أثناء وقت التشغيل؛ كأن تكون ورقة العمل محمية بكلمة مرور تمنع الكتابة في العمود المستهدف، أو حدوث خلل عارض في تخصيص الذاكرة. يتم ذلك من خلال ميكانيزم إدارة الأخطاء الصريح عبر التعليمة On Error GoTo.

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

Sub RobustExtractMonths()
    On Error GoTo ErrorHandler
    ' [الشفرة التنفيذية الرئيسية والحلقات التكرارية هنا]
    Exit Sub
ErrorHandler:
    MsgBox "حدث خطأ غير متوقع أثناء معالجة البيانات: " & Err.Description, vbCritical, "خطأ نظام"
    Err.Clear
End Sub

تقوم التعليمة Exit Sub بحماية كتلة معالجة الأخطاء من التنفيذ العفوي في الحالات الطبيعية للبرنامج. أما في حال تعثر أي تعبير برمجي، يقفز المحرك فورياً إلى ملصق ErrorHandler، فيعرض رسالة مهذبة تشرح طبيعة المشكلة استناداً إلى خاصية Err.Description، ثم يقوم بتفريغ كائن الخطأ عبر Err.Clear لضمان ترك النظام في حالة مستقرة وآمنة تماماً.

9. المناهج البديلة لاستخراج اسم الشهر في في بي إيه: دراسة مقارنة

9.1 استخدام دالة التنسيق Format لاستخراج اسم الشهر

تُمثل دالة التنسيق Format في بيئة في بي إيه البديل الأكثر تفضيلاً وشيوعاً لدى كثير من المطورين المحترفين مقارنة بدالة MonthName. ترجع هذه الأفضلية إلى أن دالة Format تستطيع التعامل مباشرة مع كائن التاريخ أو رقمه التسلسلي الأصلي، دون الحاجة إلى تفكيكه مسبقاً باستخدام دالة Month، مما يلغي خطوة حسابية كاملة ويبسط التعبير البرمجي بدرجة كبيرة.

تعتمد دالة Format على رموز توجيهية (Format Tokens) للتحكم في بنية النص الناتج:

  • رمز التنسيق "mmmm": يُرجع الاسم النصي الكامل للشهر مباشرة من كائن التاريخ (مثال: Format(dt, "mmmm") يُرجع “October”).
  • رمز التنسيق "mmm": يُرجع الاسم النصي المختصر للشهر بثلاثة أحرف (مثال: Format(dt, "mmm") يُرجع “Oct”).
  • رمز التنسيق "mm": يُرجع الترتيب الرقمي للشهر بخانتين مع صفر إضافي للشمال عند الحاجة (مثال: “10”).
  • رمز التنسيق "m": يُرجع الترتيب الرقمي للشهر كرقم فردي أو مزدوج دون صفر إضافي (مثال: “10”).

تتميز دالة Format بالبساطة والأناقة البصرية في كتابة الشفرة؛ حيث يُكتب التعبير البرمجي بسلاسة تامة: Range("C" & i).Value = Format(Range("A" & i).Value, "mmmm"). كما تمتاز بقدرتها الفائقة على قراءة السلاسل النصية التي ترمز لتواريخ بصورة أكثر مرونة وتسامحاً من دالة Month، مما يجعلها أداة بالغة القوة والفعالية في المهام الروتينية السريعة.

9.2 استدعاء دوال ورقة العمل عبر كائن WorksheetFunction

يتيح محرك VBA للمطورين إمكانية استدعاء دوال ورقة عمل إكسيل القياسية واستخدامها داخل الشفرات البرمجية عبر الكائن الوسيط Application.WorksheetFunction. ومن بين هذه الدوال تبرز دالة Text، وهي المقابل المباشر لدالة Format على مستوى واجهة المصنّف الأساسية، وتُستدعى بالشكل التالي: Application.WorksheetFunction.Text(dt, "mmmm").

ورغم قوة هذا الأسلوب وقدرته على استغلال نفس الصياغات التي يألفها مستخدمو الصيغ الرياضية في إكسيل، إلا أن استدعاء دوال ورقة العمل من داخل بيئة VBA يفرض ضريبة أداء ملحوظة (Performance Penalty)؛ حيث يضطر المحرك البرمجي إلى كسر العزل بين بيئة تشغيل VBA ومحرك حسابات ورقة العمل الخارجي عبر جسور كائنية معقدة (COM Interop Boundary) في كل تكرار للحلقة، مما يبطئ وقت التنفيذ الإجمالي مقارنة بالدوال المضمنة أصلياً في لغة البرمجة مثل MonthName وFormat.

يوضح الجدول المقارن التالي السمات الفنية والاختلافات المعمارية بين المناهج الثلاثة الرئيسية:

  • دالة MonthName المدمجة:
    • المدخل المطلوب: عدد صحيح من 1 إلى 12 (تتطلب دمجها مع دالة Month).
    • السرعة الحاسوبية: عالية جداً (دالة أصلية خفيفة الوزن).
    • المرونة التنسيقية: تقتصر على خياري الاسم الكامل أو المختصر عبر معامل منطقي.
    • أفضل استخدام: عندما يكون رقم الشهر متوفراً بالفعل كعدد صحيح مستقل.
  • دالة Format المدمجة:
    • المدخل المطلوب: كائن تاريخ كامل أو رقم تسلسلي أو نص زمني.
    • السرعة الحاسوبية: عالية جداً ومثالية للعمليات النصية المكثفة.
    • المرونة التنسيقية: فائقة المرونة تتيح استخراج الأسماء الكاملة، والمختصرة، والأرقام بتعديل بسيط للرمز.
    • أفضل استخدام: استخراج اسم الشهر مباشرة من خلايا التواريخ بأقل عدد من الأسطر والتعقيدات.
  • دالة WorksheetFunction.Text:
    • المدخل المطلوب: كائن تاريخ أو قيمة خلية تتوافق مع معايير إكسيل.
    • السرعة الحاسوبية: متوسطة إلى منخفضة بسبب تكلفة استدعاء محرك إكسيل الخارجي.
    • المرونة التنسيقية: فائقة وتدعم كافة رموز التنسيق المعتمدة في واجهة إكسيل الرياضية.
    • أفضل استخدام: الحالات الخاصة التي تتطلب استخدام محددات إقليمية معقدة جداً غير متوفرة في دوال VBA.

10. أفضل الممارسات الهندسية وتحسين كفاءة المعالجة للنطاقات الضخمة

10.1 تعطيل خصائص التطبيق غير الضرورية أثناء المعالجة

عند تنفيذ الماكرو البرمجي على جداول بيانات تتضمن عشرات الآلاف من الصفوف، فإن التفاعل اللحظي مع واجهة المستخدم الرسومية يمثل المستهلك الأكبر لموارد المعالج وبطاقة الرسوميات. في كل مرة تُكتب فيها قيمة اسم الشهر داخل خلية عبر تعبير مثل Range("C" & i).Value = ...، يقوم إكسيل تلقائياً بإعادة رسم الشاشة لتحديث العرض البصري، ويعيد حساب كافة الصيغ الرياضية المرتبطة في المصنف، ويفحص الأحداث البرمجية التابعة لورقة العمل.

لتسريع وتيرة التنفيذ بنسبة قد تتجاوز 90%، يتبع المطورون الهندسيون تقنية “الإخماد المؤقت” لخصائص التطبيق عند بداية الإجراء، ثم إعادة تفعيلها فور الانتهاء من العمليات الحسابية، كما هو موضح أدناه:

Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False

يوقف السطر الأول تحديث وميض الشاشة بالكامل أثناء جريان الحلقة التكرارية، مما يوفر آلاف النداءات الرسومية المهدرة. بينما يمنع السطر الثاني إكسيل من إعادة احتساب معادلات المصنف بعد كل كتابة مفردة في الخلايا. أما السطر الثالث فيعطل مراقبة الأحداث التشغيلية (مثل حدث Worksheet_Change)، مما يمنع الدخول في حلقات برمجية لا نهائية أو استدعاءات جانبية مبطئة، مع التأكيد الصارم على ضرورة إعادة ضبط هذه القيم على True وxlCalculationAutomatic قبل إنهاء الإجراء لضمان عودة إكسيل إلى حالته التشغيلية الطبيعية.

10.2 معالجة البيانات عبر مصفوفات الذاكرة (Memory Arrays)

تمثل تقنية “مصفوفات الذاكرة المؤقتة” الذروة المعمارية للأداء البرمجي في في بي إيه؛ حيث يُلغى التفاعل الخلوي الفردي تماماً لصالح تفاعل مجمع ثنائي الخطوة (Bulk Operation). بدلاً من القراءة والكتابة في خلايا ورقة العمل 50,000 مرة داخل حلقة تكرارية، يتم تحميل النطاق بالكامل في مصفوفة داخل الذاكرة العشوائية (RAM) في خطوة واحدة، ومعالجة التحويلات بسرعة الضوء داخل المعالج، ثم تفريغ النتائج دفعة واحدة إلى النطاق المستهدف.

تُطبق هذه الاستراتيجية الاحترافية وفق المنهجية البرمجية التالية:

Dim DataRange As Variant
Dim OutputRange As Variant
Dim r As Long
DataRange = Range("A2:A" & LastRow).Value
ReDim OutputRange(1 To UBound(DataRange, 1), 1 To 1)

For r = 1 To UBound(DataRange, 1)
    If IsDate(DataRange(r, 1)) Then
        OutputRange(r, 1) = MonthName(Month(DataRange(r, 1)))
    Else
        OutputRange(r, 1) = ""
    End If
Next r

Range("C2:C" & LastRow).Value = OutputRange

في هذا النموذج، نُقلت مصفوفة المدخلات بالكامل إلى الذاكرة عبر السطر DataRange = ...، وتولى أمر المعالجة حلقة سريعة تتنقل بين مؤشرات الذاكرة بدلاً من خلايا الشيت، وعند الوصول للسطر الأخير، تم إسناد مصفوفة OutputRange إلى العمود C في جزء من الثانية. تتيح هذه الهندسة المتطورة معالجة مئات الآلاف من التواريخ الزمنية دون أي تأخير ملحوظ، مما يجسد أفضل معايير الكفاءة الحوسبية في أتمتة العمليات المكتبية.

10.3 بناء دالة معرفة من قبل المستخدم (UDF) لإعادة الاستخدام

لتحقيق مبدأ إعادة استخدام الكود البرمجي (Code Reusability) وتقليل التكرار، يمكن تحويل منطق استخراج اسم الشهر من إجراء ماكرو مغلق (Sub Procedure) إلى دالة وظيفية معرفة من قبل المستخدم (User-Defined Function – UDF). تتيح هذه الخطوة استدعاء الدالة مباشرة من داخل صيغ خلايا ورقة العمل تماماً مثل أي دالة قياسية مضمنة في إكسيل (كـ SUM وAVERAGE).

تُصاغ الدالة الوظيفية المعيارية داخل وحدة نمطية قياسية كالتالي:

Public Function GetMonthNameFromDate(TargetCell As Range, Optional Abbr As Boolean = False) As String
    If IsDate(TargetCell.Value) Then
        GetMonthNameFromDate = MonthName(Month(TargetCell.Value), Abbr)
    Else
        GetMonthNameFromDate = "قيمة غير صالحة"
    End If
End Function

بمجرد كتابة هذه الدالة، يستطيع أي مستخدم كتابة الصيغة التالية داخل الخلية C2: =GetMonthNameFromDate(A2) أو =GetMonthNameFromDate(A2, TRUE) للحصول على الاسم المختصر. يحقق هذا المنهج أعلى درجات التجريد والمرونة؛ حيث يتم إخفاء التعقيد البرمجي وضمانات التحقق من صحة البيانات خلف واجهة استخدام بسيطة ومألوفة، مما يسهل نشر الحلول البرمجية بين المستخدمين غير المتخصصين في البرمجة مع الحفاظ على صرامة المعالجة ودقتها.

خاتمة

استعرضت هذه الدراسة التأصيلية الأبعاد النظرية والتطبيقية الشاملة لعملية استخلاص أسماء الشهور من التواريخ في بيئة Visual Basic for Applications (VBA) وتطبيق مايكروسوفت إكسيل. لقد تبين أن التفاعل البرمجي الواعي مع المتغيرات الزمنية يتطلب فهماً عميقاً لطبيعة التمثيل الرقمي للتواريخ كنظام أرقام تسلسلية مبني على الأيام والكسور، وفصلاً جلياً بين القيمة الرياضية التخزينية الموجهة للعمليات الحسابية والتمثيل النصي الموجه للعرض التحليلي والإحصائي.

من خلال المقارنة التحليلية الدقيقة، اتضح أن دالة MonthName تقدم حلاً معيارياً متخصصاً وخفيف الوزن عندما تتكامل مع دالة Month الوسيطة، بينما توفر دالة Format مرونة فائقة واختصاراً شفراتياً متميزاً بقراءتها لكائن التاريخ مباشرة دون وسائط رقمية. كما أظهرت الدراسة أن النظم الاحترافية لا تكتفي بكتابة الكود الأساسي فحسب، بل تُعنى بتأصيل استراتيجيات الحلقات الديناميكية المتكيفة، والتحقق الدفاعي من سلامة البيانات باستخدام IsDate، ومراعاة الأبعاد الإقليمية واللغوية عبر المصفوفات المخصصة لعزل النظم عن تقلبات بيئات التشغيل، وصولاً إلى تطبيق المعالجة المجمعة عبر مصفوفات الذاكرة لتحقيق أقصى درجات الكفاءة الحاسوبية في مواجهة البيانات الضخمة.

المراجع

  • da Silva, A. G., Gomes, M. V. M., & Winkler, I. (2022). Virtual Reality and Digital Human Modeling for Ergonomic Assessment in Industrial Product Development: A Patent and Literature Review. Applied Sciences. https://doi.org/10.3390/app12031084
  • Alfaifi, A. Y. G. (2015). Building the Arabic Learner Corpus and a System for Arabic Error Annotation (Doctoral dissertation, University of Leeds, The University of Sheffield, University of York). White Rose eTheses Online. https://doi.org/10.13140/rg.2.2.32081.53608
★

تقييم هذا المحتوى

5.0 / 5 • 7 تقييمات

اقتباس هذا المقال

looti, M. (2026, أكتوبر 22). في بي إيه: كيفية الحصول على اسم الشهر من التاريخ. عرب سايكلوجي. https://arabpsychology.com/statistics/vba-how-to-get-month-name-from-date/
looti, Mohammed. “في بي إيه: كيفية الحصول على اسم الشهر من التاريخ.” عرب سايكلوجي, 22 أكتوبر 2026, https://arabpsychology.com/statistics/vba-how-to-get-month-name-from-date/.
looti, Mohammed. “في بي إيه: كيفية الحصول على اسم الشهر من التاريخ.” عرب سايكلوجي. أكتوبر 22, 2026. https://arabpsychology.com/statistics/vba-how-to-get-month-name-from-date/.