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

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

قام بنشر

السلام عليكم

كما في الصورة والملف المرفقين

اريد عند الضغط على زر الحفظ .. يتم ادراج مجموع ساعات العمل في الفترة الصباحية والفترة المسائية تدرج في الفترتين (صباحي/مسائي)

image.png.d5b18758667b2517499b532919c8a480.png

 

Database1.rar

قام بنشر
16 دقائق مضت, ابوخليل said:

اريد عند الضغط على زر الحفظ .. يتم ادراج مجموع ساعات العمل في الفترة الصباحية والفترة المسائية تدرج في الفترتين (صباحي/مسائي)

 

انا مش فاهم معلش محتاج لتوضيح

قام بنشر

كما تشاهد في الصورة : الحقل الأول الأعلى فارغ .. الخاص بالفترتين  ... لأن السجل مجرد مسمى ليس امامه وقت دخول ولا خروج

اريد ان يتم ادراج قيمة في هذا الحقل

هذه القيمة =  مجموع ساعات العمل : المسائية + الصباحية 

بحيث تصبح القيمة= 09:40

  • Thanks 1
قام بنشر

يعنى المفروض يكون الفترين موجودين
حضور وانصراف

وعند الضغط على زر الحفظ يتم جمع ساعات العمل ؟

 

قام بنشر

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

هل المقصود كهذه النتيجة :-

image.png.73bae8e38ac0f2e48b5f6df0a65c4daf.png

قام بنشر

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


ولو انا فهمت صح

فى خطأ فى حساب الفترة المسائية هى الان : 5:40
والمفروض الصح تكون : 6:10

قام بنشر

بغض النظر عن الخطأ الذي ذكره أبو جودي ، ومن المؤكد أن السجلات هي للتجربة فقط لا غير ..

في الدالة العامة التالية :-

Public Sub UpdateRecordWithID(frm As Form, idField As String, idValue As Variant, targetField As String, sumField As String)
    Dim rs As DAO.Recordset
    Dim total As Double
    Dim foundTarget As Boolean
    Set rs = frm.RecordsetClone
    rs.MoveFirst
    Do Until rs.EOF
        If foundTarget Then
            If rs!ftraName = "فترة صباحية" Or rs!ftraName = "فترة مسائية" Then
                total = total + Nz(rs.Fields(sumField).Value, 0)
            End If
        ElseIf rs.Fields(idField).Value = idValue Then
            foundTarget = True
        End If
        rs.MoveNext
    Loop
    If Not foundTarget Then
        rs.Close: Set rs = Nothing
        Exit Sub
    End If
    rs.MoveFirst
    Do Until rs.EOF
        If rs.Fields(idField).Value = idValue Then
            frm.Recordset.Bookmark = rs.Bookmark
            frm.Controls(targetField).Value = total
            frm.Dirty = False
            Exit Do
        End If
        rs.MoveNext
    Loop
    rs.Close: Set rs = Nothing
End Sub

تركت لك حرية تحديد اسم الحقل الفريد ورقمه ، واسم الحقل المستهدف تحديثه بالقيم التي تريدها من خلال الاستدعاء كالآتي :-

Call UpdateRecordWithID(Me, "ID", 1, "countWorkHours", "countWorkHours")

 

 

الملف مع الفكرة المقترحة :-

Database1.zip

  • Haha 1
قام بنشر

هل يفى ذلك بالغرض و يحقق المطلوب ؟ 

 

Private Sub cmdSave_Click()
    On Error GoTo ErrorHandler

    Dim rst As DAO.Recordset
    Dim datInterval As Date
    Dim dblTotalMinutes As Double
    Dim strFtraName As String
    
    Set rst = CurrentDb.OpenRecordset("tbl_Ftrat", dbOpenDynaset)

    dblTotalMinutes = 0
    Do While Not rst.EOF
        strFtraName = Trim(Nz(rst!ftraName, ""))
        If strFtraName = "فترة صباحية" Or strFtraName = "فترة مسائية" Then
            If Not IsNull(rst!countWorkHours) Then
                ' تحويل الوقت إلى دقائق: القيمة * 24 * 60
                dblTotalMinutes = dblTotalMinutes + (rst!countWorkHours * 24 * 60)
                If DebugMode Then Debug.Print "تمت إضافة عدد الدقائق: "; rst!countWorkHours
            End If
        End If
        rst.MoveNext
    Loop

    ' تحويل عدد الدقائق الإجمالية إلى قيمة Time لتخزينها في الحقل Date/Time
    datInterval = dblTotalMinutes / (24 * 60)

    rst.MoveFirst
    Do While Not rst.EOF
        strFtraName = Trim(Nz(rst!ftraName, ""))
        If strFtraName Like "*فترتين*" Then
            rst.Edit
            rst!countWorkHours = datInterval
            rst.Update
            
            Exit Do
        End If
        rst.MoveNext
    Loop
    countWorkHours.Requery
    Me.Repaint
    
    rst.Close
    Set rst = Nothing

    MsgBox " تم تحديث عدد ساعات الفترة المجمعة بنجاح.", vbInformation
    Exit Sub

