Имя: Пароль:
1C
1С v8
Вопрос возможностей формата даты в 1С
0 findpol
 
03.09.25
17:14
Отцы, приветствую и сразу поясняю, что такое ТЗ получил от аналитега.

Хотят из реквизита с типом дата получить в форме списка значение вида " 1 д 1 час 1 мин", т.е. срок в днях, часах и минутах.

Невозможно же такое сделать форматной строкой, а надо в реквизит уже писать текстом по этому шаблону и текстом выводить. Верно?
1 Волшебник
 
03.09.25
17:15
Верно. Это же не дата, а интервал
2 Kigo_Kigo
 
03.09.25
17:17
ну и сделай дату строкой отфарматируй ее как тебе надао строковыми функциями
3 shuhard
 
03.09.25
17:19
(0) всё верно
4 Asmody
 
03.09.25
17:19
(0) в реквизите типа Дата написано "03.09.2025 17:19:23"
Это сколько в днях-минутах-часах?
5 findpol
 
03.09.25
17:23
(4) согласен, но это же люди после старших капитанских курсов пишут.. Всегда кажется, может, пропустил что и они дело говорят.
6 Волшебник
 
03.09.25
17:26
(5) они же не программисты
7 Tarlich
 
03.09.25
17:31
... (Удалите - сори)
8 Asmody
 
03.09.25
17:31
(7) формат ДЛФ=Д не подходит?
9 ejikbeznojek
 
03.09.25
17:34
ДФ='д "день" ЧЧ "час" mm "минута"'
Если от пустой даты часы и дни отсчитаны.

Ну или посчитать разностью дат, если есть точка отсчёта.
10 PR
 
03.09.25
17:34
(0) Нельзя, потому что если будет не 1 минута, то будет показываться " д  час 1 мин", ну или "0 д 0 час 1 мин"
11 Гена
 
гуру
03.09.25
17:37
(0) Здравствуй, сынок. Перевожу на русский язык - от ТЕКУЩЕЙ даты (точное время на компе) хотят видеть свой результат.
12 findpol
 
04.09.25
09:39
(9) не выйдет, потому что и так предел это 31 день, а период может быть и 90 дней.
13 findpol
 
03.09.25
17:42
(11) не, там у меня есть две даты между которыми нужен интервал. Не от текущей.
14 PR
 
03.09.25
17:46
(13) В общем, считай сам, выводи строкой, там не сложно
15 Garykom
 
гуру
03.09.25
17:49
Главное чтоб не запросом это...
16 Гена
 
гуру
03.09.25
17:54
(13) Х = РАЗНОСТЬДАТ(<Дата1>, <Дата2>, МИНУТА)
далее целое от деления на 24*60 = Дней
Дробную часть делим на 60 и берём целое = Часов
Евойная дробная часть = Минут
17 findpol
 
03.09.25
17:55
(14) да, я накидал уже, спасибо. Мне надо по календарю, т.е. будни, рабочие, переход через год, начало/окончание рабочего дня учесть и всё такое.
18 findpol
 
03.09.25
17:56
(15) кодом буду делать потому что запросом это если и возможно, то будет такой зверь, что хрен отладишь.
19 Климов Сергей
 
03.09.25
17:59
20 findpol
 
03.09.25
18:04
(19) спасибо, Сергей. См (17) - там не просто разность двух дат.
21 PR
 
03.09.25
18:07
(15) Да там элементарно в запросе посчитать
22 PR
 
03.09.25
18:07
(17) А, ну так ты сразу и сказал бы, тогда точно сам считай
23 Гена
 
гуру
03.09.25
18:21
(17) Давайте сюда свой код - мне интересно.
24 Волшебник
 
03.09.25
18:34
(23) кхм... Там надо ещё соблюдать масштаб. Если интервал 1 год или хотя бы месяц, то нет смысла показывать часы.
25 Garykom
 
гуру
03.09.25
18:39
Имхо я бы выводил только один показатель
В дробном варианте
Типа 1.2д или 1.5ч или 10м
26 findpol
 
03.09.25
18:40
(25) ну так да, но заказчик видит иначе ))
27 PR
 
03.09.25
18:44
(26) Рекомендую тебе сразу для сортировки и отбора сделать еще одно поле РазностьВСекундах
28 Гена
 
гуру
03.09.25
18:46
Это... так код можно глянуть?
29 findpol
 
03.09.25
19:17
(28) я его на коленке накидал в ночи под свою задачу, поэтому там есть неоптимальные вещи, которые, если будет не лень, я перепишу, но на данный момент код сделан как шла моя мысль ))

Есть пока не обработанные моменты как больше двух лет не делал, разные календари в разных годах и т.д. Но, повторюсь, просто накидал для тестов и конкретно у меня календари не мешают.

Подробности
&НаСервере
Функция ПолучитьРабочихМинутМеждуДатами(ЗНАЧ ДатаНачала,ЗНАЧ ДатаОкончания, ЧасН, ЧасО)
	
	Если ДатаНачала > ДатаОкончания Тогда
		ИтогоСрокМинут = 0;	
	ИначеЕсли Год(ДатаНачала) = Год(ДатаОкончания) Тогда
		Если НачалоДня(ДатаНачала) = НачалоДня(ДатаОкончания) Тогда
			ИтогоСрокМинут = РабочихМинутВнутриДня(ДатаНачала, ДатаОкончания, ЧасН, ЧасО);
		Иначе
			МинутПоГраницам = РабочихМинутПоДвумГраницамИнтервалаОтдельно(ДатаНачала, ДатаОкончания, ЧасН, ЧасО);
			ДнейМеждуДат = РабочихДнейМеждуИсключаяГраничныеДаты(ДатаНачала, ДатаОкончания);
			МинутМеждуДат = ДнейМеждуДат * 10 * 60;
			ИтогоСрокМинут = МинутПоГраницам + МинутМеждуДат;
		КонецЕсли;
	ИначеЕсли Год(ДатаНачала) = Год(ДатаОкончания) - 1 Тогда
		//Первый год
		ДатаОкончанияПГ = КонецГода(ДатаНачала);
		Если НачалоДня(ДатаНачала) = НачалоДня(ДатаОкончанияПГ) Тогда
			МинутПервыйГод = РабочихМинутВнутриДня(ДатаНачала, ДатаОкончанияПГ, ЧасН, ЧасО);
		Иначе		
			МинутПоГраницам = РабочихМинутПоДвумГраницамИнтервалаОтдельно(ДатаНачала, ДатаОкончанияПГ, ЧасН, ЧасО);
			ДнейМеждуДат = РабочихДнейМеждуИсключаяГраничныеДаты(ДатаНачала, ДатаОкончанияПГ);
			МинутМеждуДат = ДнейМеждуДат * 10 * 60;
			МинутПервыйГод = МинутПоГраницам + МинутМеждуДат;
		КонецЕсли;
		
		//Второй год
		ДатаНачалаВГ = НачалоГода(ДатаОкончания);
		Если НачалоДня(ДатаНачалаВГ) = НачалоДня(ДатаОкончания) Тогда
			МинутВторойГод = РабочихМинутВнутриДня(ДатаНачалаВГ, ДатаОкончания, ЧасН, ЧасО);
		Иначе
			МинутПоГраницам = РабочихМинутПоДвумГраницамИнтервалаОтдельно(ДатаНачалаВГ, ДатаОкончания, ЧасН, ЧасО);
			ДнейМеждуДат = РабочихДнейМеждуИсключаяГраничныеДаты(ДатаНачалаВГ, ДатаОкончания);
			МинутМеждуДат = ДнейМеждуДат * 10 * 60;
			МинутВторойГод = МинутПоГраницам + МинутМеждуДат;
		КонецЕсли;
		
		ИтогоСрокМинут = МинутПервыйГод + МинутВторойГод;
	Иначе
		ИтогоСрокМинут = 599940;
	КонецЕсли;			
	
	Возврат ИтогоСрокМинут;
	
КонецФункции

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

&НаСервере
Функция РабочихМинутВнутриДня(ДатаНачала, ДатаОкончания, ЧасН, ЧасО)
	
	РабочийДень = ДеньЯвляетсяРабочим(ДатаОкончания);
	
	Если РабочийДень Тогда
		
		ДатаНачалаРабочегоДня	= НачалоДня(ДатаНачала) + 9 * 60 * 60;
		ДатаОкончанияРабочегоДня = НачалоДня(ДатаОкончания) + 19 * 60 * 60;
		
		Если ДатаНачала < ДатаНачалаРабочегоДня Тогда
			ДатаНачала = ДатаНачалаРабочегоДня 
		КонецЕсли;
		
		Если ДатаОкончания > ДатаОкончанияРабочегоДня Тогда
			ДатаОкончания = ДатаОкончанияРабочегоДня 
		КонецЕсли;
		
		Если ДатаОкончания > ДатаНачала Тогда 
			Результат = (ДатаОкончания - ДатаНачала) / 60;
		Иначе
			Результат = 0;
		КонецЕсли;
	Иначе
		Результат = 0;
	КонецЕсли;
		
	Возврат Результат;
	
