Имя: Пароль:
1C
1С v8
Выбрать свободный период. Как ?
, ,
0 Koliaff
 
24.04.13
08:46
Доброго времени суток, господа форумчани.
Есть регистр сведений, который  фиксирует аренду или бронь недвижимости. Периодичность у данного регистра - "По позиции регистратора", у данного регистра есть реквизит дата окончания. "Период" использую как "дата начала". Т.е. получается у нас есть документы которые записывают сведения в данный регистр "ДатаНачала" и "ДатаОкончания" аренды. Периоды могут пересекаться (бронь может заходить на ареду).  Сейчас стоит задача сформировать алгоритм. Суть алгоритма такова :
Пользователь выбирает в диалоге интервал, а алгоритм должен проанализировать и выдать свободен ли хоть один день  от брони или резерва по объекту недвижимости в выбранном интервале пользователем или занят полностью данные интервал. Что-то ни как не могу придумать алгоритм.
1 Wobland
 
24.04.13
08:50
для размышления
В документе есть табличная часть «Периоды» содержащая Дату начала периода и Дату окончания периода. Необходимо проверить, что периоды не «пересекаются» друг с другом (но «дырки» между периодами разрешены).

   "ВЫБРАТЬ
   |    Т1.Ссылка
   |ИЗ
   |    Документ.ДокументСТабличнойЧастью.Периоды КАК Т1
   |        ЛЕВОЕ СОЕДИНЕНИЕ Документ.ДокументСТабличнойЧастью.Периоды КАК Т2
   |        ПО Т1.НомерСтроки <> Т2.НомерСтроки
   |            И (Т1.ДатаНачала МЕЖДУ Т2.ДатаНачала И Т2.ДатаОкончания
   |                ИЛИ Т1.ДатаОкончания МЕЖДУ Т2.ДатаНачала И Т2.ДатаОкончания)
   |ГДЕ
   |    Т1.Ссылка = &Ссылка
   |    И Т2.Ссылка = &Ссылка";
2 Koliaff
 
24.04.13
09:00
(Wobland) Другая задача у меня стоит, более сложная. В моем случае пересечения не важны, надо найти именно дырки. )
3 Koliaff
 
24.04.13
09:01
+(2) и не для одного пересечения, а в совокупности для всех.
4 Wobland
 
24.04.13
09:02
(2) да я понял. но мне думать лениво, так что, как грится, чем могу. может, после обеда подтянусь. вопрос уж интересный
5 Rie
 
24.04.13
09:03
(2) Самый тупой алгоритм: отсортировал периоды по дате начала.
И смотришь - если дата начала следующего периода больше даты окончания предыдущего, то вот она, дырка!
6 Koliaff
 
24.04.13
09:23
(Rie) Если бы периоды не пересекались, тогда - да. А так алгоритм сортировки теряет смысл, т.к. один период может находиться в другом. И тогда опа...
8 Rie
 
24.04.13
09:26
(6)  Нарисуй на бумажке и сравни даты _начала следующего_ и _окончания предыдущего_.
Если один период внутри другого - то дата окончания первого будет после даты начала второго.
Если периоды пересекаются - то дата окончания первого будет после даты начала второго.
Так что всё ОК.
9 Koliaff
 
24.04.13
09:32
(Rie)

Пользователь выбрал период весь январь

Пример1 :
1. Бронь с 1 января по 30 января
2. Резерв со 2 января по 29 января
Итог должен быть - положительный
Привер2
1. Бронь с 1 января по 31 января
2. Резерв со 2 января по 29 января
Итог должен быть - Отрицательный
=====================================
Как с сортировкой алгоритм здесь будет действовать ?
10 Fish
 
24.04.13
09:35
(9) А что тебя смущает? В первом случае 31 января свободно, во втором - нет.
11 Koliaff
 
24.04.13
09:36
(Fish) просто алгоритм сортировки предложенный (Rie) тогда не сработает.
12 Fish
 
24.04.13
09:37
(11) Прекрасно сработает.
13 Koliaff
 
24.04.13
09:38
Пробую сейчас Регистр расчета с вытеснением приладить. Должно вроде получится тогда с сортировкой ...
14 butterbean
 
