اذهب الي المحتوي
أوفيسنا

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

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

السلام عليكم ورحمة الله

في الملف المرفق تجدون جدول باسم Students يحتوي على حقلين فقط هما Name و Marks لمجموعة من الطلاب ، وقمت بإنشاء  استعلام اسمه Rank_Query  لترتيب الطلاب بحسب درجاتهم بحيث لا يتم القفز على المنزلة المشغولة بالمكرر ، بمعنى إذا كان هناك ثلاثة طلاب درجاتهم 250  سيأخذون جميهم الترتيب (1) بينما صاحب الدرجة 249 سيأخذ الترتيب (2) وليس (4) كما هو معهود.

طبعا دالة الترتيب موجودة في عرض SQL وتقوم بترتيب القيم بفعالية دون القفز على المرتبة المشغولة بالمكرر

دالة الترتيب

SELECT T2.Marks, 1+(SELECT
         COUNT(*)
      FROM
         (
            SELECT DISTINCT
               Marks
            FROM [Students]
               ) AS T1
      WHERE
         T1.Marks > T2.Marks) AS Rank
FROM Students AS T2
ORDER BY T2.Marks DESC;

ما أريد فعله هو أن يتم ترتيب الدرجات وهي مقربة وليست كسرية ولكن المشكلة الوحيدة التي تواجهني هي أن برنامج الاكسس يعتمد طريقة تقريب الـ ( Banker's ) وليس التقريب المعتاد كما في الاكسل حيث يقرب الرقم 2.5 الى 2 وليس 3 كما يفترض.

وللتغلب على هذه المشكلة قمت بوضع دالة اسمها StandardRound خصيصا  لهذا الغرض في Module  على النحو التالي

' This function overcomes the bankers Rounding that occurs in the
' built-in VBA Round function to provide true (symmetric) numeric Rounding
' Created by TechOnTheNet.com
Public Function StandardRound(pValue As Double, pDecimalPlaces As Integer) As Variant

    Dim LValue As String
    Dim LPos As Integer
    Dim LNumDecimals As Long
    Dim LDecimalSymbol As String
    Dim QValue As Double

    ' Return an error if the decimal places provided is negative
    If pDecimalPlaces < 0 Then
       StandardRound = CVErr(2001)
          Exit Function
    End If

    ' If your country uses a different symbol than the "." to denote a decimal
    ' then change the following LDecimalSymbol variable to that character
    LDecimalSymbol = "."

    ' Determine the number of decimal places in the value provided using
    ' the length of the value and the position of the decimal symbol
    LValue = CStr(pValue)
    LPos = InStr(LValue, LDecimalSymbol)
    LNumDecimals = Len(LValue) - LPos

    ' Round if the value provided has decimals and the number of decimals
    ' is greater than the number of decimal places we are rounding to
    If (LPos > 0) And (LNumDecimals > 0) And (LNumDecimals > pDecimalPlaces) Then

        ' Calculate the factor to add
        QValue = (1 / (10 ^ (LNumDecimals + 1)))

        ' Symmetric rounding is commonly desired so if the value is
        ' negative, make the factor negative
        ' (Remove the following 3 lines if you require "Round Up" rounding)
        If (pValue < 0) Then
            QValue = -QValue
        End If

        ' Add a 1 to the end of the value (For example, if pValue is 12.65
        ' then we will use 12.651 when rounding)
        StandardRound = Round(pValue + QValue, pDecimalPlaces)

    ' Otherwise return the original value
    Else
        StandardRound = pValue
    End If

End Function

حيث قمت بعمل حقل جديد في نفس الاستعلام السابق باسم Rounded وقمت باستدعاء الدالة في منشئ التعبير الخاص به على النحو التالي:

StandardRound( [Marks],0)

فتم تقريب الدرجات بشكل ممتاز وطبيعي بعيدا عن الـ Bankers

طيب ..

المطلوب يا إخواني الاعزاء وأصحاب الخبرة كيف يمكنني تطبيق دالة الترتيب السابقة وذلك على الحقل الجديد المقرب  Roundedوتكون النتيجة في نفس جدول الاستعلام بجوار عمود الدرجات المقربة بالدالة وليس في استعلام منفصل.

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

ودمتم بخير

ملاحظة : جميع الدوال والاكواد منقوله ولم اقم بإنشاء او اختراع اي منها.

Ranks.accdb

تم تعديل بواسطه Salem2020
قام بنشر (معدل)
1 ساعه مضت, ابوخليل said:

عليكم السلام

هل تريد تقريب 249.5  الى 250 ام الى 249 ؟

بالتأكيد اخي الكريم ارغب بتقريب 249.5 الى 250 وهذا سيتم بدون اي مشاكل لكن المشكلة قد تحدث في رقم مثل 244.5 حيث سيتم تقريبة الى 244 او رقم مثل 248.5 سيتم تقريبة الى 248  كون التقريب في اكسس يعتمد على الرقم  الموجود يسار الجزء العشري فإن كان فردي سيتم التقريب بشكل طبيعي اما اذا كان العدد زوجي فسيتم حذف الجزء العشري بالكامل وقد تجاوزت هذه المشكلة بالدالة الموضحة حيث قمت بتقريب جميع العلامات بشكل صحيح وسليم وتبقى المشكلة هو كيفية انشاء استعلام متداخل احصل من خلاله على ترتيب الارقام المقربة في نفس الاستعلام  فلو كان عندي الدرجات التالية:

احمد     249.5    سيقرب الى  250 وسيحصل على المركز  الاول

علي     248.5    سيقرب الى 248 وسيحصل على المركز الثاني 

وسيم    248.0    سيقرب الى  248 وسيحصل على المركز الثاني بالاشتراك مع الطالب (علي) والمفترض ان يحصل على المركز الثالث بينما الطالب (علي) هو المركز الثاني وهذا الامر لا يحصل في اكسس بسبب تقريب الـ ( Banker's ) على عكس الاكسل وهنا ينشأ الاختلاف في الترتيب.

طبعا أنا قد تجاوزت مشكلة التقريب والترتيب بنجاح ولكن يبقى كيف اجعل الناتج الجديد في نفس جدول الاستعلام بجوار العلامات المقربة

ارجوا أن اكون قد وفقت في ايصال الفكرة المطلوبة ، وتقبل خالص التحية 

 

تم تعديل بواسطه Salem2020
  • أفضل إجابة
قام بنشر

آمل ان يكون هذا هو مطلوبك

Public Function OrderAwael(Roundx As Double) As String
    Set rs = CurrentDb.OpenRecordset("SELECT COUNT(*) + 1 FROM (SELECT qryRank.Rounded FROM qryRank GROUP BY qryRank.Rounded) As temp WHERE temp.Rounded > " & Roundx, dbOpenSnapshot)
    OrderAwael = rs(0)
    rs.Close
    End Function

 

Ranks.accdb

  • Like 1
  • Thanks 1

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