КонецФункции

&НаСервере
Функция РабочихМинутПоДвумГраницамИнтервалаОтдельно(ДатаНачала, ДатаОкончания, ЧасН, ЧасО)
	
	//Считаем минуты по левой границе интервала
	ГраницаРабочийДень = ДеньЯвляетсяРабочим(ДатаНачала);
	
	Если ГраницаРабочийДень Тогда
		
		ДатаНачалаРабочегоДня	= НачалоДня(ДатаНачала) + 9 * 60 * 60;
		ДатаОкончанияРабочегоДня = НачалоДня(ДатаНачала) + 19 * 60 * 60;
		
		Если ДатаНачала < ДатаНачалаРабочегоДня Тогда
			ДатаНачала = ДатаНачалаРабочегоДня 
		КонецЕсли;
		
		Если ДатаОкончанияРабочегоДня > ДатаНачала Тогда 
			МинутЛеваяГраница = (ДатаОкончанияРабочегоДня - ДатаНачала) / 60;
		Иначе
			МинутЛеваяГраница = 0;
		КонецЕсли;
	Иначе
		МинутЛеваяГраница = 0;
	КонецЕсли;
	
	//Считаем минуты по правой границе интервала
	ГраницаРабочийДень = ДеньЯвляетсяРабочим(ДатаОкончания);
	
	Если ГраницаРабочийДень Тогда
		ДатаНачалаРабочегоДня	= НачалоДня(ДатаОкончания) + 9 * 60 * 60;
		ДатаОкончанияРабочегоДня = НачалоДня(ДатаОкончания) + 19 * 60 * 60;
		
		Если ДатаОкончания <= ДатаНачалаРабочегоДня Тогда 
			МинутПраваяГраница = 0;
		ИначеЕсли ДатаОкончания >= ДатаОкончанияРабочегоДня Тогда
			МинутПраваяГраница = 10 * 60;
		Иначе
			МинутПраваяГраница = (ДатаОкончания - ДатаНачалаРабочегоДня) / 60;	
		КонецЕсли;
	Иначе
		МинутПраваяГраница = 0;
	КонецЕсли;
	
	Результат = МинутЛеваяГраница + МинутПраваяГраница;
	
	Возврат Результат;
	
КонецФункции

&НаСервере
Функция ДеньЯвляетсяРабочим(ДатаДляПроверки, КалендарьОтбора = Неопределено)
	
	Результат = Ложь;
	
	Запрос = Новый Запрос;
	
	Запрос.Текст = "ВЫБРАТЬ 
	|	т1.ДатаГрафика 
	|ИЗ РегистрСведений.КалендарныеГрафики КАК т1
	|ГДЕ 
	|  т1.ДатаГрафика = &ДатаП
	|  И т1.ДеньВключенВГрафик = Истина";
	
	Если НЕ КалендарьОтбора = Неопределено Тогда
		Запрос.УстановитьПараметр("Календарь", КалендарьОтбора);
		Запрос.Текст = Запрос.Текст + " И т1.Календарь = &Календарь";
	КонецЕсли;
	Запрос.УстановитьПараметр("ДатаП", НачалоДня(ДатаДляПроверки));
	
	Выборка = Запрос.Выполнить().Выбрать();
	
	Если Выборка.Следующий() Тогда
		Результат = Истина;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции
30 findpol
 
03.09.25
19:01
Ну и где-то часы остались вместо параметров..
31 Garykom
 
гуру
03.09.25
19:02
(29) Эмм раз у тебя один фиг запросы
То перенеси код из основной функции по максимуму так же в запросы с ВТ

И да сразу не для пары дат а для таблицы
32 Волшебник
 
03.09.25
19:14
(31) у профессионалов запросы в циклах не тормозят
33 Garykom
 
гуру
03.09.25
19:21
(32) Но зачем делать несколько простых запросов, когда можно всего один посложней?
34 findpol
 
03.09.25
19:28
(33) я пока просто накидал простой в отладке код, решающий мою задачу и повторяющий ход мысли.

Далее буду оптимизировать и дорабатывать при встраивании в конфу.
35 Волшебник
 
03.09.25
19:29
(33) Я ж без претензий. Это пусть они думают
36 Гена
 
