473,386 Members | 1,715 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Working with work days

55
Hi,

I'm working in Access 2000. I have a form with a series of date fields, showing the progress of a project from start to completion. There's a set of fields/controls for projected dates (when the project is projected to enter each stage of the process) and another set for actual dates. For my purposes, I'm only working with the projected dates.

There is a formula, based on the size of the project (how many hours it will take), for how many days each step of the process will require. I'm trying to set up the code so that when the projected completion date is entered, and based on the number of hours that has been entered, all the other projected dates will fill in automatically.

So in other words, if someone enters a project that will take 525 hours with a projected completion date (CompletionPJ) of 6/25/09, the database will automatically fill in the projected start date as [CompletionPJ] - 60 (and will fill in all the other projected dates in the middle according to their respective equations).

I've figured out the easy part of this (code is below), but I'm trying to figure out how to get it to count only work days. For instance, in the formula above, it would be [CompletionPJ] - [60 work days, not counting weekends or holidays].

I have a separate calendar table with CalendarID (autonumber), CalendarDate, CalendarDate2, isWorkDay, and isHoliday. (CalendarDate and CalendarDate2 are identical date fields; they make it possible for me to find the number of working days between two dates for other reports in the database.) isWorkDay and isHoliday are yes/no (all weekend dates are false in isWorkDay; weekday holidays are marked true in isHoliday). So I'm trying to figure out how to tell Access to subtract from [completionPJ] a certain number of days where isWorkDay = True and isHoliday = False.

At this point I don't have the Calendar table included in the query for this form, but I'm guessing I'll need to add it (unless it's possible to make VB code check info in a table that's not part of the data source for the form??).

Here's the code I have so far:
Expand|Select|Wrap|Line Numbers
  1. Private Sub txtCompletionPJ_AfterUpdate()
  2.  
  3. If Not IsNull(Me![txtHours]) Then
  4.  
  5.     Select Case txtHours
  6.  
  7.     Case 1 To 499
  8.         Me!txtStartPJ.Value = Me!txtCompletionPJ - 30
  9.  
  10.     Case 500 To 999
  11.         Me!txtStartPJ.Value = Me!txtCompletionPJ - 60
  12.  
  13.     Case 1000 To 1499
  14.         Me!txtStartPJ.Value = Me!txtCompletionPJ - 90
  15.  
  16.     Case 1500 To 1999
  17.         Me!txtStartPJ.Value = Me!txtCompletionPJ - 120
  18.  
  19.     Case Is >= 2000
  20.         Me!txtStartPJ.Value = Me!txtCompletionPJ - 180
  21.  
  22.     End Select
  23.  
  24. End If
  25.  
  26. End Sub
In all there are about 12 steps in the process, so there will actually be a dozen lines for each case.

Anybody have an idea to help me out?

Thanks,
Angi
Nov 12 '08 #1
2 2772
Hi, there are a few examples of workdays functions around if you google ms access workdays function, you could also look at [HTML]http://www.mvps.org/access/datetime/date0012.htm[/HTML]

Also here's a couple of functions that I've borrowed and/or reworked a few times. From what I remember I had problems with the first one, where I couldn't get it to infallibly return the correct number of days (when compared against manual counts), but I use the second one regularly without probs. I know I adapted this from one I saw elsewhere, until it worked for me in my particular context so you may also need to fiddle with it.

One thing, when I first tried to solve this same issue I spent hours and hours fighting with the original functions trying to get them to work properly - the major problem (I subsequently realised) was that I needed to control for nulls within the query formula as well as or instead of from within the formula, otherwise it just locked up and hung. Just a tip that might save you some pain!

HTH
Kevin


