Link to home
Create AccountLog in
Avatar of bfuchs
bfuchsFlag for United States of America

asked on

Update Lunch column break according to schedule start/end time.

Hi Experts,

This is in reference to the following.
I would like to have the lunch column getting populated with the correct amount.

Thanks in advance.
Avatar of Martin Liss
Martin Liss
Flag of United States of America image

Please attach a sample workbook.
Avatar of bfuchs

ASKER

Hi Martin,
Everything is included in the other thread, the sample workbook along with the current logic used for calculating times, we're just missing one column which is the lunch break.
Thanks,
Ben
Please re-attach the sample workbook from that thread because I don't see it.
Avatar of bfuchs

ASKER

Attached.

Thanks,
Ben
Book4.csv
Avatar of Bill Prew
Bill Prew

Give this a try, seems to be working here...

Const ForReading = 1
Const ForWriting = 2
Const TriStateUseDefault = -2

strInFile = "B:\EE\EE29139695\Book4.csv"
strOutFile = "B:\EE\EE29139695\Book4.new"

Set objFSO = CreateObject("Scripting.FileSystemObject")
strInFile = objFSO.GetAbsolutePathname(strInFile)
strOutFile = objFSO.GetAbsolutePathname(strOutFile)

If Not objFSO.FileExists(strInFile) Then
   Wscript.Echo "ERROR: Input file """ & strInFile & """ does not exist."
   Wscript.Quit
End If

Set objFile = objFSO.OpenTextFile(strInFile, ForReading, False, TriStateUseDefault)
strData = objFile.ReadAll
objFile.Close

arrData = Split(strData, vbCrLf)

For i = 1 To UBound(arrData)

    If arrData(i) <> "" Then
        ' Split this input line into it's fields
        arrFields = Split(arrData(i), ",")
        
        ' Make sure we have at least 101 fields
        If UBound(arrFields) > 6 Then

            If arrFields(4) <> "" And arrFields(5) <> "" And arrFields(7) <> "" Then

                ' Look for matching field value and perform needed edit
                If Right(UCase(arrFields(4)), 1) <> "M" And Right(UCase(arrFields(5)), 1) <> "M" Then
                    strAmPm = GetAmPm(arrFields(4), arrFields(5), arrFields(7))
                    If strAmPm <> "" Then
                        arrFields(4) = arrFields(4) & " " & Left(strAmPm, 2)
                        arrFields(5) = arrFields(5) & " " & Right(strAmPm, 2)
                    End If
                End If

                ' Calculate lunch hours
                arrFields(6) = CalcLunchTime(arrFields(4), arrFields(5), arrFields(7))
                arrData(i) = Join(arrFields, ",")

            End If

        End If

    End If

Next

Set objFile = objFSO.OpenTextFile(strOutFile, ForWriting, True)
objFile.Write Join(arrData, vbCrLf)
objFile.Close


Function GetAmPm(strStartTime, strEndTime, strTotalHours)
    Dim dblTotalHours, i, j, datStartTime, datEndTime, arrAmPm
    arrAmPm = Array("AM", "PM")

    dblTotalHours = CDbl(strTotalHours)
    GetAmPm = ""

    For i = 0 To 1
        For j = 0 To 1
            datStartTime = CDate("1/1/1900 " & strStartTime & " " & arrAmPm(i))
            datEndTime = CDate("1/1/1900 " & strEndTime & " " & arrAmPm(j))
            If datStartTime > datEndTime Then
                datEndTime = DateAdd("d", 1, datEndTime)
            End If
            If Abs(DateDiff("h", datStartTime, datEndTime) - dblTotalHours) <= 2 Then
                GetAmPm = arrAmPm(i) & arrAmPm(j)
                Exit Function
            End If
        Next
    Next
End Function

Function CalcLunchTime(strStartTime, strEndTime, strTotalHours)
    Dim dblTotalHours, datStartTime, datEndTime

    dblTotalHours = CDbl(strTotalHours)
    datStartTime = CDate("1/1/1900 " & strStartTime)
    If Right(strStartTime, 2) = "PM" And Right(strEndTime, 2) = "AM" Then
        datEndTime = CDate("1/2/1900 " & strEndTime)
    Else
        datEndTime = CDate("1/1/1900 " & strEndTime)
    End If
    CalcLunchTime = DateDiff("h", datStartTime, datEndTime) - dblTotalHours
End Function

Open in new window


»bp
Avatar of bfuchs

ASKER

Hi,

Mostly are fine.
However some numbers are negative, see below.

StartTime      EndTime      Lunch      TotalHours      
9:00 AM      6:30 PM      -0.5      9.5       
7:00 AM      7:30 PM      -0.5      12.5       
7:15 AM      12:15 AM      -21      14       
8:00 AM      12:00 AM      -22      14       
8:00 AM      3:15 PM      -0.25      7.25       
8:00 AM      3:30 PM      -0.5      7.5       
8:00 AM      4:15 PM      -0.25      8.25       
7:00 AM      11:45 AM      -0.75      4.75       

Thanks,
Ben
Okay, give this adjustment a try:

Const ForReading = 1
Const ForWriting = 2
Const TriStateUseDefault = -2

strInFile = "B:\EE\EE29139695\Book4.csv"
strOutFile = "B:\EE\EE29139695\Book4.new"

Set objFSO = CreateObject("Scripting.FileSystemObject")
strInFile = objFSO.GetAbsolutePathname(strInFile)
strOutFile = objFSO.GetAbsolutePathname(strOutFile)

If Not objFSO.FileExists(strInFile) Then
   Wscript.Echo "ERROR: Input file """ & strInFile & """ does not exist."
   Wscript.Quit
End If

Set objFile = objFSO.OpenTextFile(strInFile, ForReading, False, TriStateUseDefault)
strData = objFile.ReadAll
objFile.Close

arrData = Split(strData, vbCrLf)

For i = 1 To UBound(arrData)

    If arrData(i) <> "" Then
        ' Split this input line into it's fields
        arrFields = Split(arrData(i), ",")
        
        ' Make sure we have at least 101 fields
        If UBound(arrFields) > 6 Then

            If arrFields(4) <> "" And arrFields(5) <> "" And arrFields(7) <> "" Then

                ' Look for matching field value and perform needed edit
                If Right(UCase(arrFields(4)), 1) <> "M" And Right(UCase(arrFields(5)), 1) <> "M" Then
                    strAmPm = GetAmPm(arrFields(4), arrFields(5), arrFields(7))
                    If strAmPm <> "" Then
                        arrFields(4) = arrFields(4) & " " & Left(strAmPm, 2)
                        arrFields(5) = arrFields(5) & " " & Right(strAmPm, 2)
                    End If
                End If

                ' Calculate lunch hours
                arrFields(6) = CalcLunchTime(arrFields(4), arrFields(5), arrFields(7))
                arrData(i) = Join(arrFields, ",")

            End If

        End If

    End If

Next

Set objFile = objFSO.OpenTextFile(strOutFile, ForWriting, True)
objFile.Write Join(arrData, vbCrLf)
objFile.Close


Function GetAmPm(strStartTime, strEndTime, strTotalHours)
    Dim dblTotalHours, i, j, datStartTime, datEndTime, arrAmPm
    arrAmPm = Array("AM", "PM")

    dblTotalHours = CDbl(strTotalHours)
    GetAmPm = ""

    For i = 0 To 1
        For j = 0 To 1
            datStartTime = CDate("1/1/1900 " & strStartTime & " " & arrAmPm(i))
            datEndTime = CDate("1/1/1900 " & strEndTime & " " & arrAmPm(j))
            If datStartTime > datEndTime Then
                datEndTime = DateAdd("d", 1, datEndTime)
            End If
            If Abs(DateDiff("h", datStartTime, datEndTime) - dblTotalHours) <= 2 Then
                GetAmPm = arrAmPm(i) & arrAmPm(j)
                Exit Function
            End If
        Next
    Next
End Function

Function CalcLunchTime(strStartTime, strEndTime, strTotalHours)
    Dim dblTotalHours, datStartTime, datEndTime

    dblTotalMins = CDbl(strTotalHours) * 60
    datStartTime = CDate("1/1/1900 " & strStartTime)
    If Right(strStartTime, 2) = "PM" And Right(strEndTime, 2) = "AM" Then
        datEndTime = CDate("1/2/1900 " & strEndTime)
    Else
        datEndTime = CDate("1/1/1900 " & strEndTime)
    End If
    CalcLunchTime = (DateDiff("n", datStartTime, datEndTime) - dblTotalMins) / 60
    Wscript.Echo strStartTime & ", " & strEndTime & ", " & datStartTime & ", " & datEndTime  & ", " & DateDiff("n", datStartTime, datEndTime) & ", " & dblTotalMins & ", " & CalcLunchTime
End Function


'====================================================================================


Sub SavedCode()
    Set objFSO = CreateObject("Scripting.FileSystemObject")

    If (WScript.Arguments.Count > 0) Then
       strInFile = objFSO.GetAbsolutePathname(WScript.Arguments(0))
    Else
       WScript.Echo "No input filename specified."
       WScript.Quit
    End If

    If (WScript.Arguments.Count > 1) Then
       strOutFile = WScript.Arguments(1)
       strOutFile = objFSO.GetAbsolutePathname(WScript.Arguments(1))
    Else
       strOutFile = strInFile
    End If

    If Not objFSO.FileExists(strInFile) Then
       Wscript.Echo "ERROR: Input file """ & strInFile & """ does not exist."
       Wscript.Quit
    End If
End Sub

Open in new window


»bp
Avatar of bfuchs

ASKER

Hi Bill,
Not in the office.
Will do it on Monday.
Have a nice weekend.
Thanks,
Ben
Avatar of bfuchs

ASKER

Hi Bill,

We are still getting negative values for lunch (3rd column), see below.

7:15 AM      12:15 AM      -21      14
8:00 AM      12:00 AM      -22      14
7:30 AM      12:00 AM      -23      15.5

Thanks,
Ben
Avatar of bfuchs

ASKER

In addition, the following records didn't get lunch, neither did they got AM/PM...

3:00      11:30            7.5
11:30      7:30            6

Thanks,
Ben
Okay, I'll have to revisit the logic I'm using and shake out the issues...


»bp
So can we clarify something?  Will the input start and end times in the file being read have AM and PM already on all values?  Or will there be no AM and PM on any values?  Or is there a mix?

The way you have the data structured with a start date but no end date makes this a challenging question, and some assumptions have to be made.  I want to make sure I know what the incoming data will always look like so I make the right assumptions.


»bp
ASKER CERTIFIED SOLUTION
Avatar of Bill Prew
Bill Prew

Link to home
membership
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
Avatar of bfuchs

ASKER

Hi,

Will the input start and end times in the file being read have AM and PM already on all values?  Or will there be no AM and PM on any values?  Or is there a mix?
There will be a mix as original data comes from from two sources, one with AM/PM and one w/o them.
The way you have the data structured with a start date but no end date
Are you referring to Start/End times? In cases where there is no start or end time I guess you can ignore them and no need to do anything.
...makes this a challenging question
If that turns out to be quite challenging perhaps would close the question and open another one on the remaining issues so you can be awarded properly.
if you want to try it there...
I can test for errors or just randomly but real testing would have to wait for users tom.

Thanks,
Ben
Avatar of bfuchs

ASKER

while testing this new version I came across these records.

7:00 PM      12:00      -12      5      

which should be filled with 12AM and no lunch.

and
 11:45      8:00      -10      6.25
which should be either AM or PM, and lunch 2 hours.

P.S. I might be wrong, so perhaps lets wait for users to say their input.

Thanks,
Ben
When I ran these two test case through the latest version I sent you:

,a,b,2/1/2019,7:00 PM,12:00,,5,,,
,a,b,2/1/2019,11:45,8:00,,6.25,,,

Open in new window

I got the correct output I believe of:

,a,b,2/1/2019,7:00:00 PM,12:00:00 AM,0,5,,,
,a,b,2/1/2019,11:45:00 AM,8:00:00 PM,2,6.25,,,

Open in new window


»bp
Avatar of bfuchs

ASKER

Hi Bill,
Not sure why it didn't show on mine yesterday but now it works.
Thank you!
Welcome.


»bp
Avatar of bfuchs

ASKER

Hi Bill,

Would prefer to add something to this script.
Are you avail for a new Q?

Thanks,
Ben
Yes, I'm still around...


»bp
Avatar of bfuchs

ASKER

Hi,

Here you go..

Thanks,
Ben