гуру
03.09.25
19:37
(29) Сын мой, проще надо быть... проще...
Глянул этот РС Календарные графики - там же подённые данные и никаких переходов года не надо. К тому же в БП есть готовая Функция РазностьДатПроизводственныхКалендарейПоВидамДней(ПроизводственныйКалендарь, НачалоПериода, ОкончаниеПериода) Экспорт

Достаточно такой рыбы:
Функция КоличествоРабочихДнейПоГрафику(НачалоПериода, КонецПериода, График)
    
    ЕвойныйКалендарь = График.ЕвойныйКалендарь();
    
    ДанныеКалендаря = РасчетЗарплатыБазовый.РазностьДатПроизводственныхКалендарейПоВидамДней(
        ЕвойныйКалендарь,
        НачалоПериода,
        КонецПериода);
        
    Возврат ДанныеКалендаря.Получить(Перечисления.ВидыДнейПроизводственногоКалендаря.Рабочий);
    
КонецФункции
37 Гена
 
гуру
03.09.25
19:40
Не пугайтесь справочника Календари. У него синоним - Графики работы.
38 Волшебник
 
03.09.25
19:50
(36) фейковый программный код
39 Гена
 
гуру
03.09.25
19:57
(38) Отнюдь, рабочий код, только язык поправить )
Суть в том, что почти во всех конфигурациях 1С, даже в УТ, есть графики работы. РС заполняется по КАЖДОМУ дню, которые уже раскрашены в рабочие и выходные.
Нет проблем ну очень короткой функцией получить их количество по выбранному виду между двумя датами. Запросом, Волшебник, запросом )
Коротким.
40 Волшебник
 
04.09.25
10:34
(39) Перепишите на Python
41 findpol
 
03.09.25
19:59
(36) это в ЗУПе есть такой модуль "РасчетЗарплатыБазовый"?
42 Волшебник
 
03.09.25
20:03
(41) это галлюцинации
43 findpol
 
03.09.25
20:06
(36) просто рабочих дней можно и запросом получить - основная сложность в получении минут рабочего дня по границам с учетом рабочего времени.

Переход через год нужен потому, что с новым годом меняется календарь. На один рабочий день, например, 01.03.2025 может быть две записи в регистре потому что два календаря (офис, склад и т.д.), а за два года календаря может быть 4 и т.д. Соответственно, в переходе через год мы задаём корректный календарь для каждого года.
44 Гена
 
гуру
03.09.25
20:08
(41) В БП. Для ЗУПа, КА и ЕРП ещё проще. Там графики тем более подённые в регистрах и вообще собирается разность дат типовыми функциями.
45 Гена
 
гуру
03.09.25
20:10
(43) Так Вы от графика идите к рабочим дням, а не наоборот. Тогда и переход не нужен.
46 Гена
 
гуру
03.09.25
20:13
Короче, всё ясно. Неинтересно. Действуйте.
47 findpol
 
04.09.25
10:19
(44) в УТ нет. Посмотрел в БП - ну тот же запрос, только ещё избыточные данные будут для конкретной задачи. Решил не перетягивать метод, а использовать свой.
48 findpol
 
04.09.25
10:24
Раз уже такая пьянка, то прикладываю код после оптимизации. Буду рад объективной критике:

