1с проверить пересечение периодов
У меня есть четыре объекта DateTime. А1, А2 и В1, В2.
Мне нужно знать, что период A1-A2 не пересекается с периодом B1-B2. Но я не хочу писать грязный код, как многие блоки if.
Я пытался использовать это: Сравнение диапазонов
Он вернул true , но я ожидал false . Потому что этот код всегда возвращает true
Я не думаю, что такой код грязный, я думаю, что лучшее, что вы можете/должны сделать, чтобы очистить его, это просто назвать переменные чем-то значимым, а не A1, B2, C3.
Никак не обойти это:
* Отредактировано для упрощения:
Предполагая, что B2>B1 и A2>A1:
Это обнаружит, находится ли какая- либо часть A1-A2 в B1-B2.
Если вам нужно определить, полностью ли A1-A2 находится в B1-B2:
Если в вашей программе диапазоны A1-A2 и B1-B2 являются «правильными» в том смысле, что известно, что A1
тогда ваш тест на непересечение просто
Обратите внимание, что я не упомянул, является ли это > или >=. Правильный выбор оператора зависит от того, как вы определили свои диапазоны, чтобы включить или исключить их конечные точки; т.е. представляют ли они закрытые, открытые или полуоткрытые интервалы.
В моем случае я хотел наоборот, я хотел знать, пересекаются ли эти диапазоны, поэтому я просто вставляю НЕ в тест. В моем случае я использовал if(!(A1>B2 || B1>A2)) простой для использования в лямбда-выражениях.
Methods like IsSamePeriod, HasInside, OverlapsWith, or IntersectsWith are available for convenience to query for special, often used variants of such period relations.
Мой подход заключается в создании класса, Period который содержит Start и End свойства (DateTime). Этот класс может иметь методы или методы расширения для вычисления таких вещей, как пересечения. Допустим, у вас есть такой метод в вашем классе Period:
Затем вы можете написать такой код:
Намного проще и эффективнее, чем принятый ответ. Только два теста, а не куча если/то, лучшее решение здесь.
Я не верю, что будет какой-то «легкий» код для написания; вы должны учитывать 4 различных варианта использования. Если вам нужно часто выполнять такие проверки, я бы написал метод расширения. В противном случае вам просто нужно проверить эти условия:
РЕДАКТИРОВАТЬ: Чтобы предоставить фактический код:
Это должно охватывать варианты использования.
Кроме того, ваш код кажется чрезмерно сложным, потому что вы создали четыре случая из двух, которые могли бы быть. Ваши случаи два и три - это один и тот же случай, а именно случай "является ли конец Date2 внутри Date1"? И ваши случаи один и четыре - это один и тот же случай, а именно: "конец даты1 внутри даты2?"
В качестве альтернативы вы можете показать, что ваши четыре случая сводятся к двум, рассмотрев противоположное . Превратите вопрос из «сколько существует способов перекрытия?» на «сколько способов НЕ перекрываться?» Есть только два. Либо второй диапазон дат начинается после окончания первого, либо первый диапазон дат начинается после окончания второго. Если ни один из этих двух случаев не соответствует действительности, то они пересекаются. Вам не нужно рассматривать четыре способа, которыми они пересекаются, если вы просто рассматриваете два способа, которыми они не пересекаются.
В этом прелесть решения Кори Косака ниже. Гораздо проще, чем это. Есть и другие ответы, которые выражают ту же простоту (включая мой), но я считаю, что Кори был первым, кто опубликовал его.
@Tejs: я проголосовал против этого, потому что, хотя он был выбран ОП, он не соответствует ключевому требованию, которое он опубликовал: «Я не хочу писать грязный код, как многие блоки if». Есть более чистые способы сделать это.
Собираюсь решить задачу, но ни разу с таким не сталкивался - может кто имеет опыт и поделиться?
Задача - необходимо проанализировать гарфик работника(по периодам в часах)(это план) и проходы его через электронную проходную(факт)
на основании анализа ввести документы отклонений(типа прогул)
итого сотрудник отсутствовал всего 1:30 и нужно ввести документ отклонения от графика как прогул на 1:30.
Пересечение 2 конкретных периодов можно отловить и проаналзировать а вот как проанализировать пересечения групп периодов ?
Если кто сталкивался с такой задачей, буду рад любому совету.
В чем проблема.
Добавь к периодам плана поле "ЧасовПоПлану" и вычитай из него часы тех периодов факта, которые в них попали.
(0) А если он не хочет никуда выходить на обед?
Не проще считать время проведенное на территории и если оно меньше того, что он должен отработать, тогда уже прогул
(2) Ты еще предложи не считать прогулы, если работник справляется со своими обязанностями. Не для того такие системы внедряются.
(2)
проще - но у кадров свой однозначный запрос - зачем? - не могу знать!
есть трафарет(план) и факт должен с ним совпадать.
Насчет обедов - допускается присутствие сотрудников во время обеда на территории, но это время согласно плану не считается рабочим.
(0) Не понял, почему в обед нужно сразу писать прогул, а после обеда "нужно посмотреть другие периоды"?
Нужно уточнить постановку. Если общее время за день закрывает план, этого достаточно? А за месяц?
(4) Чем отличается:
> 12-12:30 и 12-13 - факт обеда больше на 30 минут - нужно ввести прогул на 30 минут
от
> 12:30-17 и 13-15 - факт не закрывает план - но ничего не вводим - нужно посмотреть другие периоды, вдруг он дальше все закрыл
Почему там нужно, а тут не нужно?
(5) Недостаточно - рабочим временем в итоге учитывается время которое строго вошло в рамки плана.
Кстати - факт и план я собрал, в том же виде как они приведены в примере(т.е. периодами)
но как их сравнить? не могу понять.
(7) Суммируешь время проведенное на территории в 2 интервалах (до обеда и после обеда) - это есть факт
Время по плану и так известно и их сравниваешь.
(6) скорректирую пример
Факт
16-17
вот так лучше - 12-13 человек не был на территории.(вышел в 12 и вернулся только в 13) т.к. это время ближе всего к периоду плана "обед" то и сравниваем с ним.
И немного не понятно тут "факт не закрывает план - но ничего не вводим - нужно посмотреть другие периоды, вдруг он дальше все закрыл".
Как он в принципе может "закрыть" дальше, если вы не даете ему работать свыше плана
(13) например факт может быть таким
15:10-17
Тогда человек всего 10 минут не был на рабочем месте - предположим что он встречал курьера. в любом случаем до 15 минут отклонений за раз - мы ему простим итого план он выполнил.
(14) Тогда так.
1) Взять пересечения интервалов факта и плана (только рабочее время), Просуммировать.
2) Просуммировать план (только рабочее время).
3) Сравнить, разницу пишем в прогул.
(4) Нет. Не свожу. Из остатка часов планового присутствия вычитаются только то количество часов, которое определяется пересечением фактического периода с плановыми. Мне казалось, это очевидно.
Удобнее всего, как я и говорил, просто добавить в табличку периодов планового присутствия колонку, где на старте рассчитать количество плановых часов присутствия для каждого периода.
Потом при обходе фактических периодов пробегаешься по табличке плановых периодов и "примеряешь" каждый фактический период к каждому плановому. Если есть пересечение, то вычитаешь количество часов НА ПЕРЕСЕЧЕНИИ из количества часов планового присутствия для периода. Итог по колонке в конце даст общее количество часов прогула.
Можно и без колонки, тупо из общего количества часов планового присутствия вычитать. Но так не останется инфы, в какие конкретно периоды сотр не вписался, а это может быть полезным.
Это как раз фигня задача. Я как увидел тему, подумал что речь про более интересную задачу - как получить эти самые периоды фактического присутствия из данных СКУД, где вход и выход отдельными событиями пишется. С учетом всевозможных отклонений. Двойных срабатываний, проходом без отметки и так далее.
мыслите множествами. тогда пересечение интервалов не важно. а важно только общая сумма отработанных часов.
(19) Сравнивать каждый с каждым хм. я такое предлагал кадрам но они почему то забраковали. сегодня добьюсь от них письменного ответа. спасибо.
(20) да случаи прохода бывают разные, "волшебные" - 2 входа подряд с разницей в 2 часа. пока принято решение что это был выход по "чужой карте" и наказывается не зачётом того периода где нет выхода.
(23) Причем тут вообще "кадры"? Это детали внутренней реализации.
У тебя же небольшое количество периодов планового присутствия. В сабже - два. Дообеденный и послеобеденный. В чем проблема сравнивать их на пересечение с каждым фактическим?
(23) Вот интересно - а у программистов, разрабатывающих эту чудо-систему, есть план пристуствия на рабочем месте, который надо закрывать? Или это другое?
(24) в чем проблема - если у нас 1 вид документа отклонения(прогул) на любое отклонение от плана и мы можем все отклонения просто просуммировать между собой, если больше одного то получается что на каждое отклонение от плана необходимо вводить свой документ(со своим видом)(например прогул И отпуск без сохранения зп(уж не знаю чем это от прогула отличается, но вот такое бывает))
(25) план есть у любого сотрудника предприятия(даже у директора) - часть программистов не являются сотрудниками текущего предприятия и имеют право свободного входа\выхода. любопытный вы наш.
ну и как мы узнаем отклонение в часах при
План
12:30-17
Если последовательно сравнивать периоды - то 12:30-17 и 13-15 даст отклонение в 2,5 часа от плана
и 12:30-17 и 16-17 - 3,5 часа. после того как просуммируем будет отклонение 6 часов. что неверно - ведь реальное отклонение только 1,5 часа с 12:30-13 и с 15-16 - этого мы не сможем узнать просто последовательно сравнивая периоды. так что пока план нерабочий.
внедряя подобные системы не нужно забывать о том что любое действие порождает противодействие.
чем жестче закручивают гайки контролируя каждый шаг сотрудников и карая за любое отклонение тем меньше сотрудник заинтересован в результатах своего труда, а лишь в соблюдении всего этого бреда за который могут наказать.
через некоторое время адекватные люди задаются вопросом а нахрена я вообще тут нахожусь если вместо работы голова забита только прогулами объяснительными как не опоздать как не выйти позже чем положено и т.д. и уходят туда где нет подобного бреда.
(29) а без этого тривиальная задача.
перебираем фактические периоды, вырезаем их из плановых. все что осталось - отсутствия. все что сверху вырезалось - переработки.
дальше поступаем с этими периодами согласно имеющемуся ТЗ. вводим документы например.
(29) Мне чет не совсем понятно, что это за отметки факта, у вас сотрудники по несколько раз на дню через проходную проходят? Если так, то если человек вышел через проходную не в обед, то все, прогул?
(32) у нас на предприятии проще, считаются только крайние отметки, чтобы зафиксировать когда пришел на работу и когда ушел домой. Обед вообще не привязан ко времени, есть час в течении дня, когда захотел, тогда и покушал. И нет никаких проблем
(27) Не понял, как ты считаешь.
Факт 13:00 - 15.00 (2 часа, они же результат пересечения с планом, вычитаем из плана остается остаток 2.5 плановых часа)
Факт 16:00 - 17:00 (1 час, он же результат пересечения с планом, вычитаем из остатка плановых часов, остается 1.5 плановых часа)
(32) все верно
проход через проходную может быть сколько угодно раз в день. отсутствие на предприятии больше 15 минут в рабочее(плановое) время - сразу прогул.
Ну смотри сравниваем последовательно периоды
план
12:30-17
1. 12:30-17 и 13-15 даст отклонение в 2,5 часа от плана - 12:30-13 - 30 минут и 15-17 2 часа. итого отклонения по текущему факту 2,5 часа
2. 12:30-17 и 16-17 - 3,5 часа. с 12:30 - 16 - 3,5 часа отклонения.
Итого 6 часов отклонения.
а ты как предлагаешь?
У вас графики работы с началом и окончанием рабочего времени? Время обеда прописано? Внутрисменные неявки с привязкой ко времени?
(41) Я тебе уже на пальцах расписал. Не тупи. Пересечение множеств/промежутков - это их общая часть. А ты чего насчитал?
(45) Нарисуй на бумажке два отрезочка. Один под другим. Заштрихуй ту часть, где одновременно две линии придется. Это и будет общая часть. Пересечение.
(47) Писал навскидку, поэтому лучше перепроверить:
(48) Уважаемый у нас же не двух а 3 - как вы утверждаете
так вот мой вопрос - как т определяешь что эти 2 периода это некая общая часть?
(49) Уважаемый писатель. Перечитайте еще раз мои посты. Особенное внимание посту (36) на вашем же примере. Нигде не было речи про ОДНОВРЕМЕННОЕ сравнение трех периодов. Речь о попарном сравнении всех плановых периодов с каждым фактическим.
Там где про "общую" часть писалось - это про сравнение ДВУХ периодов. А не трех. Потому что ты не понимал что такое пересечение двух множеств и вместо этого считал их разность.
(50) можно алгоритм этого "попарного сравнения"?
я знаю только алгоритм сравнения 2 периодов между собой (именного его вы и привели).
еще раз в (48) вы указали сравнение 2 периодов между собой. а что за алгоритм "Речь о попарном сравнении всех плановых периодов с каждым фактическим". как вы выразились - можно его увидеть?
(55) имея вот такие простые входные данные
План
12:30-17
итого 16200-9000 -12600 = -5400 сек. что неверно.
верный ответ 5400 сек отклонения от плана.
то ваш алгоритм и того ошибочней посчитает.
(37) вообще-то прогул по ТК это совсем другое.
и ваши истории с прогулом за 15 минутное опоздание продолжаются ровно до того момента пока не найдется принципиальный и грамотный сотрудник который натравит на вас трудинспекцию, которая вас там уже всех за такие прогулы поставит в коленно-локтевую позицию.
(60) А по теме до сих пор вопросы остались?
(61) остались. я привел пример расчета по вашему циклу в (56) - вы нет.
откуда вы взяли ваш результат мне решительно непонятно. прошу раскрыть вопрос.
(62) Подставил эти исходные данные в (55)
А вот проверка для (57):
(65) Приношу свои искренние извинения за свой тупизм.
На тестовом примере алгоритм выдал верный результат.
ухожу в отладку и применение алгоритма к реальным данным.
Ближе к вечеру отпишу все ли нормально.
Спасибо за помощь.
еще раз. прошу меня простить, что я неверно прочитал алгоритм, а он работает так как задумано.
(66) Я до последнего не был уверен, что ты не троллишь и успел и разозлиться и пожалеть, что ввязался.
Так что тоже извиняюсь, если был местами резок. Но мне казалось, что это довольно тривиальная задача и тема себя быстро исчерпает.
(67) ты еще погоди.
я же только на тестовом примере проверил.
надо
проверить на реальных данных, возможно там будет не так все радужно.
но в любом случае , спасибо за помощь.
выдает корректный результат
Отсутствовал 15 минут (которые прощаются, но главное что мы их видим).
Еще раз спасибо. продолжаю тестирование.
(0) о, я с этой темой сталкивался очень подробно.
Реализовывал одну такую систему. Пиши в лычку, скину описалово.
для затравки:
Учет отметок о приходе
Время сотрудника первоначально делится на моменты его нахождения на работе и за ее пределами, например, так:
При этом первая и последняя запись всегда «на работе». На работе обозначает что сотрудник находился на рабочем месте, на территории предприятия
Расписания вводятся в базе «1С: Биометрия».
Расписания заносятся в справочник «Расписания».
Учет отклонений рабочего времени
Когда задано расписание, то появляется возможность учитывать отклонения рабочего времени.
Виды рабочего времени бывают такими:
1. Рабочее время (РВ) – сотрудник находится на рабочем месте.
2. Опоздание (ОП) – сотрудник пришел на работу позже назначенного времени
5. Перерыв (ПР) – сотрудник ушел с работы внутри интервала не рабочего времени.
6. Прогул (НВ) – если сотрудник должен быть на рабочем месте, но отсутствовал, задается рамками начала и окончания рабочего дня.
7. Отсутствие(ОТ) – сотрудник ушел с работы внутри интервала рабочего времени.
8. Прогул (ПГ) – прогул.
Каждый интервал времени расписания помечается следующими полями:
1. Рабочее время – флажок того, что время считается рабочим. Если не установлен, то время не рабочее, например, перерыв – не рабочее время.
2. Опоздание – фиксировать опоздание, если первая отметка рабочего времени позже интервала.
3. Преждевременный уход – фиксировать преждевременный уход, если последняя отметка рабочего времени раньше интервала.
4. Переработка – присутствие сотрудника в этом интервале времени считается переработкой.
5. Перерыв – время относится к перерыву.
Для расписания в целом задаются следующие параметры:
1. Норма перерывов – какое количество перерывов допустимо в течении рабочего дня. Время, превышающее норму перерывов относится в «Отсутствие».
2. Максимальное опоздание – какое максимальное опоздание начисляется, в минутах. После этого время относится в «Отсутствие». Если не задано, то опоздание считается по факту.
3. Допустимое опоздание – какое опоздание разрешается, в минутах.
4. Вычитать допустимое опоздание – если флаг установлен, то из зафиксированного опоздания вычитается допустимое опоздание, иначе опоздание считается без вычетов.
5. Максимальная переработка – какое максимальное время переработки учитывается. Если не задано, то переработка учитывается по факту.
6. Максимальный преждевременный уход – какое максимальное время преждевременного ухода учитывать.
7. Допустимый преждевременный уход – какой преждевременный уход разрешается, в минутах.
8. Вычитать допустимый преждевременный уход – если флаг установлен, то из зафиксированного преждевременного ухода вычитается преждевременный уход, иначе преждевременный уход считается без вычетов.
9. Минимальное рабочее время – если задано, то в случае, если рабочее время получилось меньше, рабочее время обнуляется и фиксируется прогул.
Итогом расчета рабочего времени является список интервалов, каждый из которых относится к определенному виду времени.
В итоге получается сумма по каждому из видов времени в минутах. Она сохраняется по каждому расчету в регистре «Начисленное время».
Пример: Рабочее время 420, Опоздание 10, Перерыв 60, Переработка 30.
Чтобы скорректировать рабочее время используется регистр «Корректировки времени», где для каждого сотрудника на определенную дату можно указать другое значение по виду времени. Значения из этого регистра имеют приоритет над расчетными. Каждую запись можно сопроводить комментарием.
Пример: Сотрудник ездил по делам в течении трех часов, в итоге у него Отсутствие 180. Нужно создать корректировочную запись Отсутствие 0, с комментарием «Отсутствие по делам, согласовано с руководством».
Пример: Сотрудник опоздал на час из-за сбоя в работе транспорта, в итоге у него Опоздание 60. Нужно создать корректировочную запись Опоздание 0, с комментарием «Опоздал из-за сбоя транспорта, объяснительная приложена и проверена Ивановым И.И.».
Назначение расписаний сотрудникам
В регистре «Назначения» назначается расписание сотрудникам. Одному сотруднику можно назначить на дату несколько расписаний, тогда по каждому из них ему будут посчитаны показатели рабочего времени.
Алгоритм расчета часов по расписаниям
Алгоритм позволяет определить прогулы сотрудников. Поэтому анализируются данные за выбранный в обработке период времени. Если период не выбран, то используется дата от начальной до минимальной.
Изначально таблица проходов рассчитывается в разрезе Person ID + Дата + Точка.
Затем за каждый анализируемый день по таблице назначения расписаний определяется, какие расписания действуют для сотрудников на этот день.
Формируется таблица расчета часов в разрезе: Физлицо + Дата + Точка + Расписание + Подразделение.
Собираюсь решить задачу, но ни разу с таким не сталкивался - может кто имеет опыт и поделиться?
Задача - необходимо проанализировать гарфик работника(по периодам в часах)(это план) и проходы его через электронную проходную(факт)
на основании анализа ввести документы отклонений(типа прогул)
итого сотрудник отсутствовал всего 1:30 и нужно ввести документ отклонения от графика как прогул на 1:30.
Пересечение 2 конкретных периодов можно отловить и проаналзировать а вот как проанализировать пересечения групп периодов ?
Если кто сталкивался с такой задачей, буду рад любому совету.
В чем проблема.
Добавь к периодам плана поле "ЧасовПоПлану" и вычитай из него часы тех периодов факта, которые в них попали.
(0) А если он не хочет никуда выходить на обед?
Не проще считать время проведенное на территории и если оно меньше того, что он должен отработать, тогда уже прогул
(2) Ты еще предложи не считать прогулы, если работник справляется со своими обязанностями. Не для того такие системы внедряются.
(2)
проще - но у кадров свой однозначный запрос - зачем? - не могу знать!
есть трафарет(план) и факт должен с ним совпадать.
Насчет обедов - допускается присутствие сотрудников во время обеда на территории, но это время согласно плану не считается рабочим.
(0) Не понял, почему в обед нужно сразу писать прогул, а после обеда "нужно посмотреть другие периоды"?
Нужно уточнить постановку. Если общее время за день закрывает план, этого достаточно? А за месяц?
(4) Чем отличается:
> 12-12:30 и 12-13 - факт обеда больше на 30 минут - нужно ввести прогул на 30 минут
от
> 12:30-17 и 13-15 - факт не закрывает план - но ничего не вводим - нужно посмотреть другие периоды, вдруг он дальше все закрыл
Почему там нужно, а тут не нужно?
(5) Недостаточно - рабочим временем в итоге учитывается время которое строго вошло в рамки плана.
Кстати - факт и план я собрал, в том же виде как они приведены в примере(т.е. периодами)
но как их сравнить? не могу понять.
(7) Суммируешь время проведенное на территории в 2 интервалах (до обеда и после обеда) - это есть факт
Время по плану и так известно и их сравниваешь.
(6) скорректирую пример
Факт
16-17
вот так лучше - 12-13 человек не был на территории.(вышел в 12 и вернулся только в 13) т.к. это время ближе всего к периоду плана "обед" то и сравниваем с ним.
И немного не понятно тут "факт не закрывает план - но ничего не вводим - нужно посмотреть другие периоды, вдруг он дальше все закрыл".
Как он в принципе может "закрыть" дальше, если вы не даете ему работать свыше плана
(13) например факт может быть таким
15:10-17
Тогда человек всего 10 минут не был на рабочем месте - предположим что он встречал курьера. в любом случаем до 15 минут отклонений за раз - мы ему простим итого план он выполнил.
(14) Тогда так.
1) Взять пересечения интервалов факта и плана (только рабочее время), Просуммировать.
2) Просуммировать план (только рабочее время).
3) Сравнить, разницу пишем в прогул.
(4) Нет. Не свожу. Из остатка часов планового присутствия вычитаются только то количество часов, которое определяется пересечением фактического периода с плановыми. Мне казалось, это очевидно.
Удобнее всего, как я и говорил, просто добавить в табличку периодов планового присутствия колонку, где на старте рассчитать количество плановых часов присутствия для каждого периода.
Потом при обходе фактических периодов пробегаешься по табличке плановых периодов и "примеряешь" каждый фактический период к каждому плановому. Если есть пересечение, то вычитаешь количество часов НА ПЕРЕСЕЧЕНИИ из количества часов планового присутствия для периода. Итог по колонке в конце даст общее количество часов прогула.
Можно и без колонки, тупо из общего количества часов планового присутствия вычитать. Но так не останется инфы, в какие конкретно периоды сотр не вписался, а это может быть полезным.
Это как раз фигня задача. Я как увидел тему, подумал что речь про более интересную задачу - как получить эти самые периоды фактического присутствия из данных СКУД, где вход и выход отдельными событиями пишется. С учетом всевозможных отклонений. Двойных срабатываний, проходом без отметки и так далее.
мыслите множествами. тогда пересечение интервалов не важно. а важно только общая сумма отработанных часов.
(19) Сравнивать каждый с каждым хм. я такое предлагал кадрам но они почему то забраковали. сегодня добьюсь от них письменного ответа. спасибо.
(20) да случаи прохода бывают разные, "волшебные" - 2 входа подряд с разницей в 2 часа. пока принято решение что это был выход по "чужой карте" и наказывается не зачётом того периода где нет выхода.
(23) Причем тут вообще "кадры"? Это детали внутренней реализации.
У тебя же небольшое количество периодов планового присутствия. В сабже - два. Дообеденный и послеобеденный. В чем проблема сравнивать их на пересечение с каждым фактическим?
(23) Вот интересно - а у программистов, разрабатывающих эту чудо-систему, есть план пристуствия на рабочем месте, который надо закрывать? Или это другое?
(24) в чем проблема - если у нас 1 вид документа отклонения(прогул) на любое отклонение от плана и мы можем все отклонения просто просуммировать между собой, если больше одного то получается что на каждое отклонение от плана необходимо вводить свой документ(со своим видом)(например прогул И отпуск без сохранения зп(уж не знаю чем это от прогула отличается, но вот такое бывает))
(25) план есть у любого сотрудника предприятия(даже у директора) - часть программистов не являются сотрудниками текущего предприятия и имеют право свободного входа\выхода. любопытный вы наш.
ну и как мы узнаем отклонение в часах при
План
12:30-17
Если последовательно сравнивать периоды - то 12:30-17 и 13-15 даст отклонение в 2,5 часа от плана
и 12:30-17 и 16-17 - 3,5 часа. после того как просуммируем будет отклонение 6 часов. что неверно - ведь реальное отклонение только 1,5 часа с 12:30-13 и с 15-16 - этого мы не сможем узнать просто последовательно сравнивая периоды. так что пока план нерабочий.
внедряя подобные системы не нужно забывать о том что любое действие порождает противодействие.
чем жестче закручивают гайки контролируя каждый шаг сотрудников и карая за любое отклонение тем меньше сотрудник заинтересован в результатах своего труда, а лишь в соблюдении всего этого бреда за который могут наказать.
через некоторое время адекватные люди задаются вопросом а нахрена я вообще тут нахожусь если вместо работы голова забита только прогулами объяснительными как не опоздать как не выйти позже чем положено и т.д. и уходят туда где нет подобного бреда.
(29) а без этого тривиальная задача.
перебираем фактические периоды, вырезаем их из плановых. все что осталось - отсутствия. все что сверху вырезалось - переработки.
дальше поступаем с этими периодами согласно имеющемуся ТЗ. вводим документы например.
(29) Мне чет не совсем понятно, что это за отметки факта, у вас сотрудники по несколько раз на дню через проходную проходят? Если так, то если человек вышел через проходную не в обед, то все, прогул?
(32) у нас на предприятии проще, считаются только крайние отметки, чтобы зафиксировать когда пришел на работу и когда ушел домой. Обед вообще не привязан ко времени, есть час в течении дня, когда захотел, тогда и покушал. И нет никаких проблем
(27) Не понял, как ты считаешь.
Факт 13:00 - 15.00 (2 часа, они же результат пересечения с планом, вычитаем из плана остается остаток 2.5 плановых часа)
Факт 16:00 - 17:00 (1 час, он же результат пересечения с планом, вычитаем из остатка плановых часов, остается 1.5 плановых часа)
(32) все верно
проход через проходную может быть сколько угодно раз в день. отсутствие на предприятии больше 15 минут в рабочее(плановое) время - сразу прогул.
Ну смотри сравниваем последовательно периоды
план
12:30-17
1. 12:30-17 и 13-15 даст отклонение в 2,5 часа от плана - 12:30-13 - 30 минут и 15-17 2 часа. итого отклонения по текущему факту 2,5 часа
2. 12:30-17 и 16-17 - 3,5 часа. с 12:30 - 16 - 3,5 часа отклонения.
Итого 6 часов отклонения.
а ты как предлагаешь?
У вас графики работы с началом и окончанием рабочего времени? Время обеда прописано? Внутрисменные неявки с привязкой ко времени?
(41) Я тебе уже на пальцах расписал. Не тупи. Пересечение множеств/промежутков - это их общая часть. А ты чего насчитал?
(45) Нарисуй на бумажке два отрезочка. Один под другим. Заштрихуй ту часть, где одновременно две линии придется. Это и будет общая часть. Пересечение.
(47) Писал навскидку, поэтому лучше перепроверить:
(48) Уважаемый у нас же не двух а 3 - как вы утверждаете
так вот мой вопрос - как т определяешь что эти 2 периода это некая общая часть?
(49) Уважаемый писатель. Перечитайте еще раз мои посты. Особенное внимание посту (36) на вашем же примере. Нигде не было речи про ОДНОВРЕМЕННОЕ сравнение трех периодов. Речь о попарном сравнении всех плановых периодов с каждым фактическим.
Там где про "общую" часть писалось - это про сравнение ДВУХ периодов. А не трех. Потому что ты не понимал что такое пересечение двух множеств и вместо этого считал их разность.
(50) можно алгоритм этого "попарного сравнения"?
я знаю только алгоритм сравнения 2 периодов между собой (именного его вы и привели).
еще раз в (48) вы указали сравнение 2 периодов между собой. а что за алгоритм "Речь о попарном сравнении всех плановых периодов с каждым фактическим". как вы выразились - можно его увидеть?
(55) имея вот такие простые входные данные
План
12:30-17
итого 16200-9000 -12600 = -5400 сек. что неверно.
верный ответ 5400 сек отклонения от плана.
то ваш алгоритм и того ошибочней посчитает.
(37) вообще-то прогул по ТК это совсем другое.
и ваши истории с прогулом за 15 минутное опоздание продолжаются ровно до того момента пока не найдется принципиальный и грамотный сотрудник который натравит на вас трудинспекцию, которая вас там уже всех за такие прогулы поставит в коленно-локтевую позицию.
(60) А по теме до сих пор вопросы остались?
(61) остались. я привел пример расчета по вашему циклу в (56) - вы нет.
откуда вы взяли ваш результат мне решительно непонятно. прошу раскрыть вопрос.
(62) Подставил эти исходные данные в (55)
А вот проверка для (57):
(65) Приношу свои искренние извинения за свой тупизм.
На тестовом примере алгоритм выдал верный результат.
ухожу в отладку и применение алгоритма к реальным данным.
Ближе к вечеру отпишу все ли нормально.
Спасибо за помощь.
еще раз. прошу меня простить, что я неверно прочитал алгоритм, а он работает так как задумано.
(66) Я до последнего не был уверен, что ты не троллишь и успел и разозлиться и пожалеть, что ввязался.
Так что тоже извиняюсь, если был местами резок. Но мне казалось, что это довольно тривиальная задача и тема себя быстро исчерпает.
(67) ты еще погоди.
я же только на тестовом примере проверил.
надо
проверить на реальных данных, возможно там будет не так все радужно.
но в любом случае , спасибо за помощь.
выдает корректный результат
Отсутствовал 15 минут (которые прощаются, но главное что мы их видим).
Еще раз спасибо. продолжаю тестирование.
(0) о, я с этой темой сталкивался очень подробно.
Реализовывал одну такую систему. Пиши в лычку, скину описалово.
для затравки:
Учет отметок о приходе
Время сотрудника первоначально делится на моменты его нахождения на работе и за ее пределами, например, так:
При этом первая и последняя запись всегда «на работе». На работе обозначает что сотрудник находился на рабочем месте, на территории предприятия
Расписания вводятся в базе «1С: Биометрия».
Расписания заносятся в справочник «Расписания».
Учет отклонений рабочего времени
Когда задано расписание, то появляется возможность учитывать отклонения рабочего времени.
Виды рабочего времени бывают такими:
1. Рабочее время (РВ) – сотрудник находится на рабочем месте.
2. Опоздание (ОП) – сотрудник пришел на работу позже назначенного времени
5. Перерыв (ПР) – сотрудник ушел с работы внутри интервала не рабочего времени.
6. Прогул (НВ) – если сотрудник должен быть на рабочем месте, но отсутствовал, задается рамками начала и окончания рабочего дня.
7. Отсутствие(ОТ) – сотрудник ушел с работы внутри интервала рабочего времени.
8. Прогул (ПГ) – прогул.
Каждый интервал времени расписания помечается следующими полями:
1. Рабочее время – флажок того, что время считается рабочим. Если не установлен, то время не рабочее, например, перерыв – не рабочее время.
2. Опоздание – фиксировать опоздание, если первая отметка рабочего времени позже интервала.
3. Преждевременный уход – фиксировать преждевременный уход, если последняя отметка рабочего времени раньше интервала.
4. Переработка – присутствие сотрудника в этом интервале времени считается переработкой.
5. Перерыв – время относится к перерыву.
Для расписания в целом задаются следующие параметры:
1. Норма перерывов – какое количество перерывов допустимо в течении рабочего дня. Время, превышающее норму перерывов относится в «Отсутствие».
2. Максимальное опоздание – какое максимальное опоздание начисляется, в минутах. После этого время относится в «Отсутствие». Если не задано, то опоздание считается по факту.
3. Допустимое опоздание – какое опоздание разрешается, в минутах.
4. Вычитать допустимое опоздание – если флаг установлен, то из зафиксированного опоздания вычитается допустимое опоздание, иначе опоздание считается без вычетов.
5. Максимальная переработка – какое максимальное время переработки учитывается. Если не задано, то переработка учитывается по факту.
6. Максимальный преждевременный уход – какое максимальное время преждевременного ухода учитывать.
7. Допустимый преждевременный уход – какой преждевременный уход разрешается, в минутах.
8. Вычитать допустимый преждевременный уход – если флаг установлен, то из зафиксированного преждевременного ухода вычитается преждевременный уход, иначе преждевременный уход считается без вычетов.
9. Минимальное рабочее время – если задано, то в случае, если рабочее время получилось меньше, рабочее время обнуляется и фиксируется прогул.
Итогом расчета рабочего времени является список интервалов, каждый из которых относится к определенному виду времени.
В итоге получается сумма по каждому из видов времени в минутах. Она сохраняется по каждому расчету в регистре «Начисленное время».
Пример: Рабочее время 420, Опоздание 10, Перерыв 60, Переработка 30.
Чтобы скорректировать рабочее время используется регистр «Корректировки времени», где для каждого сотрудника на определенную дату можно указать другое значение по виду времени. Значения из этого регистра имеют приоритет над расчетными. Каждую запись можно сопроводить комментарием.
Пример: Сотрудник ездил по делам в течении трех часов, в итоге у него Отсутствие 180. Нужно создать корректировочную запись Отсутствие 0, с комментарием «Отсутствие по делам, согласовано с руководством».
Пример: Сотрудник опоздал на час из-за сбоя в работе транспорта, в итоге у него Опоздание 60. Нужно создать корректировочную запись Опоздание 0, с комментарием «Опоздал из-за сбоя транспорта, объяснительная приложена и проверена Ивановым И.И.».
Назначение расписаний сотрудникам
В регистре «Назначения» назначается расписание сотрудникам. Одному сотруднику можно назначить на дату несколько расписаний, тогда по каждому из них ему будут посчитаны показатели рабочего времени.
Алгоритм расчета часов по расписаниям
Алгоритм позволяет определить прогулы сотрудников. Поэтому анализируются данные за выбранный в обработке период времени. Если период не выбран, то используется дата от начальной до минимальной.
Изначально таблица проходов рассчитывается в разрезе Person ID + Дата + Точка.
Затем за каждый анализируемый день по таблице назначения расписаний определяется, какие расписания действуют для сотрудников на этот день.
Формируется таблица расчета часов в разрезе: Физлицо + Дата + Точка + Расписание + Подразделение.
Здравствуйте. Проблема в том, что я не могу найти строки в ТЧ документа, в которых пересекаются периоды дат.
Есть документ с ТЧ. В ТЧ есть колонки: "контрагент", "договор контрагента", "дата начала", "дата окончания". Нахожу строки с одинаковым контрагентом и договором и потом мне нужно сопоставить эти строки на "пересечение". И потом, если даты пересекаются - сообщить об ошибке, записать и не проводить. Вот запрос, который находит одинаковых контрагентов с договорами, кто-нибудь знает как можно прописать условие на пересечение в нем же?
ВЫБРАТЬ
| СрокиОтсрочкиОплатыСроки.НомерСтроки КАК НомерСтроки,
| СрокиОтсрочкиОплатыСроки.Контрагент КАК Контрагент,
| СрокиОтсрочкиОплатыСроки.ДоговорКонтрагента,
| СрокиОтсрочкиОплатыСроки.ДатаНачала КАК Дата1,
| СрокиОтсрочкиОплатыСроки.ДатаОкончания КАК Дата2
|ИЗ
| Документ.СрокиОтсрочкиОплаты.Сроки КАК СрокиОтсрочкиОплатыСроки
|ГДЕ
| СрокиОтсрочкиОплатыСроки.Контрагент В
| (ВЫБРАТЬ
| ВложенныйЗапрос.Контрагент
| ИЗ
| (ВЫБРАТЬ
| СрокиОтсрочкиОплатыСроки.Контрагент КАК Контрагент,
| КОЛИЧЕСТВО(СрокиОтсрочкиОплатыСроки.Контрагент) КАК Колво
| ИЗ
| Документ.СрокиОтсрочкиОплаты.Сроки КАК СрокиОтсрочкиОплатыСроки
| ГДЕ
| СрокиОтсрочкиОплатыСроки.Ссылка = &Ссылка
| СГРУППИРОВАТЬ ПО
| СрокиОтсрочкиОплатыСроки.Контрагент
| ) КАК ВложенныйЗапрос
| ГДЕ
| ВложенныйЗапрос.Колво <> 1)
| И СрокиОтсрочкиОплатыСроки.ДоговорКонтрагента В
| (ВЫБРАТЬ
| ВложенныйЗапрос.ДоговорКонтрагента
| ИЗ
| (ВЫБРАТЬ
| СрокиОтсрочкиОплатыСроки.ДоговорКонтрагента КАК ДоговорКонтрагента,
| КОЛИЧЕСТВО(СрокиОтсрочкиОплатыСроки.ДоговорКонтрагента) КАК КолвоДог
| ИЗ
| Документ.СрокиОтсрочкиОплаты.Сроки КАК СрокиОтсрочкиОплатыСроки
| ГДЕ
| СрокиОтсрочкиОплатыСроки.Ссылка = &Ссылка
| СГРУППИРОВАТЬ ПО
| СрокиОтсрочкиОплатыСроки.ДоговорКонтрагента
| ) КАК ВложенныйЗапрос
| ГДЕ
| ВложенныйЗапрос.КолвоДог <> 1)
| И СрокиОтсрочкиОплатыСроки.Ссылка = &Ссылка
|
|УПОРЯДОЧИТЬ ПО
| Контрагент,
| НомерСтроки
Напишем функцию:
Функция ПолучитьРазностьДатВДняхЗапрос(НачалоПериода, КонецПериода)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РАЗНОСТЬДАТ(&ДатаНачалаПериода, &ДатаОкончанияПериода, ДЕНЬ) КАК Результат";
Запрос.УстановитьПараметр("ДатаНачалаПериода", НачалоДня(НачалоПериода));
Запрос.УстановитьПараметр("ДатаОкончанияПериода", НачалоДня(КонецПериода));
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
КоличествоДней = 0;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
КоличествоДней = ВыборкаДетальныеЗаписи.Результат;
КонецЦикла;
Возврат КоличествоДней;
КонецФункции
Из плюсов данного способа можно отметить: простота реализации, не надо ничего делить и вычитать; третий параметр функции языка запросов, отвечающий за тип разности, можно параметризировать, то есть можно легко получить разность дат не только в днях, но и в минутах, часах и так далее.
Из минусов стоит отметить исполнение функции только на стороне сервера, так как используется объект Запрос.
Во втором способе нужно уметь делить и знать сколько секунд в минуте, минут в часах и так далее. Если на платформе 1С произвести вычитание над датами, то получим целое число - это разница между датами в секундах. Если исходная дата больше чем вычитаемая, то получим положительное количество секунд, если исходная дата меньше чем вычитаемая, то отрицательное количество секунд.
Напишем функцию, которая будет вычислять разность между двумя датами в днях:
Функция ПолучитьРазностьДатВДнях(НачалоПериода, КонецПериода)
РазностьВСекундах = НачалоДня(КонецПериода) - НачалоДня(НачалоПериода);
КоличествоДней = Окр(РазностьВСекундах / 60 / 60 / 24);
Возврат КоличествоДней;
КонецФункции
Хочу заметить, что как и в первом способе, рассчитывается календарная разница между датами. Из плюсов хочу отметить исполнение функции в любом контексте, из минусов - для параметризации типа разности придется написать сочинение из условий или как-то так.
На практике мне встретился тот факт, что программисты предпочитают пользоваться первым способом, и я так же последовал этому мейнстриму и применил первый способ в одном из тяжелых алгоритмов, где вычисление разницы между двумя датами в днях выполнялось тысячи раз.
Читайте также: