2024HISHAMKAMAL قام بنشر مارس 13 قام بنشر مارس 13 (معدل) يوجد لديا قاعدة بيانات عبارة عن نموذج New Doctor اريد عند اختيار اسم الفرع ( فرع 1 ) يتم ترقيم رقم السند برقم يبد مثلا 00001/1000 عند اختيار اسم الفرع ( فرع 2 ) يتم ترقيم رقم السند برقم يبد مثلا 00001/2000 ترقيم تلقائي حسب الفرع.accdb تم تعديل مارس 13 بواسطه 2024HISHAMKAMAL
ابوخليل قام بنشر مارس 13 قام بنشر مارس 13 مشاركة مع حبيبنا وأستاذنا ابا جودي قد اعددت الاجابة قبل الافطار ولم اتمكن من الرفع وقتها هذه محاولتي المختصرة وراعيت فيها لو تغير الرقم الذي يشير الى الفرع على اعتباره 1000 او 2000 او 3000 ... الخ شريطة ان يستمر على هذا النسق Dim i, ii As String Dim x As Integer i = Specialty ii = i & "000" x = DCount("*", "tblDoctors", "[Specialty]='" & i & "'") + 1 Me!DoctorID = Format(Str(x), "00000") & "/" & ii طبعا يوجد ثغرة فيما لو تم حذف سجل فعند الترقيم قد يتم تكرار رقم موجود ، وعادة يكون هو آخر رقم تم تسجيله وعلاجه ان يتم ضبط الحقل بحيث لا يقبل التكرار وقد يستمر هذا الخطأ لأن الكود يعد السجلات مارأي اخي محمد @ابو جودي هل نستخدم Dmax بدلا من ذلك ؟ ترقيم تلقائي حسب الفرع2.rar 1
ابوخليل قام بنشر مارس 13 قام بنشر مارس 13 الآن : عالجت المشكلة في مسألة التكرار وعدلت حسب اقتراحي السابق ليصبح الكود هكذا : Dim i, ii As String Dim x As Integer i = Specialty ii = i & "000" x = Left(DMax("DoctorID", "tblDoctors", "[Specialty]='" & i & "'"), 5) + 1 Me!DoctorID = Format(Str(x), "00000") & "/" & ii الآن الترقيم اصبح مثل الترقيم التلقائي في اكسس : الرقم او السجل الذي يحذف يتم تجاهله و لا يدرج مرة اخرى .. الا اذا المحذوف هو السجل الأخير ترقيم تلقائي حسب الفرع3.rar
Foksh قام بنشر مارس 13 قام بنشر مارس 13 مساهمتي المتواضعة مع الأساتذة ، وتقصيراً لكود المهندس @ابو جودي ، Public Function FlexiBranchSerial(tableName As String, serialField As String, branchCode As String) As String On Error GoTo ErrorHandler If Trim(tableName & serialField & branchCode) = "" Then FlexiBranchSerial = "خطأ: مدخلات غير صالحة" Exit Function End If Dim db As DAO.Database Dim maxNum As Long Dim sql As String Dim qdf As QueryDef Set db = CurrentDb sql = "SELECT Max(Val(Left([" & serialField & "], InStr([" & serialField & "],'/') - 1))) AS MaxNum " & _ "FROM " & tableName & " WHERE [" & serialField & "] LIKE '*" & branchCode & "'" Set qdf = db.CreateQueryDef("", sql) maxNum = Nz(qdf.OpenRecordset()(0), 0) + 1 FlexiBranchSerial = Format(maxNum, "00") & "/" & branchCode Set qdf = Nothing Set db = Nothing Exit Function ErrorHandler: FlexiBranchSerial = "خطأ: فشل في توليد الرقم" End Function الإستدعاء :- Private Sub Specialty_AfterUpdate() DoctorID = FlexiBranchSerial("tblDoctors", "DoctorID", Specialty.Column(2)) End Sub ترقيم تلقائي حسب الفرع.accdb 13 دقائق مضت, ابوخليل said: الآن الترقيم اصبح مثل الترقيم التلقائي في اكسس : الرقم او السجل الذي يحذف يتم تجاهله و لا يدرج مرة اخرى .. الا اذا المحذوف هو السجل الأخير جميل جداً ، للخبرة دور في ترك أثر عظيم يدل على ركازة التفكير أبدعتم معلمنا الحبيب 2
ابو جودي قام بنشر مارس 13 قام بنشر مارس 13 26 دقائق مضت, ابوخليل said: مشاركة مع حبيبنا ابا جودي العفو منكم استاذى الجليل ومعلمى القدير و والدى الحبيب الاستاذ @ابوخليل اولا: رمضان كريم و كل عام وانتم بخير و كل عام و انتم الى الله أقرب ثانيا : انتم لا تشاركون مع طلاب العلم بل أنتم تتقدمون كل طلاب العلم و انا قبلهم و أولهم فإذا حضر الماء بطل التيمم بخصوص الثغرة اللى حضرتك قلت عليها عند حذف السجلات فلقد كتبت الكود بهذه الطريقة مستخدما : SELECT TOP لاسد أمامها كل الثغرات تماما 39 دقائق مضت, ابوخليل said: مارأي اخي محمد @ابو جودي هل نستخدم Dmax بدلا من ذلك ؟ طبعا وقطعا هى الافضل على الاطلاق مع الترقيم و يا والدى الحبيب دعنى اعيد صياغة الاجابة على هذه النقطه خصيصا بشرح واف اكثر من ذلك وخاصة مع دوال المجال الثلاث والتى تكون مرجع للمطورين عند عمل الترقيم والتى قد تسبب الحيرة للبعض حتى تتضح الرؤية تماما ان شاء الله وتنكشف الغمة الفرق بين DLast , DCount , DMax مع الترقيم التلقائي وخاصة عند حذف السجلات 1. DLast تستخدم DLast لاسترجاع آخر سجل تمت إضافته إلى الجدول بناء على الترتيب الداخلي لقاعدة البيانات لا تضمن إرجاع آخر قيمة بالمعنى الزمني أو الرقمي لأن ترتيب السجلات ليس ثابتا عند الحذف أو إعادة الإدخال غير موثوقة عند التعامل مع الترقيم التلقائى أو عند الحاجة إلى أعلى قيمة بشكل دقيق 2. DCount تستخدم DCount لحساب عدد السجلات التي تستوفي شرط/شروط لا تعطي أي معلومات عن القيم المخزنة نفسها فقط عدد الإدخالات "السجلات" الموجودة مفيدة عندما تحتاج إلى معرفة عدد السجلات المتبقية بعد الحذف أو عدد السجلات الحاليه اما مطلقا أو مع وجود شرط /شروط 3. DMax تستخدم DMax لاسترجاع أكبر قيمة في حقل معين سواء كان رقميا أو نصيا عند التعامل مع حقل نصي يحتوي على ترقيم تلقائى بتنسيق مثل 1/1000 يجب استخدام DMax مع معالجة إضافية لاستخراج الجزء الرقمي 1
ابو جودي قام بنشر مارس 13 قام بنشر مارس 13 16 دقائق مضت, Foksh said: مساهمتي وتقصيراً لكود @ابو جودي ، هههههه طيب مبدئيا وتعالى نقول ليه كودك افضل من الكود الاول والمستخدم فى المرفق : الفرق بينهما المعيار الكود الأول الكود الثاني طريقة الاستعلام يستخدم Recordset مع SELECT TOP 1 ... ORDER BY لجلب أعلى قيمة. يستخدم DMax للحصول على أعلى قيمة مباشرة. الأداء أبطأ نسبيًا لأنه يفتح Recordset ويتعامل مع البيانات يدويًا. أسرع لأن DMax يعمل على مستوى المحرك دون الحاجة إلى فتح Recordset. الدقة دقيق إذا كان النمط ثابتًا (XX/CCCC)، لكنه قد يفشل إذا كان هناك بيانات غير متوقعة. دقيق بنفس القدر، مع تحكم أفضل في شرط البحث باستخدام Right. المرونة أقل مرونة لأنه يعتمد على LIKE وتحليل النص يدويًا. أكثر مرونة لأن DMax يسمح بتخصيص الشرط بسهولة. معالجة الأخطاء جيدة، لكن يمكن تحسينها بإضافة تفاصيل الخطأ. جيدة، لكن قد تفشل إذا كان تعبير DMax معقدًا جدًا. الكفاءة في الذاكرة يستهلك ذاكرة أكثر بسبب Recordset. أقل استهلاكًا لأنه لا يفتح كائنات إضافية. طيب ولأن وقت الجواب كنت صايم وكان وقت الفطار خلاص وكنت مستعجل وبعد قراءة كودك الجميل كودك افضل ولكن ايه رايك فى كتابة الكود بهذه الطريقة Public Function FlexiBranchSerial(tableName As String, serialField As String, branchCode As String, Optional minDigits As Integer = 2) As String On Error GoTo ErrorHandler ' التحقق من المدخلات If Len(Trim(tableName)) = 0 Or Len(Trim(serialField)) = 0 Or Len(Trim(branchCode)) = 0 Then FlexiBranchSerial = "خطأ: مدخلات غير صالحة" Exit Function End If If minDigits < 1 Then minDigits = 2 ' ضمان حد أدنى معقول Dim db As DAO.Database Dim maxSerial As Variant Dim formatPattern As String ' إعداد نمط التنسيق بناءً على minDigits formatPattern = String(minDigits, "0") Set db = CurrentDb ' استخدام DMax للحصول على أعلى قيمة تسلسلية مع شرط دقيق maxSerial = DMax("Val(Left([" & serialField & "], InStr([" & serialField & "], '/') - 1))", tableName, _ "[" & serialField & "] LIKE '*/" & branchCode & "'") ' إذا لم يكن هناك قيمة، ابدأ من 0 If IsNull(maxSerial) Then maxSerial = 0 ' زيادة الرقم التسلسلي بـ 1 maxSerial = maxSerial + 1 ' توليد الرقم التسلسلي النهائي FlexiBranchSerial = Format(maxSerial, formatPattern) & "/" & branchCode Set db = Nothing Exit Function ErrorHandler: Debug.Print "خطأ في FlexiBranchSerial: " & Err.Number & " - " & Err.Description & " | جدول: " & tableName & ", حقل: " & serialField & ", رمز الفرع: " & branchCode FlexiBranchSerial = "خطأ: فشل في توليد الرقم - " & Err.Description End Function وبعد مشاركتى للكود الاخير دعنا نضع مقارنه بين الكود الاول لحضرتك يا استاذ @Foksh والكود الثانى المعيار الكود الأول الكود الثاني طريقة الاستعلام يستخدم QueryDef مع استعلام SQL يدوي لجلب أعلى قيمة باستخدام Max. يستخدم DMax للحصول على أعلى قيمة مباشرة. الأداء أبطأ نسبيًا بسبب إنشاء QueryDef وفتح Recordset في كل استدعاء. أسرع لأن DMax يعمل مباشرة على مستوى محرك قاعدة البيانات دون كائنات إضافية. الدقة دقيق، لكن شرط LIKE '*branchCode' قد يتطابق مع قيم غير مرغوبة (مثل "X/1000Y"). أكثر دقة بسبب شرط LIKE '*/branchCode' الذي يضمن النمط الصحيح. المرونة أقل مرونة (تنسيق ثابت "00"). أكثر مرونة بفضل minDigits لتخصيص عدد الأرقام (مثل "001" أو "0001"). معالجة الأخطاء أساسية، تفتقر إلى تفاصيل الخطأ. أفضل، تتضمن رقم الخطأ والوصف والمدخلات لتسهيل التصحيح. الكفاءة في الذاكرة يستهلك ذاكرة أكثر بسبب QueryDef وRecordset. أقل استهلاكًا لأنه يعتمد على DMax فقط. التحقق من المدخلات أقل دقة (Trim(tableName & serialField & branchCode) قد يفشل إذا كان أحد الحقول فارغًا ولكن الباقي ليس كذلك). أكثر دقة (يتحقق من كل حقل على حدة). تحياتى لكل اساتذتى العظماء 1
ابو جودي قام بنشر مارس 13 قام بنشر مارس 13 اراك تضحك يا @Foksh أفندى وعارفك بتضحك ليه : لانه دائما استلهم افكارى منك ومن مشاركاتك الجميله
Foksh قام بنشر مارس 13 قام بنشر مارس 13 29 دقائق مضت, ابو جودي said: اراك تضحك يا @Foksh أفندى ربي يخليك ويسعدك ، بالعكس دا انا اللي بحب أستنير بأفكاركم العظيمة ،
ابو جودي قام بنشر مارس 13 قام بنشر مارس 13 الان بعد ان تمت الاجابة بشكل عملي اجمالا وتفصيلا انا لى بعض التعقيبات البسيطه انا افضل ان كان هناك جزء ثابت يكون فى الجهة اليسرى وليس فى الجهة اليمنى <<---< هذا افضل من وجهة نظرى انا لا افضل استخدام التسيق الذى يحدد عد منازل الترقيم لانه مثلا لو افترضنا انه تم التعامل على ان عدد منازل الترقيم سوف يكون 6 وبما أننا تحدثنا سابقا ان DMax تستخدم لاسترجاع أكبر قيمة في حقل معين سواء كان رقميا أو نصيا مع معالجة إضافية لاستخراج الجزء الرقمي لو لم تتم المعالجة بشكل صحيح عندما يكون الحقل نصيا بعد الوصول الى الحد النهائى للترقيم سوف يتوقف الكود عن العمل دعونا نشرح النقطة الثانية باستفاضه لنفترض ان الثابت فى الشق الايسر هو : ABC/ ثم بعد ذلك يأتى الترقيم والمكون من 6 منازل سوف يكون الترقيم بالشكل التالى تمام ABC/000001 ABC/000002 ABC/000003 ABC/000004 ABC/000005 ABC/000006 ABC/000007 ABC/000097 ولنفترض انه تم حذف سجلات والتى تبدأ من الرقم 8 الى الى الرقم 97 سوف يكمل بالشكل التالى بدون مشاكل ABC/000098 ABC/000099 ABC/000100 ABC/000101 ABC/000102 ABC/000103 ABC/000104 ABC/999997 طيب لنفترض انه تم حذف سجلات أخرى والتى تبدأ من الرقم ABC/000105 الى الى الرقم ABC/999997 سوف يكمل الكود ABC/999998 ABC/999999 والى هنا تكون نهاية الترقيم طبقا لاختيار عدد 6 منازل للترقيم فى المحاولة التاليه فورا سوف يتوقف الترقيم عن العمل لذلك لا أنصح بالوقوع فى هه المعضله التى لابد وحتما سوف تحدث فى وقت ما ومشكلة أخرى يمكن أن تحدث مع المعالجة الخاطئة عند الوصول الى القيمة القصوى سوف يتم تكرار هذه القيم دائما يعنى لو افترضنا انه كان عدد المنازل 2 ABC/01 ABC/02 ABC/03 ABC/04 ABC/05 ABC/06 ABC/07 ABC/08 ABC/09 ABC/10 سوف تتم تكرار القيمة القصوى ABC/10 ABC/10 ABC/10 ABC/10 لذلك وجب التنويه الى الانتباه عند تعامل المبرمج مع هذه الجزئيــة وفى المشاركة القادمة ان شاء الله تعالى سوف اضع بين آياديكم تحديث لداله كنت كتبتها قبل ذلك هى داله بشكل عام شامله ووافيه يمكن أن تحقق هذه الجزئية وأكثر من ذلك بكثير حسب رغبة المستخدم أو بالاخص حسب رغبة المصمم ومطور النظم وكنبذه عن الموضوع والفكرة القادمه ان شاء الله تعالى الدالة التى أنوه عنها كانت فى هذه المشاركة ولكن سوف يتم تلافى بعض الأخطاء فى التحديث الجديد لها مع اضافات بسيطه تضفى القوة والمرونة والشموليه بشكل أكثر احترافيه من الاصدار السابق يتبع ...... 1
Foksh قام بنشر مارس 13 قام بنشر مارس 13 في الكود الأخير لي ، لا أعتقد أنه يوجد نهاية للترقيم ❗ من -2,147,483,648 إلى 2,147,483,647 Dim maxNum As Long 1
ابو جودي قام بنشر مارس 13 قام بنشر مارس 13 27 دقائق مضت, Foksh said: في الكود الأخير لي ، لا أعتقد أنه يوجد نهاية للترقيم ❗ متخافش كودك حلو و جميل و أنت احلى و أجمل يا صديقى العزيز واخى الحبيب انا لم اوجه كلام اليك مطلقا ولا لاى أحد أنا أتكلم وأشرح بشكل عام نتائج أخطائى السابقة التى حدثت معى فى تكويد مثل هذه الافكار وكذلك نتائج تجارب عمليه على مدى تجارب طويلة الامد والتى قد لا يفطن اليها البعض كما حدث معى تمام فى وقت من الأوفات وفى النهايه يصطدم بالأخطاء أو المشاكل والتى قد لا تخطر له على باله وقتها سببها ويعانى الى أن يصل الى الحلول لهذه المشاكل احببت فقط التوضيح والتنويه لان هذه الجزئية وهى الترقيم المخصص من خلال الاكواد هامة وحساسة ويعتمد عليها الكثير من المبرمجين فى أعمالهم أو المطورين وذلك فقط ليكون الموضوع هذا مرجعا كافايا و وافيات وشاملا فيما بعد لرواد المنتدى حيث تم وضع الافكار والاطروحات المتعددة و تم تفنيد الموضوع عمليا ونظريا 1
Foksh قام بنشر مارس 14 قام بنشر مارس 14 11 ساعات مضت, ابو جودي said: متخافش كودك حلو و جميل و أنت احلى و أجمل أنا مش خايف يا عسل أنا قلت أنوِّه بس ، للتذكير ليس إلا
2024HISHAMKAMAL قام بنشر مارس 15 الكاتب قام بنشر مارس 15 تمام جزاكم الله خير الجزاء المثال وافي جدا وجعله الله في ميزان حسناتكم
الردود الموصى بها
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.