&НаСервере
Функция ПолучитьРабочихМинутМеждуДатами(ДатаНачала, ДатаОкончания, ЧасН, ЧасО, Календарь = Неопределено)
	
	Если ДатаНачала >= ДатаОкончания ИЛИ ЧасН < 0 ИЛИ ЧасО > 24 ИЛИ ЧасН >= ЧасО Тогда
		Возврат 0;
	КонецЕсли;
	
	ПродолжительностьРабДня = (ЧасО - ЧасН) * 60;
	НачалоДняН = НачалоДня(ДатаНачала);
	НачалоДняК = НачалоДня(ДатаОкончания);
	
	// Получаем все рабочие дни в интервале одним запросом
	РабочиеДниМножество = ПолучитьРабочиеДниВИнтервале(НачалоДняН, НачалоДняК, Календарь);
	
	// Обработка случая, когда обе даты в одном дне
	Если НачалоДняН = НачалоДняК Тогда
		Если РабочиеДниМножество.Получить(НачалоДняН) <> Неопределено Тогда
			Возврат РасчетМинутВДень(ДатаНачала, ДатаОкончания, ЧасН, ЧасО);
		Иначе
			Возврат 0;
		КонецЕсли;
	КонецЕсли;
	
	Общееминуты = 0;
	
	// Обрабатываем начальный день
	Если РабочиеДниМножество.Получить(НачалоДняН) <> Неопределено Тогда
		Общееминуты = Общееминуты + РасчетМинутВДень(ДатаНачала, КонецДня(НачалоДняН), ЧасН, ЧасО);
	КонецЕсли;
	
	// Обрабатываем конечный день
	Если РабочиеДниМножество.Получить(НачалоДняК) <> Неопределено Тогда
		Общееминуты = Общееминуты + РасчетМинутВДень(НачалоДня(НачалоДняК), ДатаОкончания, ЧасН, ЧасО);
	КонецЕсли;
	
	// Обрабатываем полные дни между
	КоличествоДней = РабочиеДниМножество.Количество();
	
	// Вычитаем начальный и конечный дни, если они рабочие
	Если РабочиеДниМножество.Получить(НачалоДняН) <> Неопределено Тогда
		КоличествоДней = КоличествоДней - 1;
	КонецЕсли;
	
	Если РабочиеДниМножество.Получить(НачалоДняК) <> Неопределено Тогда
		КоличествоДней = КоличествоДней - 1;
	КонецЕсли;
	
	// Убедимся, что количество дней не отрицательное
	КоличествоДней = Макс(КоличествоДней, 0);
	
	Общееминуты = Общееминуты + КоличествоДней * ПродолжительностьРабДня;
	
	Возврат Общееминуты;
	
КонецФункции

&НаСервере
Функция ПолучитьРабочиеДниВИнтервале(ДатаНачала, ДатаОкончания, Календарь = Неопределено)
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	т1.ДатаГрафика КАК Дата
		|ИЗ
		|	РегистрСведений.КалендарныеГрафики КАК т1
		|ГДЕ
		|	т1.ДатаГрафика >= &ДатаНачала
		|	И т1.ДатаГрафика <= &ДатаОкончания
		|	И т1.ДеньВключенВГрафик = Истина";
	
	Если Календарь <> Неопределено Тогда
		Запрос.Текст = Запрос.Текст + " И т1.Календарь = &Календарь";
		Запрос.УстановитьПараметр("Календарь", Календарь);
	КонецЕсли;
	
	Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);
	Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания);
	
	РезультатЗапроса = Запрос.Выполнить();
	Выборка = РезультатЗапроса.Выбрать();
	
	Результат = Новый Соответствие;
	Пока Выборка.Следующий() Цикл
		Результат.Вставить(Выборка.Дата, Истина);
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

&НаСервере
Функция РасчетМинутВДень(ДатаНачала, ДатаОкончания, ЧасН, ЧасО)
	
	НачалоРабочегоДня = НачалоДня(ДатаНачала) + ЧасН * 3600;
	КонецРабочегоДня = НачалоДня(ДатаНачала) + ЧасО * 3600;
	
	// Ограничиваем расчет рабочим временем дня
	Если ДатаНачала < НачалоРабочегоДня Тогда
		ДатаНачала = НачалоРабочегоДня;
	КонецЕсли;
	
	Если ДатаОкончания > КонецРабочегоДня Тогда
		ДатаОкончания = КонецРабочегоДня;
	КонецЕсли;
	
	Если ДатаНачала >= ДатаОкончания Тогда
		Возврат 0;
	КонецЕсли;
	
	Возврат (ДатаОкончания - ДатаНачала) / 60;
	
КонецФункции
49 findpol
 
04.09.25
10:21
Лично мне не очень нравится момент с соответствием, в котором передаются рабочие дни, но как сделать лучше?
50 Волшебник
 
04.09.25
10:30
(48) два раза проверяется условие: Если РабочиеДниМножество.Получить(НачалоДняН) <> Неопределено Тогда
Аналогично для конечного дня.
Можно так:

// Обрабатываем начальный день
	Если РабочиеДниМножество.Получить(НачалоДняН) <> Неопределено Тогда
		Общееминуты = Общееминуты + РасчетМинутВДень(ДатаНачала, КонецДня(НачалоДняН), ЧасН, ЧасО);
		КоличествоДней = КоличествоДней - 1;
	КонецЕсли;
	
	// Обрабатываем конечный день
	Если РабочиеДниМножество.Получить(НачалоДняК) <> Неопределено Тогда
		Общееминуты = Общееминуты + РасчетМинутВДень(НачалоДня(НачалоДняК), ДатаОкончания, ЧасН, ЧасО);
		КоличествоДней = КоличествоДней - 1;
	КонецЕсли;
	
	// Обрабатываем полные дни между
	КоличествоДней = РабочиеДниМножество.Количество();