Expand|Select|Wrap|Line Numbers
  1. Option Compare Database
  2. Option Explicit
  3.  
  4. Function funWorkDaysDifference(dtStartDay As Date, dtEndDay As Date) As Long
  5. 'Function designed by Thom Rose - Permission to use is granted as long as you acknowledge the author
  6. 'This function calculates the number of workdays between two dates.
  7. 'The number of workdays is inclusive of the beginning and ending dates.
  8. 'There must be a table present called tblHolidays which contains the field dtObservedDate in the format date/time
  9. 'The table must list the dates of holidays to be observed.
  10. 'The user may include other fields in that table, for example, a description of the holiday being observed.
  11.  
  12. Dim lngTotalDays As Long
  13. Dim lngTotalWeeks As Long
  14. Dim dtNominalEndDay As Date
  15. Dim lngTotalHolidays As Long
  16.  
  17. 'Check to see if dtStartDay > dtEndDay.  If so, then switch the dates
  18. If dtStartDay > dtEndDay Then
  19.     dtNominalEndDay = dtStartDay
  20.     dtStartDay = dtEndDay
  21.     dtEndDay = dtNominalEndDay
  22. End If
  23. 'Here are how many weeks are between the two dates
  24. lngTotalWeeks = DateDiff("w", dtStartDay, dtEndDay)
  25. 'Here are the number of weekdays in that total week
  26. lngTotalDays = lngTotalWeeks * 5
  27. 'Here is the date that is at the end of that many weeks
  28. dtNominalEndDay = DateAdd("d", (lngTotalWeeks * 7), dtStartDay)
  29. 'Now add the number of weekdays between the nominal end day and the actual end day
  30. While dtNominalEndDay <= dtEndDay
  31.     If WeekDay(dtNominalEndDay) <> 1 Then
  32.         If WeekDay(dtNominalEndDay) <> 7 Then
  33.             lngTotalDays = lngTotalDays + 1
  34.         End If
  35.     End If
  36.     dtNominalEndDay = dtNominalEndDay + 1
  37. Wend
  38. 'Here are how many holiday days there are between the two days
  39. lngTotalHolidays = DCount("dtObservedDate", "tblHolidays", "dtObservedDate <= #" & dtEndDay & "#  AND dtObservedDate >= #" & dtStartDay & "# AND Weekday(dtObservedDate) <> 1 AND Weekday(dtObservedDate) <> 7")
  40.  
  41. 'Here are how many total days are between the two dates - this is inclusive of the start and end date
  42. funWorkDaysDifference = lngTotalDays - lngTotalHolidays
  43.  
  44. End Function

Expand|Select|Wrap|Line Numbers
  1. Public Function fWorkDays(StartDate As Variant, EndDate As Variant) As Variant
  2. 'Public Function fWorkDays(StartDate As Date, EndDate As Date) As Long
  3. On Error GoTo Err_fWorkDays
  4.  
  5. Dim intCount As Integer
  6. Dim rst As DAO.Recordset
  7. Dim DB As DAO.Database
  8.  
  9. Set DB = CurrentDb
  10. Set rst = DB.OpenRecordset("SELECT [HolidayDate] FROM tblHolidays", dbOpenSnapshot)
  11.  
  12. 'StartDate = StartDate + 1
  13. 'To count StartDate as the 1st day comment out the line above
  14.  
  15. intCount = 0
  16.  
  17. Do While StartDate <= EndDate
  18.  
  19. If Not IsNull(StartDate) And Not IsNull(EndDate) Then
  20.     rst.FindFirst "[HolidayDate] = #" & StartDate & "#"
  21.         If Weekday(StartDate) <> vbSunday And Weekday(StartDate) <> vbSaturday Then
  22.             If rst.NoMatch Then
  23.             intCount = intCount + 1
  24.             End If
  25.         End If
  26. End If
  27.  
  28. StartDate = StartDate + 1
  29.  
  30. Loop
  31.  
  32. fWorkDays = intCount
  33.  
  34. Exit_fWorkDays:
  35. Exit Function
  36.  
  37. Err_fWorkDays:
  38. Select Case Err
  39.  
  40. Case Else
  41. MsgBox Err.Description
  42. Resume Exit_fWorkDays
  43. End Select
  44.  
  45. End Function
Nov 12 '08 #2
angi35
55
Thanks for the ideas. I googled and found a function that does work in theory, but now I'm trying to figure out how to connect this function/module to the code in my form. I haven't worked with functions a whole lot, so I'm still figuring this out.

Here's the function (based on http://www.tech-archive.net/Archive/Access/microsoft.public.access.forms/2008-10/msg00851.html):

