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

ابو جودي

أوفيسنا
  • Posts

    7009
  • تاريخ الانضمام

  • Days Won

    203

كل منشورات العضو ابو جودي

  1. طب مبدئيا كل الشكر والتقدير لاساتذتنا العظماء استاذى الجليل و معلمى القدير و والدى الحبيب الاستاذ @ابوخليل والاستاذ @Foksh ما قصور و وفوا وكفوا والله وبما أن الموضوع فى بدايته وقبل الابحار "روح" أي مشروع ناجح وضع الأساس السليم والذى يبدأ بالتحليل قبل التفكير فى الجدول ولكن الاهم كيف يمكن عمل تحليل النظم بأسس منهجيه صحيحة اولا وباختصار عند تصميم أى نظام: ابدأ بجمع كل المتطلبات بشكل كامل حدد الكيانات الأساسية وصفاتها أنشئ الجداول بشكل نظيف مع تحديد المفاتيح الأساسية اربط الجداول ببعضها عبر علاقات فعلية منظمة حافظ على مرونة الاستعلامات عبر بناء علاقات إضافية مؤقتة عند الحاجة سامع اللى بيقول هناك ايه الكلام ده ؟ ردا على هذا السؤال تفصيلا : كيف تقوم بعمل التحليل المناسب لمشروع قاعدة بيانات؟ 1. فهم متطلبات المشروع (Gather Requirements) اجمع كل التفاصيل من العميل أو من نفسك (لو بتعمل لنفسك). اسأل أسئلة مثل: ما هو الهدف الأساسي من القاعدة؟ ما هي أنواع المعلومات التي يجب تخزينها؟ ما العمليات التي يقوم بها المستخدمون؟ (إدخال، تعديل، بحث، تقارير، الخ) هل في صلاحيات مختلفة للمستخدمين؟ ما العمليات المستقبلية المحتملة؟ 2. تحديد الكيانات (Entities) الرئيسية الكيانات هي الأشياء أو الأشخاص أو الأحداث التي تحتاج إلى تسجيل بيانات عنها في مثال "شئون العاملين" الكيانات قد تكون: الموظف (Employee) الوظيفة (Job Title) القسم (Department) الإجازات (Vacations) المرتبات (Salaries) الحضور والانصراف (Attendance) التأمينات (Insurance) الجزاءات (Penalties) المكافآت (Rewards) 3. تعريف السمات (Attributes) لكل كيان لكل كيان تحدد المعلومات المرتبطة به مثلا للموظف (Employee): رقم الموظف الاسم تاريخ الميلاد العنوان رقم الهوية رقم الهاتف تاريخ التعيين الوظيفة الحالية المرتب الأساسي الحالة الاجتماعية .... الخ... 4. تحديد العلاقات بين الكيانات حدد كيف ترتبط الكيانات ببعضها مثال: كل موظف ينتمي إلى قسم واحد ⇚ علاقة واحد إلى متعدد (One-to-Many) كل موظف يمكن أن يكون له أكثر من إجازة ⇚ علاقة واحد إلى متعدد أيضا ¤ مهم جدا تحديد اتجاه العلاقة ونوعها كيف تحدد وضع التصور للجداول والهيكل؟ 1. تصميم الجداول بشكل طبيعي (Normalization) تأكد إن الجداول تكون بدون تكرار للمعلومات (تجنب تكرار نفس البيانات في أكثر من جدول) كل جدول يمثل كيان مستقل. 2. المفاتيح الأساسية (Primary Keys) كل جدول لازم يحتوي على مفتاح أساسي (Primary Key) يميز كل سجل بشكل فريد مثال: جدول الموظفين : الحقل EmployeeID \ مفتاح أساسي ولكن أنا لا احب و لا أفضل التعامل مع حقل الـ ID الافتراضى داخل الجداول الأفضل ترك حقل ID الذي ينشئه Access كمفتاح أساسي (AutoNumber) بدون تغيير حقل ID الأساسي يبقى دائما موجود داخل الجدول داخلي ما نلمسه وما نستعمله في الربط الخارجي فقط يحفظ سلامة السجلات داخليا إنشاء حقل يدوي خاص بك مثلا EmployeeID نوعه Number (Long Integer) / أو نص حسب الرغبة ضبط خاصية الفهرسة: "مفهرس بدون تكرار" عندما يكون نوعه أساسي (Primary ) أو "مفهرس يقبل التكرار" حسب نوعه أجنبي (Foreign Key) استخدام الحقل اليدوي (EmployeeID مثلا) للربط بين الجداول بدلا من ID هل عمل العلاقات مباشرة أم أثناء الاستعلامات؟ الأساس الدائم = العلاقات الفعلية في تصميم القاعدة الحالات الخاصة المؤقتة = علاقات مؤقتة داخل الاستعلامات ✍️ نصيحة ذهبية: دائما أنشئ المفتاح الأساسي بيدك سميه باسم يعبر عن الجدول خصائص فهرسته: فهرسة بدون تكرار كيف تسمي الحقول والمعرفات بطريقة صحيحة واحترافية؟ هذا رأيى الضئيل المتواضع وقد أكون مخطئ لانه سوف أختلف مع اساتذتى العظماء حتى لا تواجه مشاكل لاحقا مع الاستعلامات أو الربط أو حتى مع البرمجة اتبع القواعد دي: اسم المعرف = اسم الجدول بدون تكرار زائد + "ID" مثلاً: اسم الجدول اسم الحقل المفتاح الأساسي Employees EmployeeID Departments DepartmentID Vacations VacationID Salaries SalaryID قاعدة تسمية المفاتيح الأجنبية (Foreign Keys) لما تيجي تنقل مفتاح لجدول تاني (رابط)، خليه بنفس الاسم تمامًا! مثال: عندك جدول tblEmployees وفي جدول tblVacations بتربط الموظف اسم الحقل في Vacations هيكون أيضا : EmployeeID نفس الاسم بدون تغيير ليه؟ عشان لما تستخدم استعلامات فيها JOIN تربطهم بدون لخبطة أو إعادة تسمية أو لبس في فهم العلاقات خصائص الفهرسة لكل حالة الحالة الفهرسة في الجدول الأصلي (المفتاح الأساسي) مفهرس لا يقبل التكرار (Indexed - No Duplicates) في الجدول المرتبط (مفتاح أجنبي) مفهرس يقبل التكرار (Indexed - Duplicates OK) هل استخدام نفس الاسم (EmployeeID مثلا) يسبب مشكلة؟ لا طالما أنت ملتزم بالعلاقات الصحيحة (Relationships) واستخدمت أسماء الجداول والحروف الواضحة في الاستعلامات فلن تحدث مشكلة Access سوف يتعامل مع الحقول حسب السياق (اسم الجدول قبل الحقل لو حصل تعارض بسيط) ملاحظة إضافية تجنب الأسماء المحجوزة مثل (Name, Date, Year, User) لأنها قد تسبب مشاكل لاحقًا في الكود أو الاستعلامات حاول دائمًا تسمية الحقول بشكل يوحي بالمحتوى (BirthDate أفضل من Date فقط). ✍️ المختصر المفيد و الخلاصة : أنشئ أنت الحقول بنفسك = أفضل تحكم وجودة سم المفاتيح بشكل احترافي اسم الجدول + ID الفهرسة تكون حسب النوع: أساسي = بدون تكرار / أجنبي = يقبل التكرار لا تخف من تكرار اسم الحقل طالما هناك علاقة صحيحة مدعومة جيدا ..... يتبع
  2. طيب انا مش عارف انت مش بترد ليه ولو على حسب فهمى الضئيل بعد تحليلى لقاعدة بيانات انت عندك جدول اسمه : tblStudyMaterials يحتوى على المواد الدراسية والبيانات الرئيسية لإنشاء البار كود والكود القادم ده هيريحك من انك تكتب جمل فيها IIf متعدده لانه كارثه لو فقدت تركيزك معها يا صديقة وبدلا من كثر التكرار ده الكود داخل وحده نمطية عامة باسم : basGenerateBarcode '----------------------------------------------------------------------------------- ' الوحدة النمطية: توليد باركود المواد الدراسية بناءً على الكود واختصارات المواد ' تحتوي على: ' - تحميل بيانات المواد إلى قاموس مرة واحدة ' - دالة لتوليد الباركود مع ملاحظة اختيارية ' ' أمثلة الاستخدام (داخل الاستعلامات أو الأكواد): ' - Barcode: GenerateBarcode([StudyMaterialsEng], [St_Code]) ' - Barcode: GenerateBarcode([StudyMaterialsEng], [St_Code], "ملاحظة إضافية") ' ' ملاحظات: ' - إذا لم يتم العثور على المادة، يتم استخدام St_Code فقط بدون رمز. ' - في حالة الحاجة لتحديث القاموس أثناء الجلسة، يجب إعادة تحميله يدوياً. '----------------------------------------------------------------------------------- ' تحميل جدول المواد الدراسية إلى قاموس Public Function LoadStudyMaterialSymbols() As Object Dim dict As Object Dim rs As DAO.Recordset Set dict = CreateObject("Scripting.Dictionary") Set rs = CurrentDb.OpenRecordset("SELECT StudyMaterialsEng, Symbol FROM tblStudyMaterials", dbOpenSnapshot) Do While Not rs.EOF If Not dict.Exists(UCase(Nz(rs!StudyMaterialsEng, ""))) Then dict.Add UCase(Nz(rs!StudyMaterialsEng, "")), Nz(rs!Symbol, "") End If rs.MoveNext Loop rs.Close Set rs = Nothing Set LoadStudyMaterialSymbols = dict End Function ' توليد باركود بناءً على المادة والكود مع إضافة ملاحظة اختيارية Public Function GenerateBarcode(ByVal StudyMaterialsEng As String, ByVal St_Code As String, Optional ByVal AdditionalNote As String = "") As String Static MaterialSymbols As Object Dim Symbol As String Dim Barcode As String If MaterialSymbols Is Nothing Then Set MaterialSymbols = LoadStudyMaterialSymbols() End If If MaterialSymbols.Exists(UCase(StudyMaterialsEng)) Then Symbol = MaterialSymbols(UCase(StudyMaterialsEng)) Barcode = St_Code & Symbol Else Barcode = St_Code End If If Len(AdditionalNote) > 0 Then Barcode = Barcode & " " & AdditionalNote End If GenerateBarcode = Barcode End Function وعلشان انا فهمى على ادى ومش عارف قصدك من جملة اضافة ملاحظات انا كتبت لك كود الاستدعاء بالشكل اللى انت استخدمته داخل الاستعلام: Barcode: GenerateBarcode([StudyMaterialsEng], [St_Code]) ولو أردت اضافة أى ملاحظات يكون الاستدعاء بالكشل التالى : Barcode: GenerateBarcode([StudyMaterialsEng], [St_Code], "ملاحظة إضافية") طبعا مع كتابة ملاحظاتك حسب الحاجة باستبدال: ملاحظة إضافية وأخيرا كود توليد الباركود الذكي! هذا الكود يقوم بإنشاء باركود مميز وسريع للمواد الدراسية بناء على الكود واختصارات المواد مميزات الكود : تحميل ذكي للمواد إلى قاموس منظم ومرن توليد باركود فوري مع امكانية إضافة ملاحظات اختيارية التعامل مع البيانات بشكل سلس ومنظم تحسين مستوى الدقة في إدارة المواد كيف يعمل الكود ببساطة : يتم قراءة البيانات من قاعدة البيانات يتم تخزين اختصار كل مادة في قاموس للوصول السريع يقوم بإنشاء كود منفرد متكون من كود المادة + رمز المادة + ملاحظة اختيارية 📢 للاستفسارات والتطوير : يسعدني دعمكم بكل ما يخص تطوير وتحسين هذا الكود شعارنا : نحو تكويد و إدارة أكواد أذكى وأكثر فاعلية ومرونة فى الاستعلام الاول قمت بإضافة الحقل : NewBarcode والذى يعتمد على الأكواد DDMhamed(2).accdb
  3. طيب بالنسبه لموضوعك انا حملت المرفق مفيش اكسل ومش فاهم علاقة الاكسل هنا ايه بصراحة ياريت توضح النقطه دى ثم بعد ذلك وضح مقصدك من : كيف الصق فيه واضيف عليه ملاحظة النسخ يكون من ملف اكسل هل ممكن عمل مكان أضع فيه الباركود أسماء الطلاب ورقم القيد والصف والشعبة ولازمة الباركود ده ايه فى الاخر الباركود اللى فى الاستعلام ده عباره الحقل التالى Barcode: IIf([StudyMaterialsEng]="Religion", [St_Code] & "REL", IIf([StudyMaterialsEng]="ARABIC", [St_Code] & "ARA", IIf([StudyMaterialsEng]="MATH", [St_Code] & "MAT", IIf([StudyMaterialsEng]="ENGLISH", [St_Code] & "ENG", IIf([StudyMaterialsEng]="SOCIAL", [St_Code] & "SOC", IIf([StudyMaterialsEng]="SCIENCE", [St_Code] & "SCI", IIf([StudyMaterialsEng]="ART", [St_Code] & "ART", IIf([StudyMaterialsEng]="SPORT", [St_Code] & "SPO"))))))))) تفسير السطر بالتفصيل: السطر يقوم بإنشاء قيمة حقل يسمى Barcode بناءً على القيمة في الحقل [StudyMaterialsEng]. في البداية، يفحص قيمة [StudyMaterialsEng] ثم يضيف اختصارًا معينًا إلى قيمة [St_Code] بناءً على المادة التي يتم تدريسها. التفصيل : إذا كانت قيمة [StudyMaterialsEng] هي "Religion": يتم إضافة "REL" إلى قيمة [St_Code]. إذا كانت قيمة [StudyMaterialsEng] هي "ARABIC": يتم إضافة "ARA" إلى قيمة [St_Code]. إذا كانت قيمة [StudyMaterialsEng] هي "MATH": يتم إضافة "MAT" إلى قيمة [St_Code]. إذا كانت قيمة [StudyMaterialsEng] هي "ENGLISH": يتم إضافة "ENG" إلى قيمة [St_Code]. إذا كانت قيمة [StudyMaterialsEng] هي "SOCIAL": يتم إضافة "SOC" إلى قيمة [St_Code]. إذا كانت قيمة [StudyMaterialsEng] هي "SCIENCE": يتم إضافة "SCI" إلى قيمة [St_Code]. إذا كانت قيمة [StudyMaterialsEng] هي "ART": يتم إضافة "ART" إلى قيمة [St_Code]. إذا كانت قيمة [StudyMaterialsEng] هي "SPORT": يتم إضافة "SPO" إلى قيمة [St_Code].
  4. اخى الحبيب لا داعى للاعتذار .. أولا كلنا أخوه فقط انا طلبت منكم ذلك للمصلحة العامة بحيث يسهل الوصول الى الموضوع عند عمليات البحث داخل موضوعات المنتدى فى المستقبل لكم او لاى طالب علم أخى الحبيب بالفعل تم تعديل العنوان
  5. اخى الكريم من فضلك اختر عنوانا مناسبا دالا على الموضوع من فضلك لك علينا حقوق ولنا عندك كذلك وحقوقنا هى الالتزام بالقوانين المنظمة للمشاركات داخل المنتدى من اجل المصلحة العامة قوانين الموقع: من هنا واقتبس منها : المنتدى مثله مثل أي عمل جماعي لابد أن تكون هناك أسس واضحة للمشاركة فيه، يقرها ويلتزم بها جميع الأعضاء للحصول على الفائدة العامة عنوان المشاركة يجب أن يكون عنوان المشاركة يدل على محتواها
  6. انا شكلى جيت متأخر حبتين لكن أن تأتى متأخرا افضل من أن لا تأتى مبدئيا حتى انتهى من قرآة الموضوع من بدايته لارى تسلسل الافكار والأطروحات والنظريات اتمنى ان نلقى نظرة على هذا الموضوع :- ان شاء الله سوف أعود فى أقرب فرصة لأكمل وأنتهى لما بدأته ولكن ربما تجدون افكار جديده
  7. مشاركة مع استاذى الجليل و معلمى القدير الاستاذ @ابو عارف وبعد إذن أستاذى هناك بعض الحالات التي قد تستوجب تعديلات إضافية لضمان التوافق بين الأنوية المختلفة (32 بت و 64 بت) وكذلك بين إصدارات الويندوز وأوفيس المختلفة عند التعامل مع دوال الـ API في VBA و يجب الانتباه لها: في النظام 32 بت، النوع Long يستخدم بشكل طبيعي لتخزين المؤشرات (pointers)، لكن في النظام 64 بت، يجب استخدام LongPtr بدلاً من Long لتخزين المؤشرات. المشكلة: إذا لم تستخدم LongPtr في النظام 64 بت، فقد تحدث أخطاء في الحسابات التي تتعلق بالحجم أو العناوين، لأن الـ Long لا يدعم العناوين الأكبر في الأنظمة 64 بت. ملاحظة: في الأنظمة 64 بت، LongPtr قادر على التعامل مع الأرقام التي تتجاوز سعة الـ Long العادية (التي تصل إلى 2,147,483,647). في الأنظمة 32 بت، LongPtr يتم تحديده تلقائيًا ليكون Long. التعامل مع السلاسل النصية (Strings) في بعض الأحيان، قد تحتاج إلى تعديل طريقة تعريف السلاسل النصية المستخدمة مع الـ API إذا كنت تستخدم سلاسل نصية مع الـ API، تأكد من إضافة ByVal و ByRef بشكل صحيح استخدم String * n بدلاً من String في بعض الحالات التي تتطلب أن تكون السلسلة ثابتة الطول التعامل مع الهياكل (Structures) في بعض الأحيان، تستخدم الهياكل (مثل Type في VBA) مع دوال الـ API. إذا كنت تستخدم هياكل كبيرة، فقد تحتاج إلى التأكد من أن الأنواع داخلها متوافقة مع النظام 64 بت تأكد من أن جميع الهياكل تتعامل بشكل صحيح مع الأنواع مثل LongPtr بدلاً من Long أو Integer عندما يتعلق الأمر بالمؤشرات لأنه قد يتغير حجم الحقول في الهيكل بين الأنوية 32 و 64 بت، مما يسبب أخطاء في التعامل مع الذاكرة أو المؤشرات التأكد من استخدام #If و #ElseIf بشكل مناسب عند التعامل مع دوال API في VBA وتحديد التوافق بين الأنظمة 32 بت و 64 بت، تأكد من استخدام #If, #ElseIf و #End If بشكل صحيح عند تخصيص الوظائف للأجهزة ذات الأنوية المختلفة. الشرح السابق يوضح الفرق فى التعامل مع النواتان و كتابة الكود بشكل صحيح ليصبح الكود متوافقا بين النواتان لانه لو قمت بالاستبدال لن يعمل على النواة 32
  8. أولًا: أهداف النظام تنظيم عمليات تسجيل اليوميات بجميع أنواعها (اعتيادية - عارضة - بدل ساعات - بدل مبيت – تصريح تأخير – تصريح إنصراف مبكر - .... الخ ). ضمان الالتزام بالسياسات المعتمدة للموارد البشرية و اللوائح المنظمة. تسهيل الرقابة الداخلية عبر ربط قواعد لوائح العمل و تالحقق منها و قبل التسجيل الفوري لأنواع اليوميات التى تخص الأجازات. ثانيًا: قواعد الأجازات العامة ضرورة إدخال كافة البيانات المطلوبة (كود الموظف - نوع الأجازة - تاريخ البداية والنهاية). التحقق من صلاحية التواريخ وإدخالها بالشكل الصحيح. يتم التحقق من وجود يوميات سابقة فى نفس التاريخ لتفادي التعارض أو التكرار. ثالثًا: القواعد الخاصة بالأجازة العارضة أقصى مدة للأجازة العارضة : يومان عمل متتاليان فقط. ممنوع أن تتخلل الأجازة العارضة عطلات رسمية أو أسبوعية. يمنع تسجيل أجازة عارضة بعد أو قبل أجازة اعتيادية سواء مباشرة أو غير مباشرة حتى لو بينهما عطلات ( أسبوعية / رسمية ). ممنوع تسجيل أجازة عارضة تالية مباشرةً لإجازة عارضة سابقة مدتها يومان، لتفادي أجازات مطولة غير مسموحة حتى لا تتعدى اليومان. يخضع الحد السنوي للأجازات الاعتيادية أو العارضة لسياسات الموارد البشرية المعتمدة. رابعًا: القواعد الخاصة بالأجازات الأخرى الأجازة الاعتيادية تخضع للسياسات العامة دون حدود لعدد الأيام المتتالية بشرط اعتماد التوافر في الرصيد. رقم مسلسل خاص بكل أجازة اعتيادية لعمل حصر عدد ألايام المتصلة أى التى تتاببع فى التاريخ ولكن يتخللها عطلات. أجازات بدل الساعات وبدل المبيت يتم التحقق من أحقيتها بناءً على النوع المختار يمكن فقط لبدل الساعات والبدل مبيت أن يكون تاريخ بدء الأجازة أكبر من أو أصغر من تاريخ النهاية على يكون تاريخ نهاية الاجازة هو يوم البدل والذى قد يكون يوم عطلة أو يوم عمل عادى. أى نوع أخر من الأجازات أو اليوميات لابد وأن يكون تاريخ البدء أصغر من تاريخ الإنتهاء. السؤال هو : كيف يمكن تحقيق ذلك ؟! أم هو صعب مرفق صغير يحتوى على الجداول الاساسية حتى يتم أخذ النقاط التالية فى الحسبان عند بناء قاعدة البيانات و العمل عليها جدول يحدد تواريخ العطلات الرسمية "tblHolidaysOfficial". جدول يحدد أسماء أيام العطلات الأسبوعية "tblHolidaysWeekly". جدول يحدد انواع اليوميات "tblDailyType". بالنسبه لجدول " tblDailyType" يحتوى على الحقل : IsRecordMultiple بوليانى ليدل على أن اليومية تستوجب أن يتم تسجيلها فى سجل واحد فقط فردى أى لتاريخ واحد فقط أم لعدة تواريخ على عدة سجلات. وأخير الجدول المطلوب تسجيل اليوميات بداخله "tblDailyRecords". توضيح مطلوب عند إدخال أو تحديد تاريخ البدء وتاريخ الإنتهاء يتم التسجيل للبيانات داخل جدول "tblDailyRecords" على أن يكون سجل لكل تاريخ بداية من تاريخ البدء وحتى تاريخ الانتهاء. و طبعا الشروط اللى انا كتبتها تخص لائحة قانونيه حسب قانون العمل المصرى لا اعرف قد يختلف من بلد لأخر ولكن على الأقل ما أعرفه لإضفاء المرونة و عدم التقيد بإستخدام أسماء العطلات الرسمية بشكل مباشر من الكود لذلك طلبت أن يتم الإعتماد على الجدول "tblHolidaysWeekly". و إن أمكن تحقيق ذلك هل يمكن أن أرى طرح أساتذتى و أخوانى الكرام هذا الجزء و بدون منازع هو ثلث إدارة الموارد البشرية للعاملن داخل أى مؤسسة بدون مبالغة و هو صعب مش سهل لان ممكن يتم تسجيل اجازة فى يوم أو فى جلسة عمل و بعد حفظ السجل أو اغلاق وإعادة فتح القاعدة يتم عمل إمتداد لنفس نوع الأجازة و هنا هو التحدى الحقيقى و بوجه خاص مع النوعين ( أجازة إعتيادية / أجازة عارضة ) بسبب اللوائح التى تم ذكرها سابقا فى القواعد السابقة و مرة أخرى لابد من عمل حصر لعدد الاجازات الاعتيادية لكل موظف و التى تساوي أو تتعدي عدد 6 أيام متصلين أى يتخللهم عطلات ( أسبوعيه / رسمية ) و التى قد يتم تسجيلها على أكثر من جلسة عمل أو جلستين عمل أو حتى 6 جلسات عمل وهنا تحدى آخر أه علشان محدش يقول داخل يشغلنا أو داخل يستظرف وبيطلب طلب كبير أو ضخم لأنه متشعب جدا وقد يكون معقد أو هو مش عارف يعنى يعمل اللى بيقوله ده أنا تقريبا بفضل الله تعالى انتهيت من كل ده وفى حيز التجربــة ولكن الموضوع كان تحدى وكان مبنى على أفكارى الضئيلة و المتواضعة وطبعا لأن أفكارى دائما قد تكون معقدة أو لأنه أنا مجرد هاو لذلك أريد أن أرى أفكاركم و أطروحاتكم نظريا و عمليا و مناقشة عندما تستدعى الحاجة إما لأعدل أفكارى أو أكمل ما ينقصنى لا تعنى كلمة تحدى التى استخدمها هو التنافس او تحدى الاشخاص فمن أنا لأتحدث مستخدما هذه العبارات بمعناها الحرفى مع أساتذتى العظماء و أخوانى الكرام ولكن أقصد التحدى فى ترتيب الإفكار والخطوات وتطبيق القيود والتحققات داخل الكود واثناء التسجيل سواء كان التسجيل لليومية فى جلسه عمل واحده أو مع عدة جلسات عمل لنفس نوع اليومية أو أنواع اليوميات التى لها تحققات خاصة لنفس الموظف وأخيرا دمتم بكل حب و طيبتم وبيض الله وجوهكم شروط وقيود لائحة الأجازات.accdb
  9. طيب يا فؤش انا مش عارف انت فاهم واللا انت بتحلب الاجابه علشان تكون كامله هو مش مقصود انى انزل الاجابة ناقصه بقدر ما هو مقصود ان تقتصر القاعدة على الفكرة المحاسبية فقط اه وشئ تانى علشان نقول عاوزين كل شئ يبقى بنتكلم فى برنامج كبير ما هو نقطه هتجر وراها نقطه تانيه مرتبطه بيها وده مش موضوعنا مبدئيا هو مينفعش ومش منطقى ان نفس المنتج فى فاتورة واحده يتكرر يعنى كل ما تيحب تعمل عملية بيع لنفس المنتج للتجربه فى كل مره تضيف سجل جديد لعمل فاتورة جديده يا فؤش أفندى صحصح وركز كده وانا قلت ملاحظة ان القاعدة تعتمد على شئ واحد فقط ضبط الحسابات بطريقة دقيقه ومرنه للحساب لرصد وجرد المبيعات بشكل صحيح نحلل كلامك ده يا فؤش أفندي تحليل كلامك بخصوص (سيناريو الشراء المتعدد بأسعار مختلفة) الدُفعة الكمية سعر الشراء الكمية المباعة الكمية المتبقية 1 24 10 4 20 2 24 12 10 14 3 24 9 0 24 المتبقي بالمخزون: 20 + 14 + 24 = 58 وحدة بثلاث أسعار مختلفة و أنت تتساءل: لما أبيع بعد كده… أبيع بأي سعر؟ هل أبيع بالسعر الأخير (9)؟ ولا الأعلى (12)؟ ولا (10)؟ هنا نرجع لفكرة "طريقة البيع" أو "طريقة صرف المخزون"، وهي شيء مهم جدًا يعتمد عليه النظام: الطرق المدعومة في جدول اعداد طرق البيع "طريقة صرف المخزون" : الطريقة شرح FIFO بيع من الدفعة الأقدم أولًا (10 جنيه أولًا ثم 12 ثم 9) LIFO بيع من الأحدث أولًا (9 جنيه أولًا ثم 12 ثم 10) HighestPrice بيع من الدُفعة الأعلى سعرًا أولًا LatestPrice بيع من أحدث دفعة (حسب التاريخ) وبالتالي: السعر الذي يظهر في الفاتورة عند إدخال الكمية يعتمد على طريقة البيع المختارة من الإعدادات. ما المشكلة اللي حصلت معاك؟ انت قلت : السعر اللي اتحدد في الفاتورة عند الرجوع ليها كان 109! وأن أنت مش متأكد هل هو متوسط ولا إيه... هنا فيه احتمالين: إما فى جدول الاعدادات لطريقة البيع تم اختيار طريقة البيع LatestPrice → وبالتالي تم اختيار أحدث دفعة (وسعرها ممكن يكون 109). أو فيه خطأ منطقي حصل أثناء إعادة تحميل الفاتورة (مثلاً: إعادة الحساب تم بطريقة مختلفة بعد الحفظ) هراجع الكود تانى اما بالنسبه للنقطه دى انا اعتمد فى عملى على المرونه وعلى الدقه بتقليل الاخطاء بقدر المستطاع يبقى النقطه اللى انت بتقولها غير انها هتزود خطوات الا ان المستخدم او الكاشير او البائع ممكن يغلط ليه انا بقه من الاول ما اسدد كل الثغرات اللى ممكن يحدث من ورائها اخطاء مقصودة او غير مقصودة يا فؤش افندى ولو تركت للبائع التحكم يا فؤش افندى ممكن يبيع مره من ده ومره أخرى من ده على المزاج بقه او بالنيه او بحسن وسوء الظن او حسب الغزاله جاى تهزر حضرتك يا افندم طيب انا قدمت فكرة وتطبيق عملى على اساس محاسبى صحيح وفى حالة رغبه صاحب العمل فى تغيير النظام المحاسبى يتم ذلك بدون التدخل فى تعديل الاكواد وفى النهايه اللى حابب ينفذ اى اقتراحات اخرى يمكنه عمل ذلك ما هو أنا مش هأقول لحد لا تنفذ اقتراحاتك التى تلبى رغباتك بكل بساطه تعتمد فكرتى على اختيار النظام المحاسبى لالية البيع من جدول اعداد خاص بذلك تحديد سعر الشراء وسعر البيع للدفعة وتاريخ وارد هذه الدفعه عند شرائها لعدم تدخل البائع فى كتابة السعر لتلافى اى مشكل محاسبية احتساب الكميات اليا وديناميكا بدون تدخل امكانية حساب الربح والخسارة بسهولة جدا جدا جدا بناء على ما سبق ومن واقع جدول الفواتير او التفاصيل وبناء على ما سبق عمل جرد مفصل لكل منتج حتى مع اختلاف اسعار البيع والشراء وتعدد الدفعات و تواريخ شراء الدفعات المختلفة طيب جرب المرفق ده يا فؤش أفندى ملاحظة أخيره الاستعلامات المستخدمه فى الأكواد هى : qryAvailableBatchesByProduct , qryAvailableByProduct أما بقية الاستعلامات مجرد استعلامات خدميه يمكن استخدامها فى : التقارير او فى عمل الجرد أو فى عمل حساب المبيعات والمشتريات لمعرفة هامش الربح أو الخسارة لم أهتم بموضوع ضبط الاكواد فى حالة التعديل على الفاتورة او المرتجعات أنا لست بصدد تقديم برنامج ولا بصدد تطبيق هذه الأفكار أنا فقط موضوعى هو اتمتتة عمليات البيع وفق التحكم بختيار طريقة البيع من جدول الاعدادات وفق الاصول المحاسبية التاليه وذلك على حسب فهمى المتواضع من البحث على الانترنت فى هذه الجزئية لإانا لست محاسب ولا أعلم شيئا عن المحاسبة ولا التكالبف قد أكون مخطئا أو مصيبا لذلك يرجى التأكد من أهل الإختصاص .. انا نصحتك وأنت براحتك علشان متجيش تزعق لى بعد كده FIFO بيع من الدفعة الأقدم أولًا (10 جنيه أولًا ثم 12 ثم 9) LIFO بيع من الأحدث أولًا (9 جنيه أولًا ثم 12 ثم 10) HighestPrice بيع من الدُفعة الأعلى سعرًا أولًا LatestPrice بيع من أحدث دفعة (حسب التاريخ) أتمتة عمليات البيع بكل الطرق (V 1.2).accdb
  10. مشاركة مع اساتذتى الكرام واحبابى اقدم اليكم هذه المشاركة اثراء للمضوع و تعمدت كتابة موضوع خاص بها ليكون مرجعا للباحثين والدارسين وفق رؤيتى المتواضعه وأفكارى البسيطه فكرتى تعتمد على اختيار النظام المحاسبى لالية البيع من جدول اعداد خاص بذلك تحديد سعر الشراء وسعر البيع للدفعة وتاريخ وارد هذه الدفعه عند شرائها لعدم تدخل البائع فى كتابة السعر لتلافى اى مشكل محاسبية احتساب الكميات اليا وديناميكا بدون تدخل امكانية حساب الربح والخسارة بسهولة جدا جدا جدا بناء على ما سبق ومن واقع جدول الفواتير او التفاصيل وبناء على ما سبق عمل جرد مفصل لكل منتج حتى مع اختلاف اسعار البيع والشراء وتعدد الدفعات وتواريخ شراء الدفعات
  11. السلام عليكم ورحمة الله تعالى وبركاته سوف اقدم لكم اليوم ان شاء الله تعالى فكرة أتمتة عمليات البيع بكل الطرق (FIFO , LIFO , HighestPrice , LatestPrice) ولكن أولا مقدمه بشكل نظرى عن هذه العبارة لتوضيح هذه المصطلحات هى تعنى أن النظام أو البرنامج يقوم بشكل آلي (تلقائي) باختيار الكمية المناسبة من المخزون عند تنفيذ عملية البيع، بناءً على طريقة معينة وذلك لتحديد أي دفعة (Batch) من المخزون سيتم السحب منها. هذه الطرق هي ما تُعرف بـ "سياسات تقييم المخزون أو صرف المخزون"، وشرحها كالتالي: FIFO (First In, First Out - الوارد أولاً يصرف أولاً) تعني أن النظام سيبدأ في بيع الكميات من أول دفعة تم شراؤها أو إدخالها للمخزون تخصم الكميات التي تُباع أولاً من أول دفعة تم شرائها. تستخدم غالبًا في المنتجات القابلة للتلف (مثل الطعام أو الدواء). مثال: اشتريت 100 وحدة بـ10 جنيه، ثم 100 وحدة بـ12 جنيه. عند بيع 50 وحدة، سيتم بيعهم من الدفعة الأولى (10 جنيه). LIFO (Last In, First Out - الوارد أخيراً يصرف أولاً) تعني أن النظام سيبدأ في بيع الكميات من آخر دفعة تم شراؤها تخصم الكميات التي تُباع أولاً من آخر دفعة تم شرائها. تُستخدم في بعض الأنظمة المحاسبية عند توقع ارتفاع الأسعار. مثال: نفس المثال السابق. عند بيع 50 وحدة، سيتم بيعهم من الدفعة الثانية (12 جنيه). HighestPrice (أعلى سعر أولاً) يعني أن النظام سيبدأ في بيع الكميات من الدُفَع ذات السعر الأعلى تخصم الكميات التي تُباع أولاً من الدفع ذات السعر الأعلى. مفيد في حالات تحسين الربحية أو تقليل الخسائر تُستخدم في حالات معينة عند الرغبة في التخلص من البضاعة ذات التكلفة الأعلى لتقليل الخسائر أو تقليل التكاليف المخزنية المرتفعة. مثال: عندك 3 دفعات بأسعار 10، 12، 15. النظام يبدأ البيع من الدفعة بسعر 15. LatestPrice (أحدث دفعة أولاً) المقصود هنا بيع الكمية من أحدث تاريخ شراء تخصم الكميات التي تُباع أولاً من الدفع ذات تاريخ الشراء الأحدث. يختلف عن LIFO بإنه يعتمد على تاريخ الشراء وليس ترتيب الإدخال. مفيد عندما تكون تواريخ الشراء غير مرتبة أو النظام يسمح بإدخال متأخر. التطبيق يعتمد على التالى جدول يحتوي على إعدادات طريقة البيع : tblSalesSettings المفروض الجدول يحتوى على سجل واحد فقط ويتم تحديد طريقة البيع حسب الرغبة او حسب النظام المحاسبى المتبع جدول المنتجات : tblProducts - يحتوي على بيانات المنتجات الأساسية. جدول الواردات : tblPurchaseBatches - يتبع كل دفعة شراء لمنتج معين. جدول لتسجيل عمليات الارتجاع : tblReturns - يتبع كل عمليات الإرتجاع بعد إتمام عملية شراء لمنتج معين. جدول تفاصيل كميات المبيعات حسب الدفعات : tblSaleBatchDetails- يتبع كل دفعة بيع لمنتج معين حسب الكمية وتبعا لمعرف الدغعات. جدول تفاصيل المبيعات : tblSaleDetails - يتبع كل المنتجات التى يتم بيعها داخل الفاتورة. جدول المبيعات : tblSales - يحتوي على إجمالي كل فاتورة. وأخيرا المرفق للتجربــــــــــــة ملاحظة لم أهتم بأى تفاصيل لا للحذف أو للارتجاع لانها لن يكون لها أى تأثير يذكر لأن الكميات يتم حسابها بناء على معرف الدفعات بشكل ديناميكى حسب المبيعات و بناء على الواردات للدفعات ما تم الاهتمام به فقط هو التعامل مع طرق البيع المختلفة لاصدار الفواتير او صرف الكميات حسب الطرق المحاسبية بشكل صحيح ومرن وبناء عليه حصر الكميات المتبقية يعنى ببساطه بيع وجرد فى نفس الوقت على اساس محاسبى صحيح بمرونة وفاعليه نسيت توضيح شئ مهم : مثلا يوجد وارد لمنتج بأكثر من دفعه ولكل دفعه سعر بيع وسعر شراء طيب لنفترض ان الدفعه 1 للمنتج 101 عدد الكميات لها 5 الدفعه 2 للمنتج 101 عدد الكميات لها 10 اذا اجمال الكميات هو 15 طيب عند اصدار الفاتورة مع الاختيار : FIFO من جدول اعدادت طرق البيع لنفترض اننا نريد بيع 8 قطع من ها المنتج فى هذه الحاله يتم عمل التالى صرف 5 من الدفعه 1 وصرف 3 من الدفعه 2 طيب سعر بيع الدفعه الاولى لو 120 وسعر بيع الدفعه الثانيه 130 يكون ( 5*120 ) + ( 3 * 130 ) = 600 + 390 = يكون الناتج 990 وفى هذه الحاله لا يتم كتابة سعر للوحده فى الفاتورة بل يتم حساب المتوسط أتمتة عمليات البيع بكل الطرق .accdb
  12. مشاركة مع اساتذتى الكرام واحبابى اليك هذه الاكواد Public Function CalculateTimeDifference(startDate As Variant, endDate As Variant) As String On Error GoTo ErrorHandler Dim totalSeconds As Double Dim days As Long Dim hours As Long Dim minutes As Long Dim seconds As Long ' التحقق من أن التاريخين ليسا فارغين وهما صالحان If IsNull(startDate) Or IsNull(endDate) Then CalculateTimeDifference = "أحد التواريخ فارغ" Exit Function ElseIf Not IsDate(startDate) Or Not IsDate(endDate) Then CalculateTimeDifference = "أحد التواريخ غير صالح" Exit Function End If ' تحويل التاريخين إلى نوع Date Dim start As Date Dim endD As Date start = CDate(startDate) endD = CDate(endDate) ' حساب الفرق بالثواني totalSeconds = DateDiff("s", start, endD) ' التحقق من القيمة السالبة If totalSeconds < 0 Then CalculateTimeDifference = "تاريخ النهاية يجب أن يكون بعد تاريخ البداية" Exit Function End If ' تحويل الثواني إلى أيام days = Int(totalSeconds / 86400) ' 86400 = عدد ثواني اليوم totalSeconds = totalSeconds - (days * 86400) ' تحويل الثواني إلى ساعات hours = Int(totalSeconds / 3600) ' 3600 = عدد ثواني الساعة totalSeconds = totalSeconds - (hours * 3600) ' تحويل الثواني إلى دقائق minutes = Int(totalSeconds / 60) ' الثواني المتبقية seconds = totalSeconds - (minutes * 60) ' إرجاع النتيجة كنص CalculateTimeDifference = days & " أيام, " & hours & " ساعات, " & minutes & " دقائق, " & seconds & " ثواني" Exit Function ErrorHandler: CalculateTimeDifference = "حدث خطأ: " & Err.Description End Function Public Function CalculateTimeParts(startDate As Variant, endDate As Variant, part As String) As Long On Error GoTo ErrorHandler Dim years As Long Dim months As Long Dim days As Long Dim hours As Long Dim minutes As Long Dim seconds As Long Dim tempDate As Date ' التحقق من أن التاريخين ليسا فارغين If IsNull(startDate) Or IsNull(endDate) Then CalculateTimeParts = 0 Exit Function End If ' التحقق من ترتيب التواريخ If startDate > endDate Then CalculateTimeParts = 0 Exit Function End If ' البدء بحساب الفرقات الزمنية tempDate = startDate ' حساب الفرق في السنوات years = DateDiff("yyyy", tempDate, endDate) tempDate = DateAdd("yyyy", years, tempDate) ' حساب الفرق في الأشهر months = DateDiff("m", tempDate, endDate) tempDate = DateAdd("m", months, tempDate) ' التأكد من عدم وجود قيم سالبة بعد التعديلات If tempDate > endDate Then months = months - 1 tempDate = DateAdd("m", -1, tempDate) End If ' حساب الفرق في الأيام days = DateDiff("d", tempDate, endDate) tempDate = DateAdd("d", days, tempDate) ' حساب الفرق في الساعات hours = DateDiff("h", tempDate, endDate) tempDate = DateAdd("h", hours, tempDate) ' حساب الفرق في الدقائق minutes = DateDiff("n", tempDate, endDate) tempDate = DateAdd("n", minutes, tempDate) ' حساب الفرق في الثواني seconds = DateDiff("s", tempDate, endDate) ' التأكد من عدم وجود قيم سالبة نهائياً If months < 0 Then months = 0 If days < 0 Then days = 0 If hours < 0 Then hours = 0 If minutes < 0 Then minutes = 0 If seconds < 0 Then seconds = 0 ' إرجاع الجزء المطلوب Select Case part Case "Years": CalculateTimeParts = years Case "Months": CalculateTimeParts = months Case "Days": CalculateTimeParts = days Case "Hours": CalculateTimeParts = hours Case "Minutes": CalculateTimeParts = minutes Case "Seconds": CalculateTimeParts = seconds Case Else: CalculateTimeParts = 0 End Select Exit Function ErrorHandler: CalculateTimeParts = 0 End Function الاستعلام الاول والمعتمد على الإجراء : CalculateTimeDifference SELECT Tbl_IN_OUT.ID, Tbl_IN_OUT.Nname, Tbl_IN_OUT.Start_Day, Tbl_IN_OUT.End_Day, CalculateTimeDifference([Start_Day], [End_Day]) AS Sub_Time FROM Tbl_IN_OUT; الاستعلام الثانى والمعتمد على الإجراء : CalculateTimeParts SELECT Tbl_IN_OUT.ID, Tbl_IN_OUT.Nname, Tbl_IN_OUT.Start_Day, Tbl_IN_OUT.End_Day, CalculateTimeParts([Start_Day], [End_Day], "Years") AS Years_Diff, CalculateTimeParts([Start_Day], [End_Day], "Months") AS Months_Diff, CalculateTimeParts([Start_Day], [End_Day], "Days") AS Days_Diff, CalculateTimeParts([Start_Day], [End_Day], "Hours") AS Hours_Diff, CalculateTimeParts([Start_Day], [End_Day], "Minutes") AS Minutes_Diff, CalculateTimeParts([Start_Day], [End_Day], "Seconds") AS Seconds_Diff FROM Tbl_IN_OUT;
  13. الكلام مش مفهوم وبصراحة قواعد البيانات اللى بتكوووووون زحمه زياده عن الللازم ما باحاول حتى افتحها لانها هتعمل لى صداع وانا معنديش استعداد ولا وقت للتحليل وسط هذا الزحام الشديد وانا نوهت ووضحت هذه النقطه من قبل
  14. انت صح وانا بس خليت الكود اكثر مرونه ليعمل مع كل انواع الحقول نص او رقم او تاريخ
  15. استبدل كود الموديول بالكود التالى Public Function Horizontal(tabelle As String, Feld1 As String, Feld2 As String, valFeld1 As Variant) As String Dim DB As DAO.Database Dim rs As DAO.Recordset Dim fieldType As Integer Dim sqlWhere As String Dim first As Boolean ' تعيين قاعدة البيانات الحالية Set DB = CurrentDb ' استرجاع نوع الحقل Feld1 fieldType = DB.TableDefs(tabelle).Fields(Feld1).Type ' تنسيق القيمة بناءً على نوع الحقل Select Case fieldType Case dbText, dbMemo, dbChar ' النصوص: وضع القيمة بين علامات اقتباس مفردة مع معالجة علامات الاقتباس الداخلية sqlWhere = "[" & Feld1 & "]='" & Replace(valFeld1, "'", "''") & "'" Case dbDate, dbTime, dbTimeStamp ' التواريخ: وضع القيمة بين علامات # مع تنسيق التاريخ sqlWhere = "[" & Feld1 & "]=#" & Format(valFeld1, "yyyy-mm-dd hh:nn:ss") & "#" Case dbInteger, dbLong, dbSingle, dbDouble, dbCurrency, dbDecimal ' الأرقام: إدراج القيمة مباشرة sqlWhere = "[" & Feld1 & "]=" & valFeld1 Case Else ' معالجة الأنواع غير المدعومة MsgBox "نوع البيانات غير مدعوم للحقل: " & Feld1, vbExclamation Exit Function End Select ' إنشاء وتنفيذ استعلام SQL Set rs = DB.OpenRecordset("SELECT DISTINCT [" & Feld2 & "] FROM [" & tabelle & "] WHERE " & sqlWhere & " ORDER BY [" & Feld2 & "] DESC") ' تهيئة متغير للسجل الأول first = True ' معالجة السجلات المسترجعة Do While Not rs.EOF If first Then Horizontal = rs(Feld2) ' القيمة الأولى first = False Else Horizontal = Horizontal & vbCrLf & rs(Feld2) ' إضافة القيم التالية مع فاصل سطر End If rs.MoveNext Loop ' تحرير الموارد rs.Close Set rs = Nothing Set DB = Nothing End Function
  16. شوف يا فؤش خطر بالى كتابة الكود بالشكل التالى فى وحده نمطية عامة ' تعداد لتحديد نوع العنصر Public Enum fileType ftAccessDB = 1 ' قاعدة بيانات Access ftExcel = 2 ' ملف Excel ftWord = 3 ' ملف Word ftText = 4 ' ملف نصي ftFolder = 5 ' مجلد ftDrive = 6 ' قسم (Drive) ftAnyFile = 7 ' أي ملف End Enum ' تعداد لتحديد نوع المعلومات المطلوبة Public Enum infoType itPathOnly = 1 ' جلب المسار فقط itSizeOnly = 2 ' جلب الحجم فقط itPathAndSize = 3 ' جلب المسار والحجم itFileNameOnly = 4 ' جلب اسم الملف فقط itFileExtension = 5 ' جلب امتداد الملف فقط itFileNameAndExt = 6 ' جلب اسم الملف مع الامتداد itCreationDate = 7 ' جلب تاريخ الإنشاء itModifiedDate = 8 ' جلب تاريخ التعديل itFileCount = 9 ' جلب عدد الملفات (لمجلد) itFreeSpace = 10 ' جلب المساحة الحرة (لقسم) itTotalSpace = 11 ' جلب المساحة الإجمالية (لقسم) itDriveType = 12 ' جلب نوع القسم itParentPath = 13 ' جلب المسار الأصلي End Enum ' تعداد لتحديد الامتدادات Public Enum FileExtension feAccessDB = 1 ' *.accdb;*.mdb feExcel = 2 ' *.xlsx;*.xls feWord = 3 ' *.docx;*.doc feText = 4 ' *.txt feAnyFile = 7 ' *.* End Enum ' دالة مساعدة للحصول على وصف وامتداد بناءً على FileType Private Function GetFileFilter(fileType As fileType) As Variant Dim description As String Dim extension As String Select Case fileType Case ftAccessDB description = "قواعد بيانات Access" extension = "*.accdb;*.mdb" Case ftExcel description = "ملفات Excel" extension = "*.xlsx;*.xls" Case ftWord description = "ملفات Word" extension = "*.docx;*.doc" Case ftText description = "ملفات نصية" extension = "*.txt" Case ftAnyFile description = "كل الملفات" extension = "*.*" Case Else description = vbNullString extension = vbNullString End Select GetFileFilter = Array(description, extension) End Function ' دالة رئيسية للحصول على معلومات العنصر Public Function GetFileInfo(Optional inputPath As String = vbNullString, _ Optional txtPath As TextBox = Nothing, _ Optional txtSize As TextBox = Nothing, _ Optional txtName As TextBox = Nothing, _ Optional txtExt As TextBox = Nothing, _ Optional txtExtra As TextBox = Nothing, _ Optional fileType As fileType = ftAccessDB, _ Optional infoType As infoType = itPathAndSize, _ Optional decimalPlaces As Integer = 2) As String On Error GoTo ErrorHandler Dim fso As Object Dim shellApp As Object Dim dbPath As String Dim totalSize As Double Dim fileName As String Dim fileExt As String Dim formatStr As String ' إعداد تنسيق الحجم formatStr = "0." & String(decimalPlaces, "0") ' إنشاء كائن FileSystemObject Set fso = CreateObject("Scripting.FileSystemObject") ' التحقق من المسار المدخل مباشرة فقط If Len(Trim(inputPath)) > 0 Then dbPath = inputPath Else ' إذا لم يتم تمرير inputPath، افتح المستعرض دائمًا Set shellApp = CreateObject("Shell.Application") Select Case fileType Case ftFolder Dim folder As Object Set folder = shellApp.BrowseForFolder(0, "اختر مجلدًا", 0) If Not folder Is Nothing Then dbPath = folder.Self.path Else GetFileInfo = "لم يتم اختيار مجلد" Exit Function End If Case ftDrive Dim driveFolder As Object Set driveFolder = shellApp.BrowseForFolder(0, "اختر قسمًا", 0, 17) ' 17 = ssfDRIVES If Not driveFolder Is Nothing Then dbPath = driveFolder.Self.path If Right(dbPath, 1) <> "\" Then dbPath = dbPath & "\" Else GetFileInfo = "لم يتم اختيار قسم" Exit Function End If Case Else ' ملفات Dim fd As Object Set fd = Application.fileDialog(3) ' 3 = msoFileDialogFilePicker With fd .Title = "اختر ملفًا" .Filters.Clear Dim filter As Variant filter = GetFileFilter(fileType) If Len(filter(0)) > 0 Then .Filters.Add filter(0), filter(1) End If .AllowMultiSelect = False If .Show = -1 Then dbPath = .SelectedItems(1) Else GetFileInfo = "لم يتم اختيار ملف" Exit Function End If End With End Select End If ' التحقق من وجود العنصر If Not fso.FileExists(dbPath) And Not fso.FolderExists(dbPath) And Not fso.DriveExists(dbPath) Then GetFileInfo = "العنصر غير موجود" Exit Function End If ' استخراج المعلومات بناءً على infoType Select Case infoType Case itPathOnly If Not txtPath Is Nothing Then txtPath.Value = dbPath GetFileInfo = dbPath Case itSizeOnly totalSize = GetSize(fso, dbPath, fileType) Dim sizeStr As String sizeStr = FormatSize(totalSize, formatStr) If Not txtSize Is Nothing Then txtSize.Value = sizeStr GetFileInfo = sizeStr Case itPathAndSize totalSize = GetSize(fso, dbPath, fileType) sizeStr = FormatSize(totalSize, formatStr) If Not txtPath Is Nothing Then txtPath.Value = dbPath If Not txtSize Is Nothing Then txtSize.Value = sizeStr GetFileInfo = dbPath & " - " & sizeStr Case itFileNameOnly If fso.FileExists(dbPath) Then fileName = fso.GetBaseName(dbPath) If Not txtName Is Nothing Then txtName.Value = fileName GetFileInfo = fileName Else GetFileInfo = "المسار ليس ملفًا" End If Case itFileExtension If fso.FileExists(dbPath) Then fileExt = fso.GetExtensionName(dbPath) If Not txtExt Is Nothing Then txtExt.Value = fileExt GetFileInfo = fileExt Else GetFileInfo = "المسار ليس ملفًا" End If Case itFileNameAndExt If fso.FileExists(dbPath) Then fileName = fso.GetFileName(dbPath) If Not txtName Is Nothing Then txtName.Value = fileName GetFileInfo = fileName Else GetFileInfo = "المسار ليس ملفًا" End If Case itCreationDate If fso.FileExists(dbPath) Then GetFileInfo = fso.GetFile(dbPath).DateCreated ElseIf fso.FolderExists(dbPath) Then GetFileInfo = fso.GetFolder(dbPath).DateCreated ElseIf fso.DriveExists(dbPath) Then GetFileInfo = "غير متاح للأقسام" End If If Not txtExtra Is Nothing Then txtExtra.Value = GetFileInfo Case itModifiedDate If fso.FileExists(dbPath) Then GetFileInfo = fso.GetFile(dbPath).DateLastModified ElseIf fso.FolderExists(dbPath) Then GetFileInfo = fso.GetFolder(dbPath).DateLastModified ElseIf fso.DriveExists(dbPath) Then GetFileInfo = "غير متاح للأقسام" End If If Not txtExtra Is Nothing Then txtExtra.Value = GetFileInfo Case itFileCount If fso.FolderExists(dbPath) Then GetFileInfo = CStr(fso.GetFolder(dbPath).files.Count) If Not txtExtra Is Nothing Then txtExtra.Value = GetFileInfo Else GetFileInfo = "المسار ليس مجلدًا" End If Case itFreeSpace If fso.DriveExists(dbPath) Then totalSize = fso.GetDrive(fso.GetDriveName(dbPath)).FreeSpace sizeStr = FormatSize(totalSize, formatStr) If Not txtSize Is Nothing Then txtSize.Value = sizeStr GetFileInfo = sizeStr Else GetFileInfo = "المسار ليس قسمًا" End If Case itTotalSpace If fso.DriveExists(dbPath) Then totalSize = fso.GetDrive(fso.GetDriveName(dbPath)).totalSize sizeStr = FormatSize(totalSize, formatStr) If Not txtSize Is Nothing Then txtSize.Value = sizeStr GetFileInfo = sizeStr Else GetFileInfo = "المسار ليس قسمًا" End If Case itDriveType If fso.DriveExists(dbPath) Then Select Case fso.GetDrive(fso.GetDriveName(dbPath)).FileSystem Case "FAT", "FAT32", "NTFS", "exFAT" GetFileInfo = fso.GetDrive(fso.GetDriveName(dbPath)).FileSystem Case Else GetFileInfo = "غير معروف" End Select If Not txtExtra Is Nothing Then txtExtra.Value = GetFileInfo Else GetFileInfo = "المسار ليس قسمًا" End If Case itParentPath If fso.FileExists(dbPath) Then GetFileInfo = fso.GetParentFolderName(dbPath) ElseIf fso.FolderExists(dbPath) Then GetFileInfo = fso.GetParentFolderName(dbPath) ElseIf fso.DriveExists(dbPath) Then GetFileInfo = "لا يوجد مسار أصلي للقسم" End If If Not txtPath Is Nothing Then txtPath.Value = GetFileInfo End Select Exit Function ErrorHandler: GetFileInfo = "حدث خطأ (" & Err.Number & "): " & Err.description If Not fso Is Nothing Then Set fso = Nothing If Not shellApp Is Nothing Then Set shellApp = Nothing End Function ' دالة مساعدة لحساب الحجم Private Function GetSize(fso As Object, path As String, fileType As fileType) As Double Select Case fileType Case ftAccessDB, ftExcel, ftWord, ftText, ftAnyFile If fso.FileExists(path) Then GetSize = fso.GetFile(path).size End If Case ftFolder If fso.FolderExists(path) Then GetSize = GetFolderSize(fso.GetFolder(path)) End If Case ftDrive If fso.DriveExists(path) Then With fso.GetDrive(fso.GetDriveName(path)) GetSize = .totalSize - .FreeSpace End With End If End Select End Function ' دالة مساعدة لتنسيق الحجم Private Function FormatSize(size As Double, formatStr As String) As String If size < 1024 Then FormatSize = Format(size, formatStr) & " بايت" ElseIf size < 1024 ^ 2 Then FormatSize = Format(size / 1024, formatStr) & " كيلوبايت" ElseIf size < 1024 ^ 3 Then FormatSize = Format(size / (1024 ^ 2), formatStr) & " ميجابايت" Else FormatSize = Format(size / (1024 ^ 3), formatStr) & " جيجابايت" End If End Function ' دالة مساعدة لحساب حجم المجلد Private Function GetFolderSize(fld As Object) As Double On Error Resume Next Dim subFld As Object Dim file As Object Dim totalSize As Double For Each file In fld.files totalSize = totalSize + file.size Next file For Each subFld In fld.SubFolders totalSize = totalSize + GetFolderSize(subFld) Next subFld GetFolderSize = totalSize End Function
  17. طيب لاحظت عند النقر على زر الامر الخاص باختيار قاعدة البيانات انه يتم فتح مستعرض الملفات مرتين واختيار القاعدة مرتين مش غريبه دى
  18. اسف لم انتبه لوجود كلمة مستمر وللاسف حسب فهمى لا يمكن عمل ذلك مع النماذج المستمرة والله اعلم
  19. رائع جدا جدا الحل السابق فى ابسط صوره الحل التالى اكثر تقدما المميزات تعداد للالوان يمكن اضافة الالوان التى تريدها مستقبلا تعداد للخصائص يمكن اضافة الخصائص التى تريدها " خلفية مربع النص , او لون الخط المستخدم " كود الوحده النمطيه Option Compare Database Option Explicit Public Enum FlashColors FlashWhite = 16777215 ' الأبيض - White (vbWhite) FlashBlack = 0 ' الأسود - Black (vbBlack) FlashRed = 255 ' الأحمر - Red (vbRed) FlashGreen = 65280 ' الأخضر - Green (vbGreen) FlashBlue = 16711680 ' الأزرق - Blue (vbBlue) FlashYellow = 65535 ' الأصفر - Yellow (vbYellow) FlashMagenta = 16711935 ' الماجنتا - Magenta (vbMagenta) FlashCyan = 16776960 ' السماوي - Cyan (vbCyan) FlashOrange = 42495 ' البرتقالي - Orange (RGB: 255, 165, 0) FlashPurple = 8388736 ' البنفسجي - Purple (RGB: 128, 0, 128) FlashPink = 13353215 ' الوردي - Pink (RGB: 255, 192, 203) FlashLime = 65280 ' الليموني - Lime (RGB: 0, 255, 0) FlashTeal = 32896 ' البترولي - Teal (RGB: 0, 128, 128) FlashViolet = 15631086 ' الفيوليت - Violet (RGB: 238, 130, 238) FlashBrown = 2763429 ' البني - Brown (RGB: 165, 42, 42) FlashGold = 55295 ' الذهبي - Gold (RGB: 255, 215, 0) FlashSilver = 12632256 ' الفضي - Silver (RGB: 192, 192, 192) FlashGray = 8421504 ' الرمادي - Gray (RGB: 128, 128, 128) FlashDarkRed = 139 ' الأحمر الداكن - Dark Red (RGB: 139, 0, 0) FlashDarkGreen = 25600 ' الأخضر الداكن - Dark Green (RGB: 0, 100, 0) FlashDarkBlue = 9109504 ' الأزرق الداكن - Dark Blue (RGB: 0, 0, 139) FlashOlive = 32896 ' الزيتوني - Olive (RGB: 128, 128, 0) FlashMaroon = 128 ' المارون - Maroon (RGB: 128, 0, 0) FlashNavy = 8388608 ' الكحلي - Navy (RGB: 0, 0, 128) FlashTurquoise = 13757312 ' التركواز - Turquoise (RGB: 64, 224, 208) FlashIndigo = 8519755 ' النيلي - Indigo (RGB: 75, 0, 130) FlashCoral = 5275647 ' المرجاني - Coral (RGB: 255, 127, 80) FlashSalmon = 7504122 ' السلموني - Salmon (RGB: 250, 128, 114) FlashBeige = 14480885 ' البيج - Beige (RGB: 245, 245, 220) FlashLavender = 16443110 ' الخزامى - Lavender (RGB: 230, 230, 250) End Enum ' تعداد لتحديد نوع الوميض: لون النص أو لون الخلفية Public Enum flashType FlashForeColor = 0 ' الوميض على لون النص - ForeColor FlashBackColor = 1 ' الوميض على لون الخلفية - BackColor End Enum ' دالة لجعل مربع النص يومض بلونين محددين بناءً على شرط معين ' txtBox: مربع النص الذي سيتم تطبيق الوميض عليه ' condition: الشرط الذي يحدد ما إذا كان الوميض سيتم تفعيله أم لا ' color1: اللون الأول للوميض (اختياري، الافتراضي هو FlashYellow) ' color2: اللون الثاني للوميض (اختياري، الافتراضي هو FlashRed) ' flashType: نوع الوميض (لون النص أو الخلفية، اختياري، الافتراضي هو FlashForeColor) Public Sub FlashTextBox(txtBox As TextBox, condition As Boolean, Optional color1 As FlashColors = FlashYellow, Optional color2 As FlashColors = FlashRed, Optional flashType As flashType = FlashForeColor) ' متغير ثابت لتتبع حالة الوميض (يتغير بين True وFalse) Static isFlashing As Boolean ' التحقق من تحقق الشرط If condition Then ' تحديد ما إذا كان الوميض سيطبق على لون النص أو الخلفية بناءً على flashType If flashType = FlashForeColor Then ' الوميض على لون النص If isFlashing Then txtBox.ForeColor = color1 ' تعيين اللون الأول للنص Else txtBox.ForeColor = color2 ' تعيين اللون الثاني للنص End If Else ' الوميض على لون الخلفية If isFlashing Then txtBox.BackColor = color1 ' تعيين اللون الأول للخلفية Else txtBox.BackColor = color2 ' تعيين اللون الثاني للخلفية End If End If ' عكس حالة الوميض للتبديل في المرة القادمة isFlashing = Not isFlashing ' تحديث الشاشة لعرض التغيير فوراً Application.Echo True Else ' إذا لم يتحقق الشرط، إعادة الإعدادات إلى الافتراضية If flashType = FlashForeColor Then txtBox.ForeColor = FlashBlack ' لون النص الأسود كافتراضي Else txtBox.BackColor = FlashWhite ' لون الخلفية الأبيض كافتراضي End If End If End Sub الاستدعاء ' استدعاء الدالة العامة للوميض ' txtValue هو اسم مربع النص الذي يحتوي على القيمة (مثل 5) ' txtFlash هو اسم مربع النص الذي سيمضي FlashTextBox Me.txtFlash, (Me.txtValue = "5"), FlashGold, FlashBlue ------------------------------------------------------- أو لتغير خلفية مربع النص FlashTextBox Me.txtFlash, (Me.txtValue = "5"), FlashMagenta, FlashWhite, FlashBackColor ------------------------------------------------------- أو لتغير لون الخط وهو الافتراضى كما بالكود FlashTextBox Me.txtFlash, (Me.txtValue = "5"), FlashMagenta, FlashWhite أو FlashTextBox Me.txtFlash, (Me.txtValue = "5"), FlashMagenta, FlashWhite, FlashForeColor
  20. اتفضل يا سيدى كود الوحده النمطيه Public Sub FlashTextBox(txtBox As TextBox, condition As Boolean, Optional color1 As Long = vbYellow, Optional color2 As Long = vbRed) ' تعريف متغير للتحكم في الوميض Static isFlashing As Boolean If condition Then ' إذا تحقق الشرط (القيمة = 5)، يتم الوميض بين اللونين If isFlashing Then txtBox.BackColor = color1 ' اللون الأول (الأصفر افتراضيًا) Else txtBox.BackColor = color2 ' اللون الثاني (الأحمر افتراضيًا) End If isFlashing = Not isFlashing ' إعادة تشغيل المؤقت لاستمرار الوميض Application.Echo True Else ' إذا لم يتحقق الشرط، يظل النص ثابتًا بلون افتراضي txtBox.BackColor = vbWhite ' اللون الافتراضي End If End Sub كود الاستدعاء داخل النموذج Private Sub Form_Current() ' استدعاء الدالة العامة للوميض ' txtValue هو اسم مربع النص الذي يحتوي على القيمة (مثل 5) ' txtFlash هو اسم مربع النص الذي سيمضي FlashTextBox Me.txtFlash, (Me.txtValue = "5"), vbYellow, vbRed End Sub Private Sub Form_Timer() ' استدعاء الدالة العامة مرة أخرى لتحديث الوميض FlashTextBox Me.txtFlash, (Me.txtValue = "5"), vbYellow, vbRed End Sub يمكن تغيير الالوان كما تريد مثلا مثل Private Sub Form_Current() ' استدعاء الدالة العامة للوميض ' txtValue هو اسم مربع النص الذي يحتوي على القيمة (مثل 5) ' txtFlash هو اسم مربع النص الذي سيمضي FlashTextBox Me.txtFlash, (Me.txtValue = "5"), vbGreen, vbBlue End Sub Private Sub Form_Timer() ' استدعاء الدالة العامة مرة أخرى لتحديث الوميض FlashTextBox Me.txtFlash, (Me.txtValue = "5"), vbGreen, vbBlue End Sub او FlashTextBox Me.txtFlash, (Me.txtValue = "5") او FlashTextBox Me.txtFlash, (Me.txtValue = "5"), RGB(0, 255, 0), RGB(0, 0, 255) طبعا مع ضبط سرعة عداد الوقت كما يناسب رغباتك يا افندم طبعا انا خليتك تمرر القيمه مع الاستدعاء للمرونه علشان تنفع مع اى قيم كمان وميض (1).accdb
  21. اضف بيانات حتى وان كانت وهميه مع الاستعلام المناسب لبياناتك والذى سوف يكون مصدر للتقرير حتى نتمكن من مساعدتك انت لم تقدم اى شئ واى اجابه لن تصلح مع هذا الغمووووووووووض طالما تبخل على نفسك بتقديم البيانات اللازمة لن تجد الا التجاهل للاسف بسبب عدم الفهم انا عن نفسي مش فاهم اى شئ
  22. طيب اليكم المرفق الاخيـــــــــــــــــــر المميزات : الاعتماد الكامل على الرقم القومى دوال منفصلة لسهولة استدعائها فى استعلام من خلال الرقم القومى يتم استخراج الجنس/النوع استخراج مكان الميلاد استخراج تاريخ الميلاد حساب العمر بالسنوات حساب العمر بالأشهر حساب العمر بالأيام بناء على حقل تاريخ الميلاد المستخرج من الرقم القومى يتم عمل التالى حساب تاريخ التقاعد حساب سن التقاعد السنوات المتبقيه للتقاعد الاشهر المتبقيه للتقاعد الايام المتبقيه للتقاعد افتح الاستعلام فى القاعده والذى يحمل الاسم : qryAllInfoFromNationalID المرونة المطلقه فقط عند نقل الوحدات النمطية الى اى قاعدة بيانات عمل استعلام وفقط تغير اسم الحقل الخاص بالرقم القومى تبعا للمسمى الموجود فى الجدول الخاص بكم والملون هنا باللون الاحمر BirthDateFromNationalID: GetBirthDateFromNationalID([Emp_NationalID]) وباقى حقول الاستعلام جميعا تعتمد على هذا الحقل لذلك يتم نقلها كما هى ولكن ولكن ولكن لا تغير اسم الحقل : BirthDateFromNationalID لان هذا الاسم تعتمد باقى وكل الحقول الاخرى عليه اعتقد بهذا المرفق يكون الموضوع قتل بحثا وتم عمل كل ما يمكن فيه ويمكن وبكل سهولة ومرونة الان استخدام الحقول المناسبه حسب الحاجه داخل التقارير او النماذج بكل بساطه تم اضافة : نموذج : frmAllInfoFromNationalID تقريــر : rptAllInfoFromNationalID مصدر بيانات كل منهما الاستعلام : qryAllInfoFromNationalID اما النموذج : frmEmployees مصدر بياناته هو الجدول مباشرة الان القاعده كاملة و متكاملة مع تحقيق أقصى درجات المرونه المطلقة والحصول على كل البيانات الممكنه من خلال الرقم القومى مباشره سن التقاعد (8).accdb
×
×
  • اضف...

Important Information