51 Fish
 
гуру
04.09.25
10:36
Можно ещё склонение добавить, чтобы писал красиво:
"5 дней 3 часа 12 минут"
и
"2 дня 5 часов 31 минута"

Тут надо курить функцию ПолучитьСклоненияСтрокиПоЧислу
52 Гена
 
гуру
04.09.25
10:39
(48) Полная хрень плясать от рабочих минут, а не от дней. Потому что как минимум есть у всех укороченные предпраздничные дни, а у многих и длины смен разные на неделе - это раз. Про полночь забыли - это два. Для каждого прошедшего месяца уже давно посчитано в регистре среднего заработка и количество рабочих дней, и количество рабочих часов/минут для любых графиковых мерцаний - это три. График мог меняться - это четыре.  

А впрочем, делайте что хотите. Вы свободный человек свободной страны.

P.S. Вас бы я к себе не взял.
53 Garykom
 
гуру
04.09.25
10:43
(52) А отпуска и отгулы не забыли?
Т.е. ты предлагаешь не просто по рабочему календарю, а по каждому сотруднику отдельно-индивидуально?
54 Гена
 
гуру
04.09.25
10:43
(53) Естественно, только индивидуально. Через Пользователь -> ФЛ -> Сотрудник
У директора - одни данные, у сторожа - другие.

Либо пусть автор перестанет мямлить и озвучит конкретную задачу. Может ему нужна только пятидневка.
55 Fish
 
гуру
04.09.25
10:44
(52) Ещё обязательно надо учитывать обеды и посещение сортира.
56 findpol
 
04.09.25
10:45
(52) пляшем от дней, но в итоге нужно вывести минуты на форму, поэтому после получения дней переходим к подсчёту минут.

Про полночь не забыли. Вы же о том, что рабочий день мог начаться в 22:00 первого дня, а закончиться в 8:0 второго? Это я понимаю, но решил не реализовывать т.к. для моей задачи не требуется.

Я делаю в УТ, тут, если не путаю, нет регистров о которых вы говорите. Если есть - поделитесь, пожалуйста.

З.Ы. Жаль, но у нас ещё есть время изменить ваше решение ))
57 Гена
 
гуру
04.09.25
10:45
(55) ЗУП Корп, кстати, обеды учитывает.
58 Гена
 
гуру
04.09.25
10:46
(56) Нет, я на Вас махнул рукой.
59 findpol
 
04.09.25
10:51
(54) это не расчёт ЗП, а вычисление сроков в УТ по общему календарю в общем для офисных подразделений. Поэтому индивидуальные графики, отгулы и больничные не играют роли.

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

Конечно, я не пытался на коленке написать альтернативу ЗУП, да и смысла в этом нет.
60 Гена
 
гуру
04.09.25
10:54
(59) Каких сроков в УТ? Что же нужно клещами каждый нюанс вытягивать.
Конкретно: сроки между чем и чем? Список чего имеется?
61 findpol
 
04.09.25
11:01
(60) в УТ падают данные (в рамках самописной интеграции): событие, дата начала, дата окончания.

Вот между ними и нужно посчитать срок. Почему минуты (не нужно клещами каждый нюанс вытягивать): точность нужна до минут, чаще всего интервал это минуты.
62 Гена
 
гуру
04.09.25
11:13
(61) Рабочие дни и часы/минуты для первого и последнего дня нужны по какому графику/календарю, для всех одинаковому?
63 Гена
 
гуру
04.09.25
11:15
ДатаНачало и ДатаКонца - они всегда внутри рабочего времени или нет?
64 findpol
 
04.09.25
11:18
(62) да, по одному календарю для всех.

ДатаНачало и ДатаКонца могут попасть как на нерабочие дни, так и на рабочие, но в нерабочее время.
65 Гена
 
гуру
04.09.25
11:45
(64) Тогда нам только нужен вот этот регистр (см. рис.)
Двумя запросами (вложенным или левым соединением?) найдёте количество рабочих дней между ДатаНачало +1 и ДатаКонца -1
Не забудьте в запросе забить:
    |    ВЫБОР
    |        КОГДА ГрафикиРаботы.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
    |                ИЛИ ГрафикиРаботы.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Предпраздничный)
    |            ТОГДА 1
    |        ИНАЧЕ 0
    |    КОНЕЦ КАК РабочийДень

Ну а со временем в первом и последнем дне разберётесь - там трудно испортить.