Сдвиг периодов

1. ixijixi 1830 02.10.23 16:19 Сейчас в теме
Коллеги, приветствую.

Зашел в тупик, нужна помощь.

Есть период, к примеру 12.08-25.08. Необходимо сдвинуть этот период на один или несколько периодов, к примеру есть пара разрывов 14.08-14.08 и 22.08-28.08 (частично пересекается). В результате должны появиться периоды
12.08-13.08
15.08-21.08
29.08-29.08 (вместо 14.08-14.08) первый сдвиг переносим сразу окончания основного периода + сдвиг после)
30.08-02.09 (вместо 22.08-25.08)

Если есть рабочий алгоритм, буду весьма признателен.

Вижу, что элементарщина, но похоже тупняк словил)
По теме из базы знаний
Найденные решения
4. ixijixi 1830 03.10.23 08:29 Сейчас в теме
(2) Спасибо, вчера вечером пошел как раз по этому пути =) Всё получилось!
МассивДат = ОбщегоНазначенияБЗК.МассивДатИзПериода(ДатаНачала, ДатаОкончания);
Для Каждого Строка Из ПериодыПриостановки Цикл
	ОбщегоНазначенияБЗК.УдалитьПериодИзМассиваДат(МассивДат, Строка.ДатаНачалаПериода, Строка.ДатаОкончанияПериода);
КонецЦикла;
НовыеПериоды = ОбщегоНазначенияБЗК.ПериодыИзМассиваДат(МассивДат);

Для Каждого Строка Из НовыеПериоды Цикл
	Сообщить("" + Строка.ДатаНачала + "-" + Строка.ДатаОкончания);
КонецЦикла;
Показать
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. Vinzor 101 03.10.23 01:24 Сейчас в теме
(1) Готового решения нет, есть задумка.
Вы сможете ваш изначальный период 12.08 - 25.08 разложить на дни (есть универсальный прием запроса), и каждому дню присвоить порядковый номер, начиная с 1 (хоть автонумерацией в запросе)?
Далее надо по каждому дню из выпадающих периодов добавить новую дату к концу изначального диапазона + задать этим новым датам новые номера, отталкиваясь от последнего номера изначального диапазона.
Получится набор номеров (с датами), которые надо будет сжать в диапазоны.

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

Например: 1, 3, 4, 5, 7, 10, 11, 12, 16 должно превратиться в 1, 3-5, 7, 10-12, 16.
Функция КолонкаСжато(ДокументСсылка, ИмяТабличнойЧасти, ИмяКолонки, Слэш = ",", Тире = "-")
    Запрос = Новый Запрос("ВЫБРАТЬ Различные " + ИмяКолонки + " ИЗ Документ." + ДокументСсылка.Метаданные().Имя + "." + ИмяТабличнойЧасти + " ГДЕ Ссылка = &Ссылка Упорядочить ПО " + ИмяКолонки);
    Запрос.УстановитьПараметр("Ссылка", ДокументСсылка);
    Ряд = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку(ИмяКолонки);
    Если Ряд.Количество() = 0 Тогда Возврат ""
    КонецЕсли;
    Ряд.Добавить(0); Ряд.Добавить(0);
    Сжато = Строка(Ряд[0]);
    Для ё = 1 По Ряд.Количество() - 3 Цикл
        Если Число(Ряд[ё + 1]) - Число(Ряд[ё - 1]) <> 2 Тогда
            Сжато = Сжато + Слэш + Строка(Ряд[ё])
        ИначеЕсли Число(Ряд[ё + 2]) - Число(Ряд[ё]) <> 2 Тогда
            Сжато = Сжато + Тире
        КонецЕсли
    КонецЦикла;
    Возврат СтрЗаменить(Сжато, Тире + Слэш, Тире)
КонецФункции
Показать
4. ixijixi 1830 03.10.23 08:29 Сейчас в теме
(2) Спасибо, вчера вечером пошел как раз по этому пути =) Всё получилось!
МассивДат = ОбщегоНазначенияБЗК.МассивДатИзПериода(ДатаНачала, ДатаОкончания);
Для Каждого Строка Из ПериодыПриостановки Цикл
	ОбщегоНазначенияБЗК.УдалитьПериодИзМассиваДат(МассивДат, Строка.ДатаНачалаПериода, Строка.ДатаОкончанияПериода);
КонецЦикла;
НовыеПериоды = ОбщегоНазначенияБЗК.ПериодыИзМассиваДат(МассивДат);

Для Каждого Строка Из НовыеПериоды Цикл
	Сообщить("" + Строка.ДатаНачала + "-" + Строка.ДатаОкончания);
КонецЦикла;
Показать
5. Vinzor 101 03.10.23 09:10 Сейчас в теме
(4) Программный интерфейс - здорово.
Для тех, у кого нет подобных программных методов.

Сжатое представление последовательности дат ЗАПРОСОМ
Дана последовательность дат. Нужно заменить ее последовательностью непрерывных интервалов дат. Вот решение

ВЫБРАТЬ 
    Даты.Дата, 
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ДатыДо.Дата) КАК Номер 
ПОМЕСТИТЬ НомераДат 
ИЗ 
    ВТДаты КАК Даты 
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТДаты КАК ДатыДо 
        ПО (ДатыДо.Дата < = Даты.Дата) 
СГРУППИРОВАТЬ ПО 
    Даты.Дата 
; 

////////////////////////////////////////////////////////////­//////////////////// 
ВЫБРАТЬ 
    МИНИМУМ(НомераДат.Дата) КАК ДатаНач, 
    МАКСИМУМ(НомераДат.Дата) КАК ДатаКон 
ИЗ 
    НомераДат КАК НомераДат 
СГРУППИРОВАТЬ ПО 
    ДОБАВИТЬКДАТЕ(НомераДат.Дата, ДЕНЬ, -НомераДат.Номер)
Показать
3. Oldsad 03.10.23 02:21 Сейчас в теме
(1) Сложности потому что вы сразу готовый ответ пытаетесь получить.
Можно последовательно применять разрывы периода, что в разы проще:
Было 12.0-25.08, добавляем разрыв 14.08-14.08
Получаем 12.08-13.08 и 15.08-26.08, добавляем еще разрыв 22.08-28.08
получаем 12.08-13.08 и 15.08-21.08 и 29.08-02.09
и т.д.
6. ubnkfl 24.10.23 15:39 Сейчас в теме
Привет. Вопрос автор вопрос уже решил, наверное, оставлю на память потомкам.
Эта задача решалась здесь:
https://infostart.ru/public/460935/ (задача 25 + добавил соед. по сотруднику во втором запросе)
Я его использовал для получения непрерывных периодов "активных" состояний сотрудников в ЗУП, когда по данным интервального регистра разные состояния, и "активные" (т.е. работа + отпуск + учеба и т.п.) надо было склеить.
ВЫБРАТЬ
	СостоянияОдобрителей.Сотрудник КАК Сотрудник,
	СостоянияОдобрителей.Начало КАК Начало,
	СостоянияОдобрителей.Окончание КАК Окончание,
	СостоянияОдобрителей.СтатусАктивный КАК СтатусАктивный
ПОМЕСТИТЬ ВТДано
ИЗ
	&СостоянияОдобрителей КАК СостоянияОдобрителей
ГДЕ
	СостоянияОдобрителей.СтатусАктивный
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТДано.Начало КАК Начало,
	ВТДано.Окончание КАК Окончание,
	ВТДано.Сотрудник КАК Сотрудник,
	СУММА(РАЗНОСТЬДАТ(Слева.Начало, Слева.Окончание, ДЕНЬ) + 1) КАК Интеграл
ПОМЕСТИТЬ ВТДаноПлюс
ИЗ
	ВТДано КАК ВТДано
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТДано КАК Слева
		ПО (Слева.Начало <= ВТДано.Начало)
			И ВТДано.Сотрудник = Слева.Сотрудник

СГРУППИРОВАТЬ ПО
	ВТДано.Начало,
	ВТДано.Окончание,
	ВТДано.Сотрудник
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	МИНИМУМ(ВТДаноПлюс.Начало) КАК Начало,
	МАКСИМУМ(ВТДаноПлюс.Окончание) КАК Окончание,
	ВТДаноПлюс.Сотрудник КАК Сотрудник,
	ДОБАВИТЬКДАТЕ(ВТДаноПлюс.Окончание, ДЕНЬ, -ВТДаноПлюс.Интеграл) КАК Интеграл
ПОМЕСТИТЬ ВТИтог
ИЗ
	ВТДаноПлюс КАК ВТДаноПлюс

СГРУППИРОВАТЬ ПО
	ВТДаноПлюс.Сотрудник,
	ДОБАВИТЬКДАТЕ(ВТДаноПлюс.Окончание, ДЕНЬ, -ВТДаноПлюс.Интеграл)
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Сотрудники.Код КАК КодСотрудника,
	ВТИтог.Сотрудник КАК Сотрудник,
	ВТИтог.Начало КАК Начало,
	ВТИтог.Окончание КАК Окончание,
	ВТИтог.Интеграл КАК Интеграл
ИЗ
	ВТИтог КАК ВТИтог
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Сотрудники КАК Сотрудники
		ПО ВТИтог.Сотрудник = Сотрудники.Ссылка

УПОРЯДОЧИТЬ ПО
	Сотрудники.Наименование,
	Начало
Показать
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот