Имя: Пароль:
1C
 
Как найти разницу между датами?
,
0 VID1234
 
19.09.23
16:12
Здравствуйте. Подскажите пожалуйста как лучше сделать. Есть документ отсутствия, например сотрудник отсутствует с 1 августа по 30 августа, нужно (желательно запросом) найти разницу дней когда у сотрудника необоснованный прогул, т.е. допустим с 5 августа по 10 у него больничный, потом с 20 по 25 тоже больничный, нужно получить следующее с 1 по 4 разница 4 дня, с 11 по 19 разница 9, с 26 по 30 разница 5. Всегда будет использоваться документ отсутствия и больничный, если больничного нет, то прогул. это зуп
1 VID1234
 
19.09.23
16:19
Запрос = Новый Запрос;
            Запрос.Текст =
            "ВЫБРАТЬ
            |    ПрогулНеявка.ДатаНачала КАК ДатаНачала,
            |    ПрогулНеявка.ДатаОкончания КАК ДатаОкончания
            |ИЗ
            |    Документ.ПрогулНеявка КАК ПрогулНеявка
            |ГДЕ
            |    ПрогулНеявка.Сотрудник = &Сотрудник
            |
            |УПОРЯДОЧИТЬ ПО
            |    ДатаНачала";
            
            Запрос.УстановитьПараметр("Сотрудник", СтрокаДанных.Сотрудник);
            
            РезультатЗапроса = Запрос.Выполнить();
            
            ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
            ТЗ = Новый ТаблицаЗначений;
            Тз.Колонки.Добавить("ДатаС", Новый ОписаниеТипов("Дата"));
            Тз.Колонки.Добавить("ДатаПо", Новый ОписаниеТипов("Дата"));

            Если ВыборкаДетальныеЗаписи.Количество() > 0 Тогда
                Запрос2 = Новый Запрос;
                Запрос2.Текст =
                "ВЫБРАТЬ
                |    БольничныйЛист.ДатаНачала КАК ДатаНачала,
                |    БольничныйЛист.ДатаОкончания КАК ДатаОкончания
                |ИЗ
                |    Документ.БольничныйЛист КАК БольничныйЛист
                |ГДЕ
                |    БольничныйЛист.Сотрудник = &Сотрудник
                |    И ВЫБОР
                |            КОГДА БольничныйЛист.ДатаНачала < &ДатаНачала
                |                ТОГДА БольничныйЛист.ДатаОкончания
                |            ИНАЧЕ ВЫБОР
                |                    КОГДА БольничныйЛист.ДатаНачала >= &ДатаНачала
                |                        ТОГДА БольничныйЛист.ДатаОкончания <= &ДатаОкончания
                |                КОНЕЦ
                |        КОНЕЦ
                |
                |УПОРЯДОЧИТЬ ПО
                |    ДатаНачала";
                Запрос2.УстановитьПараметр("Сотрудник", СтрокаДанных.Сотрудник);
                
                СтруктураДанных.Вставить("Прогулы", Новый Массив);

                Пока ВыборкаДетальныеЗаписи.Следующий() Цикл    
                    Тз.Очистить();
                    Запрос2.УстановитьПараметр("ДатаОкончания", ВыборкаДетальныеЗаписи.ДатаОкончания);
                    Запрос2.УстановитьПараметр("ДатаНачала", ВыборкаДетальныеЗаписи.ДатаНачала);
                    
                    РезультатЗапроса2 = Запрос2.Выполнить();
                    
                    ВыборкаДетальныеЗаписи22 = РезультатЗапроса2.Выгрузить();
                    ПервыйРаз = Истина;
                    ВтораяДата = Дата("00010101");
                    Сч = 1;
                    Для Каждого ВыборкаДетальныеЗаписи2 ИЗ ВыборкаДетальныеЗаписи22  Цикл
                        Если ВыборкаДетальныеЗаписи.ДатаНачала = ВыборкаДетальныеЗаписи2.ДатаНачала И ВыборкаДетальныеЗаписи2.ДатаОкончания = ВыборкаДетальныеЗаписи.ДатаОкончания Тогда
                            Продолжить;
                        КонецЕсли;
                        Если ПервыйРаз Тогда
                            ТЗСтр = ТЗ.Добавить();
                            ТЗСтр.ДатаС = ВыборкаДетальныеЗаписи2.ДатаОкончания;
                            ВтораяДата =  ВыборкаДетальныеЗаписи2.ДатаОкончания;
                            Если ВыборкаДетальныеЗаписи22.Количество() = 1 Тогда
                                ТЗСтр.ДатаПо = ВыборкаДетальныеЗаписи.ДатаОкончания;    
                            КонецЕсли;
                            ПервыйРаз = Ложь;
                        Иначе
                            
                            ТЗСтр = ТЗ.Добавить();
                            ТЗСтр.ДатаС = ВыборкаДетальныеЗаписи2.ДатаОкончания;
                            Отбор = Новый Структура;
                            Отбор.Вставить("ДатаС",ВтораяДата);
                            Резолт = ТЗ.НайтиСтроки(Отбор);
                            Резолт[0].ДатаПо = ВыборкаДетальныеЗаписи2.ДатаНачала;
                            
                            Если Сч = ВыборкаДетальныеЗаписи22.Количество() Тогда
                                ТЗСтр.ДатаПо = ВыборкаДетальныеЗаписи.ДатаОкончания;
                            Иначе                            
                                ВтораяДата =  ВыборкаДетальныеЗаписи2.ДатаОкончания;
                            КонецЕсли;
                        КонецЕсли;
                    КонецЦикла;                    
                    Тз.Сортировать("ДатаС УБЫВ",);