Expand|Select|Wrap|Line Numbers
  1. Public Function AddWorkDays(OriginalDate As Date, DaysToAdd As Long) As Date
  2. Dim lngAdd As Long
  3. Dim lngDayCount As Long
  4.  
  5. On Error GoTo AddWorkDays_Error
  6.  
  7. If DaysToAdd < 0 Then
  8.     lngAdd = -1
  9. Else
  10.     lngAdd = 1
  11. End If
  12.  
  13. AddWorkDays = OriginalDate
  14.  
  15. Do Until lngDayCount = DaysToAdd
  16. AddWorkDays = DateAdd("d", lngAdd, AddWorkDays)
  17. If Weekday(AddWorkDays, vbMonday) < 6 Then
  18.     If IsNull(DLookup("[holidate]", "HolidaysTable", "[holidate] = #" & _
  19.         AddWorkDays & "#")) Then
  20.         lngDayCount = lngDayCount + lngAdd
  21.     End If
  22. End If
  23. Loop
  24.  
  25. AddWorkDays_Exit:
  26. On Error GoTo 0
  27.     Exit Function
  28.  
  29. AddWorkDays_Error:
  30.     MsgBox "Error " & Err.Number & " (" & Err.Description & _
  31.         ") in procedure AddWorkDays of Module modDateFunctions", vbExclamation, conMsgTitle
  32.     GoTo AddWorkDays_Exit
  33.  
  34. End Function
In my form, txtCompletionPJ corresponds to OriginalDate in the function, and for each date (such as txtStartPJ or txt2ndStepPJ) in each Case I have to specify a certain (negative) number to correspond to DaysToAdd in the function. The end result of the function, AddWorkDays, corresponds to the date I'm trying to find (such as txtStartPJ or txt2ndStepPJ).

Here's another example of the code in my form (two cases with two controls each for now). Can you give me any guidance on how I connect the function to the form? I've tried but I haven't figured it out.

Expand|Select|Wrap|Line Numbers
  1. Option Compare Database
  2. Option Explicit
  3.  
  4. Private Sub txtCompletionPJ_AfterUpdate()
  5.  
  6. If Not IsNull(Me![txtHours]) Then
  7.     Select Case txtHours
  8.     Case 1 To 499
  9.         Me!txtStartPJ.Value = Me!txtCompletionPJ - 30
  10.         Me!txt2ndStepPJ.Value = Me!txtCompletionPJ - 25
  11.      Case 500 To 999
  12.         Me!txtStartPJ.Value = Me!txtCompletionPJ - 60
  13.         Me!txt2ndStepPJ.Value = Me!txtCompletionPJ - 53
  14.     End Select
  15. End If
  16.  
  17. End Sub
Thanks,
Angi
Nov 14 '08 #3

Sign in to post your reply or Sign up for a free account.

Similar topics

9
by: Larry Woods | last post by:
I have a site that works fine for days, then suddenly, I start getting ASP 0115 errors with an indication that session variables IN SEPARATE SESSIONS have disappeared! First, for background...
2
by: wireless200 | last post by:
I've got a table with some datetime fields in it. One field (call it field 1) is of the form mm/dd/yyyy and the other two (fields 2 and 3) are in the form of hh:mm:ss:xx where xx is hundreths of...
5
by: BlackFireNova | last post by:
I need to write a report in which one part shows a count of how many total records fall within the working days (Monday - Friday) inside of a (prompted) given date range, in a particular...
7
by: Rob R. Ainscough | last post by:
I'm using Visual Studio .NET 2003 (Visual Basic) and I can't seem to get my Task List to update automatically when I enter comment token: ' TODO: This is some stuff to do According to...
3
by: Jason Huang | last post by:
Hi, In our C# Windows Form application, we are using the SQL Server 2000 as the database server. The Database table MyTable has a field RegistrationDate which represents the Date a client comes...
5
by: paulmac106 | last post by:
Hi. I utilize the Calendar table, and I'm able to find how many working days between 2 dates, but does anyone use this table to find the 2nd or 5th working date? if 11/30/06 then 12/4/06 ...
29
by: Santiagoa | last post by:
If I set up a task table with an Date_assigned and a number of days to complete the task I calculate the end_date field by using the code below I found in this forum How ever when I enter the...
5
by: Basildk | last post by:
Hi. I have a strange problem. We have an asp.net application running on several server with different setups. On 2 of our servers we experience that the globalization settings are misbehaving....
2
by: Maninder Karir | last post by:
Hi, Im trying to work out how to return a date based on addition of working days only. On the userform the user enters the date using dtpicker. They then have the option to add 5, 10 or 15...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.