• דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום
כיווץ
תחומים

תחומים - פורום חרדי מקצועי

נבוך באלגוריתם - חיפוש ימים בשבוע בתוך טווח תאריכים

מתוזמן נעוץ נעול הועבר ארכיון code613m
14 פוסטים 4 כותבים 630 צפיות
    • מהישן לחדש
    • מהחדש לישן
    • הכי הרבה הצבעות
תגובה
  • תגובה כנושא
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • א מנותק
    א מנותק
    ארכיטקט
    כתב ב נערך לאחרונה על ידי
    #1

    שלום לכולם.

    מדובר במורה מקצועי שעובד על בסיס שבועי ולא כל השבוע (נניח משני עד רביעי ס"ה 3 ימים בשבוע), כאשר רצונינו לראות כמה ימים עבד המורה בתוך טווח תאריכים נתון, שהתאריך יכול להתחיל ולהסתיים באמצע השבוע, זהו אלגוריתמינו.

    פונקציה שמקבלת טווח תאריכים, וטווח ימים רצופים בשבוע, ומחזירה את סך הימים שבהם המורה עבד בטווח הנתון.

    Function GetWeekDaysCountBetweenDates(FromDate As Date, ToDate As Date, FromDay As Integer, ToDay As Integer) As Integer
    Dim FullWeeks As Integer, Total As Long
    
    If DatePart("w", FromDate) = 1 And DatePart("w", ToDate) = 7 Then
    GetWeekDaysCountBetweenDates = (CLng(ToDate - FromDate) / 7) * ((ToDay - FromDay) + 1)
    Else
    
    FullWeeks = Max(CLng((ToDate - DatePart("w", ToDate)) - (FromDate - (7 - DatePart("w", ToDate)))), 0)
    'חישוב השבועות השלמים
    Total = Total + FullWeeks * ((ToDay - FromDay) + 1)
    
    
    'מוסיף לסכום את הימים של השבוע הראשון וזה מכסה גם מצב שבו אין שבועות שלמים כלל
    If DatePart("w", FromDate) <= ToDay Then
    Total = Total + ((ToDay - Max(FromDay, DatePart("w", FromDate))) + 1)
    End If
    
    'מוסיף לסכום את הימים של השבוע האחרון
    If DatePart("w", ToDate) >= FromDay And FullWeeks > 0 Then 'מוכרח שיש שבוע שלם אחד לפחות דאם לא כן הרי השבוע מטופל בתור שבוע ראשון ואין לטפל בו גם כשבוע אחרון
    Total = Total + ((Min(ToDay, DatePart("w", ToDate)) - FromDay) + 1)
    End If
    
    GetWeekDaysCountBetweenDates = Total
    
    End If
    
    End Function
    

    לא מצליח להגיע לקוד נקי ומצוחצח ולא רוצה לעשות עבודה ערבית עמוסת if או cases.

    תשאלו מה רע במה שעשיתי?? הנה תכניסו את הפונקציה כך:
    GetWeekDaysCountBetweenDates(#24/01/2015# ,#28/01/2015#,2,2)

    נ.ב. זה קוד VBA יש פונקציות משנה נדרשות כדלהלן:

    Function Min(var1, var2)
    If IsNull(var1) And IsNull(var2) Then Exit Function
    If IsNull(var1) Then Min = var2: Exit Function
    If IsNull(var2) Then Min = var1: Exit Function
    
    If var1 < var2 Then
    Min = var1
    Else
    Min = var2
    End If
    
    End Function
    
    Function Max(var1, var2)
    If IsNull(var1) And IsNull(var2) Then Exit Function
    If IsNull(var1) Then Max = var2: Exit Function
    If IsNull(var2) Then Max = var1: Exit Function
    
    If var1 > var2 Then
    Max = var1
    Else
    Max = var2
    End If
    
    End Function
    

    פורסם במקור בפורום CODE613 ב28/01/2015 13:28 (+02:00)

    אידיאולוגיות גדולות נכנסות למטחנה של עולם המעשה ויוצאות ממנו בפירורים (ווינסטון צ'רצ'יל, סתם סתם, זה שלי)

    תגובה 1 תגובה אחרונה
    0
  • dovidD מנותק
    dovidD מנותק
    dovid ניהול
    כתב ב נערך לאחרונה על ידי
    #2

    בשורה FullWeak יש טעות: - (FromDate - (7 - DatePart("w", ToDate)))), 0)

    פורסם במקור בפורום CODE613 ב28/01/2015 22:30 (+02:00)

    אפשר ליצור קשר dovid@tchumim.com

    תגובה 1 תגובה אחרונה
    2
  • clickoneC מנותק
    clickoneC מנותק
    clickone
    כתב ב נערך לאחרונה על ידי
    #3

    ממש בשליפה, הייתי כותב את הפונקצייה ככה:

    Function GetWeekDaysCountBetweenDates(FromDate As Date, ToDate As Date, FromDay As Integer, ToDay As Integer) As Integer
    ' משתנה טוטאל
    Dim Total As Integer
    ' משתנה מערך עבור הימים
    Dim arr(7) As Variant
    'הכנסת הימים שנבחרו למערך, באותה דרך אפשר להעביר לפונקצייה ימים לא רציפים כמערך, או מופרד בפסיקים ואחר כך SPLIT
    For i = FromDay To ToDay
        arr(i) = i
    Next i
    Dim fdate As Date
    ' מעבר על כל התאריכים ובדיקה אם היום בשבוע של התאריך נמצא במערך
    
    For fdate = FromDate To ToDate
        If (UBound(Filter(arr, DatePart("w", fdate))) > -1) Then
           'אםהיום נמצא במערך, מוסיפים 1 לטוטאל
            Total = Total + 1
        End If
    
    Next
        ' החזרת התוצאה
        GetWeekDaysCountBetweenDates = Total
    End Function
    

    מה אתה אומר?

    פורסם במקור בפורום CODE613 ב28/01/2015 23:14 (+02:00)

    אין טסט כמו פרודקשן.

    המייל שלי urivpn@gmail.com

    תגובה 1 תגובה אחרונה
    0
  • dovidD מנותק
    dovidD מנותק
    dovid ניהול
    כתב ב נערך לאחרונה על ידי
    #4

    @ClickOne

    מה אתה אומר?

    הוא יאמר שזה עובד אבל אלגוריתם לא יעיל.

    תראה יש לנו מס' ימים, ויש לנו יום בשבוע שחל היום הראשון.
    אז החשבון פשוט: (מס' הימים - היום בשבוע) / 7. זה נותן שבועות שלמים, עם שארית.
    כל מה שנשאר לנתח את השבוע הראשון ואת השארית של החלוקה הנ"ל.

    פורסם במקור בפורום CODE613 ב29/01/2015 00:08 (+02:00)

    אפשר ליצור קשר dovid@tchumim.com

    תגובה 1 תגובה אחרונה
    1
  • clickoneC מנותק
    clickoneC מנותק
    clickone
    כתב ב נערך לאחרונה על ידי
    #5

    @דוד ל.ט.

    @ClickOne

    מה אתה אומר?

    הוא יאמר שזה עובד אבל אלגוריתם לא יעיל.

    תראה יש לנו מס' ימים, ויש לנו יום בשבוע שחל היום הראשון.
    אז החשבון פשוט: (מס' הימים - היום בשבוע) / 7. זה נותן שבועות שלמים, עם שארית.
    כל מה שנשאר לנתח את השבוע הראשון ואת השארית של החלוקה הנ"ל.

    ככה זה כשאתה נמצא בבית חולים, הראש מפסיק לעבוד 😞 😞

    פורסם במקור בפורום CODE613 ב29/01/2015 01:07 (+02:00)

    אין טסט כמו פרודקשן.

    המייל שלי urivpn@gmail.com

    תגובה 1 תגובה אחרונה
    1
  • א מנותק
    א מנותק
    אהרן
    כתב ב נערך לאחרונה על ידי
    #6

    לא יודע VB אבל למה לא משהו כזה?

    boolean Day[7]
    int Days
    Day[0]:=0, Day[1]:=0, Day[2]:=1, Day[3]:=1, Day[4]:=1, Day[5]:=0, Day[6]:=0
    Days:=GetSumDays(FromDay, ToDay)
    FirstDay:=DayOfWeek(00/00/0000)
    for i:=1 to Days do
    	JobDay+=Day[(FirstDay mod 7)]
    	FirstDay += 1
    End For
    return JobDay
    

    פורסם במקור בפורום CODE613 ב29/01/2015 08:22 (+02:00)

    תגובה 1 תגובה אחרונה
    0
  • dovidD מנותק
    dovidD מנותק
    dovid ניהול
    כתב ב נערך לאחרונה על ידי
    #7

    @אהרן

    לא יודע VB אבל למה לא משהו כזה?

    boolean Day[7]
    int Days
    Day[0]:=0, Day[1]:=0, Day[2]:=1, Day[3]:=1, Day[4]:=1, Day[5]:=0, Day[6]:=0
    Days:=GetSumDays(FromDay, ToDay)
    FirstDay:=DayOfWeek(00/00/0000)
    for i:=1 to Days do
    	JobDay+=Day[(FirstDay mod 7)]
    	FirstDay += 1
    End For
    return JobDay
    

    יפה מאוד! קוד מובן ומעניין.
    אבל שוב לא יעיל, באמת חייבים לעבור בלולאה על 10000 יום?
    הרי ידוע בדיוק כמה שבועות שלמים, ואת המודולו צריך לעשות רק על השבר הראשון והאחרון.

    פורסם במקור בפורום CODE613 ב29/01/2015 13:32 (+02:00)

    אפשר ליצור קשר dovid@tchumim.com

    תגובה 1 תגובה אחרונה
    1
  • א מנותק
    א מנותק
    ארכיטקט
    כתב ב נערך לאחרונה על ידי
    #8

    נראה לי שתיקנתי עד שהלקוח יתקשר יום אחד שגנבתי לו מאות אלפי שקלים של משכורות :lol: :lol: :lol: סתם יש כאן שמורות מתמטיות וזה באמת עובד טוב...

    Function GetWeekDaysCountBetweenDates(FromDate As Date, ToDate As Date, FromDay As Integer, ToDay As Integer) As Integer
    Dim FullWeeks As Integer, Total As Long
    
    If DatePart("w", FromDate) = 1 And DatePart("w", ToDate) = 7 Then
    GetWeekDaysCountBetweenDates = (CLng(ToDate - FromDate) / 7) * ((ToDay - FromDay) + 1)
    Else
    
    FullWeeks = Max(Fix(CLng((ToDate - DatePart("w", ToDate)) - (FromDate - (7 - DatePart("w", FromDate)))) / 7), 0)
    'חישוב השבועות השלמים
    Total = Total + FullWeeks * ((ToDay - FromDay) + 1)
    
    
    'מוסיף לסכום את הימים של השבוע הראשון וזה מכסה גם מצב שבו אין שבועות שלמים כלל
    If DatePart("w", FromDate) <= ToDay Then
    Total = Total + ((ToDay - Max(FromDay, DatePart("w", FromDate))) + 1)
    End If
    
    'מוסיף לסכום את הימים של השבוע האחרון
    If DatePart("w", ToDate) >= FromDay And FullWeeks > 0 Then 'מוכרח שיש שבוע שלם אחד לפחות דאם לא כן הרי השבוע מטופל בתור שבוע ראשון ואין לטפל בו גם כשבוע אחרון
    Total = Total + ((Min(ToDay, DatePart("w", ToDate)) - FromDay) + 1)
    End If
    
    GetWeekDaysCountBetweenDates = Total
    
    End If
    
    End Function
    

    פורסם במקור בפורום CODE613 ב29/01/2015 16:00 (+02:00)

    אידיאולוגיות גדולות נכנסות למטחנה של עולם המעשה ויוצאות ממנו בפירורים (ווינסטון צ'רצ'יל, סתם סתם, זה שלי)

    תגובה 1 תגובה אחרונה
    0
  • dovidD מנותק
    dovidD מנותק
    dovid ניהול
    כתב ב נערך לאחרונה על ידי
    #9

    אין לי כח, אבל זה נראה מסובך מידי.

    פורסם במקור בפורום CODE613 ב29/01/2015 16:20 (+02:00)

    אפשר ליצור קשר dovid@tchumim.com

    תגובה 1 תגובה אחרונה
    0
  • א מנותק
    א מנותק
    אהרן
    כתב ב נערך לאחרונה על ידי
    #10

    @דוד ל.ט.

    @אהרן
    לא יודע VB אבל למה לא משהו כזה?

    boolean Day[7]
    int Days
    Day[0]:=0, Day[1]:=0, Day[2]:=1, Day[3]:=1, Day[4]:=1, Day[5]:=0, Day[6]:=0
    Days:=GetSumDays(FromDay, ToDay)
    FirstDay:=DayOfWeek(00/00/0000)
    for i:=1 to Days do
    	JobDay+=Day[(FirstDay mod 7)]
    	FirstDay += 1
    End For
    return JobDay
    

    יפה מאוד! קוד מובן ומעניין.
    אבל שוב לא יעיל, באמת חייבים לעבור בלולאה על 10000 יום?
    הרי ידוע בדיוק כמה שבועות שלמים, ואת המודולו צריך לעשות רק על השבר הראשון והאחרון.

    מה הבעיה, איטיות?

    פורסם במקור בפורום CODE613 ב29/01/2015 20:56 (+02:00)

    תגובה 1 תגובה אחרונה
    0
  • א מנותק
    א מנותק
    ארכיטקט
    כתב ב נערך לאחרונה על ידי
    #11

    @אהרן

    מה הבעיה, איטיות?

    איטיות זה אולי סימפטום, אבל הבעיה האמיתית היא שיש עקרונות ברזל שאסור להתרגל להפר אותם (וזאת עבירה חמורה יותר מאיטיות!) ראה כאן

    פורסם במקור בפורום CODE613 ב30/01/2015 00:59 (+02:00)

    אידיאולוגיות גדולות נכנסות למטחנה של עולם המעשה ויוצאות ממנו בפירורים (ווינסטון צ'רצ'יל, סתם סתם, זה שלי)

    תגובה 1 תגובה אחרונה
    0
  • א מנותק
    א מנותק
    ארכיטקט
    כתב ב נערך לאחרונה על ידי
    #12

    @דוד ל.ט.

    אין לי כח, אבל זה נראה מסובך מידי.

    הקוד עובד בדיוק כמו התוכנית שלך אין משהו יותר יעיל, אפשר לפשט אותו באמצעות משתנים, אבל זה כל כך מיותר....

    פורסם במקור בפורום CODE613 ב30/01/2015 12:43 (+02:00)

    אידיאולוגיות גדולות נכנסות למטחנה של עולם המעשה ויוצאות ממנו בפירורים (ווינסטון צ'רצ'יל, סתם סתם, זה שלי)

    תגובה 1 תגובה אחרונה
    0
  • א מנותק
    א מנותק
    אהרן
    כתב ב נערך לאחרונה על ידי
    #13

    איזה ציון מגיע לי?

    boolean Day[7]
    int Days
    Day[0]:=0, Day[1]:=0, Day[2]:=1, Day[3]:=1, Day[4]:=1, Day[5]:=0, Day[6]:=0
    Days:=GetSumDays(FromDay, ToDay)
    FirstDay:=DayOfWeek(00/00/0000)
    Days -: ( 7 - FirstDay )
    LastDay := Days mod 7
    SunWeeks := Days div 7
    
    for i:=1 to 7 do
    
    		\\ FirstWeek
       JobDay += ( Day[i-1] * ( i= > FirstDay ))
    
    		\\ LastWeek
       JobDay += ( Day[i-1] * (i =< LastDay ))
    
    		\\ NormalWeek
    	JobDay += Day[i-1] * SunWeeks
    
    End For
    return JobDay
    

    פורסם במקור בפורום CODE613 ב01/02/2015 20:20 (+02:00)

    תגובה 1 תגובה אחרונה
    0
  • א מנותק
    א מנותק
    אהרן
    כתב ב נערך לאחרונה על ידי
    #14

    הוהו כמה טעויות היה כאן,
    חושב שעכשיו אמור לעבוד.

    פורסם במקור בפורום CODE613 ב01/02/2015 20:33 (+02:00)

    תגובה 1 תגובה אחרונה
    0

  • התחברות

  • אין לך חשבון עדיין? הרשמה

  • התחברו או הירשמו כדי לחפש.
  • פוסט ראשון
    פוסט אחרון
0
  • דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום
  • התחברות

  • אין לך חשבון עדיין? הרשמה

  • התחברו או הירשמו כדי לחפש.