2 gul_Sayan
 
19.09.23
16:20
В запросе  РАЗНОСТЬДАТ(<Дата1>, <Дата2>, <Тип>) где тип День.
3 VID1234
 
19.09.23
16:20
сделал так, но не совсем то.
4 VID1234
 
19.09.23
16:23
(2) Здравствуйте. Это я знаю, но как сделать вхождение дат в диапазон других дат и нахождение с, по и разницу между ними.
5 lEvGl
 
гуру
19.09.23
16:37
выбрать из рег календаря каждый день, определить каждый из дней как больничный или еще что то, в указанном периоде для указанного периода сделать также и исключить даты, имеющие обоснование отсутствия, остальное - прогул
6 gul_Sayan
 
19.09.23
16:24
И не используй документы запросы лучше по регистрам. В данном случае смотри РС СостоянияСотрудников
7 Гена
 
гуру
19.09.23
17:08
Господа, вы и выходные такими алгоритмами запрогулите работнику.
8 lEvGl
 
гуру
19.09.23
18:53
(7) да, все это нужно само собой учесть - праздники федеральные, региональные, выходные, все это есть в рег календаре. остальное типа больничных, отгулов, отпусков - в данных ЗУПа, все это нужно подружить, а в конце из "астрономической" последовательности дат исключить все указанное. ну я концепцию объяснял в (5). в таких задач всегда нужна абсолютная шкала времени в днях, в минутах или часах - точность от задачи зависит. и все телодвижения производить опираясь на нее. потому что только на данных больничного ничего не построить, основа нужна
9 Гена
 
гуру
19.09.23
19:36
(8) Как здравомыслящий форумчанин Вы несомненно должны знать, что автоматическое опрогуливание НН полный бред. Прогул - это всегда ворох бумажных документов: докладных, объяснительных и т.п.
Потому что прогул влечёт за собой уменьшение будущих средних заработков, пенсионного стажа и т.д. для избежания трудовых споров. На вершине этой кипы бумаг бумажный приказ руководителя, в котором и указаны ТОЧНЫЕ даты прогулов. Данный приказ попадает к кадровикам и они уже в РУЧНОМ порядке вводят документ Прогула. Только так.

Нельзя же бездумно автоматизировать всякие глупые хотелки, иначе как по их ПИСЬМЕННОМУ техзаданию. Иначе программист станет крайним в обязательных будущих разборках.
10 lEvGl
 
гуру
19.09.23
20:20
(9) очевидно этот запрос/отчет/документ призван дать начало таким разбирательствам. в целом мысли не понял.. ааа что автоматом поставить НН? нет, вряд ли, но информацию собрать для размышлений вполне можно
11 SleepyHead
 