ErrorHandler:
    MsgBox " خطأ: " & Err.Description, vbCritical
    If Not rst Is Nothing Then rst.Close
    Set rst = Nothing
End Sub

 

قام بنشر
8 دقائق مضت, Foksh said:

في الدالة العامة التالية

انت يا عم الحاج فؤش افندى ماشى معايا بالعكس

اكتب انا الاجابة من خلال كود فى وحده نمطية تقولى انت احب اكون مباشر والاجابة مباشرة

 

اكتب انا الكود مباشر للحالات المباشرة تكتب انت الكود فى وحده نمطيه :mad:

احنا هنلعب بئه واللا ايــــه

  • Haha 1
قام بنشر

الشكر مقدما لكما فجزاكما الله خيرا

اعتمدتما على اسم الفترة .. ولكن معرف الفترة اثبت .. لأن الفترة قد يتم تعديلها مثلا من الفترة الصباحية الى كلمة الصباح فقط ...

ما علينا لا مشكلة يمكن التعديل ..

ولكني افكر بسطر واحد فقط !! يقوم بالمهمة ..

هل يمكن سطر واحد استعلام Update ان يحقق المطلوب ؟

افكر بصوت مكتوب فقط :biggrin:

 

قام بنشر
8 دقائق مضت, ابوخليل said:

اعتمدتما على اسم الفترة .. ولكن معرف الفترة اثبت .. لأن الفترة قد يتم تعديلها مثلا من الفترة الصباحية الى كلمة الصباح فقط ...

 

طيب ، كفكرة أخرى بتحديد شروط الفلترة أكثر من خلال الاستدعاء ، جرب هذا التعديل :-

Public Sub UpdateRecordSumAfterID_ByFilter(tableName As String, idField As String, idValue As Variant, targetField As String, sumField As String, Optional filterField As String = "", Optional filterValue1 As String = "", Optional filterValue2 As String = "")
    Dim rs As DAO.Recordset
    Dim total As Double
    Dim foundTarget As Boolean

    Set rs = CurrentDb.OpenRecordset(tableName, dbOpenDynaset)
    If rs.EOF Then Exit Sub
    rs.MoveFirst
    foundTarget = False
    Do Until rs.EOF
        If foundTarget Then
            If filterField <> "" Then
                If rs.Fields(filterField).Value = filterValue1 Or rs.Fields(filterField).Value = filterValue2 Then
                    total = total + Nz(rs.Fields(sumField).Value, 0)
                End If
            Else
                total = total + Nz(rs.Fields(sumField).Value, 0)
            End If
        ElseIf rs.Fields(idField).Value = idValue Then
            foundTarget = True
        End If
        rs.MoveNext
    Loop
    rs.MoveFirst
    Do Until rs.EOF
        If rs.Fields(idField).Value = idValue Then
            rs.Edit
            rs.Fields(targetField).Value = total
            rs.Update
            Exit Do
        End If
        rs.MoveNext
    Loop

    rs.Close
    Set rs = Nothing
    DoCmd.RunCommand acCmdRefresh
End Sub

 

وسيكون الإستدعاء كالآتي :-

Call UpdateRecordSumAfterID_ByFilter( _
    "tbl_Ftrat", _
    "ID", 1, _
    "countWorkHours", _
    "countWorkHours", _
    "ftraName", _
    "فترة صباحية", _
    "فترة مسائية")

 

قام بنشر
36 دقائق مضت, ابوخليل said:

لكني افكر بسطر واحد فقط !! يقوم بالمهمة ..

هل يمكن سطر واحد استعلام Update ان يحقق المطلوب ؟

افكر بصوت مكتوب فقط 

ماشى ممكن كده

سطر واحد استعلام تحديث لتحقيق المطلوب

وكمان الاعتماد الى المعرف :wink2:

 

