Часы между двумя датами, основанные на часах работы в VBA / Excel - PullRequest
0 голосов
/ 18 января 2019

Один из наших KPI - это часы между прибытием и отъездом, однако часы, которые мы не работаем, не учитываются. Я знаю о networkdays и networkdays.intl и изначально использовал его в одном из наших файлов

IF(IF(INDIRECT("$D"&ROW())<>"",ROUNDDOWN(IF(INDIRECT("$D"&ROW())>INDIRECT("$A"&ROW()),0,(NETWORKDAYS(INDIRECT("$D"&ROW()),INDIRECT("$A"&ROW()),$W$2:$W$100)-NETWORKDAYS(INDIRECT("$D"&ROW()),INDIRECT("$D"&ROW()),$W$2:$W$100)*MOD(INDIRECT("$D"&ROW()),1)-NETWORKDAYS(INDIRECT("$A"&ROW()),INDIRECT("$A"&ROW()),$W$2:$W$100)*(1-MOD(INDIRECT("$A"&ROW()),1)))*24),0),"")>24,"X","")

где $ A - время начала, а $ D - время окончания, а W2-W100 - праздничные дни.

Однако это не сработает, потому что наши «открытые» часы, которые учитываются для нас, - с понедельника с 6:00 до 23:00 по пятницу и с субботы с 7:00 до 14:00, но у нас есть записи, которые также охватывают диапазон с пятницы 11:00 до субботы 7:00, который должен отображаться как ноль, а также потенциально суббота с 14:00 до 22:00. У нас также есть выходные, однако в эти выходные третья смена заканчивается в 6 часов утра в тот день и начинается сначала в 6 часов утра следующего дня, поэтому некоторые цифры искажаются при использовании сетевых дней.

Я месяцами пытался понять это, но ничего не получается.

Первоначально у нас была база данных доступа, которая делала все просто: неделя (начало)> неделя (конец), время = конец - начало - 2. Очевидно, что это не соответствует нашему требованию KPI.

Я тоже пытался

    Function customTime(startTime As Date, endTime As Date, holidays As Range) As Date

Dim returnTime

returnTime = endTime - startTime - (2 * (Application.WeekNum(endTime, 2) - Application.WeekNum(startTime, 2)))
    If Application.Weekday(startTime, 2) = 6 Then returnTime = returnTime + startTime - Application.RoundDown(startTime, 0)
    If Application.Weekday(startTime, 2) = 7 Then returnTime = returnTime + startTime - Application.RoundDown(startTime, 0) + 1

For Each hols In holidays
    If startTime < hols And endTime > hols + 1 Then returnTime = returnTime - 1
Next hols
CustomTime = returnTime

End Function

, который в основном делает то же самое, что и сетевые дни, но учитывает работу в выходные дни (я думаю). В конце концов мне пришлось исправить новогоднюю ошибку.

returnTime = endTime - startTime - (2 * ((Year(endTime) * 52) + Application.WeekNum(endTime, 2) - (Year(startTime) * 52) - Application.WeekNum(startTime, 2)))

Этого было достаточно некоторое время, но сейчас мы ищем более точные данные по ним и хотим исключить все наши точные часы. Я изменил его, чтобы использовать временные метки открытия и закрытия в двух столбцах, и в процессе настройки программы, чтобы она фактически выполняла здесь математические расчеты, я искажаю синтаксис (я думаю) и заставляю его ошибаться и иногда вылетать Excel полностью.

Function CTime2(startTime As Date, endTime As Date, hoursrange As Range) As Date

Dim returnTime
returnTime = endTime - startTime

Dim hours As Variant
hours = hoursrange.Value

For i = LBound(hours, 1) + 1 To UBound(hours, 1)
    If startTime < hours(i, 1) And endTime < hours(i, 1) Then
        Exit For
    ElseIf startTime > hours(i, 2) And endTime > hours(i, 2) Then
        Next i
    ElseIf startTime > hours(i, 1) And endTime < hours(i, 2) Then
        Exit For
    ElseIf startTime < hours(i - 1, 2) And endTime > hours(i, 1) Then
        returnTime = returnTime - (hours(i, 1) - hours(i - 1, 1))
    End If
Next i
CTime2 = returnTime
End Function

Это не удалось, потому что он не может найти цикл for для выхода или следующего, не может найти цикл if для else, не может найти do для цикла while (когда я использовал это как продолжение ). Я не знаю достаточно о VBA, чтобы понять, что я делаю неправильно, или даже если я нахожусь на правильном пути.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...