اذهب الي المحتوي
أوفيسنا
بحث مخصص من جوجل فى أوفيسنا
Custom Search

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

  1. ابو جودي

    ابو جودي

    أوفيسنا


    • نقاط

      3

    • Posts

      6997


  2. Foksh

    Foksh

    الخبراء


    • نقاط

      2

    • Posts

      2976


  3. Moosak

    Moosak

    أوفيسنا


    • نقاط

      2

    • Posts

      2164


  4. محمد هشام.

    محمد هشام.

    الخبراء


    • نقاط

      2

    • Posts

      1709


Popular Content

Showing content with the highest reputation on 03/18/25 in all areas

  1. السلام عليكم ورحمة الله وبركاته .. كل الشكر والتقدير لك أستاذ @ابو جودي على هذي التحفة الفنية 🙂 أنا جمعت البتاع كله في ملفات لتسهيل التطبيق على الاخوة 🙂 وبعد التجربة لم يتم إنشاء الملف المضغوط وظهرت لي هذه الرسالة من WinRAR : وبعدها : ولكن لا يتم إنشاء الملف !! 🙂 طبعا هذا يحصل في الدوال الثلاث الأولى : وهذه : وهذه : وهذا: وهذا : وهذا : وغيرها ..... 😅🖐🏻 الخلاصة : أنت راجع كل الدوال كلها .. وهناك كم دالة هم اللي أشتغلوا فقط والباقي لا . Automate compression and decompression processes for files and folders.zip
    2 points
  2. السلام عليكم ورحمة الله تعالى وبركاته هدية اليوم هى عبارة عن مكتبة برمجية متكاملة تم كتابتها وتطويرها لتوفير حلول مرنة وقوية لضغط الملفات والمجلدات وفك ضغطها باستخدام أدوات شائعة مثل WinRAR و7-Zip لأتمتة عمليات الضغط وفك الضغط للملفات و المجلدات بإحترافيه ومرونه وتحكم شامل فيما يلي نبذة عن الخصائص والمميزات والإمكانيات العامة للكود : يدعم ضغط الملفات وفك ضغطها باستخدام كل من WinRAR و7-Zip مما يتيح للمستخدم اختيار الأداة المناسبة بناء على احتياجاته يقبل المدخلات على شكل سلسلة نصية واحدة أو مصفوفة تحتوي على عدة ملفات أو مجلدات يحدد تلقائيا مسارات البرامج من سجل النظام أو المسارات الافتراضية مع خيار يدوي كبديل يستخدم ترميز Unicode في ملفات التعليق لدعم النصوص العربية وغيرها من اللغات يوفر 6 مستويات (من بدون ضغط إلى أقصى ضغط ) للتحكم في التوازن بين السرعة وحجم الملف يدعم تقسيم الأرشيف إلى أجزاء بأحجام مختلفة (50 ميجابايت إلى 2 جيجابايت) يتيح إضافة كلمة مرور للأرشيفات مع تشفير أسماء الملفات أرشيفات ذاتية الاستخراج (SFX): يمكن إنشاء ملفات تنفيذية (exe) لا تحتاج إلى برنامج لفك الضغط التعليقات: يدعم إضافة تعليقات نصية للأرشيفات في WinRAR إدارة عمليات متعددة: ضغط وفك ضغط عدة ملفات في استدعاء واحد أو عبر حلقات ( مصفوفات ) يحتوي على معالجة أخطاء شاملة مع رسائل توضيحية (مثل أخطاء المعاملات أو الملفات غير الموجودة) التخصيص:يسمح بتحديد اسم الأرشيف - المسار الهدف - ونوع الأرشيف (RAR/ZIP/7z) حسب رغبة المستخدم سيناريوهات الاستخدام ضغط التقارير أو المستندات الكبيرة وتوزيعها بسهولة إنشاء أرشيفات محمية بكلمة مرور أو ذاتية الاستخراج لمشاركة الملفات دمج الكود في تطبيقات إدارية لتبسيط عمليات النسخ الاحتياطي أو الأرشفة نقاط القوة سهولة الاستخدام: يمكن تصميم واجهة بسيطة مع معاملات اختيارية ذات قيم افتراضية منطقية الأداء: يعتمد على أدوات مثبتة مثل WinRAR و7-Zip لضمان السرعة والكفاءة التوثيق: الاهتمام بالتعليقات الشاملة داخل الكود لتسهيل فهم الكود وصيانته القيود النظرية يتطلب تثبيت WinRAR أو 7-Zip مسبقا بعض الميزات (مثل التعليقات) مدعومة فقط في WinRAR مبدئيا الأفكار والأكواد حتى الآن قيد التجربــــــه من أجل ذلك : فى حال وقوع اى مشاكل عند التجارب برجاء إخبارى فورا .. ولكم جزيل الشكر وأخيـــــــــرا الكــــــــــــــود الكود داخل وحده نمطية عامة باسم : basArchiveUtility ' يضمن مقارنة النصوص بناءً على إعدادات قاعدة البيانات (مثل ترتيب الحروف واللغة) Option Compare Database ' يجبر على تعريف المتغيرات صراحة قبل استخدامها، مما يمنع الأخطاء الناتجة عن الأسماء الخاطئة Option Explicit ' تعريف تعداد لمستويات الضغط المدعومة Enum EnumCompressionLevel CompressionNone = 0 ' بدون ضغط (تخزين فقط) CompressionFastest = 1 ' أسرع ضغط (حجم أكبر، سرعة عالية) CompressionFast = 3 ' ضغط سريع (توازن بين السرعة والحجم) CompressionNormal = 5 ' ضغط عادي (الافتراضي في معظم الأدوات) CompressionMaximum = 7 ' ضغط أقصى (حجم أصغر، أبطأ) CompressionUltra = 9 ' ضغط فائق (أقصى تقليص للحجم، أبطأ جدًا) End Enum ' تعريف تعداد لخيارات تقسيم حجم الأرشيف لدعم تقسيم الملفات الكبيرة Enum EnumSplitSizeOption ' بدون تقسيم (أرشيف واحد) SplitNone = 0 ' تقسيم إلى أجزاء بحجم 50 ميجابايت Split50MB = 50 ' تقسيم إلى أجزاء بحجم 100 ميجابايت Split100MB = 100 ' تقسيم إلى أجزاء بحجم 200 ميجابايت Split200MB = 200 ' تقسيم إلى أجزاء بحجم 500 ميجابايت Split500MB = 500 ' تقسيم إلى أجزاء بحجم 1 جيجابايت Split1GB = 1000 ' تقسيم إلى أجزاء بحجم 2 جيجابايت Split2GB = 2000 End Enum ' تعريف تعداد لأوضاع الكتابة فوق الملفات الموجودة مسبقًا Enum EnumOverwriteMode ' عدم الكتابة فوق الملفات (تجاهل العملية إذا وجد الملف) OverwriteNone = 0 ' طلب تأكيد من المستخدم عند وجود ملف OverwritePrompt = 1 ' الكتابة فوق جميع الملفات الموجودة تلقائيًا OverwriteAll = 2 End Enum ' تعريف تعداد لتحديد أداة الأرشفة المستخدمة Enum EnumArchiveMethod ' استخدام WinRAR كأداة ضغط WinRAR = 0 ' استخدام 7-Zip كأداة ضغط SevenZip = 1 End Enum ' تعريف تعداد لأنواع الأرشيف المدعومة Enum EnumArchiveType ' أرشيف بصيغة RAR (شائعة الاستخدام مع WinRAR) ArchiveRAR = 0 ' أرشيف بصيغة ZIP (صيغة قياسية مدعومة على نطاق واسع) ArchiveZIP = 1 ' أرشيف بصيغة 7z (صيغة مفتوحة المصدر توفر ضغطًا عاليًا مع 7-Zip) Archive7z = 2 ' أرشيف بصيغة TAR (يستخدم عادة في أنظمة Unix/Linux لتجميع الملفات بدون ضغط) ArchiveTAR = 3 ' أرشيف بصيغة GZ (Gzip، ضغط فعال لملف واحد) ArchiveGZ = 4 ' أرشيف بصيغة BZIP2 (ضغط قوي مشابه لـ GZ ولكن بكفاءة أعلى في بعض الحالات) ArchiveBZ2 = 5 ' أرشيف بصيغة XZ (صيغة حديثة توفر ضغطًا عاليًا، مدعومة بواسطة 7-Zip وأدوات أخرى) ArchiveXZ = 6 ' أرشيف بصيغة ISO (صورة قرص مضغوطة، يمكن التعامل معها بواسطة أدوات مثل 7-Zip أو WinRAR) ArchiveISO = 7 ' أرشيف بصيغة CAB (صيغة Microsoft Cabinet، تُستخدم في ملفات التثبيت) ArchiveCAB = 8 ' أرشيف بصيغة Z (صيغة ضغط قديمة، لا تزال مدعومة في بعض الأدوات) ArchiveZ = 9 ' أرشيف بصيغة LZH (صيغة ضغط يابانية قديمة، مدعومة بواسطة WinRAR وغيرها) ArchiveLZH = 10 ' أرشيف بصيغة ARJ (صيغة ضغط قديمة، لا تزال مدعومة بواسطة بعض الأدوات مثل WinRAR) ArchiveARJ = 11 End Enum ' متغير عام للتحكم في حالة الحلقات (مثل السماح بإيقاف عملية متكررة) Public IsInLoop As Boolean ' متغير عام لتخزين قائمة بالأرشيفات الناتجة (مثل مسارات الملفات المضغوطة) Public ArchivesList As String ' تعريف متغيرات عامة ثابتة لتخزين مسارات الأدوات المختارة يدويًا ' تحافظ على القيمة طوال جلسة تشغيل قاعدة البيانات Private m_WinRARPath As String ' مسار WinRAR المختار يدويًا Private m_SevenZipPath As String ' مسار 7-Zip المختار يدويًا ' دالة مساعدة لتحويل مستوى الضغط إلى تنسيق WinRAR (مثل -m0 إلى -m5) Function GetWinRARCompressionLevel(compressionLevel As EnumCompressionLevel) As String Select Case compressionLevel Case CompressionNone: GetWinRARCompressionLevel = "-m0" ' بدون ضغط Case CompressionFastest: GetWinRARCompressionLevel = "-m1" ' أسرع ضغط Case CompressionFast: GetWinRARCompressionLevel = "-m2" ' ضغط سريع Case CompressionNormal: GetWinRARCompressionLevel = "-m3" ' ضغط عادي Case CompressionMaximum: GetWinRARCompressionLevel = "-m5" ' ضغط أقصى Case CompressionUltra: GetWinRARCompressionLevel = "-m5" ' ضغط فائق (WinRAR لا يدعم 9) End Select End Function ' دالة مساعدة لتحويل مستوى الضغط إلى تنسيق 7-Zip (مثل mx0 إلى mx9) Function Get7ZipCompressionLevel(compressionLevel As EnumCompressionLevel) As String Select Case compressionLevel Case CompressionNone: Get7ZipCompressionLevel = "-mx0" ' بدون ضغط Case CompressionFastest: Get7ZipCompressionLevel = "-mx1" ' أسرع ضغط Case CompressionFast: Get7ZipCompressionLevel = "-mx3" ' ضغط سريع Case CompressionNormal: Get7ZipCompressionLevel = "-mx5" ' ضغط عادي Case CompressionMaximum: Get7ZipCompressionLevel = "-mx7" ' ضغط أقصى Case CompressionUltra: Get7ZipCompressionLevel = "-mx9" ' ضغط فائق End Select End Function ' دالة مساعدة لتحديد نوع الأرشيف لـ 7-Zip (مثل "zip"، "7z"، إلخ) Function Get7ZipArchiveType(ArchiveType As EnumArchiveType) As String Select Case ArchiveType Case ArchiveRAR: Get7ZipArchiveType = "rar" ' نوع RAR Case ArchiveZIP: Get7ZipArchiveType = "zip" ' نوع ZIP Case Archive7z: Get7ZipArchiveType = "7z" ' نوع 7z Case ArchiveTAR: Get7ZipArchiveType = "tar" ' نوع TAR Case ArchiveGZ: Get7ZipArchiveType = "gzip" ' نوع GZ Case ArchiveBZ2: Get7ZipArchiveType = "bzip2" ' نوع BZIP2 Case ArchiveXZ: Get7ZipArchiveType = "xz" ' نوع XZ Case ArchiveISO: Get7ZipArchiveType = "iso" ' نوع ISO Case ArchiveCAB: Get7ZipArchiveType = "cab" ' نوع CAB Case ArchiveZ: Get7ZipArchiveType = "z" ' نوع Z Case ArchiveLZH: Get7ZipArchiveType = "lzh" ' نوع LZH Case ArchiveARJ: Get7ZipArchiveType = "arj" ' نوع ARJ End Select End Function ' دالة لإرجاع امتداد الملف بناءً على نوع الأرشيف المحدد في EnumArchiveType Function GetArchiveExtension(ArchiveType As EnumArchiveType) As String Select Case ArchiveType Case ArchiveRAR: GetArchiveExtension = ".rar" ' امتداد لأرشيف RAR Case ArchiveZIP: GetArchiveExtension = ".zip" ' امتداد لأرشيف ZIP Case Archive7z: GetArchiveExtension = ".7z" ' امتداد لأرشيف 7z Case ArchiveTAR: GetArchiveExtension = ".tar" ' امتداد لأرشيف TAR Case ArchiveGZ: GetArchiveExtension = ".gz" ' امتداد لأرشيف GZ (Gzip) Case ArchiveBZ2: GetArchiveExtension = ".bz2" ' امتداد لأرشيف BZIP2 Case ArchiveXZ: GetArchiveExtension = ".xz" ' امتداد لأرشيف XZ Case ArchiveISO: GetArchiveExtension = ".iso" ' امتداد لأرشيف ISO Case ArchiveCAB: GetArchiveExtension = ".cab" ' امتداد لأرشيف CAB Case ArchiveZ: GetArchiveExtension = ".z" ' امتداد لأرشيف Z Case ArchiveLZH: GetArchiveExtension = ".lzh" ' امتداد لأرشيف LZH Case ArchiveARJ: GetArchiveExtension = ".arj" ' امتداد لأرشيف ARJ End Select End Function ' دالة لتحويل خيار تقسيم الحجم من تعداد EnumSplitSizeOption إلى سلسلة متوافقة مع أوامر 7-Zip أو WinRAR ' المدخل: خيار التقسيم من نوع EnumSplitSizeOption ' المخرج: سلسلة نصية تمثل حجم التقسيم (مثل "1g" أو "500m") أو سلسلة فارغة إذا لم يكن هناك تقسيم Function GetSplitSizeString(sizeOption As EnumSplitSizeOption) As String Select Case sizeOption Case SplitNone: GetSplitSizeString = "" ' بدون تقسيم Case Split50MB: GetSplitSizeString = "50m" ' 50 ميجابايت Case Split100MB: GetSplitSizeString = "100m" ' 100 ميجابايت Case Split200MB: GetSplitSizeString = "200m" ' 200 ميجابايت Case Split500MB: GetSplitSizeString = "500m" ' 500 ميجابايت Case Split1GB: GetSplitSizeString = "1g" ' 1 جيجابايت Case Split2GB: GetSplitSizeString = "2g" ' 2 جيجابايت End Select End Function ' دالة للتحقق من صحة المسار (عدم وجود أحرف غير قانونية أو تعقيدات غير مرغوبة) ' المدخل: سلسلة تمثل المسار المراد التحقق منه ' المخرج: قيمة منطقية (True إذا كان المسار صالحًا، False إذا كان غير صالح) Function IsValidPath(filePath As String) As Boolean On Error GoTo ErrorHandler ' تعريف الأحرف غير القانونية في مسارات Windows Dim invalidChars As String invalidChars = "\/:*?""<>|" ' متغير للتنقل عبر الأحرف غير القانونية Dim i As Integer ' فحص كل حرف غير قانوني في المسار For i = 1 To Len(invalidChars) ' إذا وُجد حرف غير قانوني، أنهِ الدالة وأرجع False If InStr(filePath, Mid(invalidChars, i, 1)) > 0 Then Exit Function Next i ' التحقق من أن المسار لا يحتوي على ".." (لمنع التنقل غير المرغوب) وأنه غير فارغ IsValidPath = (InStr(filePath, "..\") = 0) And (Len(filePath) > 0) Exit Function ErrorHandler: ' في حالة حدوث خطأ (مثل قيمة غير صالحة لـ filePath)، أرجع False IsValidPath = False End Function ' دالة لتنظيف المدخلات من الأحرف غير المرغوبة التي قد تسبب مشاكل في تنفيذ الأوامر ' المدخل: سلسلة نصية تحتاج إلى تنظيف ' المخرج: سلسلة نصية منقاة من الأحرف المحددة Function SanitizeInput(inputString As String) As String ' إزالة علامات الاقتباس المزدوجة لمنع مشاكل في بناء الأوامر SanitizeInput = Replace(inputString, """", "") ' إزالة رمز "&" لمنع تنفيذ أوامر متتالية غير مقصودة SanitizeInput = Replace(SanitizeInput, "&", "") ' إزالة رمز "|" لمنع توجيه الأوامر بشكل غير متوقع SanitizeInput = Replace(SanitizeInput, "|", "") End Function ' دالة للسماح للمستخدم باختيار مسار أداة الأرشفة يدويًا باستخدام نافذة حوار الملفات ' المدخل: اسم الأداة ("WinRAR" أو "SevenZip") ' المخرج: مسار الملف التنفيذي المختار (مثل "WinRAR.exe" أو "7z.exe")، أو سلسلة فارغة إذا فشل الاختيار Function SelectArchivePathManually(Method As String) As String On Error GoTo ErrorHandler ' التحقق من صحة المدخل للتأكد من أنه إما "WinRAR" أو "SevenZip" If Method <> "WinRAR" And Method <> "SevenZip" Then MsgBox "قيمة غير صالحة: " & Method, vbCritical ' عرض رسالة خطأ إذا كان المدخل غير صالح Exit Function ' الخروج من الدالة إذا لم يكن المدخل صحيحًا End If ' إنشاء كائن نافذة حوار الملفات للسماح للمستخدم باختيار ملف تنفيذي Dim fileDialog As Object Set fileDialog = Application.fileDialog(3) ' نوع 3 يمثل نافذة اختيار الملفات With fileDialog ' تعيين عنوان النافذة بناءً على الأداة المطلوبة لتوجيه المستخدم .Title = IIf(Method = "WinRAR", "اختر WinRAR.exe", "اختر 7z.exe") ' مسح أي فلاتر سابقة لضمان عرض الفلتر الجديد فقط .Filters.Clear ' إضافة فلتر لعرض الملفات التنفيذية (*.exe) فقط لتسهيل الاختيار .Filters.Add "Executable", "*.exe" ' منع اختيار أكثر من ملف واحد لضمان اختيار ملف واحد فقط .AllowMultiSelect = False ' عرض نافذة الحوار والتحقق مما إذا ضغط المستخدم على "موافق" (-1) If .Show = -1 Then ' تخزين المسار المختار من العنصر الأول (والوحيد) في قائمة العناصر المختارة Dim selectedPath As String selectedPath = .SelectedItems(1) ' التحقق من أن الملف المختار يتطابق مع الأداة المطلوبة (WinRAR.exe أو 7z.exe) If (Method = "WinRAR" And InStr(LCase(selectedPath), "winrar.exe") = 0) Or _ (Method = "SevenZip" And InStr(LCase(selectedPath), "7z.exe") = 0) Then MsgBox "الملف غير صحيح!", vbExclamation ' عرض تحذير إذا لم يكن الملف المختار صحيحًا Exit Function ' الخروج إذا كان الملف غير مطابق End If ' إرجاع المسار المختار إذا كان صالحًا SelectArchivePathManually = selectedPath End If End With Exit Function ErrorHandler: ' معالجة أي خطأ يحدث أثناء تنفيذ الدالة (مثل فشل إنشاء نافذة الحوار) MsgBox "خطأ في اختيار المسار: " & Err.Description, vbCritical End Function ' دالة اختيارية لإعادة تعيين المسارات المخزنة (يمكن استدعاؤها عند الحاجة) Public Sub ResetArchivePaths() m_WinRARPath = "" ' إعادة تعيين مسار WinRAR المخزن m_SevenZipPath = "" ' إعادة تعيين مسار 7-Zip المخزن End Sub ' دالة لتحديد مسار أداة الأرشفة تلقائيًا من السجل أو المسارات الافتراضية، مع الرجوع إلى الاختيار اليدوي المخزن إذا لزم الأمر ' المدخل: اسم الأداة ("WinRAR" أو "SevenZip") ' المخرج: مسار الملف التنفيذي للأداة (مثل "WinRAR.exe" أو "7z.exe")، أو سلسلة فارغة إذا فشل التحديد Function DetermineArchivePath(Method As String) As String On Error GoTo ErrorHandler ' التحقق من صحة المدخل للتأكد من أنه إما "WinRAR" أو "SevenZip" If Method <> "WinRAR" And Method <> "SevenZip" Then MsgBox "قيمة غير صالحة: " & Method, vbCritical ' عرض رسالة خطأ إذا كان المدخل غير صالح Exit Function ' الخروج إذا كان المدخل غير صالح End If ' التحقق مما إذا كان المسار مخزنًا مسبقًا في المتغير العام المناسب If Method = "WinRAR" And m_WinRARPath <> "" Then DetermineArchivePath = m_WinRARPath ' إرجاع المسار المخزن لـ WinRAR إذا كان موجودًا Exit Function ElseIf Method = "SevenZip" And m_SevenZipPath <> "" Then DetermineArchivePath = m_SevenZipPath ' إرجاع المسار المخزن لـ 7-Zip إذا كان موجودًا Exit Function End If ' إنشاء كائن للوصول إلى السجل (Registry) لاستخراج المسارات المثبتة Dim reg As Object Dim p As Variant ' متغير للتنقل عبر المسارات الافتراضية Set reg = CreateObject("WScript.Shell") Dim pathFromReg As String ' متغير لتخزين المسار المستخرج من السجل If Method = "WinRAR" Then ' محاولة استخراج مسار WinRAR من السجل باستخدام مفاتيح مختلفة On Error Resume Next ' تعطيل معالجة الأخطاء للتعامل مع مفاتيح غير موجودة pathFromReg = reg.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe\") If Err.Number <> 0 Then pathFromReg = reg.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\WinRAR\exe32") If Err.Number <> 0 Then pathFromReg = reg.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\WinRAR\exe32") On Error GoTo 0 ' إعادة تفعيل معالجة الأخطاء ' التحقق مما إذا تم العثور على مسار صالح في السجل وأن الملف موجود If pathFromReg <> "" And Dir(pathFromReg) <> "" Then m_WinRARPath = pathFromReg ' تخزين المسار في المتغير العام لـ WinRAR DetermineArchivePath = pathFromReg ' إرجاع المسار المستخرج Exit Function End If ' فحص المسارات الافتراضية لـ WinRAR إذا لم يتم العثور على المسار في السجل Dim defaultPaths defaultPaths = Array("C:\Program Files\WinRAR\WinRAR.exe", "C:\Program Files (x86)\WinRAR\WinRAR.exe") For Each p In defaultPaths If Dir(p) <> "" Then m_WinRARPath = p ' تخزين المسار في المتغير العام لـ WinRAR DetermineArchivePath = p ' إرجاع المسار الافتراضي الصالح Exit Function End If Next p ElseIf Method = "SevenZip" Then ' محاولة استخراج مسار 7-Zip من السجل باستخدام مفاتيح مختلفة On Error Resume Next ' تعطيل معالجة الأخطاء للتعامل مع مفاتيح غير موجودة pathFromReg = reg.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\7-Zip\Path") If Err.Number <> 0 Then pathFromReg = reg.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\7-Zip\Path") On Error GoTo 0 ' إعادة تفعيل معالجة الأخطاء ' التحقق من المسار وإضافة "7z.exe" إذا كان المسار صالحًا If pathFromReg <> "" Then If Right(pathFromReg, 1) <> "\" Then pathFromReg = pathFromReg & "\" ' التأكد من وجود "\" في نهاية المسار If Dir(pathFromReg & "7z.exe") <> "" Then m_SevenZipPath = pathFromReg & "7z.exe" ' تخزين المسار في المتغير العام لـ 7-Zip DetermineArchivePath = pathFromReg & "7z.exe" ' إرجاع المسار الكامل Exit Function End If End If ' فحص المسارات الافتراضية لـ 7-Zip إذا لم يتم العثور على المسار في السجل defaultPaths = Array("C:\Program Files\7-Zip\7z.exe", CurrentProject.Path & "\7-Zip64\7z.exe", "C:\Program Files (x86)\7-Zip\7z.exe", CurrentProject.Path & "\7-Zip86\7z.exe") For Each p In defaultPaths If Dir(p) <> "" Then m_SevenZipPath = p ' تخزين المسار في المتغير العام لـ 7-Zip DetermineArchivePath = p ' إرجاع المسار الافتراضي الصالح Exit Function End If Next p End If ' إذا فشلت جميع الطرق التلقائية، استدعاء الاختيار اليدوي وتخزين النتيجة Dim manualPath As String manualPath = SelectArchivePathManually(Method) ' استدعاء الدالة للاختيار اليدوي If manualPath <> "" Then If Method = "WinRAR" Then m_WinRARPath = manualPath ' تخزين المسار اليدوي لـ WinRAR في المتغير العام ElseIf Method = "SevenZip" Then m_SevenZipPath = manualPath ' تخزين المسار اليدوي لـ 7-Zip في المتغير العام End If DetermineArchivePath = manualPath ' إرجاع المسار المختار يدويًا End If Exit Function ErrorHandler: ' معالجة أي خطأ يحدث أثناء تنفيذ الدالة (مثل فشل الوصول إلى السجل) MsgBox "خطأ في تحديد المسار: " & Err.Description, vbCritical End Function ' دالة لإنشاء ملف نصي مؤقت يحتوي على تعليقات (سطر واحد أو عدة أسطر) مع خيار الحذف بعد الاستخدام ' المدخل: ' - commentLines: نص أو مصفوفة من النصوص تمثل التعليقات المراد كتابتها في الملف ' - deleteAfterUse: قيمة منطقية اختيارية (True افتراضيًا) لتحديد ما إذا كان سيتم حذف الملف بعد إنشائه ' المخرج: مسار الملف النصي المؤقت الذي تم إنشاؤه ' دالة لإنشاء ملف تعليقات مؤقت وإرجاع مساره Function CreateCommentFile(commentLines As Variant) As String Dim fso As Object Dim tempFile As String Dim file As Object Dim line As Variant Set fso = CreateObject("Scripting.FileSystemObject") tempFile = CurrentProject.Path & "\temp_comment.txt" Set file = fso.CreateTextFile(tempFile, True, True) If IsArray(commentLines) Then For Each line In commentLines file.WriteLine CStr(line) Next line Else file.WriteLine CStr(commentLines) End If file.Close CreateCommentFile = tempFile ' إرجاع المسار بدون حذف Set file = Nothing Set fso = Nothing End Function ' دالة لبناء أمر ضغط الملفات/المجلدات بناءً على الخيارات المحددة باستخدام WinRAR أو 7-Zip ' المدخلات: ' - sourceFile: ملف أو مصفوفة ملفات/مجلدات للضغط (قد تكون مسارات نسبية أو مطلقة) ' - password: كلمة المرور لتشفير الأرشيف (اختياري) ' - Method: أداة الضغط (WinRAR أو SevenZip) من EnumArchiveMethod ' - archiveType: نوع الأرشيف (RAR، ZIP، 7z، إلخ) من EnumArchiveType ' - compressionLevel: مستوى الضغط من EnumCompressionLevel ' - partSize: حجم التقسيم (إن وجد) من EnumSplitSizeOption ' - targetPath: مسار حفظ الأرشيف (اختياري، يُستخدم المشروع الحالي إذا لم يُحدد) ' - archiveName: اسم الأرشيف (اختياري، يُشتق من الملف الأصلي إذا لم يُحدد) ' - isSFX: تحديد ما إذا كان الأرشيف سيكون تنفيذيًا ذاتيًا (Self-Extracting) ' - commentFile: مسار ملف التعليقات (اختياري) ' - deleteOriginals: حذف الملفات الأصلية بعد الضغط ' المخرج: سلسلة نصية تمثل الأمر الكامل للضغط Function BuildCompressCommand( _ sourceFile As Variant, _ password As String, _ Method As EnumArchiveMethod, _ ArchiveType As EnumArchiveType, _ compressionLevel As EnumCompressionLevel, _ partSize As EnumSplitSizeOption, _ targetPath As String, _ archiveName As String, _ isSFX As Boolean, _ commentFile As String, _ Optional ByVal deleteOriginals As Boolean = True) As String ' تعريف المتغيرات اللازمة لبناء الأمر Dim Command As String ' الأمر النهائي الذي سيتم إرجاعه Dim archiveProgramPath As String ' مسار أداة الضغط (WinRAR.exe أو 7z.exe) Dim fileList As String ' قائمة الملفات/المجلدات للضغط Dim targetFile As String ' المسار الكامل للأرشيف الناتج Dim fso As Object ' كائن FileSystemObject للتعامل مع الملفات Dim file As Variant ' متغير للتنقل عبر الملفات في المصفوفة Dim fullFilePath As String ' المسار الكامل لكل ملف/مجلد ' On Error GoTo ErrorHandler ' إنشاء كائن FileSystemObject للتحقق من الملفات والمسارات Set fso = CreateObject("Scripting.FileSystemObject") '--- معالجة المسارات النسبية --- fileList = "" ' تهيئة قائمة الملفات ' تحويل المدخل إلى مصفوفة إذا لم يكن كذلك لتسهيل المعالجة If Not IsArray(sourceFile) Then sourceFile = Array(sourceFile) ' معالجة كل ملف/مجلد في المصفوفة For Each file In sourceFile ' تحديد المسار الكامل بناءً على كونه نسبيًا أو مطلقًا If InStr(file, ":\") = 0 And InStr(file, "\\") = 0 Then ' مسار نسبي (لا يحتوي على محرك أقراص أو مسار شبكة) If Left(file, 1) = "\" Then ' يبدأ بـ "\" (مثل \folder\file.txt)، يُضاف إلى مسار المشروع مباشرة fullFilePath = CurrentProject.Path & file Else ' مسار نسبي عادي (مثل folder\file.txt)، يُضاف مع فاصل "\" fullFilePath = CurrentProject.Path & "\" & file End If Else ' مسار مطلق (مثل C:\...\file.txt)، يُستخدم كما هو fullFilePath = file End If ' التحقق من وجود الملف أو المجلد في المسار المحدد If Not fso.FileExists(fullFilePath) And Not fso.FolderExists(fullFilePath) Then MsgBox "المسار غير موجود: " & fullFilePath, vbCritical Exit Function ' الخروج إذا لم يكن المسار موجودًا End If ' إضافة المسار المنظف إلى قائمة الملفات مع إحاطته بعلامات اقتباس fileList = fileList & " """ & SanitizeInput(fullFilePath) & """" Next file '--- تحديد مسار الأرشيف الناتج --- If targetPath = "" Then ' إذا لم يُحدد مسار الهدف، استخدام مسار المشروع الحالي targetPath = CurrentProject.Path End If '--- بناء اسم الأرشيف --- targetFile = targetPath & "\" & _ IIf(archiveName = "", fso.GetBaseName(sourceFile(LBound(sourceFile))), archiveName) & _ IIf(isSFX, ".exe", _ IIf(ArchiveType = ArchiveRAR, ".rar", _ IIf(ArchiveType = ArchiveZIP, ".zip", ".7z"))) ' الشرح: ' - إذا لم يُحدد اسم الأرشيف، يُشتق من اسم الملف الأول (بدون الامتداد) ' - إذا كان SFX، يُستخدم امتداد ".exe"، وإلا يُحدد الامتداد بناءً على نوع الأرشيف (RAR، ZIP، 7z) '--- التحقق من صحة الأداة --- archiveProgramPath = DetermineArchivePath(IIf(Method = WinRAR, "WinRAR", "SevenZip")) If archiveProgramPath = "" Then Exit Function ' الخروج إذا لم يتم العثور على الأداة '--- بناء الأمر بناءً على الأداة --- If Method = WinRAR Then ' بناء أمر WinRAR Command = """" & archiveProgramPath & """ a -ep1 -m" & compressionLevel ' - "a": إضافة الملفات إلى الأرشيف ' - "-ep1": استبعاد المسار الأساسي من الأسماء داخل الأرشيف ' - "-m": تحديد مستوى الضغط (0-5) Command = Command & IIf(isSFX, " -sfx", "") ' إضافة خيار SFX إذا تم تحديده Command = Command & " """ & targetFile & """" & fileList ' إضافة مسار الأرشيف وقائمة الملفات Command = Command & IIf(password <> "", " -p" & SanitizeInput(password), "") ' إضافة كلمة المرور إذا وُجدت Command = Command & IIf(partSize <> SplitNone, " -v" & GetSplitSizeString(partSize), "") ' إضافة خيار التقسيم إذا تم تحديده Command = Command & IIf(commentFile <> "" And fso.FileExists(commentFile), " -z""" & commentFile & """", "") ' إضافة ملف التعليقات إذا وُجد Command = Command & IIf(deleteOriginals, " -df", "") ' حذف الملفات الأصلية بعد الضغط إذا تم تحديده ElseIf Method = SevenZip Then ' بناء أمر 7-Zip Command = """" & archiveProgramPath & """ a -mx=" & Get7ZipCompressionLevel(compressionLevel) ' - "a": إضافة الملفات إلى الأرشيف ' - "-mx=": تحديد مستوى الضغط (0-9) باستخدام دالة GetSevenZipCompressionLevel Command = Command & IIf(isSFX, " -sfx7z.sfx", "") ' إضافة خيار SFX باستخدام ملف 7z.sfx Command = Command & " """ & targetFile & """" & fileList ' إضافة مسار الأرشيف وقائمة الملفات Command = Command & IIf(password <> "", " -p" & SanitizeInput(password) & " -mhe=on", "") ' إضافة كلمة المرور مع تشفير الأسماء Command = Command & IIf(partSize <> SplitNone, " -v" & GetSplitSizeString(partSize), "") ' إضافة خيار التقسيم إذا تم تحديده Command = Command & IIf(deleteOriginals, " -sdel", "") ' حذف الملفات الأصلية بعد الضغط إذا تم تحديده End If ' إرجاع الأمر النهائي BuildCompressCommand = Command Exit Function ' 'ErrorHandler: ' ' معالجة الأخطاء وعرض رسالة في حالة حدوث مشكلة (مثل مسار غير صالح أو فشل إنشاء الكائن) ' MsgBox "خطأ في بناء الأمر: " & Err.Description, vbCritical End Function ' إجراء لضغط العناصر (ملفات أو مجلدات) باستخدام WinRAR أو 7-Zip بناءً على الخيارات المحددة ' المدخلات (جميعها اختيارية): ' - itemsArray: ملف أو مصفوفة ملفات/مجلدات للضغط ' - password: كلمة المرور لتشفير الأرشيف (افتراضي: فارغ) ' - Method: أداة الضغط (افتراضي: SevenZip) ' - archiveType: نوع الأرشيف (افتراضي: Archive7z) ' - compressionLevel: مستوى الضغط (افتراضي: CompressionNormal) ' - partSize: حجم التقسيم (افتراضي: SplitNone) ' - targetPath: مسار حفظ الأرشيف (افتراضي: فارغ، يُستخدم المشروع الحالي) ' - archiveName: اسم الأرشيف (افتراضي: فارغ، يُشتق من الملف الأصلي) ' - isSFX: تحديد ما إذا كان الأرشيف تنفيذيًا ذاتيًا (افتراضي: False) ' - commentFile: مسار ملف التعليقات (افتراضي: فارغ) ' - deleteOriginals: حذف الملفات الأصلية بعد الضغط (افتراضي: False) ' إجراء لضغط العناصر باستخدام WinRAR أو 7-Zip بناءً على الخيارات المحددة ' إجراء لضغط العناصر باستخدام WinRAR أو 7-Zip بناءً على الخيارات المحددة ' إجراء لضغط العناصر باستخدام WinRAR أو 7-Zip بناءً على الخيارات المحددة Sub CompressItems( _ Optional ByVal itemsArray As Variant, _ Optional ByVal password As String = "", _ Optional ByVal Method As EnumArchiveMethod = SevenZip, _ Optional ByVal ArchiveType As EnumArchiveType = Archive7z, _ Optional ByVal compressionLevel As EnumCompressionLevel = CompressionNormal, _ Optional ByVal partSize As EnumSplitSizeOption = SplitNone, _ Optional ByVal targetPath As String = "", _ Optional ByVal archiveName As String = "", _ Optional ByVal isSFX As Boolean = False, _ Optional ByVal commentFile As String = "", _ Optional ByVal deleteOriginals As Boolean = False) Dim fso As Object Set fso = CreateObject("Scripting.FileSystemObject") On Error GoTo ErrorHandler If VarType(itemsArray) = vbEmpty Then MsgBox "لم يتم تحديد عناصر للضغط!", vbExclamation Exit Sub End If ' تحويل itemsArray إلى مصفوفة إذا كان سلسلة نصية واحدة Dim items As Variant If Not IsArray(itemsArray) Then items = Array(itemsArray) Else items = itemsArray End If ' التحقق من وجود الملفات قبل الضغط Dim i As Long Dim fullPath As String For i = LBound(items) To UBound(items) ' إذا كان المسار نسبيًا، أضف CurrentProject.Path If InStr(items(i), ":\") = 0 And InStr(items(i), "\\") = 0 Then fullPath = CurrentProject.Path & "\" & items(i) Else fullPath = items(i) End If If Not fso.FileExists(fullPath) And Not fso.FolderExists(fullPath) Then MsgBox "الملف أو المجلد غير موجود: " & fullPath, vbExclamation Exit Sub End If ' تحديث المسار في المصفوفة ليكون مطلقًا items(i) = fullPath Next i Dim archiveProgramPath As String archiveProgramPath = DetermineArchivePath(IIf(Method = WinRAR, "WinRAR", "SevenZip")) If archiveProgramPath = "" Then Exit Sub ' بناء المسار الكامل للأرشيف الناتج Dim archiveFullPath As String Dim baseName As String baseName = fso.GetBaseName(items(LBound(items))) ' استخدام أول عنصر بعد التأكد من المسار archiveFullPath = IIf(targetPath = "", CurrentProject.Path, targetPath) & "\" & _ IIf(archiveName = "", baseName, archiveName) & _ IIf(isSFX, ".exe", GetArchiveExtension(ArchiveType)) Dim Command As String If Method = WinRAR Then Command = """" & archiveProgramPath & """ a -ep1 """ & archiveFullPath & """ " & JoinArchivePaths(items) Command = Command & IIf(password <> "", " -p" & SanitizeInput(password), "") Command = Command & " " & GetWinRARCompressionLevel(compressionLevel) Command = Command & IIf(partSize <> SplitNone, " -v" & GetSplitSizeString(partSize), "") Command = Command & IIf(isSFX, " -sfx", "") Command = Command & IIf(commentFile <> "" And fso.FileExists(commentFile), " -z""" & commentFile & """", "") Command = Command & IIf(deleteOriginals, " -df", "") If ArchiveType = ArchiveXZ Or ArchiveType = ArchiveBZ2 Then MsgBox "WinRAR لا يدعم نوع الأرشيف المحدد: " & ArchiveType, vbExclamation Exit Sub End If ElseIf Method = SevenZip Then Command = """" & archiveProgramPath & """ a """ & archiveFullPath & """ " & JoinArchivePaths(items) Command = Command & IIf(password <> "", " -p" & SanitizeInput(password), "") Command = Command & " " & Get7ZipCompressionLevel(compressionLevel) Command = Command & IIf(partSize <> SplitNone, " -v" & GetSplitSizeString(partSize), "") Command = Command & IIf(isSFX, " -sfx", "") Command = Command & IIf(commentFile <> "" And fso.FileExists(commentFile), " -scc""" & commentFile & """", "") Command = Command & IIf(deleteOriginals, " -sdel", "") Command = Command & " -t" & Get7ZipArchiveType(ArchiveType) End If If Command = "" Then Exit Sub ' تنفيذ الأمر باستخدام ExecuteAndWait مع الانتظار حتى اكتمال العملية ' ExecuteAndWait Command, WindowHidden, True ' Command: السلسلة التي تحتوي على الأمر الكامل (مثل: """C:\Program Files\7-Zip\7z.exe"" a ""C:\output.rar"" ""C:\input.txt""") ' WindowHidden: تحديد نمط النافذة لتكون مخفية (0) أثناء التنفيذ لعدم إظهار واجهة البرنامج ' True: تشغيل الأمر بصلاحيات المسؤول (RunAsAdmin) لضمان الوصول إلى الملفات المحمية إذا لزم الأمر ' تنفيذ الأمر باستخدام ExecuteWithTimeout مع التحكم في المهلة الزمنية ExecuteWithTimeout Command, WindowHidden, 0, True ' Command: السلسلة التي تحتوي على الأمر الكامل (مثل: """C:\Program Files\7-Zip\7z.exe"" x ""C:\archive.rar"" -o""C:\destination""") ' WindowHidden: تحديد نمط النافذة لتكون مخفية (0) أثناء التنفيذ للحفاظ على تجربة مستخدم نظيفة ' 0: المهلة الزمنية بالمللي ثانية (0 تعني الانتظار إلى ما لا نهاية حتى اكتمال العملية) ' True: تشغيل الأمر كمسؤول (RunAsAdmin) If Not IsInLoop Then MsgBox "تم الضغط بنجاح إلى: " & archiveFullPath, vbInformation Else ArchivesList = ArchivesList & archiveFullPath & vbCrLf End If On Error Resume Next If commentFile <> "" And fso.FileExists(commentFile) Then fso.DeleteFile commentFile On Error GoTo 0 Set fso = Nothing Exit Sub ErrorHandler: MsgBox "خطأ في الضغط: " & Err.Description, vbCritical LogError "CompressItems Error: " & Err.Description Set fso = Nothing End Sub ' إجراء لفك ضغط الأرشيفات باستخدام WinRAR أو 7-Zip بناءً على الخيارات المحددة ' المدخلات: ' - archivePaths: مسار أو مصفوفة مسارات للأرشيفات المراد فك ضغطها ' - destinationPath: مسار الوجهة لفك الضغط ' - password: كلمة المرور لفك تشفير الأرشيف (اختياري، افتراضي: فارغ) ' - Method: أداة فك الضغط (افتراضي: WinRAR) ' - OverwriteMode: وضع الكتابة فوق الملفات الموجودة (افتراضي: OverwriteAll) ' - deleteArchive: حذف الأرشيف بعد فك الضغط (افتراضي: False) ' إجراء لفك ضغط الأرشيفات باستخدام WinRAR أو 7-Zip بناءً على الخيارات المحددة ' إجراء لفك ضغط الأرشيفات باستخدام WinRAR أو 7-Zip بناءً على الخيارات المحددة ' إجراء لفك ضغط الأرشيفات باستخدام WinRAR أو 7-Zip بناءً على الخيارات المحددة Sub ExtractItems( _ archivePaths As Variant, _ destinationPath As String, _ Optional ByVal password As String = "", _ Optional ByVal Method As EnumArchiveMethod = WinRAR, _ Optional ByVal OverwriteMode As EnumOverwriteMode = OverwriteAll, _ Optional ByVal deleteArchive As Boolean = False) Dim fso As Object Set fso = CreateObject("Scripting.FileSystemObject") On Error GoTo ErrorHandler If VarType(archivePaths) = vbEmpty Then MsgBox "لم يتم تحديد أرشيفات!", vbExclamation Exit Sub End If ' تحويل archivePaths إلى مصفوفة إذا كان سلسلة نصية واحدة Dim archives As Variant If Not IsArray(archivePaths) Then archives = Array(archivePaths) Else archives = archivePaths End If ' التحقق من وجود الأرشيفات قبل فك الضغط Dim i As Long Dim fullPath As String For i = LBound(archives) To UBound(archives) ' إذا كان المسار نسبيًا، أضف CurrentProject.Path If InStr(archives(i), ":\") = 0 And InStr(archives(i), "\\") = 0 Then fullPath = CurrentProject.Path & "\" & archives(i) Else fullPath = archives(i) End If If Not fso.FileExists(fullPath) Then MsgBox "الأرشيف غير موجود: " & fullPath, vbExclamation Exit Sub End If ' تحديث المسار في المصفوفة ليكون مطلقًا archives(i) = fullPath Next i ' التحقق من وجود مسار الوجهة وإنشاؤه إذا لم يكن موجودًا If Not fso.FolderExists(destinationPath) Then fso.CreateFolder destinationPath End If Dim archiveProgramPath As String archiveProgramPath = DetermineArchivePath(IIf(Method = WinRAR, "WinRAR", "SevenZip")) If archiveProgramPath = "" Then Exit Sub Dim Command As String If Method = WinRAR Then Command = """" & archiveProgramPath & """ x " & JoinArchivePaths(archives) & " """ & destinationPath & """" Command = Command & IIf(password <> "", " -p" & SanitizeInput(password), "") Command = Command & IIf(OverwriteMode = OverwriteAll, " -o+", IIf(OverwriteMode = OverwritePrompt, "", " -o-")) Command = Command & IIf(deleteArchive, " -df", "") ElseIf Method = SevenZip Then Command = """" & archiveProgramPath & """ x " & JoinArchivePaths(archives) & " -o""" & destinationPath & """" Command = Command & IIf(password <> "", " -p" & SanitizeInput(password), "") Command = Command & IIf(OverwriteMode = OverwriteAll, " -aoa", IIf(OverwriteMode = OverwritePrompt, "", " -aos")) Command = Command & IIf(deleteArchive, " -sdel", "") End If ' تنفيذ الأمر باستخدام ExecuteAndWait مع الانتظار حتى اكتمال العملية ' ExecuteAndWait Command, WindowHidden, True ' Command: السلسلة التي تحتوي على الأمر الكامل (مثل: """C:\Program Files\7-Zip\7z.exe"" a ""C:\output.rar"" ""C:\input.txt""") ' WindowHidden: تحديد نمط النافذة لتكون مخفية (0) أثناء التنفيذ لعدم إظهار واجهة البرنامج ' True: تشغيل الأمر بصلاحيات المسؤول (RunAsAdmin) لضمان الوصول إلى الملفات المحمية إذا لزم الأمر ' تنفيذ الأمر باستخدام ExecuteWithTimeout مع التحكم في المهلة الزمنية ExecuteWithTimeout Command, WindowHidden, 0, True ' Command: السلسلة التي تحتوي على الأمر الكامل (مثل: """C:\Program Files\7-Zip\7z.exe"" x ""C:\archive.rar"" -o""C:\destination""") ' WindowHidden: تحديد نمط النافذة لتكون مخفية (0) أثناء التنفيذ للحفاظ على تجربة مستخدم نظيفة ' 0: المهلة الزمنية بالمللي ثانية (0 تعني الانتظار إلى ما لا نهاية حتى اكتمال العملية) ' True: تشغيل الأمر كمسؤول (RunAsAdmin) If Not IsInLoop Then MsgBox "تم فك الضغط بنجاح إلى: " & destinationPath, vbInformation Else ArchivesList = ArchivesList & destinationPath & vbCrLf End If Set fso = Nothing Exit Sub ErrorHandler: MsgBox "خطأ في فك الضغط: " & Err.Description, vbCritical LogError "ExtractItems Error: " & Err.Description Set fso = Nothing End Sub ' دالة لدمج مسارات الأرشيفات في سلسلة واحدة مع إحاطة كل مسار بعلامات اقتباس ' المدخل: ' - archivePaths: مسار واحد أو مصفوفة من مسارات الأرشيفات ' المخرج: سلسلة نصية تحتوي على المسارات مفصولة بمسافات ومحاطة بعلامات اقتباس (مثل: "path1" "path2") Function JoinArchivePaths(archivePaths As Variant) As String ' تعريف متغير لتخزين النتيجة النهائية Dim Result As String ' متغير للتنقل عبر عناصر المصفوفة Dim p As Variant ' تحويل المدخل إلى مصفوفة إذا لم يكن كذلك لتسهيل المعالجة If Not IsArray(archivePaths) Then archivePaths = Array(archivePaths) ' تكرار على كل مسار في المصفوفة For Each p In archivePaths ' إضافة المسار المنظف إلى النتيجة مع إحاطته بعلامات اقتباس وفاصل مسافة Result = Result & " """ & SanitizeInput(CStr(p)) & """" ' - SanitizeInput: تنظيف المسار من الأحرف غير المرغوبة ' - CStr: تحويل المسار إلى سلسلة نصية Next p ' إرجاع السلسلة الناتجة (بدون مسافة إضافية في البداية) JoinArchivePaths = Result End Function ' إجراء لتسجيل الأخطاء في ملف نصي بمسار المشروع الحالي ' المدخل: ' - errorMessage: رسالة الخطأ المراد تسجيلها Sub LogError(errorMessage As String) ' تعريف مسار ملف السجل (ErrorLog.txt في مسار المشروع الحالي) Dim logFile As String logFile = CurrentProject.Path & "\ErrorLog.txt" ' فتح الملف في وضع الإضافة (Append) برقم قناة #1 Open logFile For Append As #1 ' كتابة التاريخ/الوقت الحالي ورسالة الخطأ في الملف مع فاصل سطر Print #1, Now & " - " & errorMessage ' إغلاق الملف لضمان حفظ التغييرات Close #1 End Sub ' إجراء لعرض نافذة تعليمات بسيطة تحتوي على إرشادات حول استخدام الكود Sub ShowHelp() ' عرض رسالة تحتوي على تعليمات أساسية حول الإجراءات والتعدادات MsgBox "التعليمات:" & vbCrLf & _ "1. CompressItems: لضغط الملفات" & vbCrLf & _ "2. ExtractItems: لفك الضغط" & vbCrLf & _ "3. استخدام التعدادات لتحديد الخيارات" & vbCrLf & _ "راجع التعليقات في الكود للمزيد من التفاصيل", vbInformation ' - vbCrLf: فاصل سطر لتنسيق النص ' - vbInformation: رمز أيقونة المعلومات في نافذة الرسالة End Sub '################################################## '# دوال مساعدة للحلقات (الضغط وفك الضغط) '################################################## ' إجراء لبدء حلقة ضغط متعددة وتهيئة المتغيرات العامة Sub StartCompressionLoop() ' تعيين المتغير العام IsInLoop إلى True للإشارة إلى أن العملية تعمل داخل حلقة IsInLoop = True ' تفعيل وضع الحلقة ' تهيئة المتغير العام ArchivesList كسلسلة فارغة لتخزين قائمة الأرشيفات الناتجة ArchivesList = "" ' تهيئة قائمة الأرشيفات End Sub ' إجراء لعرض رسالة نجاح موحدة بعد انتهاء حلقة الضغط Sub ShowCompressionSuccess() ' التحقق مما إذا كان الإجراء في وضع حلقة وما إذا كانت قائمة الأرشيفات تحتوي على بيانات If IsInLoop And ArchivesList <> "" Then ' عرض رسالة نجاح تحتوي على قائمة الأرشيفات المضغوطة MsgBox "تم الضغط بنجاح للملفات التالية:" & vbCrLf & ArchivesList, vbInformation, "نجاح" ' - vbCrLf: فاصل سطر لتنسيق القائمة ' - vbInformation: رمز أيقونة المعلومات ' - "نجاح": عنوان النافذة End If ' تعطيل وضع الحلقة بعد الانتهاء IsInLoop = False ' إنهاء وضع الحلقة ' إعادة تهيئة قائمة الأرشيفات كسلسلة فارغة للاستخدام المستقبلي ArchivesList = "" ' إعادة تهيئة القائمة End Sub ' إجراء لبدء حلقة فك ضغط متعددة وتهيئة المتغيرات العامة Sub StartExtractionLoop() ' تعيين المتغير العام IsInLoop إلى True للإشارة إلى أن العملية تعمل داخل حلقة IsInLoop = True ' تفعيل وضع الحلقة ' تهيئة المتغير العام ArchivesList كسلسلة فارغة لتخزين قائمة مسارات الوجهة ArchivesList = "" ' تهيئة قائمة الأرشيفات End Sub ' إجراء لعرض رسالة نجاح موحدة بعد انتهاء حلقة فك الضغط Sub ShowExtractionSuccess() ' التحقق مما إذا كان الإجراء في وضع حلقة وما إذا كانت قائمة الأرشيفات تحتوي على بيانات If IsInLoop And ArchivesList <> "" Then ' عرض رسالة نجاح تحتوي على قائمة مسارات الوجهة التي تم فك الضغط إليها MsgBox "تم فك الضغط بنجاح للملفات التالية:" & vbCrLf & ArchivesList, vbInformation, "نجاح" ' - vbCrLf: فاصل سطر لتنسيق القائمة ' - vbInformation: رمز أيقونة المعلومات ' - "نجاح": عنوان النافذة End If ' تعطيل وضع الحلقة بعد الانتهاء IsInLoop = False ' إنهاء وضع الحلقة ' إعادة تهيئة قائمة الأرشيفات كسلسلة فارغة للاستخدام المستقبلي ArchivesList = "" ' إعادة تهيئة القائمة End Sub ' دالة تستخدم لاختبار ' DetermineArchivePath ' التي تحدد مسار ملفي ' ("WinRAR : WinRAR.exe " أو "SevenZip : 7z.exe") ' تلقائيا أو يدوًا ' يمكن حذفها هى فقط كانت لتجربة الكود والتأكد من جلب مسارات التطبيقات Sub TestDetermineArchivePath() ' الغرض: اختبار دالة DetermineArchivePath لتحديد مسارات WinRAR و7-Zip ' المخرجات: ' - طباعة المسارات في نافذة Immediate إذا تم العثور عليها ' - عرض رسالة إذا لم يتم العثور على الأداة On Error GoTo ErrorHandler Dim tools As Variant Dim tool As Variant ' يجب أن يكون Variant لاستخدامه في For Each Dim archivePath As String ' قائمة الأدوات للاختبار tools = Array("WinRAR", "SevenZip") ' اختبار كل أداة For Each tool In tools archivePath = DetermineArchivePath(CStr(tool)) ' تحويل Variant إلى String صراحة If archivePath <> "" Then Debug.Print "تم العثور على " & tool & " في: " & archivePath Else MsgBox "لم يتم العثور على " & tool & ".", vbInformation, "نتيجة الاختبار" End If Next tool Exit Sub ErrorHandler: MsgBox "حدث خطأ أثناء اختبار DetermineArchivePath: " & Err.Description, vbCritical, "خطأ" Exit Sub End Sub الكود مرتبط بـ : ExecuteWith الغرض: تشغيل برنامج والانتظار حتى ينتهي مع السماح بمعالجة الأحداث الأخرى الكود داخل وحده نمطيه عامة باسم : basShellExecutor ' يضمن مقارنة النصوص بناءً على إعدادات قاعدة البيانات (مثل ترتيب الحروف واللغة) Option Compare Database ' يجبر على تعريف المتغيرات صراحة قبل استخدامها، مما يمنع الأخطاء الناتجة عن الأسماء الخاطئة Option Explicit '======================================================================================================================= '------ الثوابت Public Const PROCESS_TIMEOUT_INFINITE As Long = &HFFFFFFFF Public Const PROCESS_STILL_ACTIVE As Long = &H103 Public Const PROCESS_TERMINATED As Long = vbObjectError Or &HDEAD Public Const MAX_PATH_LENGTH As Long = 260 Public Const QS_ALL_INPUT As Long = &H4FF Private Const ERR_NO_COMMAND As Long = vbObjectError Or 1001 Private Const ERR_EXECUTING As Long = vbObjectError Or 1002 Private Const ERR_EXECUTION_FAILED As Long = vbObjectError Or 1003 Private Const ERR_TERMINATION_FAILED As Long = vbObjectError Or 1004 Private Const SHELL_MASK_NOCLOSEPROCESS As Long = &H40 Private Const SHELL_MASK_DOENVSUBST As Long = &H200 Private Const SHELL_MASK_SUPPRESS_ERRORS As Long = &H400 Private Const PROCESS_QUERY_INFO As Long = &H400 Private Const PROCESS_SYNCHRONIZE As Long = &H100000 Private Const PROCESS_TERMINATE As Long = &H1 Private Const ERROR_ACCESS_DENIED As Long = 5 '======================================================================================================================= '------ التعدادات Public Enum ShellWindowStyle WindowHidden = 0 WindowNormal = 1 WindowMinimized = 2 WindowMaximized = 3 WindowNoActivate = 4 End Enum '======================================================================================================================= '------ الأنواع المخصصة #If VBA7 Then Private Type ShellExecuteParams Size As Long Mask As Long ParentWindowHandle As LongPtr Verb As String filePath As String Arguments As String WorkingDirectory As String ShowCommand As Long InstanceHandle As LongPtr ItemListPointer As LongPtr ClassName As String ClassKeyHandle As LongPtr HotKey As Long IconHandle As LongPtr ProcessHandle As LongPtr End Type #Else Private Type ShellExecuteParams Size As Long Mask As Long ParentWindowHandle As Long Verb As String filePath As String Arguments As String WorkingDirectory As String ShowCommand As Long InstanceHandle As Long ItemListPointer As Long ClassName As String ClassKeyHandle As Long HotKey As Long IconHandle As Long ProcessHandle As Long End Type #End If '======================================================================================================================= '------ تعريفات API #If VBA7 Then Private Declare PtrSafe Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As LongPtr ' فتح مقبض العملية Private Declare PtrSafe Function CloseHandle Lib "kernel32.dll" (ByVal hObject As LongPtr) As Long ' إغلاق مقبض العملية Private Declare PtrSafe Function ExpandEnvironmentStringsW Lib "kernel32.dll" (ByVal lpSrc As LongPtr, Optional ByVal lpDst As LongPtr, Optional ByVal nSize As Long) As Long ' توسيع متغيرات البيئة Private Declare PtrSafe Function GetExitCodeProcess Lib "kernel32.dll" (ByVal hProcess As LongPtr, ByRef lpExitCode As Long) As Long ' جلب رمز الخروج للعملية Private Declare PtrSafe Function MsgWaitForMultipleObjects Lib "user32.dll" (ByVal nCount As Long, ByRef pHandles As LongPtr, ByVal bWaitAll As Long, ByVal dwMilliseconds As Long, ByVal dwWakeMask As Long) As Long ' انتظار العمليات مع معالجة الأحداث Private Declare PtrSafe Function SysReAllocStringLen Lib "oleaut32.dll" (ByVal pBSTR As LongPtr, Optional ByVal pszStrPtr As LongPtr, Optional ByVal Length As Long) As Long ' إعادة تخصيص حجم السلسلة Private Declare PtrSafe Function CreateWaitableTimerW Lib "kernel32.dll" (Optional ByVal lpTimerAttributes As LongPtr, Optional ByVal bManualReset As Long, Optional ByVal lpTimerName As LongPtr) As LongPtr ' إنشاء مؤقت قابل للانتظار Private Declare PtrSafe Function GetProcessId Lib "kernel32.dll" (ByVal hProcess As LongPtr) As Long ' جلب معرف العملية Private Declare PtrSafe Function PathCanonicalizeW Lib "shlwapi.dll" (ByVal lpszDst As LongPtr, ByVal lpszSrc As LongPtr) As Long ' تبسيط المسار Private Declare PtrSafe Function PathGetArgsW Lib "shlwapi.dll" (ByVal pszPath As LongPtr) As LongPtr ' استخراج المعاملات من المسار Private Declare PtrSafe Function SetWaitableTimer Lib "kernel32.dll" (ByVal hTimer As LongPtr, ByRef pDueTime As Currency, Optional ByVal lPeriod As Long, Optional ByVal pfnCompletionRoutine As LongPtr, Optional ByVal lpArgToCompletionRoutine As LongPtr, Optional ByVal fResume As Long) As Long ' ضبط المؤقت Private Declare PtrSafe Function ShellExecuteExW Lib "shell32.dll" (ByVal pExecInfo As LongPtr) As Long ' تنفيذ أمر عبر Shell Private Declare PtrSafe Function SysReAllocString Lib "oleaut32.dll" (ByVal pBSTR As LongPtr, Optional ByVal pszStrPtr As LongPtr) As Long ' إعادة تخصيص السلسلة Private Declare PtrSafe Sub PathRemoveArgsW Lib "shlwapi.dll" (ByVal pszPath As LongPtr) ' إزالة المعاملات من المسار Private Declare PtrSafe Function TerminateProcess Lib "kernel32.dll" (ByVal hProcess As LongPtr, ByVal uExitCode As Long) As Long ' إنهاء العملية قسريًا Private Declare PtrSafe Function GetTickCount Lib "kernel32.dll" () As Long ' لقياس الوقت المنقضي #Else Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long ' فتح مقبض العملية Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long ' إغلاق مقبض العملية Private Declare Function ExpandEnvironmentStringsW Lib "kernel32.dll" (ByVal lpSrc As Long, Optional ByVal lpDst As Long, Optional ByVal nSize As Long) As Long ' توسيع متغيرات البيئة Private Declare Function GetExitCodeProcess Lib "kernel32.dll" (ByVal hProcess As Long, ByRef lpExitCode As Long) As Long ' جلب رمز الخروج للعملية Private Declare Function MsgWaitForMultipleObjects Lib "user32.dll" (ByVal nCount As Long, ByRef pHandles As Long, ByVal bWaitAll As Long, ByVal dwMilliseconds As Long, ByVal dwWakeMask As Long) As Long ' انتظار العمليات مع معالجة الأحداث Private Declare Function SysReAllocStringLen Lib "oleaut32.dll" (ByVal pBSTR As Long, Optional ByVal pszStrPtr As Long, Optional ByVal Length As Long) As Long ' إعادة تخصيص حجم السلسلة Private Declare Function CreateWaitableTimerW Lib "kernel32.dll" (Optional ByVal lpTimerAttributes As Long, Optional ByVal bManualReset As Long, Optional ByVal lpTimerName As Long) As Long ' إنشاء مؤقت قابل للانتظار Private Declare Function GetProcessId Lib "kernel32.dll" (ByVal hProcess As Long) As Long ' جلب معرف العملية Private Declare Function PathCanonicalizeW Lib "shlwapi.dll" (ByVal lpszDst As Long, ByVal lpszSrc As Long) As Long ' تبسيط المسار Private Declare Function PathGetArgsW Lib "shlwapi.dll" (ByVal pszPath As Long) As Long ' استخراج المعاملات من المسار Private Declare Function SetWaitableTimer Lib "kernel32.dll" (ByVal hTimer As Long, ByRef pDueTime As Currency, Optional ByVal lPeriod As Long, Optional ByVal pfnCompletionRoutine As Long, Optional ByVal lpArgToCompletionRoutine As Long, Optional ByVal fResume As Long) As Long ' ضبط المؤقت Private Declare Function ShellExecuteExW Lib "shell32.dll" (ByVal pExecInfo As Long) As Long ' تنفيذ أمر عبر Shell Private Declare Function SysReAllocString Lib "oleaut32.dll" (ByVal pBSTR As Long, Optional ByVal pszStrPtr As Long) As Long ' إعادة تخصيص السلسلة Private Declare Sub PathRemoveArgsW Lib "shlwapi.dll" (ByVal pszPath As Long) ' إزالة المعاملات من المسار Private Declare Function TerminateProcess Lib "kernel32.dll" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long ' إنهاء العملية قسريًا Private Declare Function GetTickCount Lib "kernel32.dll" () As Long ' لقياس الوقت المنقضي #End If '======================================================================================================================= '------ المتغيرات العامة و الخاصة Public g_TerminateLoops As Boolean ' متغير للتحكم في إنهاء الحلقات يدويًا Private m_IsExecuting As Boolean ' علامة لمنع التداخل أثناء التنفيذ '======================================================================================================================= '------------------------------------------- الدوال العامة ' تشغيل أمر والانتظار حتى ينتهي مع استجابة الواجهة Public Function ExecuteAndWait(ByVal CommandLine As String, _ Optional ByVal WindowStyle As ShellWindowStyle = WindowNormal, _ Optional ByVal RunAsAdmin As Boolean = False, _ Optional ByVal MaxWaitMs As Long = PROCESS_TIMEOUT_INFINITE) As Long #If VBA7 Then Dim ShellParams As ShellExecuteParams Dim ProcessHandle As LongPtr #Else Dim ShellParams As ShellExecuteParams Dim ProcessHandle As Long #End If Dim ExpandedPath As String Dim Executable As String Dim Arguments As String Dim startTime As Long Dim ExitCode As Long Dim Result As Long If m_IsExecuting Then Err.Raise ERR_EXECUTING, "ExecuteAndWait", "عملية أخرى قيد التنفيذ" End If m_IsExecuting = True On Error GoTo Cleanup ' توسيع متغيرات البيئة ExpandedPath = ExpandEnvVars(CommandLine) ' فصل المسار التنفيذي عن المعاملات يدويًا If Left(ExpandedPath, 1) = """" Then Executable = Mid(ExpandedPath, 2, InStr(2, ExpandedPath, """") - 2) Arguments = Trim(Mid(ExpandedPath, InStr(2, ExpandedPath, """") + 2)) Else Dim Parts() As String Parts = Split(ExpandedPath, " ", 2) Executable = Parts(0) If UBound(Parts) > 0 Then Arguments = Parts(1) Else Arguments = "" End If With ShellParams .Size = LenB(ShellParams) .Mask = SHELL_MASK_NOCLOSEPROCESS Or SHELL_MASK_DOENVSUBST Or SHELL_MASK_SUPPRESS_ERRORS .ShowCommand = WindowStyle .filePath = CanonicalizePath(Executable) ' المسار التنفيذي فقط .Arguments = Arguments ' المعاملات كما هي If RunAsAdmin Then .Verb = "runas" If ShellExecuteExW(VarPtr(ShellParams)) = 0 Then Err.Raise ERR_EXECUTION_FAILED, "ExecuteAndWait", "فشل في تنفيذ الأمر: " & CommandLine End If ProcessHandle = .ProcessHandle End With startTime = GetTickCount Do Result = MsgWaitForMultipleObjects(1, ProcessHandle, False, 100, QS_ALL_INPUT) DoEvents If GetExitCodeProcess(ProcessHandle, ExitCode) Then If ExitCode <> PROCESS_STILL_ACTIVE Then Exit Do End If If MaxWaitMs <> PROCESS_TIMEOUT_INFINITE Then If (GetTickCount - startTime) > MaxWaitMs Then Debug.Print "تجاوز الحد الأقصى للانتظار: " & MaxWaitMs & " ميلي ثانية" Exit Do End If End If Loop ExecuteAndWait = ExitCode Cleanup: If ProcessHandle <> 0 Then CloseHandle ProcessHandle m_IsExecuting = False If Err.Number <> 0 Then Err.Raise Err.Number, "ExecuteAndWait", Err.Description End Function ' دالة لتنفيذ أمر مع مهلة زمنية اختيارية وخيار التشغيل كمسؤول Public Function ExecuteWithTimeout(Command As String, Optional ByVal WindowStyle As ShellWindowStyle = WindowNormal, Optional ByVal TimeoutMs As Long, Optional ByVal RunAsAdmin As Boolean = False, Optional RetryCount As Long = 0) As Long #If VBA7 Then Dim ShellParams As ShellExecuteParams Dim ProcessHandle As LongPtr #Else Dim ShellParams As ShellExecuteParams Dim ProcessHandle As Long #End If Dim ExpandedPath As String Dim Executable As String Dim Arguments As String Dim startTime As Long Dim ExitCode As Long Dim Result As Long Dim RetryIndex As Long If m_IsExecuting Then Err.Raise ERR_EXECUTING, "ExecuteWithTimeout", "عملية أخرى قيد التنفيذ" End If m_IsExecuting = True On Error GoTo Cleanup ExpandedPath = ExpandEnvVars(Command) ' فصل المسار التنفيذي عن المعاملات يدويًا If Left(ExpandedPath, 1) = """" Then Executable = Mid(ExpandedPath, 2, InStr(2, ExpandedPath, """") - 2) Arguments = Trim(Mid(ExpandedPath, InStr(2, ExpandedPath, """") + 2)) Else Dim Parts() As String Parts = Split(ExpandedPath, " ", 2) Executable = Parts(0) If UBound(Parts) > 0 Then Arguments = Parts(1) Else Arguments = "" End If For RetryIndex = 0 To RetryCount With ShellParams .Size = LenB(ShellParams) .Mask = SHELL_MASK_NOCLOSEPROCESS Or SHELL_MASK_DOENVSUBST Or SHELL_MASK_SUPPRESS_ERRORS .ShowCommand = WindowStyle .filePath = CanonicalizePath(Executable) ' المسار التنفيذي فقط .Arguments = Arguments ' المعاملات كما هي If RunAsAdmin Then .Verb = "runas" If ShellExecuteExW(VarPtr(ShellParams)) = 0 Then If RetryIndex = RetryCount Then Err.Raise ERR_EXECUTION_FAILED, "ExecuteWithTimeout", "فشل في تنفيذ الأمر بعد " & RetryCount + 1 & " محاولات: " & Command End If Else ProcessHandle = .ProcessHandle Exit For End If End With Next RetryIndex startTime = GetTickCount Do Result = MsgWaitForMultipleObjects(1, ProcessHandle, False, 100, QS_ALL_INPUT) DoEvents If GetExitCodeProcess(ProcessHandle, ExitCode) Then If ExitCode <> PROCESS_STILL_ACTIVE Then Exit Do End If If TimeoutMs > 0 Then If (GetTickCount - startTime) > TimeoutMs Then If TerminateProcess(ProcessHandle, PROCESS_TERMINATED) = 0 Then Debug.Print "فشل في إنهاء العملية بعد تجاوز المهلة" End If ExitCode = PROCESS_TERMINATED Exit Do End If End If If g_TerminateLoops Then Exit Do Loop ExecuteWithTimeout = ExitCode Cleanup: If ProcessHandle <> 0 Then CloseHandle ProcessHandle m_IsExecuting = False If Err.Number <> 0 Then Err.Raise Err.Number, "ExecuteWithTimeout", Err.Description End Function ' دالة لتشغيل أمر باستخدام WScript.Shell مع خيار الانتظار Public Function ExecuteWScript(ByVal CommandLine As String, Optional ByVal WindowStyle As ShellWindowStyle = WindowNormal, Optional ByVal WaitForCompletion As Boolean = False) As Long Dim WScriptShell As Object On Error GoTo ErrorHandler Set WScriptShell = CreateObject("WScript.Shell") ExecuteWScript = WScriptShell.Run(CommandLine, WindowStyle, WaitForCompletion) Exit Function ErrorHandler: Debug.Print "خطأ في تشغيل الأمر عبر WScript: " & Err.Description Err.Raise Err.Number, "ExecuteWScript", "خطأ في تشغيل الأمر عبر WScript: " & Err.Description End Function ' دالة محسنة لتشغيل أمر باستخدام WScript.Shell والتقاط الناتج Public Function ExecuteWScriptCapture(ByVal CommandLine As String, Optional ByVal WindowStyle As ShellWindowStyle = WindowNormal) As String Dim WScriptShell As Object Dim ShellExec As Object Dim Output As String On Error GoTo ErrorHandler Set WScriptShell = CreateObject("WScript.Shell") Set ShellExec = WScriptShell.Exec(CommandLine) Do While ShellExec.Status = 0 DoEvents Loop Output = ShellExec.StdOut.ReadAll ExecuteWScriptCapture = Output Exit Function ErrorHandler: Debug.Print "خطأ في تشغيل الأمر عبر WScript: " & Err.Description ExecuteWScriptCapture = "" Err.Raise Err.Number, "ExecuteWScriptCapture", "خطأ في تشغيل الأمر عبر WScript: " & Err.Description End Function '======================================================================================================================= '------ الدوال المساعدة ' دالة لتوسيع متغيرات البيئة في سلسلة (مثل %windir%) Private Function ExpandEnvVars(ByVal Path As String) As String Dim Buffer As String Dim Length As Long If InStr(Path, "%") Then Length = ExpandEnvironmentStringsW(StrPtr(Path), 0, 0) If Length > 0 Then Buffer = String$(Length - 1, vbNullChar) If ExpandEnvironmentStringsW(StrPtr(Path), StrPtr(Buffer), Length) Then ExpandEnvVars = Left$(Buffer, Length - 1) Else Debug.Print "فشل توسيع متغيرات البيئة، يتم إرجاع المسار الأصلي: " & Path ExpandEnvVars = Path End If Else ExpandEnvVars = Path End If Else ExpandEnvVars = Path End If End Function ' دالة لتبسيط المسار (مثل حل النقاط . و ..) Private Function CanonicalizePath(ByVal Path As String) As String Dim TempPath As String If InStr(Path, "\.") Or InStr(Path, ".\") Then If Len(Path) < MAX_PATH_LENGTH Then TempPath = String$(MAX_PATH_LENGTH - 1, vbNullChar) If PathCanonicalizeW(StrPtr(TempPath), StrPtr(Path)) Then CanonicalizePath = Left$(TempPath, InStr(TempPath, vbNullChar) - 1) Else Debug.Print "فشل تبسيط المسار، يتم إرجاع المسار الأصلي: " & Path CanonicalizePath = Path End If Else CanonicalizePath = Path End If Else CanonicalizePath = Path End If End Function ' دالة لاستخراج المعاملات من المسار Private Function ExtractArguments(ByRef Path As String) As String SysReAllocString VarPtr(ExtractArguments), PathGetArgsW(StrPtr(Path)) If LenB(ExtractArguments) Then PathRemoveArgsW StrPtr(Path) If InStr(ExtractArguments, """") Then ExtractArguments = Replace(ExtractArguments, """", """""") End If End Function ' دالة مساعدة لاستخراج اسم العملية من الأمر Private Function ExtractProcessName(ByVal CommandLine As String) As String Dim Parts() As String Dim FirstPart As String If Left(CommandLine, 1) = """" Then FirstPart = Mid(CommandLine, 2, InStr(2, CommandLine, """") - 2) Else Parts = Split(CommandLine, " ") FirstPart = Parts(0) End If ExtractProcessName = Mid(FirstPart, InStrRev(FirstPart, "\") + 1) End Function ' دالة لإنهاء عملية باستخدام WMI بناءً على اسم العملية Public Function KillProcess(sProcessName As String, Optional sHost As String = ".") As Boolean On Error GoTo Error_Handler Dim oWMI As Object Dim sWMIQuery As String Dim oCols As Object Dim oCol As Object Set oWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & sHost & "\root\cimv2") sWMIQuery = "SELECT Name FROM Win32_Process" Set oCols = oWMI.ExecQuery(sWMIQuery) For Each oCol In oCols If LCase(sProcessName) = LCase(oCol.Name) Then oCol.Terminate End If Next oCol KillProcess = True Error_Handler_Exit: On Error Resume Next Set oCol = Nothing Set oCols = Nothing Set oWMI = Nothing Exit Function Error_Handler: Debug.Print "خطأ في KillProcess: " & Err.Description & " - رقم الخطأ: " & Err.Number KillProcess = False Resume Error_Handler_Exit End Function اوامر الاستدعاء المختلفة : سوف نقوم بعمل وحده نمطيه عامه لتجربة : WinRAR اسم الوحده النمطيه : basArchiveExamplesWinRAR ' يضمن مقارنة النصوص بناءً على إعدادات قاعدة البيانات (مثل ترتيب الحروف واللغة) Option Compare Database ' يجبر على تعريف المتغيرات صراحة قبل استخدامها، مما يمنع الأخطاء الناتجة عن الأسماء الخاطئة Option Explicit ' وحدة نمطية تحتوي على أمثلة شاملة لضغط وفك ضغط باستخدام WinRAR مع كل الخيارات ' =========================================================================== ' 1. ضغط ملف واحد ' =========================================================================== ' بدون كلمة مرور، مستوى ضغط عادي Sub CompressSingleFileNoPasswordWinRAR() CompressItems "file1.txt", , WinRAR, ArchiveZIP, CompressionNormal ' الناتج: file1.rar في CurrentProject.Path End Sub ' مع كلمة مرور، مستوى ضغط أقصى Sub CompressSingleFileWithPasswordMaxCompressionWinRAR() Dim password As String ' تعيين كلمة المرور password = "officena" CompressItems "file1.txt", password, WinRAR, ArchiveZIP, CompressionMaximum ' الناتج: file1.rar (مشفر، مضغوط بأقصى مستوى) في CurrentProject.Path End Sub ' مع تقسيم الأرشيف (Split500MB) Sub CompressSingleFileWithSplitWinRAR() Dim password As String ' تعيين كلمة المرور password = "officena" CompressItems "file1.txt", password, WinRAR, ArchiveRAR, CompressionNormal, Split500MB ' الناتج: file1.rar مقسم إلى أجزاء بحجم 500 ميجابايت End Sub ' ذاتي الاستخراج (SFX) مع تعليق ' ضغط مجلد واحد مع تعليق باستخدام متغير لكلمة المرور Sub CompressSingleFileSFXWithCommentWinRAR() Dim commentLines As Variant Dim commentFile As String Dim password As String ' تعيين كلمة المرور password = "officena" ' إعداد التعليق باستخدام المتغير commentLines = Array( _ "منتديات أوفيسنا", _ "www.officena.net", _ "وقت وتاريخ إنشاء الأرشيف:", _ Format(Now, "dd-mm-yyyy hh:nn AM/PM"), _ "كلمة المرور لفك الضغط: " & password, _ "مع أطيب الأماني: أبو جودى") commentFile = CreateCommentFile(commentLines) ' استخدام كلمة المرور في الضغط CompressItems "Folder1", password, WinRAR, ArchiveRAR, CompressionNormal, , , , True, commentFile ' الناتج: Folder1.rar (مشفر بكلمة المرور "MS-Access(officena)"، مع تعليق) في CurrentProject.Path End Sub ' =========================================================================== ' 2. فك ضغط ملف واحد ' =========================================================================== ' بدون كلمة مرور، الكتابة فوق الملفات Sub ExtractSingleFileNoPasswordOverwriteWinRAR() ExtractItems CurrentProject.Path & "\file1.zip", CurrentProject.Path & "\Extracted", , WinRAR, OverwriteAll ' الناتج: محتويات file1.rar مفكوكة في CurrentProject.Path\Extracted مع الكتابة فوق الملفات End Sub ' مع كلمة مرور، تجاهل الملفات الموجودة Sub ExtractSingleFileWithPasswordNoOverwriteWinRAR() Dim password As String ' تعيين كلمة المرور password = "officena" ExtractItems CurrentProject.Path & "\file1.zip", CurrentProject.Path & "\Extracted", password, WinRAR, OverwriteNone ' الناتج: محتويات file1.rar مفكوكة في CurrentProject.Path\Extracted مع تجاهل الملفات الموجودة End Sub ' =========================================================================== ' 3. ضغط عدة ملفات (كل ملف على حدة) ' =========================================================================== ' بدون كلمة مرور، نوع ZIP Sub CompressMultipleFilesSeparateNoPasswordZipWinRAR() Dim filesArray As Variant filesArray = Array(CurrentProject.Path & "\file1.txt", CurrentProject.Path & "\file2.docx", CurrentProject.Path & "\file3.pdf") StartCompressionLoop Dim filePath As Variant For Each filePath In filesArray CompressItems CStr(filePath), , WinRAR, ArchiveZIP, CompressionNormal Next filePath ShowCompressionSuccess ' الناتج: file1.zip, file2.zip, file3.zip في CurrentProject.Path End Sub ' مع كلمة مرور وتعليق Sub CompressMultipleFilesSeparateWithCommentWinRAR() Dim commentLines As Variant Dim commentFile As String Dim password As String ' تعيين كلمة المرور password = "officena" ' إعداد التعليق باستخدام المتغير commentLines = Array( _ "منتديات أوفيسنا", _ "www.officena.net", _ "وقت وتاريخ إنشاء الأرشيف:", _ Format(Now, "dd-mm-yyyy hh:nn AM/PM"), _ "كلمة المرور لفك الضغط: " & password, _ "مع أطيب الأماني: أبو جودى") commentFile = CreateCommentFile(commentLines) Dim filesArray As Variant filesArray = Array("file1.txt", "file2.docx", "file3.pdf", "Folder1", "Folder2") StartCompressionLoop Dim filePath As Variant For Each filePath In filesArray CompressItems CStr(filePath), password, WinRAR, ArchiveRAR, CompressionNormal, , , , , commentFile Next filePath ShowCompressionSuccess ' الناتج: file1.rar, file2.rar, file3.rar (مشفرة، مع تعليق) في CurrentProject.Path End Sub ' =========================================================================== ' 4. فك ضغط عدة ملفات (كل ملف على حدة) ' =========================================================================== ' بدون كلمة مرور Sub ExtractMultipleFilesSeparateNoPasswordWinRAR() Dim filesArray As Variant filesArray = Array(CurrentProject.Path & "\file1.rar", CurrentProject.Path & "\file2.rar", CurrentProject.Path & "\file3.rar") StartExtractionLoop Dim filePath As Variant For Each filePath In filesArray ExtractItems CStr(filePath), CurrentProject.Path, , WinRAR, OverwriteAll Next filePath ShowExtractionSuccess ' الناتج: محتويات كل ملف مفكوكة في CurrentProject.Path End Sub ' مع كلمة مرور Sub ExtractMultipleFilesSeparateWithPasswordWinRAR() Dim password As String ' تعيين كلمة المرور password = "officena" Dim filesArray As Variant filesArray = Array(CurrentProject.Path & "\file1.rar", CurrentProject.Path & "\file2.rar", CurrentProject.Path & "\file3.rar") StartExtractionLoop Dim filePath As Variant For Each filePath In filesArray ExtractItems CStr(filePath), CurrentProject.Path, password, WinRAR, OverwriteNone Next filePath ShowExtractionSuccess ' الناتج: محتويات كل ملف مفكوكة في CurrentProject.Path مع تجاهل الموجود End Sub ' =========================================================================== ' 5. ضغط عدة ملفات في أرشيف واحد ' =========================================================================== ' بدون كلمة مرور، تقسيم 100MB Sub CompressMultipleFilesOneArchiveWithSplitWinRAR() Dim files As Variant files = Array("file1.txt", "file2.docx", "file3.pdf") CompressItems files, , WinRAR, ArchiveRAR, CompressionNormal, Split100MB, , "CompressedFiles" ' الناتج: CompressedFiles.rar مقسم إلى أجزاء بحجم 100 ميجابايت End Sub ' مع كلمة مرور وتعليق Sub CompressMultipleFilesOneArchiveWithCommentWinRAR() Dim commentLines As Variant Dim commentFile As String Dim password As String ' تعيين كلمة المرور password = "officena" ' إعداد التعليق باستخدام المتغير commentLines = Array( _ "منتديات أوفيسنا", _ "www.officena.net", _ "وقت وتاريخ إنشاء الأرشيف:", _ Format(Now, "dd-mm-yyyy hh:nn AM/PM"), _ "كلمة المرور لفك الضغط: " & password, _ "مع أطيب الأماني: أبو جودى") commentFile = CreateCommentFile(commentLines) Dim files As Variant files = Array("file1.txt", "file2.docx", "file3.pdf") CompressItems files, password, WinRAR, ArchiveRAR, CompressionMaximum, , , "CompressedFiles", , commentFile ' الناتج: CompressedFiles.rar (مشفر، مع تعليق) في CurrentProject.Path End Sub ' =========================================================================== ' 6. فك ضغط أرشيف واحد يحتوي على عدة ملفات ' =========================================================================== ' بدون كلمة مرور Sub ExtractMultipleFilesOneArchiveNoPasswordWinRAR() Dim archives As Variant archives = Array(CurrentProject.Path & "\CompressedFiles.rar") ExtractItems archives, CurrentProject.Path, , WinRAR, OverwriteAll ' الناتج: محتويات CompressedFiles.rar مفكوكة في CurrentProject.Path End Sub ' مع كلمة مرور Sub ExtractMultipleFilesOneArchiveWithPasswordWinRAR() Dim password As String ' تعيين كلمة المرور password = "officena" Dim archives As Variant archives = Array(CurrentProject.Path & "\CompressedFiles.rar") ExtractItems archives, CurrentProject.Path, password, WinRAR, OverwriteNone ' الناتج: محتويات CompressedFiles.rar مفكوكة في CurrentProject.Path مع تجاهل الموجود End Sub ' =========================================================================== ' 7. ضغط مجلد واحد ' =========================================================================== ' مع تعليق Sub CompressSingleFolderWithCommentWinRAR() Dim commentLines As Variant Dim password As String ' تعيين كلمة المرور password = "officena" ' إعداد التعليق باستخدام المتغير commentLines = Array( _ "منتديات أوفيسنا", _ "www.officena.net", _ "وقت وتاريخ إنشاء الأرشيف:", _ Format(Now, "dd-mm-yyyy hh:nn AM/PM"), _ "كلمة المرور لفك الضغط: " & password, _ "مع أطيب الأماني: أبو جودى") Dim commentFile As String commentFile = CreateCommentFile(commentLines) CompressItems CurrentProject.Path & "\Folder1", password, WinRAR, ArchiveRAR, CompressionNormal, , , , , commentFile ' الناتج: Folder1.rar (مشفر، مع تعليق) في CurrentProject.Path End Sub ' مع تقسيم وSFX Sub CompressSingleFolderWithSplitSFXWinRAR() Dim password As String ' تعيين كلمة المرور password = "officena" CompressItems CurrentProject.Path & "\Folder1", password, WinRAR, ArchiveRAR, CompressionNormal, Split1GB, , "Folder1SFX", True ' الناتج: Folder1SFX.exe مقسم إلى أجزاء بحجم 1 جيجابايت End Sub ' =========================================================================== ' 8. ضغط عدة مجلدات (كل مجلد على حدة) ' =========================================================================== ' بدون كلمة مرور Sub CompressMultipleFoldersNoPasswordWinRAR() Dim foldersArray As Variant foldersArray = Array(CurrentProject.Path & "\Folder1", CurrentProject.Path & "\Folder2") StartCompressionLoop Dim folderPath As Variant For Each folderPath In foldersArray CompressItems CStr(folderPath), , WinRAR, ArchiveRAR, CompressionNormal Next folderPath ShowCompressionSuccess ' الناتج: Folder1.rar, Folder2.rar في CurrentProject.Path End Sub ' مع كلمة مرور وتعليق Sub CompressMultipleFoldersWithCommentWinRAR() Dim commentLines As Variant Dim password As String ' تعيين كلمة المرور password = "officena" ' إعداد التعليق باستخدام المتغير commentLines = Array( _ "منتديات أوفيسنا", _ "www.officena.net", _ "وقت وتاريخ إنشاء الأرشيف:", _ Format(Now, "dd-mm-yyyy hh:nn AM/PM"), _ "كلمة المرور لفك الضغط: " & password, _ "مع أطيب الأماني: أبو جودى") Dim commentFile As String commentFile = CreateCommentFile(commentLines) Dim foldersArray As Variant foldersArray = Array(CurrentProject.Path & "\Folder1", CurrentProject.Path & "\Folder2") StartCompressionLoop Dim folderPath As Variant For Each folderPath In foldersArray CompressItems CStr(folderPath), password, WinRAR, ArchiveRAR, CompressionNormal, , , , , commentFile Next folderPath ShowCompressionSuccess ' الناتج: Folder1.rar, Folder2.rar (مشفرة، مع تعليق) في CurrentProject.Path End Sub ' =========================================================================== ' 9. فك ضغط مجلد واحد ' =========================================================================== ' بدون كلمة مرور Sub ExtractSingleFolderNoPasswordWinRAR() ExtractItems CurrentProject.Path & "\Folder1.rar", CurrentProject.Path & "\Extracted", , WinRAR, OverwriteAll ' الناتج: محتويات Folder1.rar مفكوكة في CurrentProject.Path\Extracted End Sub ' مع كلمة مرور Sub ExtractSingleFolderWithPasswordWinRAR() Dim password As String ' تعيين كلمة المرور password = "officena" ExtractItems CurrentProject.Path & "\Folder1.rar", CurrentProject.Path & "\Extracted", password, WinRAR, OverwriteNone ' الناتج: محتويات Folder1.rar مفكوكة في CurrentProject.Path\Extracted مع تجاهل الموجود End Sub سوف نقوم بعمل وحده نمطيه عامه لتجربة : 7Zip اسم الوحده النمطيه : basArchiveExamples7Zip ' يضمن مقارنة النصوص بناءً على إعدادات قاعدة البيانات (مثل ترتيب الحروف واللغة) Option Compare Database ' يجبر على تعريف المتغيرات صراحة قبل استخدامها، مما يمنع الأخطاء الناتجة عن الأسماء الخاطئة Option Explicit ' وحدة نمطية تحتوي على أمثلة شاملة لضغط وفك ضغط باستخدام 7-Zip مع كل الخيارات ' =========================================================================== ' 1. ضغط ملف واحد ' =========================================================================== ' بدون كلمة مرور، مستوى ضغط عادي Sub CompressSingleFileNoPasswordSevenZip() CompressItems "file1.txt", , SevenZip, Archive7z, CompressionNormal ' الناتج: file1.7z في CurrentProject.Path End Sub ' مع كلمة مرور، مستوى ضغط أقصى Sub CompressSingleFileWithPasswordMaxCompressionSevenZip() Dim password As String ' تعيين كلمة المرور password = "officena" CompressItems "file1.txt", password, SevenZip, Archive7z, CompressionMaximum ' الناتج: file1.7z (مشفر، مضغوط بأقصى مستوى) في CurrentProject.Path End Sub ' مع تقسيم الأرشيف (Split500MB) Sub CompressSingleFileWithSplitSevenZip() Dim password As String ' تعيين كلمة المرور password = "officena" CompressItems "file1.txt", password, SevenZip, Archive7z, CompressionNormal, Split500MB ' الناتج: file1.7z مقسم إلى أجزاء بحجم 500 ميجابايت End Sub ' ذاتي الاستخراج (SFX) Sub CompressSingleFileSFXSevenZip() Dim password As String ' تعيين كلمة المرور password = "officena" CompressItems "file1.txt", password, SevenZip, Archive7z, CompressionNormal, , , "File1SFX", True ' الناتج: File1SFX.exe (مشفر) في CurrentProject.Path End Sub ' =========================================================================== ' 2. فك ضغط ملف واحد ' =========================================================================== ' بدون كلمة مرور، الكتابة فوق الملفات Sub ExtractSingleFileNoPasswordOverwriteSevenZip() ExtractItems CurrentProject.Path & "\file1.7z", CurrentProject.Path & "\Extracted", , SevenZip, OverwriteAll ' الناتج: محتويات file1.7z مفكوكة في CurrentProject.Path\Extracted مع الكتابة فوق الملفات End Sub ' مع كلمة مرور، تجاهل الملفات الموجودة Sub ExtractSingleFileWithPasswordNoOverwriteSevenZip() ExtractItems CurrentProject.Path & "\file1.7z", CurrentProject.Path & "\Extracted", "MyPassword123", SevenZip, OverwriteNone ' الناتج: محتويات file1.7z مفكوكة في CurrentProject.Path\Extracted مع تجاهل الملفات الموجودة End Sub ' =========================================================================== ' 3. ضغط عدة ملفات (كل ملف على حدة) ' =========================================================================== ' بدون كلمة مرور Sub CompressMultipleFilesSeparateNoPasswordSevenZip() Dim filesArray As Variant filesArray = Array("file1.txt", CurrentProject.Path & "\file2.docx", CurrentProject.Path & "\file3.pdf") StartCompressionLoop Dim filePath As Variant For Each filePath In filesArray CompressItems CStr(filePath), , SevenZip, Archive7z, CompressionNormal Next filePath ShowCompressionSuccess ' الناتج: file1.7z, file2.7z, file3.7z في CurrentProject.Path End Sub ' مع كلمة مرور وتقسيم Sub CompressMultipleFilesSeparateWithSplitSevenZip() Dim password As String ' تعيين كلمة المرور password = "officena" Dim filesArray As Variant filesArray = Array(CurrentProject.Path & "\file1.txt", CurrentProject.Path & "\file2.docx", CurrentProject.Path & "\file3.pdf") StartCompressionLoop Dim filePath As Variant For Each filePath In filesArray CompressItems CStr(filePath), password, SevenZip, Archive7z, CompressionNormal, Split100MB Next filePath ShowCompressionSuccess ' الناتج: file1.7z, file2.7z, file3.7z مقسمة إلى أجزاء بحجم 100 ميجابايت End Sub ' =========================================================================== ' 4. فك ضغط عدة ملفات (كل ملف على حدة) ' =========================================================================== ' بدون كلمة مرور Sub ExtractMultipleFilesSeparateNoPasswordSevenZip() Dim filesArray As Variant filesArray = Array(CurrentProject.Path & "\file1.7z", CurrentProject.Path & "\file2.7z", CurrentProject.Path & "\file3.7z") StartExtractionLoop Dim filePath As Variant For Each filePath In filesArray ExtractItems CStr(filePath), CurrentProject.Path, , SevenZip, OverwriteAll Next filePath ShowExtractionSuccess ' الناتج: محتويات كل ملف مفكوكة في CurrentProject.Path End Sub ' مع كلمة مرور Sub ExtractMultipleFilesSeparateWithPasswordSevenZip() Dim password As String ' تعيين كلمة المرور password = "officena" Dim filesArray As Variant filesArray = Array(CurrentProject.Path & "\file1.7z", CurrentProject.Path & "\file2.7z", CurrentProject.Path & "\file3.7z") StartExtractionLoop Dim filePath As Variant For Each filePath In filesArray ExtractItems CStr(filePath), CurrentProject.Path, password, SevenZip, OverwriteNone Next filePath ShowExtractionSuccess ' الناتج: محتويات كل ملف مفكوكة في CurrentProject.Path مع تجاهل الموجود End Sub ' =========================================================================== ' 5. ضغط عدة ملفات في أرشيف واحد ' =========================================================================== ' بدون كلمة مرور، تقسيم 100MB Sub CompressMultipleFilesOneArchiveWithSplitSevenZip() Dim files As Variant files = Array("file1.txt", "file2.docx", "file3.pdf") CompressItems files, , SevenZip, Archive7z, CompressionNormal, Split100MB, , "CompressedFiles" ' الناتج: CompressedFiles.7z مقسم إلى أجزاء بحجم 100 ميجابايت End Sub ' مع كلمة مرور وSFX Sub CompressMultipleFilesOneArchiveSFXSevenZip() Dim password As String ' تعيين كلمة المرور password = "officena" Dim files As Variant files = Array("file1.txt", "file2.docx", "file3.pdf") CompressItems files, password, SevenZip, Archive7z, CompressionMaximum, , , "CompressedFilesSFX", True ' الناتج: CompressedFilesSFX.exe (مشفر) في CurrentProject.Path End Sub ' =========================================================================== ' 6. فك ضغط أرشيف واحد يحتوي على عدة ملفات ' =========================================================================== ' بدون كلمة مرور Sub ExtractMultipleFilesOneArchiveNoPasswordSevenZip() Dim archives As Variant archives = Array(CurrentProject.Path & "\CompressedFiles.7z") ExtractItems archives, CurrentProject.Path, , SevenZip, OverwriteAll ' الناتج: محتويات CompressedFiles.7z مفكوكة في CurrentProject.Path End Sub ' مع كلمة مرور Sub ExtractMultipleFilesOneArchiveWithPasswordSevenZip() Dim password As String ' تعيين كلمة المرور password = "officena" Dim archives As Variant archives = Array(CurrentProject.Path & "\CompressedFiles.7z") ExtractItems archives, CurrentProject.Path, password, SevenZip, OverwriteNone ' الناتج: محتويات CompressedFiles.7z مفكوكة في CurrentProject.Path مع تجاهل الموجود End Sub ' =========================================================================== ' 7. ضغط مجلد واحد ' =========================================================================== ' مع تقسيم وSFX Sub CompressSingleFolderWithSplitSFXSevenZip() Dim password As String ' تعيين كلمة المرور password = "officena" CompressItems CurrentProject.Path & "\Folder1", password, SevenZip, Archive7z, CompressionNormal, Split1GB, , "Folder1SFX", True ' الناتج: Folder1SFX.exe مقسم إلى أجزاء بحجم 1 جيجابايت End Sub ' =========================================================================== ' 8. ضغط عدة مجلدات (كل مجلد على حدة) ' =========================================================================== ' بدون كلمة مرور Sub CompressMultipleFoldersNoPasswordSevenZip() Dim foldersArray As Variant foldersArray = Array(CurrentProject.Path & "\Folder1", CurrentProject.Path & "\Folder2") StartCompressionLoop Dim folderPath As Variant For Each folderPath In foldersArray CompressItems CStr(folderPath), , SevenZip, Archive7z, CompressionNormal Next folderPath ShowCompressionSuccess ' الناتج: Folder1.7z, Folder2.7z في CurrentProject.Path End Sub ' مع كلمة مرور وتقسيم Sub CompressMultipleFoldersWithSplitSevenZip() Dim password As String ' تعيين كلمة المرور password = "officena" Dim foldersArray As Variant foldersArray = Array(CurrentProject.Path & "\Folder1", CurrentProject.Path & "\Folder2") StartCompressionLoop Dim folderPath As Variant For Each folderPath In foldersArray CompressItems CStr(folderPath), password, SevenZip, Archive7z, CompressionNormal, Split500MB Next folderPath ShowCompressionSuccess ' الناتج: Folder1.7z, Folder2.7z مقسمة إلى أجزاء بحجم 500 ميجابايت End Sub ' =========================================================================== ' 9. فك ضغط مجلد واحد ' =========================================================================== ' بدون كلمة مرور Sub ExtractSingleFolderNoPasswordSevenZip() ExtractItems CurrentProject.Path & "\Folder1.7z", CurrentProject.Path & "\Extracted", , SevenZip, OverwriteAll ' الناتج: محتويات Folder1.7z مفكوكة في CurrentProject.Path\Extracted End Sub ' مع كلمة مرور Sub ExtractSingleFolderWithPasswordSevenZip() Dim password As String ' تعيين كلمة المرور password = "officena" ExtractItems CurrentProject.Path & "\Folder1.7z", CurrentProject.Path & "\Extracted", password, SevenZip, OverwriteNone ' الناتج: محتويات Folder1.7z مفكوكة في CurrentProject.Path\Extracted مع تجاهل الموجود End Sub وأخيــــر وحده نمطيه عامة لضغط قاعدة البيانات الحاليه( الأمامية أو الخلفيه أو الأمامية والخلفية معا أو القاعدة الحاليه فقط ان لم تكن منقسمه ) اسم الوحدة النمطية : basCompressDatabase الكود ' يضمن مقارنة النصوص بناءً على إعدادات قاعدة البيانات (مثل ترتيب الحروف واللغة) Option Compare Database ' يجبر على تعريف المتغيرات صراحة قبل استخدامها، مما يمنع الأخطاء الناتجة عن الأسماء الخاطئة Option Explicit ' تعداد لتحديد نوع القاعدة المراد ضغطها Enum EnumDatabaseType FrontEndOnly = 0 ' ضغط القاعدة الحالية (Front-End) فقط BackEndOnly = 1 ' ضغط القاعدة الخلفية (Back-End) فقط BothFrontAndBack = 2 ' ضغط القاعدة الحالية والخلفية معًا End Enum ' دالة لضغط قاعدة البيانات الحالية و/أو الخلفية بناءً على الخيارات ' المدخلات: ' - dbType: نوع القاعدة المراد ضغطها (Front-End، Back-End، أو الاثنين) ' - archiveName: اسم الأرشيف الناتج (اختياري، لو فارغ بيستخدم اسم القاعدة) ' - targetPath: مسار حفظ الأرشيف (اختياري، لو فارغ بيستخدم مسار القاعدة) ' - Method: أداة الضغط (WinRAR أو SevenZip، افتراضي SevenZip) ' - ArchiveType: نوع الأرشيف (افتراضي Archive7z) ' - compressionLevel: مستوى الضغط (افتراضي CompressionNormal) ' - password: كلمة المرور لتشفير الأرشيف (اختياري) ' - commentFile: مسار ملف التعليقات لإضافته إلى الأرشيف (اختياري) ' دالة لضغط قاعدة البيانات الحالية و/أو الخلفية بناءً على الخيارات ' المدخلات: ' - dbType: نوع القاعدة المراد ضغطها (Front-End، Back-End، أو الاثنين) ' - archiveName: اسم الأرشيف الناتج (اختياري، لو فارغ بيستخدم اسم القاعدة) ' - targetPath: مسار حفظ الأرشيف (اختياري، لو فارغ بيستخدم مسار القاعدة) ' - Method: أداة الضغط (WinRAR أو SevenZip، افتراضي SevenZip) ' - ArchiveType: نوع الأرشيف (افتراضي Archive7z) ' - compressionLevel: مستوى الضغط (افتراضي CompressionNormal) ' - password: كلمة المرور لتشفير الأرشيف (اختياري) ' - commentFile: مسار ملف التعليقات لإضافته إلى الأرشيف (اختياري) ' - showHelp: عرض تعليمات قبل الضغط إذا كان True (افتراضي False) ' دالة لضغط قاعدة البيانات الحالية و/أو الخلفية بناءً على الخيارات ' المدخلات: ' - dbType: نوع القاعدة المراد ضغطها (إجباري: FrontEndOnly, BackEndOnly, BothFrontAndBack) ' - archiveName: اسم الأرشيف الناتج (اختياري، لو فارغ بيستخدم اسم القاعدة) ' - targetPath: مسار حفظ الأرشيف (اختياري، لو فارغ بيستخدم مسار القاعدة) ' - Method: أداة الضغط (اختياري: WinRAR أو SevenZip، افتراضي SevenZip) ' - ArchiveType: نوع الأرشيف (اختياري، افتراضي Archive7z) ' - compressionLevel: مستوى الضغط (اختياري، افتراضي CompressionNormal) ' - password: كلمة المرور لتشفير الأرشيف (اختياري) ' - commentFile: مسار ملف التعليقات لإضافته إلى الأرشيف (اختياري) Sub CompressDatabase( _ ByVal dbType As EnumDatabaseType, _ Optional ByVal archiveName As String = "", _ Optional ByVal targetPath As String = "", _ Optional ByVal Method As EnumArchiveMethod = SevenZip, _ Optional ByVal ArchiveType As EnumArchiveType = Archive7z, _ Optional ByVal compressionLevel As EnumCompressionLevel = CompressionNormal, _ Optional ByVal password As String = "", _ Optional ByVal commentFile As String = "") Dim fso As Object Set fso = CreateObject("Scripting.FileSystemObject") On Error GoTo ErrorHandler ' التحقق من صحة dbType If dbType < FrontEndOnly Or dbType > BothFrontAndBack Then MsgBox "خطأ: نوع القاعدة (dbType) غير صحيح!", vbExclamation ShowHelp Exit Sub End If ' متغيرات لتخزين مسارات القاعدة Dim frontEndPath As String Dim backEndPath As String Dim tempFrontEndPath As String Dim tempBackEndPath As String ' الحصول على مسار القاعدة الحالية (Front-End) frontEndPath = CurrentDb.Name ' مثل: "C:\Users\YourUser\Documents\FrontEnd.accdb" ' الحصول على مسار القاعدة الخلفية (Back-End) إذا كانت موجودة backEndPath = GetBackEndPath() ' تحديد المسارات المؤقتة في مجلد Temp tempFrontEndPath = Environ$("TEMP") & "\" & fso.GetFileName(frontEndPath) If backEndPath <> "" Then tempBackEndPath = Environ$("TEMP") & "\" & fso.GetFileName(backEndPath) End If ' تحديد مسار واسم الأرشيف الناتج Dim finalTargetPath As String finalTargetPath = IIf(targetPath = "", fso.GetParentFolderName(frontEndPath), targetPath) ' معالجة حسب نوع القاعدة المطلوب Select Case dbType Case FrontEndOnly ' ضغط القاعدة الحالية فقط fso.CopyFile frontEndPath, tempFrontEndPath, True Dim frontEndArchiveName As String frontEndArchiveName = IIf(archiveName = "", fso.GetBaseName(frontEndPath), archiveName) & GetArchiveExtension(ArchiveType) Dim uniqueFrontEndArchive As String uniqueFrontEndArchive = GenerateUniqueFileName(finalTargetPath, frontEndArchiveName) CompressItems tempFrontEndPath, password, Method, ArchiveType, compressionLevel, SplitNone, finalTargetPath, fso.GetBaseName(uniqueFrontEndArchive), , commentFile If fso.FileExists(tempFrontEndPath) Then fso.DeleteFile tempFrontEndPath Case BackEndOnly ' ضغط القاعدة الخلفية فقط If backEndPath = "" Then MsgBox "لا توجد قاعدة خلفية مرتبطة!", vbExclamation Exit Sub End If fso.CopyFile backEndPath, tempBackEndPath, True Dim backEndArchiveName As String backEndArchiveName = IIf(archiveName = "", fso.GetBaseName(backEndPath), archiveName) & GetArchiveExtension(ArchiveType) Dim uniqueBackEndArchive As String uniqueBackEndArchive = GenerateUniqueFileName(finalTargetPath, backEndArchiveName) CompressItems tempBackEndPath, password, Method, ArchiveType, compressionLevel, SplitNone, finalTargetPath, fso.GetBaseName(uniqueBackEndArchive), , commentFile If fso.FileExists(tempBackEndPath) Then fso.DeleteFile tempBackEndPath Case BothFrontAndBack ' ضغط القاعدتين معًا If backEndPath = "" Then MsgBox "لا توجد قاعدة خلفية، سيتم ضغط القاعدة الحالية فقط!", vbInformation fso.CopyFile frontEndPath, tempFrontEndPath, True Dim singleArchiveName As String singleArchiveName = IIf(archiveName = "", fso.GetBaseName(frontEndPath) & "_Full", archiveName) & GetArchiveExtension(ArchiveType) Dim uniqueSingleArchive As String uniqueSingleArchive = GenerateUniqueFileName(finalTargetPath, singleArchiveName) CompressItems tempFrontEndPath, password, Method, ArchiveType, compressionLevel, SplitNone, finalTargetPath, fso.GetBaseName(uniqueSingleArchive), , commentFile If fso.FileExists(tempFrontEndPath) Then fso.DeleteFile tempFrontEndPath Else fso.CopyFile frontEndPath, tempFrontEndPath, True fso.CopyFile backEndPath, tempBackEndPath, True Dim bothFiles(1) As String bothFiles(0) = tempFrontEndPath bothFiles(1) = tempBackEndPath Dim bothArchiveName As String bothArchiveName = IIf(archiveName = "", fso.GetBaseName(frontEndPath) & "_Full", archiveName) & GetArchiveExtension(ArchiveType) Dim uniqueBothArchive As String uniqueBothArchive = GenerateUniqueFileName(finalTargetPath, bothArchiveName) CompressItems bothFiles, password, Method, ArchiveType, compressionLevel, SplitNone, finalTargetPath, fso.GetBaseName(uniqueBothArchive), , commentFile If fso.FileExists(tempFrontEndPath) Then fso.DeleteFile tempFrontEndPath If fso.FileExists(tempBackEndPath) Then fso.DeleteFile tempBackEndPath End If End Select Set fso = Nothing Exit Sub ErrorHandler: MsgBox "خطأ في ضغط قاعدة البيانات: " & Err.Description, vbCritical LogError "CompressDatabase Error: " & Err.Description ShowHelp ' عرض التعليمات عند حدوث أي خطأ ' تنظيف الملفات المؤقتة في حالة الخطأ If fso.FileExists(tempFrontEndPath) Then fso.DeleteFile tempFrontEndPath If fso.FileExists(tempBackEndPath) Then fso.DeleteFile tempBackEndPath Set fso = Nothing End Sub ' دالة مساعدة للحصول على مسار القاعدة الخلفية من الجداول المرتبطة Private Function GetBackEndPath() As String On Error GoTo ErrorHandler Dim tdf As DAO.TableDef Dim db As DAO.Database Set db = CurrentDb ' فحص الجداول المرتبطة For Each tdf In db.TableDefs If Len(tdf.Connect) > 0 Then ' إذا كان الجدول مرتبطًا ' استخراج المسار من خاصية Connect Dim connectString As String connectString = tdf.Connect If InStr(connectString, "DATABASE=") > 0 Then GetBackEndPath = Mid(connectString, InStr(connectString, "DATABASE=") + 9) Exit Function End If End If Next tdf ' إذا لم يتم العثور على قاعدة خلفية GetBackEndPath = "" Exit Function ErrorHandler: GetBackEndPath = "" End Function ' توليد اسم ملف فريد Public Function GenerateUniqueFileName(Folderpath As String, Filename As String) As String Dim baseName As String Dim extension As String Dim counter As Integer Dim uniqueName As String baseName = Left(Filename, InStrRev(Filename, ".") - 1) extension = Mid(Filename, InStrRev(Filename, ".")) uniqueName = Folderpath & "\" & Filename counter = 1 Do While Dir(uniqueName) <> "" uniqueName = Folderpath & "\" & baseName & " (" & counter & ")" & extension counter = counter + 1 Loop GenerateUniqueFileName = uniqueName End Function ' إجراء لتسجيل الأخطاء في ملف نصي بمسار المشروع الحالي Sub LogError(errorMessage As String) Dim logFile As String logFile = CurrentProject.Path & "\ErrorLog.txt" Open logFile For Append As #1 Print #1, Now & " - " & errorMessage Close #1 End Sub ' إجراء لعرض نافذة تعليمات تحتوي على تعريف الباراميترات Sub ShowHelp() MsgBox "تعليمات CompressDatabase:" & vbCrLf & _ "الباراميترات:" & vbCrLf & _ "- dbType (إجباري): نوع القاعدة المراد ضغطها" & vbCrLf & _ " * FrontEndOnly: ضغط القاعدة الحالية فقط" & vbCrLf & _ " * BackEndOnly: ضغط القاعدة الخلفية فقط" & vbCrLf & _ " * BothFrontAndBack: ضغط القاعدتين معًا" & vbCrLf & _ "- archiveName (اختياري): اسم الأرشيف، لو فارغ يستخدم اسم القاعدة" & vbCrLf & _ "- targetPath (اختياري): مسار الحفظ، لو فارغ يستخدم مسار القاعدة" & vbCrLf & _ "- Method (اختياري): أداة الضغط (WinRAR أو SevenZip)، افتراضي SevenZip" & vbCrLf & _ "- ArchiveType (اختياري): نوع الأرشيف (مثل Archive7z, ArchiveZIP)، افتراضي Archive7z" & vbCrLf & _ "- compressionLevel (اختياري): مستوى الضغط (مثل CompressionNormal)، افتراضي CompressionNormal" & vbCrLf & _ "- password (اختياري): كلمة المرور للتشفير" & vbCrLf & _ "- commentFile (اختياري): مسار ملف التعليقات" & vbCrLf & _ "ملاحظات: راجع التعدادات (EnumDatabaseType, EnumArchiveMethod, EnumArchiveType, EnumCompressionLevel) في الكود", vbInformation End Sub Sub TestCompressDatabase() Dim commentLines As Variant Dim commentFile As String Dim password As String ' تعيين كلمة المرور password = "officena" ' إعداد التعليق باستخدام المتغير commentLines = Array( _ "منتديات أوفيسنا", _ "www.officena.net", _ "وقت وتاريخ إنشاء الأرشيف:", _ Format(Now, "dd-mm-yyyy hh:nn AM/PM"), _ "كلمة المرور لفك الضغط: " & password, _ "مع أطيب الأماني: أبو جودى") commentFile = CreateCommentFile(commentLines) ' ضغط القاعدة الحالية فقط CompressDatabase FrontEndOnly, , , WinRAR, ArchiveZIP, CompressionMaximum, password, commentFile '' ' ضغط القاعدة الخلفية فقط (لو موجودة) '' CompressDatabase BackEndOnly, "MyBackend", "", WinRAR, ArchiveRAR '' ' الناتج: C:\Backups\MyBackend.zip '' '' ' ضغط القاعدتين معًا '' CompressDatabase BothFrontAndBack, "FullBackup", "", WinRAR, ArchiveRAR, CompressionMaximum '' ' الناتج: C:\Backups\FullBackup.7z يحتوي على الـ Front-End والـ Back-End (لو موجود) End Sub فى انتظار آرائكم بشغف انا كتبت اكواد التجربة على اعتبار وجود المجلدات والملفات فى مسار قاعدة البيانات على ان يكون اسماء المجلدات كالتالى : Folder1 Folder2 واسماء الملفات كالتالى : file1.txt file2.docx file3.pdf طبعا يمكنكم تغيير اسماء وأماكن المجلدات والمسارات فى اكواد التجربه كما يحلو لكم ولكن قد أكون أخطأت فى أى شئ بسبب كبر الكود وتشعبه لذلك فى انتظار مراجعتكم وآرائكم ان شاء الله التحديثات الأخيــــره فى حالة التعامل مع البرامج المحموله امكانيه تحديد مسار التطبيق مره واحده فقط طوال الجلسة الحاليه اضافة نسخ محمولة مختلفة الانويه فى مسار القاعدة ل 7-zip ودعم الكود للعمل من خلالهما مباشرة فى حالة عدم التسطيب دعم اضافى لانواع الارشيف المختلفه والتعامل مع الانواع بمرونه اكبر اضافة وظائف لضغط قاعدة البيانات الحلفيه سواء كانت امامية فقط أو امامية وخلفيه لكل واحده على حده او كلاهما معا مع اسم فريد للاحتفاظ بالنسخ القديمه المضغوطة بتعداد متزايد اتمنى لكم تجربة ممتعة وأخيـــــــــــرا المرفق كلمة مرور فك الضغط للمرفق : officena OfficenaZip V2.zip
    1 point
  3. عند فتح التقرير و حذف مربع نص سرد و تحرير تظهر البيانت صحيحة . لكن عند وضع مربع نص سرد و تحرير في حقل" رقم القسم" في استعلام نتايج 01 تظهر خطأ كما مبين في الصورة . أرجو من الأساتذة تصيح الخطأ . شكرا Database.rar
    1 point
  4. بارك الله بجهودك استاذي الكريم ساجرب الكود عل جهاز الماسح الضوئي في مكان عملي واوافيك بالرد غدا باذن الله مع التقدير...
    1 point
  5. التزاماً بسياسة وقوانين المنتدى ، ارجو منك فتح الموضوع كموضوع جديد ، وسيتم ان شاء الله متابعته يا صديقي ،
    1 point
  6. السلام عليكم برجاء منك مساعدتي لقد قمت بتوحيد الاصناف وجعلت سعر شراء في فاتورة المشتريات اضعه كل مره بايدي قلي عليها استاذي المحترم @عبد اللطيف سلوم ولكن تواجهني مشكلة لديا صنف له 3 اسعار شراء وله نفس الاسم و عند اختيار صف من الكومبو بوكس فلنفترض الثاني يقوم سعر شراء في الفاتورة يعطيني سعر الصف الاول وليس الثاني وايضا حقل المخزن يقوم بجمعهم كلهم مع بعض وانا اريد كل واحد علي حداه اريد تحديد سعر شراء بناءً على الصف الفعلي الذي اخترته في فاتورة المبيعات وبناءً على الصورة، يظهر أن الكومبو بوكس يحتوي على عدة صفوف مكررة لنفس الصنف لكن بأسعار شراء مختلفة (1000، 1200، 1300). عند اختيار صف معين، اريد أن يتم تعيين سعر الشراء الصحيح بناءً على الصف المحدد، وليس فقط على اسم الصنف. ارجو الافادة الاقساط.rar
    1 point
  7. المطلوب غير مفهوم و واضح ، ولا وجود لمربع السرد والتحرير الذي ذكرته ؛ والفضول دفعني لسؤال وهو ما الفكرة من مربع السرد والتحرير في التقرير ؟؟؟؟ كما تعلم أن التقرير لعرض بيانات محددة تأتيك من استعلام مبني على شروط - أو بدون - حسب حاجتك أو من الجداول ، ولا اعتقد انك من خلال التقرير ستقوم باختيار القسم الذي تريده . على العموم قمت بفتح التقرير ولم يظهر لي أي خطأ وهذا ما جعلني أقوم بالتعليق
    1 point
  8. لا تترك فراغات في الاماكن التي تشير لها الاسهم اتاكد من الجميع
    1 point
  9. إدن لنجرب هدا 1) إظهار جميع القيم الموجودة بالعمود سواءا رقمية أو نصية وكدالك الفراغات بعد تمييزها بكلمة فارغة 2) عند اختيار قيمة معينة من عنصر الكومبوبوكس سواءا نصية أو رقمية سيتم حدف الصفوف التي تتضمن القيمة المحددة 3) لجدف الصفوف الفارغة قم بتحديد كلمة فارغة من عنصر كومبوبوكس 1 4) تمت إظافة دالة لترتيب القيم أبجديا على عنصر كومبوبوكس1 لتسهيل العثور على القيمة المطلوبة 5) تم إظافة إعادة ترقيم البيانات على عمود A عند الحدف في حالة كنت بحاجة لدالك Private Sub UserForm_Initialize() Dim Tbl As Object, c As Range, temp As Variant, lastRow As Long Set Tbl = CreateObject("Scripting.Dictionary") If Not CrWS Is Nothing Then lastRow = CrWS.Cells(CrWS.Rows.Count, "B").End(xlUp).Row If lastRow > 1 Then For Each c In CrWS.Range("B2:B" & lastRow) If Trim(c.Value) <> "" Then Tbl.Item(c.Value) = c.Value End If Next c End If If Application.WorksheetFunction.CountBlank(CrWS.Range("B2:B" & lastRow)) > 0 Then Tbl.Item("فارغة") = "فارغة" End If If Tbl.Count > 0 Then temp = Tbl.Items Call Tri(temp, LBound(temp), UBound(temp)) Me.ComboBox1.List = temp End If Else MsgBox "المصنف أو الورقة المحددة غير موجودة", vbExclamation End If End Sub Private Sub CommandButton1_Click() Dim lastRow As Long, ky As Variant, c As Range, OnRng As Range If Me.ComboBox1.Value <> "" Then If Not CrWS Is Nothing Then ky = Me.ComboBox1.Value lastRow = CrWS.Cells(CrWS.Rows.Count, "B").End(xlUp).Row If lastRow < 2 Then Exit Sub Application.ScreenUpdating = False If ky = "فارغة" Then For Each c In CrWS.Range("B2:B" & lastRow) If Trim(c.Value) = "" Then If OnRng Is Nothing Then Set OnRng = c.EntireRow Else Set OnRng = Union(OnRng, c.EntireRow) End If End If Next c Else For Each c In CrWS.Range("B2:B" & lastRow) If IsNumeric(c.Value) And IsNumeric(ky) Then If CDbl(c.Value) = CDbl(ky) Then If OnRng Is Nothing Then Set OnRng = c.EntireRow Else Set OnRng = Union(OnRng, c.EntireRow) End If End If Else If Trim(c.Value) = Trim(ky) Then If OnRng Is Nothing Then Set OnRng = c.EntireRow Else Set OnRng = Union(OnRng, c.EntireRow) End If End If End If Next c End If If Not OnRng Is Nothing Then OnRng.Delete End If With CrWS.Range("A2:A" & CrWS.Cells(CrWS.Rows.Count, "B").End(xlUp).Row) .Value = Evaluate("ROW(" & .Address & ")-1") End With UserForm_Initialize Me.ComboBox1.Value = "" Application.ScreenUpdating = True End If End If End Sub Sub Tri(a, gauc, droi) ref = a((gauc + droi) \ 2) g = gauc: d = droi Do Do While a(g) < ref: g = g + 1: Loop Do While ref < a(d): d = d - 1: Loop If g <= d Then temp = a(g): a(g) = a(d): a(d) = temp g = g + 1: d = d - 1 End If Loop While g <= d If g < droi Then Call Tri(a, g, droi) If gauc < d Then Call Tri(a, gauc, d) End Sub وأي إستفسار أو تعديل سوف نكون سعداء دائما بحصولك على النتائج المطلوبة بالتوفيق ........ TEST 3.rar
    1 point
  10. جعله الله بميزان حسناتك
    1 point
  11. طيب ع العموم اتفضل دى التعديلات النهائيه بكل اللى طلبته تم تعديل واضافة الدوال اللازمة داخل الوحدة النمطية الكود النهائى والاخيـــــــــر Option Compare Database Option Explicit ' متغير عام لتخزين بيانات الحقول المستخدمة في آخر استعلام SQL Private StoredFieldsInfo As Variant ' التحقق مما إذا كانت السلسلة تحتوي على أرقام فقط Public Function IsNumericOnly(ByVal InputString As String, Optional AllowDecimal As Boolean = False, Optional AllowNegative As Boolean = False) As Boolean On Error Resume Next Dim CleanString As String CleanString = Trim(InputString) If CleanString = "" Or Not IsNumeric(CleanString) Then Exit Function If Not AllowDecimal And InStr(CleanString, ".") > 0 Then Exit Function If Not AllowNegative And Left(CleanString, 1) = "-" Then Exit Function If InStr(CleanString, " ") > 0 Then Exit Function IsNumericOnly = True End Function ' التحقق من صحة الإدخال الرقمي مع حد أقصى للطول Private Function ValidateNumericInput(InputValue As Variant, ByRef ErrorMessage As String, Optional MaxLength As Integer = 0, Optional AllowDecimal As Boolean = False) As String On Error Resume Next If IsEmpty(InputValue) Or IsNull(InputValue) Or Len(Trim(InputValue)) = 0 Then ValidateNumericInput = "" Exit Function End If Dim InputStr As String InputStr = CStr(InputValue) If Not IsNumericOnly(InputStr, AllowDecimal) Then ErrorMessage = "يرجى إدخال أرقام فقط" & IIf(AllowDecimal, " (يمكن أن تحتوي على فاصلة عشرية)!", "!") Exit Function End If If MaxLength > 0 And Len(InputStr) > MaxLength Then ErrorMessage = "الإدخال يتجاوز الحد الأقصى (" & MaxLength & " أرقام)!" Exit Function End If ValidateNumericInput = InputStr End Function ' توزيع الأرقام داخل مربعات النصوص Private Sub DistributeDigits(TextBoxCollection As Collection, NumericString As String) ' التحقق من أن الإدخال الرقمي ليس فارغًا If Trim(NumericString & "") = "" Then Dim i As Integer For i = 1 To TextBoxCollection.Count TextBoxCollection(i).Value = "" Next i Exit Sub End If For i = 1 To TextBoxCollection.Count If i <= Len(NumericString) Then TextBoxCollection(i).Value = Mid(NumericString, i, 1) Else TextBoxCollection(i).Value = "" End If Next i End Sub ' توزيع الأرقام العشرية (الجزء الصحيح والعشري) Private Sub DistributeDecimal(TextBoxCollection As Collection, NumericString As String) On Error Resume Next ' التحقق من أن الإدخال الرقمي ليس فارغًا If Trim(NumericString & "") = "" Then Dim i As Integer For i = 1 To TextBoxCollection.Count TextBoxCollection(i).Value = "" Next i Exit Sub End If Dim parts() As String parts = Split(NumericString, ".") If TextBoxCollection.Count >= 1 Then TextBoxCollection(1).Value = Nz(parts(0), "") ' الجزء الصحيح If TextBoxCollection.Count >= 2 Then TextBoxCollection(2).Value = Nz(parts(1), "00") ' الجزء العشري (افتراضي 00) End Sub ' جمع مربعات النصوص Private Function CollectTextBoxes(TargetObject As Object, ControlPrefix As String, MaxFields As Integer) As Collection Dim i As Integer, ctrl As Control Set CollectTextBoxes = New Collection For i = 1 To MaxFields On Error Resume Next Set ctrl = TargetObject.Controls(ControlPrefix & i) If Not ctrl Is Nothing Then CollectTextBoxes.Add ctrl On Error GoTo 0 Next i End Function ' توزيع الإدخال الرقمي على مربعات النصوص مع خيار فصل الأرقام العشرية Public Sub DistributeNumericInput(Optional TargetObject As Object = Nothing, Optional InputValue As Variant, _ Optional ControlPrefix As String = "", Optional MaxFields As Integer = 0, _ Optional SplitDecimal As Boolean = False) On Error GoTo ErrorHandler ' التحقق من القيم الفارغة If IsEmpty(InputValue) Or IsNull(InputValue) Or Trim(InputValue & "") = "" Then ' إعادة تهيئة مربعات النصوص إلى فارغة Dim TextBoxes As Collection Set TextBoxes = CollectTextBoxes(TargetObject, ControlPrefix, MaxFields) Dim i As Integer For i = 1 To TextBoxes.Count TextBoxes(i).Value = "" Next i Exit Sub End If Dim ValidInput As String, ErrorMessage As String ValidInput = ValidateNumericInput(InputValue, ErrorMessage, MaxFields, SplitDecimal) If ValidInput = "" Then If ErrorMessage <> "" Then MsgBox ErrorMessage, vbExclamation, "خطأ في الإدخال" Exit Sub End If If MaxFields = 0 Then MaxFields = IIf(SplitDecimal, 2, Len(ValidInput)) If TargetObject Is Nothing Then Debug.Print "الإدخال الموزع: " & ValidInput Exit Sub End If Set TextBoxes = CollectTextBoxes(TargetObject, ControlPrefix, MaxFields) If SplitDecimal Then If TextBoxes.Count < 2 Then MsgBox "عدد مربعات النصوص (" & TextBoxes.Count & ") أقل من المطلوب (2) للأرقام العشرية!", vbExclamation, "خطأ" Exit Sub End If DistributeDecimal TextBoxes, ValidInput Else If TextBoxes.Count < Len(ValidInput) Then MsgBox "عدد مربعات النصوص (" & TextBoxes.Count & ") أقل من طول الإدخال (" & Len(ValidInput) & ")!", vbExclamation, "خطأ" Exit Sub End If DistributeDigits TextBoxes, ValidInput End If Exit Sub ErrorHandler: MsgBox "خطأ في توزيع الإدخال: " & Err.Description, vbCritical, "خطأ" End Sub ' التحقق من صحة الرقم القومي Private Function ValidateNationalID(NationalID As Variant, ByRef ErrorMessage As String) As String On Error Resume Next Dim InputStr As String InputStr = Trim(Nz(NationalID, "")) If InputStr = "" Or Not IsNumericOnly(InputStr) Or Len(InputStr) <> 14 Then ErrorMessage = "يجب إدخال رقم قومي صحيح مكون من 14 رقمًا!" Exit Function End If ValidateNationalID = InputStr End Function ' استخراج تاريخ الميلاد من الرقم القومي بصيغة YYYY-MM-DD Public Function ExtractBirthDateFromID(NationalID As Variant) As String On Error GoTo ErrorHandler Dim ValidInput As String, YearPart As String, MonthPart As String, DayPart As String, CenturyCode As String, ErrorMessage As String ValidInput = ValidateNationalID(NationalID, ErrorMessage) If ValidInput = "" Then ExtractBirthDateFromID = "خطأ: " & ErrorMessage Exit Function End If CenturyCode = Mid(ValidInput, 1, 1) YearPart = Mid(ValidInput, 2, 2) MonthPart = Mid(ValidInput, 4, 2) DayPart = Mid(ValidInput, 6, 2) Select Case CenturyCode Case "2": YearPart = "19" & YearPart Case "3": YearPart = "20" & YearPart Case "4": YearPart = "21" & YearPart Case Else: ExtractBirthDateFromID = "خطأ: رمز القرن غير صالح!" Exit Function End Select If Not IsDate(YearPart & "/" & MonthPart & "/" & DayPart) Then ExtractBirthDateFromID = "خطأ: تاريخ ميلاد غير صالح!" Exit Function End If If CDate(YearPart & "-" & MonthPart & "-" & DayPart) > Date Then ExtractBirthDateFromID = "خطأ: تاريخ الميلاد في المستقبل!" Exit Function End If ExtractBirthDateFromID = YearPart & "-" & MonthPart & "-" & DayPart Exit Function ErrorHandler: ExtractBirthDateFromID = "خطأ: " & Err.Description End Function ' توزيع تاريخ الميلاد في 3 مربعات نص (السنة - الشهر - اليوم) Public Sub DistributeBirthDateFromID(Optional TargetObject As Object = Nothing, Optional NationalID As Variant, Optional ControlPrefix As String = "") On Error GoTo ErrorHandler Dim BirthDate As String, TextBoxes As Collection BirthDate = ExtractBirthDateFromID(NationalID) If Left(BirthDate, 5) = "خطأ" Then MsgBox BirthDate, vbExclamation, "خطأ في الرقم القومي" Exit Sub End If If TargetObject Is Nothing Then Debug.Print "السنة: " & Left(BirthDate, 4) Debug.Print "الشهر: " & Mid(BirthDate, 6, 2) Debug.Print "اليوم: " & Right(BirthDate, 2) Exit Sub End If Set TextBoxes = CollectTextBoxes(TargetObject, ControlPrefix, 3) If TextBoxes.Count < 3 Then MsgBox "عدد مربعات النص غير كافٍ! (مطلوب 3)", vbExclamation, "خطأ" Exit Sub End If TextBoxes(1).Value = Left(BirthDate, 4) TextBoxes(2).Value = Mid(BirthDate, 6, 2) TextBoxes(3).Value = Right(BirthDate, 2) Exit Sub ErrorHandler: MsgBox "خطأ في توزيع تاريخ الميلاد: " & Err.Description, vbCritical, "خطأ" End Sub ' دالة اختبار لطباعة تاريخ الميلاد Public Sub TestPrintDistributeBirthDate(NationalID As Variant) Dim BirthDate As String BirthDate = ExtractBirthDateFromID(NationalID) If Left(BirthDate, 5) = "خطأ" Then Debug.Print BirthDate Else Debug.Print "تجربة الطباعة للرقم القومي: " & NationalID Debug.Print "تاريخ الميلاد: " & BirthDate End If End Sub ' إنشاء استعلام SQL ديناميكي Public Function GenerateDynamicSQL(tableName As String, ParamArray RequiredFieldsDistribute() As Variant) As String On Error GoTo ErrorHandler Dim sqlQuery As String, i As Integer, j As Integer, fieldName As String, MaxDigits As Integer, fieldPrefix As String If Trim(tableName) = "" Or UBound(RequiredFieldsDistribute) < 0 Then GenerateDynamicSQL = "خطأ: الجدول أو الحقول غير محددة" Exit Function End If StoredFieldsInfo = RequiredFieldsDistribute sqlQuery = "SELECT " & tableName & ".*, " For i = LBound(RequiredFieldsDistribute) To UBound(RequiredFieldsDistribute) fieldName = RequiredFieldsDistribute(i)(0) MaxDigits = RequiredFieldsDistribute(i)(1) fieldPrefix = RequiredFieldsDistribute(i)(2) For j = 1 To MaxDigits sqlQuery = sqlQuery & "IIf(IsNull([" & fieldName & "]) OR Len([" & fieldName & "]) < " & j & ", Null, Mid([" & fieldName & "], " & j & ", 1)) AS " & fieldPrefix & j & ", " Next j Next i sqlQuery = Left(sqlQuery, Len(sqlQuery) - 2) & " FROM " & tableName & ";" GenerateDynamicSQL = sqlQuery Exit Function ErrorHandler: GenerateDynamicSQL = "خطأ: " & Err.Description End Function ' حذف مصادر البيانات من الحقول غير المستخدمة Public Sub ClearUnusedTextBoxes(frm As Form) On Error GoTo ErrorHandler Dim ctl As Control, i As Integer, Prefix As String, MaxDigits As Integer If IsEmpty(StoredFieldsInfo) Or Not IsArray(StoredFieldsInfo) Then Exit Sub For i = LBound(StoredFieldsInfo) To UBound(StoredFieldsInfo) Prefix = StoredFieldsInfo(i)(2) MaxDigits = StoredFieldsInfo(i)(1) For Each ctl In frm.Controls If TypeName(ctl) = "TextBox" And ctl.Name Like Prefix & "*" Then Dim num As Integer num = Val(Mid(ctl.Name, Len(Prefix) + 1)) If num > MaxDigits Then ctl.ControlSource = "" End If Next ctl Next i Exit Sub ErrorHandler: Debug.Print "خطأ في ClearUnusedTextBoxes: " & Err.Description End Sub ' استخراج أجزاء التاريخ (سنة، شهر، يوم) من تاريخ مدخل Public Function ExtractDateParts(ByVal InputDate As Variant, ByRef ErrorMessage As String) As Variant On Error GoTo ErrorHandler Dim DateParts(1 To 3) As String Dim TempDate As Date ' تهيئة المصفوفة بقيم افتراضية فارغة DateParts(1) = "" DateParts(2) = "" DateParts(3) = "" ' حالة الحقل الفارغ If IsEmpty(InputDate) Or IsNull(InputDate) Or Trim(InputDate & "") = "" Then ExtractDateParts = DateParts ' إرجاع أجزاء فارغة Exit Function End If ' حالة الإدخال غير الصحيح If Not IsDate(InputDate) Then ErrorMessage = "تنسيق التاريخ غير صحيح!" Exit Function End If ' تحويل إلى تاريخ TempDate = CDate(InputDate) ' (اختياري) التحقق من أن التاريخ ليس في المستقبل ' If TempDate > Date Then ' ErrorMessage = "التاريخ لا يمكن أن يكون في المستقبل!" ' Exit Function ' End If ' تعبئة الأجزاء بتنسيق صحيح DateParts(1) = Format(Year(TempDate), "0000") DateParts(2) = Format(Month(TempDate), "00") DateParts(3) = Format(Day(TempDate), "00") ExtractDateParts = DateParts Exit Function ErrorHandler: ErrorMessage = "خطأ غير متوقع: " & Err.Description ExtractDateParts = Array("", "", "") ' إرجاع قيم فارغة مع رسالة خطأ End Function ' توزيع أجزاء التاريخ على مربعات النصوص Public Sub DistributeDateParts(Optional TargetObject As Object = Nothing, Optional InputDate As Variant, _ Optional ControlPrefix As String = "DatePart") On Error GoTo ErrorHandler Dim DateParts As Variant, TextBoxes As Collection Dim ErrorMessage As String DateParts = ExtractDateParts(InputDate, ErrorMessage) If Not IsArray(DateParts) Then MsgBox ErrorMessage, vbExclamation, "خطأ في التاريخ" Exit Sub End If If TargetObject Is Nothing Then Debug.Print "السنة: " & DateParts(1) Debug.Print "الشهر: " & DateParts(2) Debug.Print "اليوم: " & DateParts(3) Exit Sub End If Set TextBoxes = CollectTextBoxes(TargetObject, ControlPrefix, 3) If TextBoxes.Count < 3 Then MsgBox "يجب توفير 3 مربعات نصية للتوزيع!", vbExclamation, "خطأ" Exit Sub End If TextBoxes(1).Value = DateParts(1) ' السنة TextBoxes(2).Value = DateParts(2) ' الشهر TextBoxes(3).Value = DateParts(3) ' اليوم Exit Sub ErrorHandler: MsgBox "خطأ في التوزيع: " & Err.Description, vbCritical, "خطأ" End Sub ' دالة اختبار باستخدام DateSerial Public Sub TestPrintDistributeDate() Dim InputDate As Date Dim parts As Variant Dim ErrorMessage As String ' إنشاء التاريخ باستخدام DateSerial لتجنب الغموض InputDate = DateSerial(2025, 5, 9) ' 9 May 2025 (السنة، الشهر، اليوم) parts = ExtractDateParts(InputDate, ErrorMessage) If IsArray(parts) Then Debug.Print "السنة: " & parts(1) ' 2025 Debug.Print "الشهر: " & parts(2) ' 05 Debug.Print "اليوم: " & parts(3) ' 09 Else Debug.Print "خطأ: " & ErrorMessage End If End Sub فصل وتوزيع ارقام الرقم القومى 3.accdb
    1 point
  12. انا حليت لك هذه المشكلة من قبل ولكنك مصمم تعرض من ليس له ادخال بالجدول !!!!!!!!!!!!! test.rar
    1 point
  13. السلام عليكم ورحمة الله تعالى وبركاته اليكم هديه اخرى ولكن الحق أحق أن يتبع كل الشكر و التقدير لاستاذى الجليل ومعلمى القدير و اخى الحبيب الاستاذ @Foksh على موضوع : ⭐ هدية ~ تغيير لغة النظام في Unicode⭐ قمت بعمل تحديثات جذرية فى هيكل وبناء الكود المميزات : عدم الاعتماد على وسيط بانشاء ملف فى مسار محدد لتمرير اومر الاعدادات ثم حذفه بعد تمرريرها وتطبيقها اضافة نموذج جديد للتحكم فى اختيار وتنسيق الوقت والتاريخ بشكل فورى امكانيه اضافة تخطيط لوحات مفاتيح للغات مختلفة حسب الحاجة والرغبه امكانية حذف تخطيط لغة/لغات لوحات مفاتيح من مربع القيم باختيار مفرد او متعدد لاكثر من لغة التخلص من تخطيطات لوحات المفاتيح المزعجة وحذفها بسهوله و التى قد تصادف العديد عند استخدام قواعد بيانات تعديل التنسيق للوقت والتاريخ او اضافة تخطيط لغة مفاتيح او حذفها لا يتطلب اعادة التشغيل مطلقا امكانية نقل النماذج لاى قاعدة للعمل فورا بدون اى تعديلات تذكر واخيـــــــــــــر المرفق اتمنى لكم تجربة ممتعة LanguageCheck V3.0.1.accdb
    1 point
  14. وعليكم السلام ورحمة الله تعالى وبركاته في الجزء الأخير من الكود قم بإظافة هدا With crWS.PageSetup xlSheet.PageSetup.PaperSize = .PaperSize xlSheet.PageSetup.Orientation = .Orientation xlSheet.PageSetup.LeftMargin = .LeftMargin xlSheet.PageSetup.RightMargin = .RightMargin xlSheet.PageSetup.TopMargin = .TopMargin xlSheet.PageSetup.BottomMargin = .BottomMargin xlSheet.PageSetup.HeaderMargin = .HeaderMargin xlSheet.PageSetup.FooterMargin = .FooterMargin xlSheet.PageSetup.PrintArea = .PrintArea xlSheet.PageSetup.PrintTitleRows = .PrintTitleRows xlSheet.PageSetup.PrintTitleColumns = .PrintTitleColumns xlSheet.PageSetup.Zoom = .Zoom End With ActiveWindow.View = xlPageBreakPreview ActiveWindow.Zoom = 100 حدود طباعة ثابتة v2.xlsm
    1 point
  15. استاذ ابواحمد حياك وتقبل الله صيامك وقيامك عند تعديلك على الدالة وكانت المطلوب ولكن ضاعت الشروط من الجهة الثانية التي قام التعديل عليها الاستاذ Barna اي وقعت مشكلة عند الشروط في فورم FrmMenah وعند الغاء التعديل الذي تم من حضرتك تنفذ الدالة الشرط بشكل عادي فياريت اعادة النظر في تعديل الكود الكود الصحيح من غير (FrmCridi ) المعدل من طرف الاستاذ Barna هو Public Function CheckInkhirat(ByRef ID As Integer) As String On Error GoTo err_CheckInkhirat Dim yearNow As Integer, totalPaid As Currency Dim paymentMarch As Boolean, paymentJuly As Boolean Dim t As Integer, t1 As Integer Dim result_haj As Variant, latestDate As Variant Dim todayDate As Date, yearsDifference As Long Dim menhaID As Integer, eligibilityPeriod As Integer Dim menhaName As String, menhaType As String Dim message As String ' تحديد السنة الحالية If Month(Date) < 3 Then yearNow = Year(Date) - 1 t = 1 Else yearNow = Year(Date) t = 2 End If ' الحصول على تاريخ اليوم todayDate = Date ' إجمالي المبلغ المدفوع totalPaid = Nz(DSum("Payment_Made", "tbl_Loans", "EmployeeID = " & ID & " AND Year(Auto_Date) = " & yearNow & " AND Loan_ID = 0"), 0) ' جلب معرف المنحة من النموذج والتحقق من نوع الامتياز menhaID = 0 Select Case [Forms]![FrmMenah]![Etar] Case "المنح العائلية" menhaID = [Forms]![FrmMenah]![Frm_sub].[Form]![CmdMenha] latestDate = Nz(DMax("Menha_Date", "[Mena7]", "[EmployeeID] = " & ID & " AND [Menha_ID] = " & menhaID), #1/1/1900#) Case "التعويضات الطبية" menhaID = [Forms]![FrmMenah]![Frm_sub].[Form]![cmdSanitaire] latestDate = Nz(DMax("[Sanitaire_Date]", "[Sanitaire]", _ "[EmployeeID] = " & [Forms]![FrmMenah]![EmployeeID] & _ " And [Nom_Beneficiaire] = '" & Replace([Forms]![FrmMenah]![Frm_sub].[Form]![Nom_Beneficiaire], "'", "''") & "'" & _ " And [Sanitaire_ID] = " & [Forms]![FrmMenah]![Frm_sub].[Form]![cmdSanitaire]), #1/1/1900#) End Select ' جلب اسم المنحة ونوعها وفترة الاستحقاق من الجدول menhaName = Nz(DLookup("Menha_Name", "tbl_MenhaRules", "Menha_ID = " & menhaID & " AND Menha_Type = '" & [Forms]![FrmMenah]![Etar] & "'"), "") menhaType = Nz(DLookup("Menha_Type", "tbl_MenhaRules", "Menha_ID = " & menhaID & " AND Menha_Type = '" & [Forms]![FrmMenah]![Etar] & "'"), "") eligibilityPeriod = Nz(DLookup("Eligibility_Period", "tbl_MenhaRules", "Menha_ID = " & menhaID & _ " AND Menha_Type = '" & menhaType & "' AND Eligibility_Period > 0"), 0) ' التحقق إذا كانت هناك فترة استحقاق مسجلة If eligibilityPeriod > 0 Then ' yearsDifference = DateDiff("yyyy", latestDate, todayDate) yearsDifference = Int(DateDiff("d", [latestDate], todayDate) / 365.25) t1 = IIf(yearsDifference < eligibilityPeriod, 1, 2) End If ' التحقق من دفع المبلغ في مارس ويوليو paymentMarch = Nz(DLookup("Payment_Made", "tbl_Loans", "EmployeeID = " & ID & " AND Year(Auto_Date) = " & yearNow & " AND Month(Auto_Date) = 3"), 0) = 1500 paymentJuly = Nz(DLookup("Payment_Made", "tbl_Loans", "EmployeeID = " & ID & " AND Year(Auto_Date) = " & yearNow & " AND Month(Auto_Date) = 7"), 0) = 1500 ' بناء الرسالة بناءً على الشروط If totalPaid = 3000 Then message = "عزيزي المنخرط(ة)، يمكنك الاستفادة من " & menhaType & ": " & menhaName & "." If t = 1 Then message = message & " لأنك دفعت مبلغ الانخراط الخاص بالسنة الماضية كاملاً." ElseIf t = 2 Then message = message & " لأنك دفعت مبلغ الانخراط كاملاً." If paymentMarch And paymentJuly Then message = message & " على دفعتين." End If End If ' التحقق من آخر تاريخ لاستفادة المنحة If Not IsNull(latestDate) And eligibilityPeriod > 0 Then If eligibilityPeriod = 100 Then ' إذا كانت فترة الاستحقاق 100، تكون المنحة لمرة واحدة فقط message = "عزيزي المنخرط(ة)، لا يمكنك الاستفادة من " & menhaType & ": " & menhaName & "." & vbNewLine & _ "هذه المنحة يتم الاستفادة منها مرة واحدة فقط." ElseIf t1 = 1 Then ' في حالة الرفض بسبب فترة الاستحقاق message = "عزيزي المنخرط(ة)، لا يمكنك الاستفادة من " & menhaType & ": " & menhaName & "." & vbNewLine & _ "لقد استفدت من هذه المنحة بتاريخ: " & Format(latestDate, "dd/mm/yyyy") & "." & vbNewLine & _ "يجب الانتظار لمدة " & eligibilityPeriod & " سنة قبل الاستفادة مجددًا." Else ' في حالة القبول بعد انتهاء فترة الاستحقاق message = message & vbNewLine & "يمكنك الاستفادة من المنحة مجددًا." End If End If Else ' في حالة عدم دفع مبلغ الانخراط message = "عزيزي المنخرط(ة)، لا يمكنك الاستفادة من " & menhaType & ": " & menhaName & "." & vbNewLine & _ "لم تقم بدفع مبلغ الانخراط بالكامل المطلوب للاستفادة." End If ' إرجاع الرسالة CheckInkhirat = message Exit Function err_CheckInkhirat: MsgBox "خطأ رقم " & Err.Number & ": " & Err.Description, vbCritical, "خطأ" CheckInkhirat = "حدث خطأ أثناء التحقق من بيانات الانخراط." End Function واستدعائها result = CheckInkhirat(emp) الكود المعدل (به مشكلة شرط النظارات الطبية ) من طرف الاستاذ ابو احمد هو Public Function CheckInkhirat(ByRef ID As Integer, Optional FrmName As String = "FrmMenah") As String On Error GoTo err_CheckInkhirat Dim yearNow As Integer, totalPaid As Currency Dim paymentMarch As Boolean, paymentJuly As Boolean Dim t As Integer, t1 As Integer Dim result_haj As Variant, latestDate As Variant Dim todayDate As Date, yearsDifference As Long Dim menhaID As Integer, eligibilityPeriod As Integer Dim menhaName As String, menhaType As String Dim message As String Dim Etar As String Dim Frm As Form Set Frm = Forms(FrmName) Etar = Frm.Etar ' تحديد السنة الحالية If Month(Date) < 3 Then yearNow = Year(Date) - 1 t = 1 Else yearNow = Year(Date) t = 2 End If ' الحصول على تاريخ اليوم todayDate = Date ' إجمالي المبلغ المدفوع totalPaid = Nz(DSum("Payment_Made", "tbl_Loans", "EmployeeID = " & ID & " AND Year(Auto_Date) = " & yearNow & " AND Loan_ID = 0"), 0) ' جلب معرف المنحة من النموذج والتحقق من نوع الامتياز menhaID = 0 Select Case Itar Case "المنح العائلية" menhaID = Frm.Frm_sub.Form.CmdMenha latestDate = Nz(DMax("Menha_Date", "[Mena7]", "[EmployeeID] = " & ID & " AND [Menha_ID] = " & menhaID), #1/1/1900#) Case "التعويضات الطبية" menhaID = Frm.Frm_sub.Form.cmdSanitaire latestDate = Nz(DMax("[Sanitaire_Date]", "[Sanitaire]", _ "[EmployeeID] = " & Frm.EmployeeID & _ " And [Nom_Beneficiaire] = '" & Replace(Frm.Frm_sub.Form.Nom_Beneficiaire, "'", "''") & "'" & _ " And [Sanitaire_ID] = " & Frm.Frm_sub.Form.cmdSanitaire), #1/1/1900#) End Select ' جلب اسم المنحة ونوعها وفترة الاستحقاق من الجدول menhaName = Nz(DLookup("Menha_Name", "tbl_MenhaRules", "Menha_ID = " & menhaID & " AND Menha_Type = '" & Etar & "'"), "") menhaType = Nz(DLookup("Menha_Type", "tbl_MenhaRules", "Menha_ID = " & menhaID & " AND Menha_Type = '" & Etar & "'"), "") eligibilityPeriod = Nz(DLookup("Eligibility_Period", "tbl_MenhaRules", "Menha_ID = " & menhaID & _ " AND Menha_Type = '" & menhaType & "' AND Eligibility_Period > 0"), 0) ' التحقق إذا كانت هناك فترة استحقاق مسجلة If eligibilityPeriod > 0 Then ' yearsDifference = DateDiff("yyyy", latestDate, todayDate) yearsDifference = Int(DateDiff("d", [latestDate], todayDate) / 365.25) t1 = IIf(yearsDifference < eligibilityPeriod, 1, 2) End If ' التحقق من دفع المبلغ في مارس ويوليو paymentMarch = Nz(DLookup("Payment_Made", "tbl_Loans", "EmployeeID = " & ID & " AND Year(Auto_Date) = " & yearNow & " AND Month(Auto_Date) = 3"), 0) = 1500 paymentJuly = Nz(DLookup("Payment_Made", "tbl_Loans", "EmployeeID = " & ID & " AND Year(Auto_Date) = " & yearNow & " AND Month(Auto_Date) = 7"), 0) = 1500 ' بناء الرسالة بناءً على الشروط If totalPaid = 3000 Then message = "عزيزي المنخرط(ة)، يمكنك الاستفادة من " & menhaType & ": " & menhaName & "." If t = 1 Then message = message & " لأنك دفعت مبلغ الانخراط الخاص بالسنة الماضية كاملاً." ElseIf t = 2 Then message = message & " لأنك دفعت مبلغ الانخراط كاملاً." If paymentMarch And paymentJuly Then message = message & " على دفعتين." End If End If ' التحقق من آخر تاريخ لاستفادة المنحة If Not IsNull(latestDate) And eligibilityPeriod > 0 Then If eligibilityPeriod = 100 Then ' إذا كانت فترة الاستحقاق 100، تكون المنحة لمرة واحدة فقط message = "عزيزي المنخرط(ة)، لا يمكنك الاستفادة من " & menhaType & ": " & menhaName & "." & vbNewLine & _ "هذه المنحة يتم الاستفادة منها مرة واحدة فقط." ElseIf t1 = 1 Then ' في حالة الرفض بسبب فترة الاستحقاق message = "عزيزي المنخرط(ة)، لا يمكنك الاستفادة من " & menhaType & ": " & menhaName & "." & vbNewLine & _ "لقد استفدت من هذه المنحة بتاريخ: " & Format(latestDate, "dd/mm/yyyy") & "." & vbNewLine & _ "يجب الانتظار لمدة " & eligibilityPeriod & " سنة قبل الاستفادة مجددًا." Else ' في حالة القبول بعد انتهاء فترة الاستحقاق message = message & vbNewLine & "يمكنك الاستفادة من المنحة مجددًا." End If End If Else ' في حالة عدم دفع مبلغ الانخراط message = "عزيزي المنخرط(ة)، لا يمكنك الاستفادة من " & menhaType & ": " & menhaName & "." & vbNewLine & _ "لم تقم بدفع مبلغ الانخراط بالكامل المطلوب للاستفادة." End If ' إرجاع الرسالة CheckInkhirat = message Set Frm = Nothing Exit Function err_CheckInkhirat: MsgBox "خطأ رقم " & Err.Number & ": " & Err.Description, vbCritical, "خطأ" CheckInkhirat = "حدث خطأ أثناء التحقق من بيانات الانخراط." End Function واستدعائها result = CheckInkhirat(emp, Me.Parent.NAME)
    0 points
×
×
  • اضف...

Important Information