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

الردود الموصى بها

قام بنشر (معدل)

يوجد لديا قاعدة بيانات عبارة عن نموذج New Doctor 

اريد

عند اختيار اسم الفرع ( فرع 1 ) يتم ترقيم رقم السند برقم يبد مثلا 00001/1000

عند اختيار اسم الفرع ( فرع 2 ) يتم ترقيم رقم السند برقم يبد مثلا 00001/2000

 

ترقيم تلقائي حسب الفرع.accdb

تم تعديل بواسطه 2024HISHAMKAMAL
  • 2024HISHAMKAMAL changed the title to عمل ترقيم تلقائي بناء حسب فرع الشركة
قام بنشر

مشاركة مع حبيبنا وأستاذنا ابا جودي

 قد اعددت الاجابة قبل الافطار ولم اتمكن من الرفع وقتها

هذه محاولتي المختصرة وراعيت فيها لو تغير الرقم الذي يشير الى الفرع على اعتباره 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

  • Like 1
قام بنشر

الآن :

عالجت المشكلة في مسألة التكرار وعدلت حسب اقتراحي السابق ليصبح الكود هكذا :

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

قام بنشر

مساهمتي المتواضعة مع الأساتذة ، وتقصيراً لكود المهندس @ابو جودي :biggrin: ،

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:

الآن الترقيم اصبح مثل الترقيم التلقائي في اكسس : الرقم او السجل الذي يحذف يتم تجاهله و لا يدرج مرة اخرى .. الا اذا المحذوف هو السجل الأخير

 

جميل جداً ، للخبرة دور في ترك أثر عظيم يدل على ركازة التفكير :wub:

أبدعتم معلمنا الحبيب :smile:

  • Thanks 2
قام بنشر
26 دقائق مضت, ابوخليل said:

مشاركة مع حبيبنا ابا جودي

 

العفو منكم استاذى الجليل ومعلمى القدير و والدى الحبيب الاستاذ @ابوخليل :fff:
اولا: رمضان كريم و كل عام وانتم بخير  و كل عام و انتم الى الله أقرب 

ثانيا : انتم لا تشاركون مع طلاب العلم بل أنتم تتقدمون كل طلاب العلم و انا قبلهم و أولهم فإذا حضر الماء بطل التيمم

بخصوص الثغرة اللى حضرتك قلت عليها عند حذف السجلات فلقد كتبت الكود بهذه الطريقة مستخدما : SELECT TOP لاسد أمامها كل الثغرات تماما 
 

39 دقائق مضت, ابوخليل said:

مارأي اخي محمد  @ابو جودي هل نستخدم  Dmax بدلا من ذلك ؟

طبعا وقطعا هى الافضل على الاطلاق مع الترقيم

و يا والدى الحبيب دعنى اعيد صياغة الاجابة على هذه النقطه خصيصا بشرح واف اكثر من ذلك وخاصة مع دوال المجال الثلاث والتى تكون مرجع للمطورين عند عمل الترقيم والتى قد تسبب الحيرة للبعض حتى تتضح الرؤية تماما ان شاء الله وتنكشف الغمة

الفرق بين DLast  ,  DCount  ,  DMax مع الترقيم التلقائي وخاصة عند حذف السجلات

1. DLast

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

2. DCount

  • تستخدم DCount لحساب عدد السجلات التي تستوفي شرط/شروط 
  • لا تعطي أي معلومات عن القيم المخزنة نفسها فقط عدد الإدخالات "السجلات" الموجودة
  • مفيدة عندما تحتاج إلى معرفة عدد السجلات المتبقية بعد الحذف أو عدد السجلات الحاليه اما مطلقا أو مع وجود شرط /شروط

3. DMax

  • تستخدم DMax لاسترجاع أكبر قيمة في حقل معين سواء كان رقميا أو نصيا
  • عند التعامل مع حقل نصي يحتوي على ترقيم تلقائى بتنسيق مثل 1/1000  يجب استخدام DMax مع معالجة إضافية لاستخراج الجزء الرقمي
     
  • Thanks 1
قام بنشر
16 دقائق مضت, Foksh said:

مساهمتي وتقصيراً لكود @ابو جودي :biggrin: ،

هههههه طيب مبدئيا وتعالى نقول ليه كودك افضل من الكود الاول والمستخدم فى المرفق : الفرق بينهما

المعيار الكود الأول الكود الثاني
طريقة الاستعلام  يستخدم Recordset مع SELECT TOP 1 ... ORDER BY لجلب أعلى قيمة. يستخدم DMax للحصول على أعلى قيمة مباشرة.
الأداء     أبطأ نسبيًا لأنه يفتح Recordset ويتعامل مع البيانات يدويًا. أسرع لأن DMax يعمل على مستوى المحرك دون الحاجة إلى فتح Recordset.
الدقة  دقيق إذا كان النمط ثابتًا (XX/CCCC)، لكنه قد يفشل إذا كان هناك بيانات غير متوقعة.    دقيق بنفس القدر، مع تحكم أفضل في شرط البحث باستخدام Right.
المرونة    أقل مرونة لأنه يعتمد على LIKE وتحليل النص يدويًا. أكثر مرونة لأن DMax يسمح بتخصيص الشرط بسهولة.
معالجة الأخطاء   جيدة، لكن يمكن تحسينها بإضافة تفاصيل الخطأ. جيدة، لكن قد تفشل إذا كان تعبير DMax معقدًا جدًا.
الكفاءة في الذاكرة   يستهلك ذاكرة أكثر بسبب Recordset. أقل استهلاكًا لأنه لا يفتح كائنات إضافية.


طيب ولأن وقت الجواب كنت صايم وكان وقت الفطار خلاص وكنت مستعجل وبعد قراءة كودك الجميل

كودك افضل  ولكن ايه رايك فى كتابة الكود بهذه الطريقة  :yes:

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 :fff:  والكود الثانى 

المعيار الكود الأول الكود الثاني
طريقة الاستعلام يستخدم QueryDef مع استعلام SQL يدوي لجلب أعلى قيمة باستخدام Max. يستخدم DMax للحصول على أعلى قيمة مباشرة.
الأداء أبطأ نسبيًا بسبب إنشاء QueryDef وفتح Recordset في كل استدعاء. أسرع لأن DMax يعمل مباشرة على مستوى محرك قاعدة البيانات دون كائنات إضافية.
الدقة دقيق، لكن شرط LIKE '*branchCode' قد يتطابق مع قيم غير مرغوبة (مثل "X/1000Y"). أكثر دقة بسبب شرط LIKE '*/branchCode' الذي يضمن النمط الصحيح.
المرونة أقل مرونة (تنسيق ثابت "00"). أكثر مرونة بفضل minDigits لتخصيص عدد الأرقام (مثل "001" أو "0001").
معالجة الأخطاء أساسية، تفتقر إلى تفاصيل الخطأ. أفضل، تتضمن رقم الخطأ والوصف والمدخلات لتسهيل التصحيح.
الكفاءة في الذاكرة يستهلك ذاكرة أكثر بسبب QueryDef وRecordset. أقل استهلاكًا لأنه يعتمد على DMax فقط.
التحقق من المدخلات أقل دقة (Trim(tableName & serialField & branchCode) قد يفشل إذا كان أحد الحقول فارغًا ولكن الباقي ليس كذلك). أكثر دقة (يتحقق من كل حقل على حدة).

تحياتى لكل اساتذتى العظماء :fff:

 
  • Haha 1
قام بنشر

اراك تضحك يا @Foksh أفندى :eek2:

وعارفك بتضحك ليه : لانه دائما استلهم افكارى منك ومن مشاركاتك الجميله :tongue2: 

قام بنشر
29 دقائق مضت, ابو جودي said:

اراك تضحك يا @Foksh أفندى :eek2:

 

ربي يخليك ويسعدك ، بالعكس دا انا اللي بحب أستنير بأفكاركم العظيمة ، :wub:

قام بنشر

الان بعد ان تمت الاجابة بشكل عملي اجمالا وتفصيلا

انا لى بعض التعقيبات البسيطه

انا افضل ان كان هناك جزء ثابت يكون فى الجهة اليسرى وليس فى الجهة اليمنى <<---<  هذا افضل من وجهة نظرى
انا لا افضل استخدام التسيق الذى يحدد عد منازل الترقيم لانه مثلا لو افترضنا انه تم التعامل على ان عدد منازل الترقيم سوف يكون 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 منازل للترقيم فى المحاولة التاليه فورا سوف يتوقف الترقيم عن العمل 

لذلك لا أنصح بالوقوع فى هه المعضله التى لابد وحتما سوف تحدث فى وقت ما :yes:

ومشكلة أخرى يمكن أن تحدث مع المعالجة الخاطئة 
عند الوصول الى القيمة القصوى سوف يتم تكرار هذه القيم دائما
يعنى لو افترضنا انه كان عدد المنازل 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

لذلك وجب التنويه الى الانتباه عند تعامل المبرمج مع هذه الجزئيــة

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

وكنبذه عن الموضوع والفكرة القادمه ان شاء الله تعالى الدالة التى أنوه عنها كانت فى هذه المشاركة



ولكن سوف يتم تلافى بعض الأخطاء فى التحديث الجديد لها مع اضافات بسيطه تضفى القوة والمرونة والشموليه بشكل أكثر احترافيه من الاصدار السابق

يتبع ......  

  • Like 1
قام بنشر

في الكود الأخير لي ، لا أعتقد أنه يوجد نهاية للترقيم

من -2,147,483,648 إلى 2,147,483,647

Dim maxNum As Long

 

  • Haha 1
قام بنشر
27 دقائق مضت, Foksh said:

في الكود الأخير لي ، لا أعتقد أنه يوجد نهاية للترقيم

 

متخافش كودك حلو و جميل :yes:  و أنت احلى و أجمل :wub::fff:

يا صديقى العزيز واخى الحبيب انا لم اوجه كلام اليك مطلقا ولا لاى أحد :eek2:

 

أنا أتكلم وأشرح بشكل عام نتائج أخطائى السابقة التى حدثت معى فى تكويد مثل هذه الافكار وكذلك نتائج تجارب عمليه على مدى تجارب طويلة الامد والتى قد لا يفطن اليها البعض كما حدث معى تمام فى وقت من الأوفات

وفى النهايه يصطدم بالأخطاء أو المشاكل والتى قد لا تخطر له على باله وقتها سببها ويعانى الى أن يصل الى الحلول لهذه المشاكل

احببت فقط التوضيح والتنويه لان هذه الجزئية وهى الترقيم المخصص من خلال الاكواد هامة وحساسة ويعتمد عليها الكثير من المبرمجين فى أعمالهم أو المطورين

وذلك فقط ليكون الموضوع هذا مرجعا كافايا و وافيات وشاملا فيما بعد لرواد المنتدى حيث تم وضع الافكار والاطروحات المتعددة و تم تفنيد الموضوع عمليا ونظريا

  • Haha 1
قام بنشر
11 ساعات مضت, ابو جودي said:

متخافش كودك حلو و جميل :yes:  و أنت احلى و أجمل :wub::fff:

 

أنا مش خايف يا عسل :wub:

أنا قلت أنوِّه بس ، للتذكير ليس إلا :smile: 

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

زائر
اضف رد علي هذا الموضوع....

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • تصفح هذا الموضوع مؤخراً   0 اعضاء متواجدين الان

    • لايوجد اعضاء مسجلون يتصفحون هذه الصفحه
×
×
  • اضف...

Important Information