24.04.13
09:39
если надо в запросе, тогда надо брать таблицу со всеми датами из выбранного интервала и ее соединять с регистром по Таблица.Дата < Регистр.ДатаНачала И Таблица.Дата > Регистр.ДатаОкончания
15 SeraFim
 
24.04.13
09:40
(14) +1
16 В тылу врага
 
24.04.13
09:41
во временную таблицу выбираем начала и концы не лежащие в других интервалах, соединяем их - получаем пустые дырки

а вообще структура регистра кривая
17 azernot
 
24.04.13
10:05
ВЫБРАТЬ
   1 КАК Разряд
ПОМЕСТИТЬ Цифры

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   2

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   3

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   4

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   5

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   6

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   7

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   8

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   9

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   0
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   Числа.Число
ПОМЕСТИТЬ Числа
ИЗ
   (ВЫБРАТЬ
       Единицы.Разряд + ЕСТЬNULL(Десятки.Разряд, 0) * 10 + ЕСТЬNULL(Сотни.Разряд, 0) * 100 + ЕСТЬNULL(Тысячи.Разряд, 0) * 1000 КАК Число
   ИЗ
       Цифры КАК Единицы
           ЛЕВОЕ СОЕДИНЕНИЕ Цифры КАК Десятки
           ПО (РАЗНОСТЬДАТ(&ДатаНачала, &ДатаКонца, ДЕНЬ) >= 10)
           ЛЕВОЕ СОЕДИНЕНИЕ Цифры КАК Сотни
           ПО (РАЗНОСТЬДАТ(&ДатаНачала, &ДатаКонца, ДЕНЬ) >= 100)
           ЛЕВОЕ СОЕДИНЕНИЕ Цифры КАК Тысячи
           ПО (РАЗНОСТЬДАТ(&ДатаНачала, &ДатаКонца, ДЕНЬ) >= 1000)) КАК Числа
ГДЕ
   Числа.Число МЕЖДУ 0 И РАЗНОСТЬДАТ(&ДатаНачала, &ДатаКонца, ДЕНЬ)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ДОБАВИТЬКДАТЕ(&ДатаНачала, ДЕНЬ, Числа.Число) КАК ДатаДень
ПОМЕСТИТЬ ТаблицаДат
ИЗ
   Числа КАК Числа
ГДЕ
   ДОБАВИТЬКДАТЕ(&ДатаНачала, ДЕНЬ, Числа.Число) <= &ДатаКонца

ИНДЕКСИРОВАТЬ ПО
   ДатаДень
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ДАТАВРЕМЯ(2013, 1, 2) КАК НачалоЗанятости,
   ДАТАВРЕМЯ(2013, 1, 10) КАК КонецЗанятости
ПОМЕСТИТЬ ПериодыЗанятости

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   ДАТАВРЕМЯ(2013, 1, 12),
   ДАТАВРЕМЯ(2013, 1, 15)

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   ДАТАВРЕМЯ(2013, 1, 17),
   ДАТАВРЕМЯ(2013, 1, 18)

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   ДАТАВРЕМЯ(2013, 1, 20),
   ДАТАВРЕМЯ(2013, 1, 25)

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   ДАТАВРЕМЯ(2013, 1, 26),
   ДАТАВРЕМЯ(2013, 1, 27)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ТаблицаДат.ДатаДень
ИЗ
   ТаблицаДат КАК ТаблицаДат
       ЛЕВОЕ СОЕДИНЕНИЕ ПериодыЗанятости КАК ПериодыЗанятости
       ПО ТаблицаДат.ДатаДень >= ПериодыЗанятости.НачалоЗанятости
           И ТаблицаДат.ДатаДень <= ПериодыЗанятости.КонецЗанятости
ГДЕ
   ПериодыЗанятости.НачалоЗанятости ЕСТЬ NULL


Как-то так... Вместо таблицы ПериодыЗанятости подсунуть свой регистр..
18 Koliaff
 
24.04.13
10:12
Всем спасибо за обсуждение, приладил регистр расчета пока, экспериментирую ....
19 DirecTwiX
 
24.04.13
10:46
20 azernot
 
24.04.13
11:57
(19) эээ... Чёта я сегодня туплю.. Это к чему?
21 acsent
 
24.04.13
12:00
нужно разбить общий интервал границами на несколько мелких и каждый проверить