jjafferr قام بنشر الثلاثاء at 08:23 قام بنشر الثلاثاء at 08:23 السلام عليكم بالاشارة الى الموضوع التالي ، والطرق التي تمت الاشارة اليها : في المشاريع اللي احتاج لها اعدادات ، كنت استعمل جدول بسطر واحد ، ولكن في احد مشاريعي ، هذه الاعدادات وصلت الى 21 ولا تزال في زيادة ، فعملت تغيير في الجدول ، واصبح هناك سجل خاص لكل واحدة من الاعدادات: . . وهذا شكل النموذج المستمر للمستخدم: . وبياناته : . ونعرف انه في النموذج المستمر ، لا نستطيع التحكم بشكل حقل دون آخر (إلا عن طريق التنسيق الشرطي ، وعن طريق كود خاص يخص مربع الزر Command button) ، لذلك كان من المهم ان اكتب عبارة معين في اسم الحقل حتى اميزه عن الآخرين (او ان اعمل حقل اكتب فيه طريقة التعامل مع هذا السجل (استفيد منه في التنسيق الشرطي مثلا)) ، لذا نرى ان زر (command button) جميع الحقول التي بحاجة الى اختيار مجلد لها ، بدأ اسم الحقل بالكلمة Path (طبعا هذا مثال) ، وعليه استطعت ان اخفي الزر لبقية السجلات هكذا: Private Sub Detail_Paint() If Left(Me.sName, 4) <> "Path" Then Me.cmd_Path.Transparent = True Else Me.cmd_Path.Transparent = False End If End Sub وعند فتح البرنامج ، اقوم بتشغيل هذه الدالة حتى يتم استيراد البيانات من الجدول الى ذاكرة اكسس : Option Compare Database Option Explicit ' '- tbl_Settings contain the defaults for this program, '- instead of having all these fields in one record, '- we have records of these fields sName, sValue, sDataType '- so here we deal with these values, read/write ' '- jjafferr '- v1. 17/04/2025 ' Function tbl_Settings_Data() '- load the values for the table to TempVars, for each field Dim rstS As DAO.Recordset Dim RC As Long, i As Long Set rstS = CurrentDb.OpenRecordset("Select * From tbl_Settings") rstS.MoveLast: rstS.MoveFirst: RC = rstS.RecordCount For i = 1 To RC '- clean the old values of THIS record TempVars.Remove (rstS!sName) '- since TempVars is Variant, lets set the actual field values based on the field sDataType If rstS!sDataType = "Number" Or rstS!sDataType = "Yes/No" Then TempVars.Add (rstS!sName), CLng(rstS!sValue) ElseIf rstS!sDataType = "Text" Then TempVars.Add (rstS!sName), CStr(rstS!sValue) ElseIf rstS!sDataType = "Date/Time" Then TempVars.Add (rstS!sName), CDate(rstS!sValue) End If rstS.MoveNext Next i rstS.Close: Set rstS = Nothing End Function Function ListTempVars() '- list all TemVars values in this Database Dim i As Long For i = 0 To TempVars.Count - 1 Debug.Print TempVars(i).Name, TempVars(i).Value, VarType(TempVars(i)) Next i End Function Function Update_a_Field(New_Value As String, Field_Name As String) ' ' usage from the Form, for example: ' Call Update_a_Field(Forms!frm_Main!BG_Pixel_Color, "Color_Reference") ' '- update the field value in the table DoCmd.SetWarnings False 'DoCmd.RunSQL ("UPDATE tbl_Settings SET sValue =" & Me.BG_Pixel_Tolerance & " WHERE sName='Color_Tolerance'") DoCmd.RunSQL ("UPDATE tbl_Settings SET sValue =" & New_Value & " WHERE sName='" & Field_Name & "'") DoCmd.SetWarnings True '- update the TempVar TempVars.Remove (Field_Name) '- Remove the field TempVars.Add (Field_Name), New_Value '- add the field with the new value End Function . وعليه ، وعند طلب اي قيمة في البرنامج ، استعمل: اسم الحقل في الجدول Path_Employees_Pic_Folder طريقة طلب القيمة TempVars!Path_Employees_Pic_Folder طريقة استعماله Me.Picture = TempVars!Path_Employees_Pic_Folder & Me.Employee_ID & ".jpg" . السبب الذي جعلني استخدم TempVars يدلا عن الاكواد العامة او الدوال الخاصة هو ، اني اخذ البيانات من الجدول مرة واحدة فقط عند تشغيل البرنامج ، وهذه البيانات تبقى في ذاكرة البرنامج حتى عند استلام رسالة خطأ (عند ظهور رسالة الخطأ ، يقوم اكسس بحذف جميع المتغيرات التي بذاكرنه ، ما عدا بيانات TempVars) ، وبكل بساطة يمكننا قراءة قيمتها من نافذة immediate window في صفحة الكود هكذا: . رجاء ملاحظة ان علامة الاستفهام يجب ان تكون بالانجليزي. ---------------------------------------------------------- 30-05-2025 تم اضافة كود تحديث بيانات الجدول و TempVars ، واتضح انه اسهل مما كنت اتوقع 🙂 جعفر 3 1
Moosak قام بنشر الثلاثاء at 11:04 قام بنشر الثلاثاء at 11:04 وعليكم السلام ورحمة الله وبركاته 🙂 خلاصة تجارب الخبراء .. هي كنوز لنا على طبق من ذهب 😊🌹 عندي ملاحظتين في بالي ( أفكار لا تزيد ولا تنقص من روعة الموضوع )😁 : 1- موضوع استخدام ال TempVars جميل جدا للسبب الذي ذكرته أنت (إفراغ الذاكرة عند حدوث خطأ ) ، ولكن كمجرد فضفضة .. موضوع استدعاء البيانات من الجداول مرة واحدة عند تشغيل البرنامج قد يؤثر على أنه لو تم تحديث البيانات بعد التشغيل فهذا لن يحدث البيانات التي في الذاكرة إلا إن تم تشغيل أكواد تخزين البيانات في حواصل المتغيرات مجددا ... وأضنك منتبه لهذه النقطة 🙂👌.. ويسترعي الانتباه أيضا إلى أنك حتى لو عملت لها تحديث بعد تغيير البيانات فإنها ستتحدث عندك في جهازك وقد لا تتحدث عند المستخدمين الآخرين الذين شغلوا أجهزتهم قبلك 😅🖐️ ... 2- روابط مواقع حفظ الملفات (Files Paths) عندما تكتب كاملة كما هي مع اسم القرص ( \:C أو \:D ) مثلا تجعل مواقع الملفات غير مقرؤة في حال تم نقل موقع المشروع .. لذلك يفضل أن يتم تخزين موقع هذه الملفات من قاعدة البيانات (سواء كانت تتبع ال FE أو ال BE ) والكود يكمل باقي الرابط بالمواقع المناسب .. مثال على ما أقصده لو كان الشعار في الرابط التالي : C:\Project Folder\Project BE\Images\LOGOs\CompanyLogo.PNG فأنت ستحتفظ في الجدول بالجزء البرتقالي فقط وتترك الباقي للبرنامج ليكمله .. وسلامتكم 🙂🌹 1
jjafferr قام بنشر الثلاثاء at 11:31 الكاتب قام بنشر الثلاثاء at 11:31 وعليكم السلام اخوي موسى شكرا على مرورك وملاحظاتك 🙂 1. كلامك صحيح بالنسبة الى معظم البرامج ، ولكن البرنامج الذي اعمل عليه هو يعمل كبرنامج مستقل ، فالبيانات محتاج لقراءتها مرة واحدة عند فتح البرنامج. 2. البرنامج لتصوير الموظفين (قريبا سأعمل موضوع خاص به ان شاء الله) ، فيجب ان اجعله يعمل مع اعدادات المؤسسة (المجلدات) ، ومكان حفظ الصور لا علاقة لها بمجلد البرنامج. وبما انني لم انتهي 100% من البرنامج ، فلن استغني عن افكاركم 🙂 1
jjafferr قام بنشر الثلاثاء at 15:02 الكاتب قام بنشر الثلاثاء at 15:02 ولا تنسى ان هذا الجدول لإعدادات البرنامج ، وليست بيانات للتداول بين المستخدمين ، لذا ، وحتى لو اضطررنا لتحديث معلومة معينة في الجدول (وهو واقع الحال هنا كذلك) ، فهذا لا يؤثر على عمل بقية المستخدمين ، فلكل مستخدم اعداداته ومزاجه في استخدام هذه الاعدادات. عند تحديث معلومة معينة (مثلا آخر مكان كان فيه كائن المربع Top و Left) : 1. عند تشغيل البرنامج ، انا آخذ هذه المعلومة من الجدول ، ويقوم البرنامج بعرضها على النموذج ، 2. اثناء عمل البرنامج ، واثناء تحريك المربع ، فانا آخذ هذه القيم من الكائن مباشرة ، 3. وعند الخروج من البرنامج ، يتم حفظ هذه المعلومة في الجدول. نعم لم اتطرق لكود التحديث ، وان شاء الله اضعه هنا حين اكتماله 2
jjafferr قام بنشر الجمعة at 19:19 الكاتب قام بنشر الجمعة at 19:19 تم اضافة كود تحديث بيانات الجدول و TempVars ، واتضح انه اسهل مما كنت اتوقع 🙂 Function Update_a_Field(New_Value As String, Field_Name As String) ' ' usage from the Form, for example: ' Call Update_a_Field(Forms!frm_Main!BG_Pixel_Color, "Color_Reference") ' '- update the field value in the table DoCmd.SetWarnings False 'DoCmd.RunSQL ("UPDATE tbl_Settings SET sValue =" & Me.BG_Pixel_Tolerance & " WHERE sName='Color_Tolerance'") DoCmd.RunSQL ("UPDATE tbl_Settings SET sValue =" & New_Value & " WHERE sName='" & Field_Name & "'") DoCmd.SetWarnings True '- update the TempVar TempVars.Remove (Field_Name) '- Remove the field TempVars.Add (Field_Name), New_Value '- add the field with the new value End Function . اخوي موسى: عندي برنامج ، على حاسبتين او ثلاث ، يطبعون منه حوالي 1000 وصل خلال نصف ساعة ، وبه صورتين وبيانات اخرى ، والسيرفر بعيد حوالي كيلومتر او اثنين (اذا تحسب اطوال كيبلات الشبكة) ، تصور اذا كنا نطلب مسار الصور كلما اردنا طباعة وصل 1
شايب قام بنشر الجمعة at 20:25 قام بنشر الجمعة at 20:25 منذ ساعه, jjafferr said: السيرفر بعيد حوالي كيلومتر او اثنين (اذا تحسب اطوال كيبلات الشبكة) ، تصور اذا كنا نطلب مسار الصور كلما اردنا طباعة وصل في العادة الحد الافصى لطول لكيبل الشبكة من نوع cat6 و cat7 و cat8 بحدود 100 متر بشرط ان يكون الكيبل من نوعية جيدة ومعزول بشكل صحيح والفرق بينهم يكون في سرعة النقل وعرض النطاق وكلما زاد طول الكيبل تقل السرعة ويزداد التشويش وفقد البيانات فمثلا كات6 يمكن الحصول على السرعة القصوى اذا كان الكيبل اقل من 55 متر وكات 7 في حدود 30 متر فقط اما الكات 8 فالحد الاقصى للحصول على سرعة نقل كاملة يتطلب ان يكون طول الكيبل لا يزيد عن 100 متر لذا عند زيادة المسافة عن 40 متر يتطلب استخدام سويتشات من نوعية تدعم السرعة المناسبة لنوع الكيبل ويستثنى الكات8 حيث يمكن وضع سوتشات كل 90 متر في جميع الاحول لمسافة 1000 متر او اكثر يكون استخدام هذا النوع من الكيابل والسويتشات امر غير مجدي واعتقد ان الخيار الامثل استخدام كيابل الفايبر حينها لن يكون هناك فقد للبيانات والاهم لن يكون هناك اختناق او عنق زجاجة يمكن للكيبل الفايبر الاحادية نقل بيانات لمسافة 100 كيلو متر او اكثر عند بناء الشبكة نهتم بسعة النطاق اكثر من الاهتمام بالسرعة سعة النطاق لكيبل cat8 وهو افضل كيبل من سلسلة كات فقط 2000 ميجا هيرتز بينما في الفايبر تكون سعة النطاق ما بين 40 الى 100 جيجا في الثانية انا هنا اتحدث الكيابل احادي الوضع والله الموفق 1
jjafferr قام بنشر بالامس في 05:25 الكاتب قام بنشر بالامس في 05:25 معلومة قيمة ، شكرا جزيلا 🙂 احنا كل اللي نعرفة عن الشبكة هو ، عندنا DNS وعندنا IP (لما ما يشتغل DNS) للوصول لمجلد المشاركة على السيرفر في الشبكة ، وكله تمام 🙂
Moosak قام بنشر بالامس في 06:04 قام بنشر بالامس في 06:04 10 ساعات مضت, jjafferr said: '- update the TempVar TempVars.Remove (Field_Name) '- Remove the field عندي سؤال خاطف - ليش تحذف المتغير قبل تعيين قيمة جديدة له ؟ وسؤال آخر ؟ - لو خزنا آلاف السجلات في TempVars بيكون عندنا عدد كبير منها ومساحة لا بأس بها في الذاكرة .. ألن يؤثر هذا على الأداء ؟ 🙂
ابوخليل قام بنشر بالامس في 06:18 قام بنشر بالامس في 06:18 في 27/5/2025 at 11:23, jjafferr said: السبب الذي جعلني استخدم TempVars يدلا عن الاكواد العامة او الدوال الخاصة هو ، اني اخذ البيانات من الجدول مرة واحدة فقط عند تشغيل البرنامج ، وهذه البيانات تبقى في ذاكرة البرنامج حتى عند استلام رسالة خطأ (عند ظهور رسالة الخطأ ، يقوم اكسس بحذف جميع المتغيرات التي بذاكرنه ، ما عدا بيانات TempVars) صحيح .. ومسح الذاكرة ما يحدث عادة .. بعض البيانات التي تحملها المتغيرات يجب ان تبقى طيلة فتح البرنامج .. وغالبا يكون وقت التحميل عند فتح البرنامج .. مثل المستخدم ورقمه وغير ذلك من البيانات انا استخدم في عملي الجدول والدوال ( جدول محلي يخص المستخدم ) تثبت القيم في الجدول عند فتح البرنامج .. ومهما حدث من اخطاء ؛ القيمة ستكون موجودة عند استدعاء الدالة .. مع امكانية التحديث لبعض القيم عند الحاجة خلال عمل البرنامج في 27/5/2025 at 18:02, jjafferr said: ولا تنسى ان هذا الجدول لإعدادات البرنامج ، وليست بيانات للتداول بين المستخدمين ، هذا بيت القصيد
jjafferr قام بنشر بالامس في 08:13 الكاتب قام بنشر بالامس في 08:13 1 ساعه مضت, Moosak said: عندي سؤال خاطف 1. - ليش تحذف المتغير قبل تعيين قيمة جديدة له ؟ وسؤال آخر ؟ 2. - لو خزنا آلاف السجلات في TempVars بيكون عندنا عدد كبير منها ومساحة لا بأس بها في الذاكرة .. ألن يؤثر هذا على الأداء ؟ 🙂 . 1. هي عادة احاول التمسك بها ، مثل عند الانتهاء من عمل Recordset ، فلا يوجد داعي لإستعمال set rst=Nothing ، ولكنها عادة جيدة خصوصا لما يكون عندك مجموعة من Recordsets 🙂 2.1. الحد الاقصى لـ TempVars هو 255 متغير فقط ، 2.2. هذه الطريقة استعملها فقط لجدول اعدادات البرنامج ، ولا اعتقد انها ستتعدى 30-40 معلومة ، وكما قلت سابقا: في 27/5/2025 at 19:02, jjafferr said: ولا تنسى ان هذا الجدول لإعدادات البرنامج ، وليست بيانات للتداول بين المستخدمين 1
jjafferr قام بنشر بالامس في 09:19 الكاتب قام بنشر بالامس في 09:19 1 ساعه مضت, ابوخليل said: ومسح الذاكرة ما يحدث عادة .. في برنامج الصور ، وبسبب شح المعلومات ، كنت اشوف نجوم السماء في كل وقت !! كل شوي ويتوقف البرنامج ، او النتائج ما تكون صحيحة ، او ... فكان اعتمادي الكبير على نافذة immediate window لقراءة القيم ، فكان مهم ان تبقى القيم عند توقف البرنامج. 2 ساعات مضت, ابوخليل said: استخدم في عملي الجدول والدوال ( جدول محلي يخص المستخدم ) نعم هي الطريقة المتعارف عليها (وعادة هي سجل واحد بعدة حقول) ، والتي ذكرها اخوي موسى كذلك بالتفصيل وبالدوال ، وانا استعمل هذه الطريقة في برامجي كذلك ، ولكني استدعي بيانات جميع الحقول مرة واحدة (دائما احاول ان اقلل من زيارات الجدول قدر الامكان ، وجعل الجدول جاهز للمستخدمين) ، فانادي القيم هكذا: dim tbl_values as string, x() as string tbl_values = dLookup("Aspect_Ratio_Width & '|' & Aspect_Ratio_Height & '|' & Lock_Aspect_Ratio & '|' & Save_On_Exit_Sides & '|' & IrfanView_Path & '|' & Employees_Pic_Folder & '|' & Others_Pic_Folder & '|' & Big_Pic_Folder & '|' & tmp_Pic_Folder & '|' & Pictures_BackUp_Folder & '|' & Left_Position & '|' & Top_Position & '|' & Save_On_Exit_Position & '|' & Percent_Smaller_Picture & '|' & EOS_or_Webcam & '|' & How_Many_EOS", "tbl_Settings") x = Split(tbl_values, "|") 'x(0)*15 Aspect_Ratio_Width 'x(1)*15 Aspect_Ratio_Height 'x(2) Lock_Aspect_Ratio 'x(3) Save_On_Exit_Sides 'x(4) IrfanView_Path 'x(5) Employees_Pic_Folder 'x(6) Others_Pic_Folder 'x(7) Big_Pic_Folder 'x(8) tmp_Pic_Folder 'x(9) Pictures_BackUp_Folder 'x(10) Left_Position 'x(11) Top_Position 'x(12) Save_On_Exit_Position 'x(13) Percent_Smaller_Picture 'x(14) EOS_or_Webcam 'x(15) How_Many_EOS 'Debug.Print x(11) . ولكن ومع استعمال الجدول ذو السجلات الكثيرة ، فعندنا 3 طرق: 1. استعمال الدوال العادية ، وتكون هناك دالة خاصة لكل سجل (لأننا لا نعرف رقم السجل وانما قيمة في حقل) ، 2. استعمال Recordset ، 3. والطريقة الاخيرة هي TempVars. نعم لكل طريقة ميزة وعيوب ، وبعد ان القيت اقلامي ، اخترت الطريقة الثالثة 🙂
ابوخليل قام بنشر بالامس في 10:56 قام بنشر بالامس في 10:56 1 ساعه مضت, jjafferr said: (دائما احاول ان اقلل من زيارات الجدول قدر الامكان ، وجعل الجدول جاهز للمستخدمين) ، تقصد بالزيارات : الجدول البعيد .. اذا نحن متفقون جلب القيمة بالدالة من جدول محلي بدلا من الاعتماد على المتغير في حمل القيمة .. لا ارى فيها أذن جحا .. بل بالعكس ومع اننا لجأنا لها للحاجة .. فنحن نعطي مساحة افضل واسرع لمتغيرات الاحداث الأخرى في الذاكرة للعلم : اكسس يستخدم هذه الفكرة 1
Foksh قام بنشر بالامس في 12:11 قام بنشر بالامس في 12:11 (معدل) الله يعطيكم العافية ، نقاشكم أثرى معلوماتي وأضاف لي الكثير ، فجزاكم الله خيراً . تسمحولي أطرح عليكم كم سؤال خطروا في بالي .. ؟ 🔸 في التطبيقات الكبيرة التي تحتوي على بيانات ضخمة ، برأيكم : هل من الأنسب تحميل البيانات من جدول الإعدادات إلى TempVars عند بدء التشغيل ، أم أن القراءة من الجدول عند الطلب أفضل ؟ ولماذا ؟ 🤔 🔸 هل ترون أن وجود جدول إعدادات واحد رئيسي كافٍ ؟ ، أم أن الأفضل تقسيم الإعدادات على جداول منفصلة حسب الحاجة (مثل إعدادات النظام ، المستخدم ، النماذج ... إلخ ) ؟ 🔸 وأخيراً ، إذا تغيّرت بعض الإعدادات أثناء تشغيل البرنامج ، فما الطريقة المثلى لإعادة تحميل أو تحديث TempVars دون الحاجة لإعادة تشغيل البرنامج ؟ 🌟 كل الشكر والتقدير لكم معلمينا وأساتذتنا الأفاضل . تم تعديل بالامس في 12:16 بواسطه Foksh تنسيق المشاركة
الردود الموصى بها
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.