Private Sub cmdSave_Click()
    Dim lngMinutesMorning As Long
    Dim lngMinutesEvening As Long
    Dim lngTotalMinutes As Long
    Dim datResult As Date
    
    '' === احسب عدد الدقائق للفترتين
    lngMinutesMorning = DateDiff("n", #00:00#, DLookup("countWorkHours", "tbl_Ftrat", "id=2"))
    lngMinutesEvening = DateDiff("n", #00:00#, DLookup("countWorkHours", "tbl_Ftrat", "id=3"))
    
    '' === إجمالي عدد الدقائق
    lngTotalMinutes = lngMinutesMorning + lngMinutesEvening
    
    '' === تحويله إلى نسبة يوم Date/Time
    datResult = lngTotalMinutes / 1440
    
    '' === تحديث السجل للمعرف رقم 1
    CurrentDb.Execute "UPDATE tbl_Ftrat SET countWorkHours = #" & Format(datResult, "hh:nn") & "# WHERE id = 1", dbFailOnError
        
    countWorkHours.Requery
    Me.Repaint
End Sub



وبالمرة ده تعديل بسيط للدالة داخل الوحدة النمطية

'' ==========================================================
'' الدالة: HoursAndMinutes
'' الوصف: تحويل قيمة وقت مخزنة كنسبة من اليوم (Date/Time) إلى نص يحتوي على عدد الساعات والدقائق
'' المعامل: interval - متغير يمثل مدة زمنية كنسبة من اليوم (مثلاً 0.5 = 12 ساعة)
'' الناتج: نص بصيغة "ساعات:دقائق"
'' ==========================================================
Public Function HoursAndMinutes(interval As Variant) As String
    Dim lngTotalMinutes As Long
    Dim lngHours As Long
    Dim lngMinutes As Long

    If IsNull(interval) Then Exit Function

    lngTotalMinutes = Int(CSng(interval * 24 * 60))     ' تحويل إلى عدد الدقائق
    lngHours = lngTotalMinutes \ 60                     ' الساعات الكاملة
    lngMinutes = lngTotalMinutes Mod 60                 ' باقي الدقائق

    HoursAndMinutes = lngHours & ":" & Format(lngMinutes, "00")  ' تنسيق بدقائق صفرية عند الحاجة
End Function

 

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

أنا سأكتفي بما لدي في آخر محاولة ,,

في الزر :-

Dim totalminutes As Double
totalminutes = Nz(DSum("countWorkHours", "tbl_Ftrat", "ftraName IN ('1','2') AND ID > 1"), 0)
CurrentDb.Execute "UPDATE tbl_Ftrat SET countWorkHours = " & totalminutes & " WHERE ID = 1", dbFailOnError
Me.Refresh

 

الملف المرفق :-

Database2.zip

تم تعديل بواسطه Foksh
التعامل مع القيم الفارغة = NZ
  • Haha 1
قام بنشر
3 دقائق مضت, Foksh said:

أنا سأكتفي بما لدي

لا تكتفى بما لديك

كلف نفسك عناء محاولة ايجاد و معرفة الفرق بين 

 

Private Sub cmdSave_Click()
    Dim lngMinutesMorning As Long
    Dim lngMinutesEvening As Long
    Dim lngTotalMinutes As Long
    Dim datResult As Date
    
    '' === احسب عدد الدقائق للفترتين
    lngMinutesMorning = DateDiff("n", #00:00#, DLookup("countWorkHours", "tbl_Ftrat", "id=2"))
    lngMinutesEvening = DateDiff("n", #00:00#, DLookup("countWorkHours", "tbl_Ftrat", "id=3"))
    
    '' === إجمالي عدد الدقائق
    lngTotalMinutes = lngMinutesMorning + lngMinutesEvening
    
    '' === تحويله إلى نسبة يوم Date/Time
    datResult = lngTotalMinutes / 1440
    
    '' === تحديث السجل للمعرف رقم 1
    CurrentDb.Execute "UPDATE tbl_Ftrat SET countWorkHours = #" & Format(datResult, "hh:nn") & "# WHERE id = 1", dbFailOnError
        
    countWorkHours.Requery
    Me.Repaint
End Sub

وبين الحل الاخير لك
 

Dim totalMinutes As Double
totalMinutes = DSum("countWorkHours", "tbl_Ftrat", "ftraName IN ('1','2') AND ID > 1")
CurrentDb.Execute "UPDATE tbl_Ftrat SET countWorkHours = " & totalMinutes & " WHERE ID = 1", dbFailOnError
Me.Refresh

 

  • Haha 1
قام بنشر

الكود الأول أفضل لأنه:

  • يضمن كتابة قيمة منسقة بشكل صحيح لنوع Date/Time باستخدام Format(datResult, "hh:nn") ورمزي #
  • يحدد السجلات بدقة (id=2 وid=3) وبذلك يتجنب أي سجلات غير مرغوبة
  • أكثر وضوحا للوضع الحالي حيث الهدف هو جمع ساعتين محددتين فقط

الكود الثاني أقل ملاءمة لأنه:

  • يكتب قيمة رقمية (Double) مباشرة مما قد يؤدي إلى تخزين غير صحيح (مثل أيام بدلا من ساعات) في حقل Date/Time
  • شرط ftraName IN ('1','2') AND ID > 1 قد يشمل سجلات غير مرغوبة إذا كانت هناك سجلات إضافية بـ ftraName='1' أو '2' وID > 3
قام بنشر
37 دقائق مضت, ابو جودي said:


وبالمرة ده تعديل بسيط للدالة داخل الوحدة النمطية

'' ==========================================================
'' الدالة: HoursAndMinutes
'' الوصف: تحويل قيمة وقت مخزنة كنسبة من اليوم (Date/Time) إلى نص يحتوي على عدد الساعات والدقائق
'' المعامل: interval - متغير يمثل مدة زمنية كنسبة من اليوم (مثلاً 0.5 = 12 ساعة)
'' الناتج: نص بصيغة "ساعات:دقائق"
'' ==========================================================
Public Function HoursAndMinutes(interval As Variant) As String
    Dim lngTotalMinutes As Long
    Dim lngHours As Long
    Dim lngMinutes As Long

    If IsNull(interval) Then Exit Function

    lngTotalMinutes = Int(CSng(interval * 24 * 60))     ' تحويل إلى عدد الدقائق
    lngHours = lngTotalMinutes \ 60                     ' الساعات الكاملة
    lngMinutes = lngTotalMinutes Mod 60                 ' باقي الدقائق

    HoursAndMinutes = lngHours & ":" & Format(lngMinutes, "00")  ' تنسيق بدقائق صفرية عند الحاجة
End Function

 

شكرا على الاضافة الجميلة

 

14 دقائق مضت, Foksh said:

أنا سأكتفي بما لدي في آخر محاولة ,,

في الزر :-

Dim totalMinutes As Double
totalMinutes = DSum("countWorkHours", "tbl_Ftrat", "ftraName IN ('1','2') AND ID > 1")
CurrentDb.Execute "UPDATE tbl_Ftrat SET countWorkHours = " & totalMinutes & " WHERE ID = 1", dbFailOnError
Me.Refresh

ا

ماذا يعني الرقمين هنا  ftraName IN ('1','2')

قام بنشر
3 دقائق مضت, ابوخليل said:

ماذا يعني الرقمين هنا  ftraName IN ('1','2')

 

معنى ftraName IN ('1','2'):

هذا الشرط يعني أن الاستعلام سيختار السجلات من جدول tbl_Ftrat التي يكون فيها حقل ftraName يساوي إما  1  أو  2 

بمعنى آخر:
سيتم تضمين أي سجل يكون فيه ftraName مساويا للقيمة 1  أو   2 

قام بنشر
3 دقائق مضت, ابوخليل said:

ماذا يعني الرقمين هنا  ftraName IN ('1','2')

فيما لو كانت القيمة المخزنة في جدولك يمثل رقم الفترة من جدولها ( معرف الفترة افترضت انه 1 = الصباحية ، 2 = المسائية بغض النظر عن التسمية )

قام بنشر

بس يا فؤش عندك غلط
ftraName IN (1, 2) ده المفروض لان الحقول رقمية مش نصية

انت استخدمتها: 
 ftraName IN ('1','2')
والمفروض ده لو كانت الحقول نصية يا فؤش

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

ولكن جميع القيم النصية لا تشتمل على هذه الارقام .... لم افهم

المفروض دى ارقام المعرف id

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

والمفروض ده لو كانت الحقول نصية يا فؤش

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

في المرفق :-

image.png.b9f8118af6703cafb48b4e6e7caa380c.png

 

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

  • Confused 1
قام بنشر

اصلا المفروض تكون كده يا فؤش
"tbl_Ftrat", "id IN (2, 3)"

لحقل id مش حقل ftraName 

والله يا فؤش بالمنطق انا مش عارف ليه جاب النتيجه صح
لكن المفروض يكون كده طالما هنعتمد على المعرف

 

Private Sub cmdSave_Click()
    Dim dblTotalMinutes As Double
    
    ' ' === جمع ساعات العمل للفترتين (المعرف 2 و 3)
    dblTotalMinutes = DSum("countWorkHours", "tbl_Ftrat", "id IN (2, 3)")
    
    ' ' === تحديث السجل للمعرف 1 بالقيمة المجمعة
    CurrentDb.Execute "UPDATE tbl_Ftrat SET countWorkHours = #" & Format(dblTotalMinutes, "hh:nn") & "# WHERE id = 1", dbFailOnError
    
    Me.Refresh
End Sub

 

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

اصلا المفروض تكون كده يا فؤش
"tbl_Ftrat", "id IN (2, 3)"

لحقل id مش حقل ftraName 

يا صاحبي ، شوف :-

totalminutes = Nz(DSum("countWorkHours", "tbl_Ftrat", "ftraName IN ('1','2') AND ID > 1"), 0)

انا حددتله الشرط في الحقل countWorkHours ، اللي عاوز اجمع قيمه اللي هو : ftraName والشرط كان IN ('1','2')

وشرط السجل اللي عاوز أحدثه : WHERE ID = 1"

تبقى فين امشكلة ؟؟

 

جرب عدل القيم أو نوع الحقل واحكيلي الخلل !!!!

قام بنشر

ما رأيكم بهذه الحيلة

على اعتبار ان النموذج تحكم ومعرفات السجلات لن تتغير ابدا .. ولو تم اضافة سجلات جديدة كفترات اضافية لا مشكلة ..

Dim i, ii As Date
Me.Recordset.FindFirst "id =2 "
i = countWorkHours
Me.Recordset.FindFirst "id =3 "
ii = countWorkHours
Me.Recordset.FindFirst "id =1 "
countWorkHours = i + ii

 

Database2.rar

  • Like 1
قام بنشر

ولكن ولكن ولكن 

خلينى اقول وجهة نظرى برضو

الكود الأول: 

Private Sub cmdSave_Click()
    Dim lngMinutesMorning As Long
    Dim lngMinutesEvening As Long
    Dim lngTotalMinutes As Long
    Dim datResult As Date
    
    '' === احسب عدد الدقائق للفترتين
    lngMinutesMorning = DateDiff("n", #00:00#, DLookup("countWorkHours", "tbl_Ftrat", "id=2"))
    lngMinutesEvening = DateDiff("n", #00:00#, DLookup("countWorkHours", "tbl_Ftrat", "id=3"))
    
    '' === إجمالي عدد الدقائق
    lngTotalMinutes = lngMinutesMorning + lngMinutesEvening
    
    '' === تحويله إلى نسبة يوم Date/Time
    datResult = lngTotalMinutes / 1440
    
    '' === تحديث السجل للمعرف رقم 1
    CurrentDb.Execute "UPDATE tbl_Ftrat SET countWorkHours = #" & Format(datResult, "hh:nn") & "# WHERE id = 1", dbFailOnError
        
    countWorkHours.Requery
    Me.Repaint
End Sub



الكود الثانى: 

Private Sub cmdSave_Click()
    Dim dblTotalMinutes As Double
    
    ' ' === جمع ساعات العمل للفترتين (المعرف 2 و 3)
    dblTotalMinutes = DSum("countWorkHours", "tbl_Ftrat", "id IN (2, 3)")
    
    ' ' === تحديث السجل للمعرف 1 بالقيمة المجمعة
    CurrentDb.Execute "UPDATE tbl_Ftrat SET countWorkHours = #" & Format(dblTotalMinutes, "hh:nn") & "# WHERE id = 1", dbFailOnError
    
    Me.Refresh
End Sub

الكود الأول أكثر دقة واحترافية لأنه:

  • يتعامل مع القيم كـ وقت Time فعلي (وليس كنسبة أو رقم عائم فقط)
  • يحوّل القيم يدويا من وقت إلى دقائق ثم يعيدها كنسبة من اليوم (وهذا هو التنسيق الفعلي المخزن في حقول Date/Time عند تمثيل مدة)
  • يستخدم DateDiff("n", #00:00#, ...)، ما يضمن أنك لا تتأثر بأي أخطاء ناتجة عن صيغ تخزين الوقت الداخلية في Access (زي ما ممكن يحصل عند استخدام DSum على Date/Time)
  • يضمن أن القيمة النهائية محسوبة بدقة ويتم تحويلها إلى تنسيق "hh:nn" صريح مع تمريرها باستخدام علامات # في جملة UPDATE وهو المطلوب تماما لـ Date/Time داخل SQL-Access


الكود الثاني أقل ملاءمة لأنه:

  • يجمع وقتين باستخدام DSum مباشرة وده مش مضمون 100% 
  • DSum بيجمع كأنك بتجمع تواريخ/أوقات كنسب من اليوم وليس بالضرورة عدد دقائق فعلي
  • ممكن القيم تطلع غير دقيقة إذا كانت محفوظة بصيغة غير متناسقة
 

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.

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

×
×
  • اضف...

Important Information