гуру
20.09.23
08:43
(0) Смотрите регистры "Данные состояний сотрудников" и "Состояния сотрудников". Из них вы поймете, что происходило с сотрудником и в какие периоды.

Построив таблицу состояний, вы уже по ней посчитаете количество дней в нужных вам периодах.
12 SleepyHead
 
гуру
20.09.23
08:44
(10) " очевидно этот запрос/отчет/документ призван дать начало таким разбирательствам. в целом мысли не понял.. ааа что автоматом поставить НН? нет, вряд ли, но информацию собрать для размышлений вполне можно"

Похожу задачу я решал в прошлом году, мне нужно было найти периоды болезни и прочих отсутствий по болезни, которые не подтверждены больничными.

В регистре состояний может стоять тип невыхода "Болезнь", но зарегистрирована она документом "Прогул, неявка", а больничного нет - вот повод для разбирательства.
13 Мимохожий Однако
 
20.09.23
09:07
(10) Ты ,видимо, не хочешь понять, что здравый смысл противоречит сбору "информации для размышления"
14 Web00001
 
20.09.23
09:38
(5)А потом окажется, что сотрудник работает два через два)
15 lEvGl
 
гуру
20.09.23
09:48
(13) виноват, исправлюсь))
(14) да не может быть.. может он и на 0.25 ставки работает, по 2 часа в день должен быть, тогда то и расчет по другом вести надо
(9)(14) прекращайте. подумайте лучше как можно решить вопрос
16 Гена
 
гуру
20.09.23
10:12
(15) подумайте лучше как можно решить вопрос
Какой вопрос? Если найти незакрытые периоды НН, так это запросом в десяток строк к РС Состояния сотрудников. А если ещё и автоматически их опрогулить - то это вне здравого смысла )
17 Web00001
 
20.09.23
10:29
(14)Почему сотрудник не может работать два через два? Немного не понял. Он как угодно может работать. Это нормальная вполне тема, для всяких там кассиров, официантов да и многих работяг на заводах. Я к тому, что рабочие дни надо выяснять не из календаря а из графика сотрудника. Я решал подобную задачу. И норма сотрудника тут не нужна. Запросом интервалы между больничными и не подтвержденными отсутствиями не осилил. Но гуглеж показал, что это +- сложная задача. Выгружал в таблицу и формировал периоды отсутствий в цикле. Потом загружал обратно в ВТ и в отчете уже юзал эти данные. Потом этот отчет переписали и сравнивали у регистра расчетов фактический период действия и плановый. Но что с чем, как и почему, не могу точно сказать, не помню уже.
18 lEvGl
 
гуру
20.09.23
10:38
(17) кто сказал что не может 2/2? может, и не только так может, могут быть еще 2 десятка особенностей графика. тем не менее вся эта информация есть в зупе, разбирать ее, чтобы было универсально, или сделать один вариант расчета, как нужно в (0), это дело заказчика/разработчика.
>>не осилил
печально
>>это +- сложная задача
на первый раз непростая, потом проще. в целом да, задачи из разряда подумать и покрутить.
Поэтому я и написал "принципиальную схему" решения таких задач. Это кейс. Возможно сделать все запросом, без циклов. А как будете считать, насколько глубоко детализировать, учитывать график работы или нет, это уже ваше дело, я не в курсе тонкостей вашей ситуации, как и вы не в курсе ситуации (0), есть там2/2 или нет, этого не обозначено.
19 Web00001
 
20.09.23
12:11
(8)мне кажется это нерешаемо запроом. Может специалисты по запросам напишут километровый запрос разбирающий каждый день и сравнивающий интервалы. Я решал именно такую задачу) возможно было можно да получить дни в одном интервале, получить дни во втором и потом их соединить да. Действительно. Может даже и подошло бы такое решение. Календарь не нужен. В ЗУП есть представление, которое вернет таблицу с заполненными датами. Можно прям его и взять. Да. Рабочая тема. Действительно.
20 Web00001
 
20.09.23
12:12
(19) к (18)