1. HIVvich 21.11.16 08:24 Сейчас в теме

Подсчитать время в работе и время в ремонте

Ребята, направьте меня, пожалуйста, наверняка с таким многие сталкивались. У меня в регистре сведений строки по скважинам, попадают в таком порядке:
Период Скважина Состояние
01.01.2016 200 Работа
10.01.2016 300 Работа
11.01.2016 200 Ремонт и т.д.
т.е. куча периодов, огромная куча скважин и их состояния (их вообще больше, но допустим их только 2). Мне надо посчитать, сколько времени выбираемая скважина находится в работе,а сколько в ремонте, причем дата отчета может быть в любой момент, естественно. Я сделала так, вначале сгруппировала строки с работой, посчитала время через разность дат между первой и последней датой, то же самое с ремонтом, потом попыталась определить последнее состояние, чтобы отсчитать плюс еще время до отчета, например последнее состояние скважины 200 с 10.01.2016 работа,а сегодня 20.01.2016 (т.е. плюс еще 10 дней). Я вообще правильно делаю? начинаю разбирать более подробно и вроде алгоритм уже и не работает, может я вообще не то делаю? пока пытаюсь все решить исключительно в консоли, уже порядочно запуталась, если честно...Помогите, пожалуйста. Вот код:
ВЫБРАТЬ
							  	МАКСИМУМ(Резерв.Период) КАК ПериодПослед,
							  	МИНИМУМ(Резерв.Период) КАК ПериодПерв,
							  	-РАЗНОСТЬДАТ(МАКСИМУМ(Резерв.Период), МИНИМУМ(Резерв.Период), ДЕНЬ) КАК БылоВРаботе,
							  	-РАЗНОСТЬДАТ(МАКСИМУМ(Резерв.Период), МИНИМУМ(Резерв.Период), ДЕНЬ) + -РАЗНОСТЬДАТ(&ДатаОтчета, МАКСИМУМ(Резерв.Период), ДЕНЬ) КАК РазностьРабота,
							  	Резерв.Водозабор,
							  	Резерв.Скважина,
							  	Резерв.Состояние,
							  	ВЫБОР
							  		КОГДА РезервСрезПоследних.Состояние = ЗНАЧЕНИЕ(Перечисление.СостояниеСкв.Работа)
							  			ТОГДА -РАЗНОСТЬДАТ(&ДатаОтчета, МАКСИМУМ(Резерв.Период), ДЕНЬ)
							  		ИНАЧЕ 0
							  	КОНЕЦ КАК ЕщеНабежалоВРаботе
							  ПОМЕСТИТЬ ВТ1
							  ИЗ
							  	РегистрСведений.Резерв.СрезПоследних(&ДатаОтчета, Скважина = &Скважина) КАК РезервСрезПоследних
							  		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Резерв КАК Резерв
							  		ПО РезервСрезПоследних.Скважина = Резерв.Скважина
							  ГДЕ
							  	Резерв.Состояние = ЗНАЧЕНИЕ(Перечисление.СостояниеСкв.Работа)
							  	И Резерв.Скважина = &Скважина
							  
							  СГРУППИРОВАТЬ ПО
							  	Резерв.Водозабор,
							  	Резерв.Скважина,
							  	Резерв.Состояние,
							  	РезервСрезПоследних.Состояние
							  ;
							  
							  ////////////////////////////////////////////////////////////­////////////////////
							  ВЫБРАТЬ
							  	МАКСИМУМ(Резерв.Период) КАК ПериодПослед,
							  	МИНИМУМ(Резерв.Период) КАК ПериодПерв,
							  	-РАЗНОСТЬДАТ(МАКСИМУМ(Резерв.Период), МИНИМУМ(Резерв.Период), ДЕНЬ) КАК БылоВРаботе,
							  	-РАЗНОСТЬДАТ(МАКСИМУМ(Резерв.Период), МИНИМУМ(Резерв.Период), ДЕНЬ) + -РАЗНОСТЬДАТ(&ДатаОтчета, МАКСИМУМ(Резерв.Период), ДЕНЬ) КАК РазностьРемонт,
							  	Резерв.Водозабор,
							  	Резерв.Скважина,
							  	Резерв.Состояние,
							  	ВЫБОР
							  		КОГДА РезервСрезПоследних.Состояние = ЗНАЧЕНИЕ(Перечисление.СостояниеСкв.ТекРемонт)
							  			ТОГДА -РАЗНОСТЬДАТ(&ДатаОтчета, МАКСИМУМ(Резерв.Период), ДЕНЬ)
							  		ИНАЧЕ 0
							  	КОНЕЦ КАК ЕщеНабежалоВРемонте
							  ПОМЕСТИТЬ ВТ2
							  ИЗ
							  	РегистрСведений.Резерв.СрезПоследних(&ДатаОтчета, Скважина = &Скважина) КАК РезервСрезПоследних
							  		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Резерв КАК Резерв
							  		ПО РезервСрезПоследних.Скважина = Резерв.Скважина
							  ГДЕ
							  	Резерв.Состояние = ЗНАЧЕНИЕ(Перечисление.СостояниеСкв.ТекРемонт)
							  	И Резерв.Скважина = &Скважина
							  
							  СГРУППИРОВАТЬ ПО
							  	Резерв.Водозабор,
							  	Резерв.Скважина,
							  	Резерв.Состояние,
							  	РезервСрезПоследних.Состояние
							  ;
							  
							  ////////////////////////////////////////////////////////////­////////////////////
							  ВЫБРАТЬ
							  	ВТ1.ЕщеНабежалоВРаботе,
							  	ВТ2.ЕщеНабежалоВРемонте,
							  	ВТ1.Разностьработа,
							  	ВТ2.РазностьРемонт,
							  	ВТ1.Скважина,
							  	ВТ1.Состояние
							  ИЗ
							  	ВТ1 КАК ВТ1,
							  	ВТ2 КАК ВТ2
Показать
Найденные решения
10. ildarovich 6718 21.11.16 12:17 Сейчас в теме
(0) Попробуйте вот такой пакетный запрос:
ВЫБРАТЬ
	&Дата1 КАК Период,
	НаНачало.Скважина,
	НаНачало.Состояние
ПОМЕСТИТЬ Дано
ИЗ
	РегистрСведений.Резерв.СрезПоследних(&Дата1, ) КАК НаНачало

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

ВЫБРАТЬ
	Резерв.Период,
	Резерв.Скважина,
	Резерв.Состояние
ИЗ
	РегистрСведений.Резерв КАК Резерв
ГДЕ
	Резерв.Период МЕЖДУ &Дата1 И &Дата2

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

ВЫБРАТЬ
	&Дата2,
	НаКонец.Скважина,
	НаКонец.Состояние
ИЗ
	РегистрСведений.Резерв.СрезПоследних(&Дата2, ) КАК НаКонец
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Раньше.Период,
	Раньше.Скважина,
	Раньше.Состояние,
	РАЗНОСТЬДАТ(Раньше.Период, МИНИМУМ(Позже.Период), СЕКУНДА) КАК Длительность
ПОМЕСТИТЬ Интервалы
ИЗ
	Дано КАК Раньше
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Дано КАК Позже
		ПО Раньше.Скважина = Позже.Скважина
			И Раньше.Период < Позже.Период

СГРУППИРОВАТЬ ПО
	Раньше.Период,
	Раньше.Скважина,
	Раньше.Состояние
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Интервалы.Скважина,
	Интервалы.Состояние,
	СУММА(Интервалы.Длительность) КАК Длительность
ИЗ
	Интервалы КАК Интервалы

СГРУППИРОВАТЬ ПО
	Интервалы.Скважина,
	Интервалы.Состояние
Показать

У него два параметра: Дата1 и Дата2 - соответственно начало и конец анализируемого интервала.

Если будут проблемы с производительностью, то можно применить подход, описанный в статье: Быстрое определение интервалов в запросе.
Peltzer; NeviD; HIVvich; M.Flint; +4 Ответить
Остальные ответы
Избранное Подписка Сортировка: Древо
2. HIVvich 21.11.16 08:41 Сейчас в теме
Ой простите, внизу у ВТ1 и ВТ2 полное соединение по скважине:
ИЗ ВТ1 КАК ВТ1
ПОЛНОЕ СОЕДИНЕНИЕ ВТ2 КАК ВТ2
ПО ВТ1.Скважина = ВТ2.Скважина
3. ipoloskov 65 21.11.16 08:41 Сейчас в теме
Смотрите, как сделан разбор по периодам в курсах валют.
Что-то типа
ВЫБРАТЬ
РС.Период,
РС.Состояние
ПОМЕСТИТЬ ВТ_Даты
Из РегистрСведений.РС КАК РС;

ВЫБРАТЬ
ВТ1.Состояние,
ВТ1.Период КАК НачалоПериода
МИНИМУМ(ВТ2.Период) КАК КонецПериода
ПОМЕСТИТЬ ВТ_Периоды
ИЗ ВТ_Даты КАК ВТ1
ЛЕВОЕ СОЕДИНЕНИЕ
ВТ_Даты КАК ВТ2
ПО ВТ2.Период > ВТ1.Период;
//и т.д.
Показать
.
4. HIVvich 21.11.16 08:46 Сейчас в теме
(3)Игорь, это у меня есть, т.е. само количество дней (например, или минут без разницы) тоже через разность дат считается? и на последний день как выполняется обсчет?
5. ipoloskov 65 21.11.16 08:55 Сейчас в теме
Добавляете в ВТ_Даты (в моем варианте) одну запись
СрезПоследних.Состояние, &ТекущаяДата
6. HIVvich 21.11.16 09:08 Сейчас в теме
Ага, а дальше что? я добавляю это, разностьдат - ?
7. ipoloskov 65 21.11.16 09:15 Сейчас в теме
(6) Тогда последняя запись в регистре ВТ_Периоды будет
(Последнее_Состояние, Дата_Установки_Последнего_Состояния, ТекущаяДата)
и, соответственно, потом вы получите последнюю разность дат как ТекущаяДата-Дата_Установки_Последнего_Состояния
8. HIVvich 21.11.16 10:09 Сейчас в теме
Это будет разность между последним состоянием и текущей датой,а мне нужно всего за год или за 10 лет.
9. M.Flint 21.11.16 11:02 Сейчас в теме
Вам нужно получить сначала набор всех периодов работы/неработы скважин. Запрос многоуровневый будет.
У вас нет выбора состояний на начало периода, только изменения состояний за выбранный период. Дата изменения состояния не всегда совпадает с отчетным периодом.

Если хотите, могу выложить свой запрос по похожей теме, но по ЗУПу, там чуть сложнее. Запрос скорее всего не оптимальный, но работает.
10. ildarovich 6718 21.11.16 12:17 Сейчас в теме
(0) Попробуйте вот такой пакетный запрос:
ВЫБРАТЬ
	&Дата1 КАК Период,
	НаНачало.Скважина,
	НаНачало.Состояние
ПОМЕСТИТЬ Дано
ИЗ
	РегистрСведений.Резерв.СрезПоследних(&Дата1, ) КАК НаНачало

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

ВЫБРАТЬ
	Резерв.Период,
	Резерв.Скважина,
	Резерв.Состояние
ИЗ
	РегистрСведений.Резерв КАК Резерв
ГДЕ
	Резерв.Период МЕЖДУ &Дата1 И &Дата2

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

ВЫБРАТЬ
	&Дата2,
	НаКонец.Скважина,
	НаКонец.Состояние
ИЗ
	РегистрСведений.Резерв.СрезПоследних(&Дата2, ) КАК НаКонец
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Раньше.Период,
	Раньше.Скважина,
	Раньше.Состояние,
	РАЗНОСТЬДАТ(Раньше.Период, МИНИМУМ(Позже.Период), СЕКУНДА) КАК Длительность
ПОМЕСТИТЬ Интервалы
ИЗ
	Дано КАК Раньше
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Дано КАК Позже
		ПО Раньше.Скважина = Позже.Скважина
			И Раньше.Период < Позже.Период

СГРУППИРОВАТЬ ПО
	Раньше.Период,
	Раньше.Скважина,
	Раньше.Состояние
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Интервалы.Скважина,
	Интервалы.Состояние,
	СУММА(Интервалы.Длительность) КАК Длительность
ИЗ
	Интервалы КАК Интервалы

СГРУППИРОВАТЬ ПО
	Интервалы.Скважина,
	Интервалы.Состояние
Показать

У него два параметра: Дата1 и Дата2 - соответственно начало и конец анализируемого интервала.

Если будут проблемы с производительностью, то можно применить подход, описанный в статье: Быстрое определение интервалов в запросе.
Peltzer; NeviD; HIVvich; M.Flint; +4 Ответить
23. rmp2007 22 28.11.16 22:24 Сейчас в теме
(10) подходит, если нет разных статусов на протяжении дня.
24. ildarovich 6718 28.11.16 23:21 Сейчас в теме
(23) В решении (10) анализируемый период разбивается на интервалы, которые измеряются с точностью до секунд и группируются по статусу, определенному в начале интервала. В течении дня статусы могут меняться сколько угодно раз. Находится (суммированием) общее время в данном статусе.
Так что разные статусы в течении дня препятствием не являются.
25. Peltzer 29.11.16 06:07 Сейчас в теме
(24) По условию в Позже попадут все ремонты, которые были позже, чем в раньше. Соответственно, будет дублирование ремонтов и работ, если периодов с ремонтами было больше, чем один. Или я не прав?
26. Sashares 18 29.11.16 07:47 Сейчас в теме
(25)
в Позже попадут все ремонты, которые были позже, чем в раньше.

Попадут. Однако следите за руками.
РАЗНОСТЬДАТ(Раньше.Период, МИНИМУМ(Позже.Период), СЕКУНДА) КАК Длительность

То есть МИНИМУМ(Позже.Период) найдет ближайшую пару, отсеяв все лишние, т.к. по остальным полям идет группировка.
28. spezc 587 29.11.16 10:22 Сейчас в теме
(10) вроде не работает запрос (прикрутил к нему данные для теста):

ВЫБРАТЬ
	ДАТАВРЕМЯ(2016, 10, 31) КАК Период,
	"Скважина №1" КАК Скважина,
	"Работает" КАК Состояние
ПОМЕСТИТЬ ИсходныеДанныеСрезПоследних

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

ВЫБРАТЬ
	ДАТАВРЕМЯ(2016, 10, 31),
	"Скважина №2",
	"Не работает"
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ДАТАВРЕМЯ(2016, 11, 3) КАК Период,
	"Скважина №1" КАК Скважина,
	"Не работает" КАК Состояние
ПОМЕСТИТЬ ИсходныеДанные

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

ВЫБРАТЬ
	ДАТАВРЕМЯ(2016, 11, 2),
	"Скважина №2",
	"Работает"

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

ВЫБРАТЬ
	ДАТАВРЕМЯ(2016, 11, 20),
	"Скважина №1",
	"Работает"

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

ВЫБРАТЬ
	ДАТАВРЕМЯ(2016, 11, 25),
	"Скважина №2",
	"Не работает"

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

ВЫБРАТЬ
	ДАТАВРЕМЯ(2016, 11, 30),
	"Скважина №3",
	"Работает"
	;
	
ВЫБРАТЬ
	ДАТАВРЕМЯ(2016, 11, 30) КАК Период,
	"Скважина №1" КАК Скважина,
	"Работает" КАК Состояние
ПОМЕСТИТЬ ИсходныеДанныеСрезПоследнихКонец

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

ВЫБРАТЬ
	ДАТАВРЕМЯ(2016, 11, 30),
	"Скважина №2",
	"Не работает"

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

ВЫБРАТЬ
	ДАТАВРЕМЯ(2016, 11, 30),
	"Скважина №3",
	"Работает"
;

ВЫБРАТЬ
    &Дата1 КАК Период,
    НаНачало.Скважина,
    НаНачало.Состояние
ПОМЕСТИТЬ Дано
ИЗ
    ИсходныеДанныеСрезПоследних КАК НаНачало

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

ВЫБРАТЬ
    Резерв.Период Как Период,
    Резерв.Скважина,
    Резерв.Состояние
ИЗ
    ИсходныеДанныеСрезПоследних КАК Резерв
ГДЕ
    Резерв.Период МЕЖДУ &Дата1 И &Дата2

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

ВЫБРАТЬ
    &Дата2,
    НаКонец.Скважина,
    НаКонец.Состояние
ИЗ
    ИсходныеДанныеСрезПоследнихКонец КАК НаКонец
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
    Раньше.Период,
    Раньше.Скважина,
    Раньше.Состояние,
    РАЗНОСТЬДАТ(Раньше.Период, МИНИМУМ(Позже.Период), СЕКУНДА) КАК Длительность
ПОМЕСТИТЬ Интервалы
ИЗ
    Дано КАК Раньше
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Дано КАК Позже
        ПО Раньше.Скважина = Позже.Скважина
            И Раньше.Период < Позже.Период

СГРУППИРОВАТЬ ПО
    Раньше.Период,
    Раньше.Скважина,
    Раньше.Состояние
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
    Интервалы.Скважина,
    Интервалы.Состояние,
    СУММА(Интервалы.Длительность) КАК Длительность
ИЗ
    Интервалы КАК Интервалы

СГРУППИРОВАТЬ ПО
    Интервалы.Скважина,
    Интервалы.Состояние
Показать
29. Sashares 18 29.11.16 11:04 Сейчас в теме
(28) Не работает, потому что у вас ошибка тут
ИсходныеДанныеСрезПоследних КАК Резерв

Если исправить на
ИсходныеДанные КАК Резерв
все будет работать =)
Прикрепленные файлы:
30. spezc 587 29.11.16 11:21 Сейчас в теме
(29) да, все верно. это у меня руки кривые)
но Скважина 3 все равно не попадет в отчет)
31. Sashares 18 29.11.16 11:29 Сейчас в теме
(30) На скрине в (29) она есть =)
Может не попадать, если параметр дата окончания 30.11.2016 00.00.00, т.к. она в эту секунду только запущена, а если 30.11.2016 0:00:01 уже попадет.
И кажется, это правильно.
11. HIVvich 21.11.16 13:18 Сейчас в теме
12. yaroslav.artem 24.11.16 08:21 Сейчас в теме
Не хочу вникать в то, что написали все выше..такие сложные запросы не понимаю я.. я бы сделал простой отчет(не СКД), следующим незамысловатым способом:
На форме отчета у нас будут параметры ДатаНачала(она же начало периода, за который нужно отобрать) ДатаОкончания(она же конец нужного вам периода).. далее эти параметры передаём в запрос.Еще нам понадобится параметр на форме отчета - "Скважина", которую пользователь выбирает и мы его тоже передаём в запрос.
Тут всё понятно надеюсь?
т.е
Запрос.УстановитьПараметр("Скважина", ВыбраннаяСкважина);
Запрос.УстановитьПараметр("ДатаНачала", ВыбраннаяДатаНачала);
и т.д..
Период отбора есть, скважина отбора есть.. предположим получилась следующая выборка..

Скважине№200 01.11.2016 В работе
Скважина№200 02.11.2016 В работе
Скважина№200 03.11.2016 Ремонт
Скважина№200 04.11.2016 Ремонт
Скважина№200 05.11.2016 В Работе

Дальше что бы я сделал..ээм..

КоличествоДнейВРаботе = 0;
КоличествоДнейВРемонте = 0;

Пока РезультатВыборки.Следующи() Цикл
      Если РезультатВыборки.Состояние = ВРаботе Тогда 
        КоличествоДнейВРаботе = КоличествоДнейВРаботе + 1;
ИначеЕсли  
        РезультатВыборки.Состояние = ВРемонте Тогда 
        КоличествоДнейВРемонте  = КоличествоДнейВРемонте  + 1;
КонецЕсли;
КонецЦикла; 
Показать


Вот и получится у нас по окончанию цикла, что переменные будут иметь следующие значения:

//КоличествоДнейВРаботе = 3;
//КоличествоДнейВРемонте = 2; 

Теперь выводим в отчет всё это дело:
ОбластьМакета.Параметры.Скважина = ВыбраннаяПользователемНаФормеСкважина;
ОбластьМакета.Параметры.НачалоПериода = ВыбранноеНачалоПериода;
ОбластьМакета.Параметры.Конецпериода = ВыбранныйКонецПериода;
//Прям в макете подписываем руками 2 статуса "Дней в работе:"<ПараметрМакетаКоличествоДнейВРаботе>
//"Дней в ремонте:"<ПараметрМакетаКоличествоДнейВРемонте>..

Ну и вот и всё впринципе..

ОбластьМакета.Параметры.ПараметрМакетаКоличествоДнейВРаботе = КоличествоДнейВРаботе; 
ОбластьМакета.Параметры.ПараметрМакетаКоличествоДнейВРемонте = КоличествоДнейВРемонте;


Это если вам по дням посчитать надо..
А если прям по времени до часов, минут и секунд надо.. тогда записи в регистре у вас должны быть тоже до минут, часов и секунд..
И тогда примерно таким же макаром, можно как сделать..
Выбрать всё тоже самое, то что выше написал, только двумя запросами и еще добавить к ним параметры "Состояние"..
В первом запросе отбираем всё тоже самое с состоянием "В работе"
Во втором запросе отбираем всё тоже самое с состоянием "Ремонт"
Потом берем все даты из запроса1(где был параметр отбора по состояние в работе), складываем эти даты друг с другом, примерно таким же образом, как и в первом варианте я вам написал, вот и получаем, сколько времени скважина была в работе.
Потом берем все даты из запроса2(где был параметр отбора по состоянию в ремонте), точно также между собой их складываем и получаем количество времени в работе и в ремонте по отдельности.. и потом уже в макет их.
Как там чего нужно с датами отнимать, вычитать, как в минутах, секундах всё это дело получить и т.д., уже сами додумаете по примерчикам с инета, я надеюсь:)
13. yaroslav.artem 24.11.16 08:24 Сейчас в теме
Если вам сводный отчет нужен по всем скважинам, я думаю тоже сможете сами додумать..
т.е все скважины надо будет перебрать циклом,по отдельности подсунуть на каждом ветке цикла каждую скважину в запрос, и точно также как то всё сложить и в макет вывести.. вот :)
14. yaroslav.artem 24.11.16 08:32 Сейчас в теме
А нет.. не получится все даты между собой сложить, как я вам написал про 2 запроса.. Надо же взять промежуток времени от смены Статуса до смены Статуса..+ статусы у вас как я понял просто обновляются переодически.. т.е может быть подряд несколько состояний "В работе"с указанным временем..вот тогда тут надо подумать)..
т.е теоретически надо от смены состояния до смены состояния выбрать минимум и максимум, сложить всё это время.. ой сложно как то.. мозг заболел))
Сделайте по дням, как я вам в первом варианте написал..так получится точно..но это при суловии, что 1 запись в регистре - 1 день..
15. HIVvich 28.11.16 08:52 Сейчас в теме
(14) В регистре в один день может быть куча записей, тут не прокатит так.
16. spezc 587 28.11.16 10:56 Сейчас в теме
17. HIVvich 28.11.16 11:00 Сейчас в теме
18. spezc 587 28.11.16 11:03 Сейчас в теме
т.е. в течение одного дня по одной скважине может быть несколько разных статусов?
19. spezc 587 28.11.16 11:36 Сейчас в теме
ВЫБРАТЬ
	ДАТАВРЕМЯ(2016, 10, 31) КАК Дата,
	"Скважина №1" КАК Объект,
	"Работает" КАК Статус
ПОМЕСТИТЬ ИсходныеДанныеСрезПоследних

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

ВЫБРАТЬ
	ДАТАВРЕМЯ(2016, 10, 31),
	"Скважина №2",
	"Не работает"
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ДАТАВРЕМЯ(2016, 11, 3) КАК Дата,
	"Скважина №1" КАК Объект,
	"Не работает" КАК Статус
ПОМЕСТИТЬ ИсходныеДанные

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

ВЫБРАТЬ
	ДАТАВРЕМЯ(2016, 11, 2),
	"Скважина №2",
	"Работает"

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

ВЫБРАТЬ
	ДАТАВРЕМЯ(2016, 11, 20),
	"Скважина №1",
	"Работает"

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

ВЫБРАТЬ
	ДАТАВРЕМЯ(2016, 11, 25),
	"Скважина №2",
	"Не работает"

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

ВЫБРАТЬ
	ДАТАВРЕМЯ(2016, 11, 17),
	"Скважина №3",
	"Работает"
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ИсходныеДанные.Дата КАК Дата,
	ИсходныеДанные.Объект КАК Объект,
	ИсходныеДанные.Статус КАК Статус
ПОМЕСТИТЬ ТаблицаОбщихДанных
ИЗ
	ИсходныеДанные КАК ИсходныеДанные

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

ВЫБРАТЬ
	ИсходныеДанныеСрезПоследних.Дата,
	ИсходныеДанныеСрезПоследних.Объект,
	ИсходныеДанныеСрезПоследних.Статус
ИЗ
	ИсходныеДанныеСрезПоследних КАК ИсходныеДанныеСрезПоследних
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ТаблицаОбщихДанных.Объект КАК Объект
ПОМЕСТИТЬ ТаблицаОбъектов
ИЗ
	ТаблицаОбщихДанных КАК ТаблицаОбщихДанных

СГРУППИРОВАТЬ ПО
	ТаблицаОбщихДанных.Объект
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ТаблицаОбщихДанных.Объект КАК Объект,
	МИНИМУМ(ВЫБОР
			КОГДА ТаблицаОбщихДанных.Дата < &НачалоПериода
				ТОГДА &НачалоПериода
			ИНАЧЕ ТаблицаОбщихДанных.Дата
		КОНЕЦ) КАК Дата
ПОМЕСТИТЬ ТаблицаНачальныхДат
ИЗ
	ТаблицаОбщихДанных КАК ТаблицаОбщихДанных

СГРУППИРОВАТЬ ПО
	ТаблицаОбщихДанных.Объект
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ТаблицаНачальныхДат.Объект КАК Объект,
	ТаблицаНачальныхДат.Дата КАК Дата,
	ЕСТЬNULL(ТаблицаОбщихДанных.Статус, "Статус неопределен") КАК Статус
ПОМЕСТИТЬ ТаблицаНачальныхСтатусов
ИЗ
	ТаблицаНачальныхДат КАК ТаблицаНачальныхДат
		ЛЕВОЕ СОЕДИНЕНИЕ ТаблицаОбщихДанных КАК ТаблицаОбщихДанных
		ПО ТаблицаНачальныхДат.Объект = ТаблицаОбщихДанных.Объект
			И ТаблицаНачальныхДат.Дата >= ТаблицаОбщихДанных.Дата
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ТаблицаНачальныхСтатусов.Объект КАК Объект,
	ТаблицаНачальныхСтатусов.Дата КАК Дата,
	ТаблицаНачальныхСтатусов.Статус КАК Статус
ПОМЕСТИТЬ ТаблицаАнализируемыхДанных
ИЗ
	ТаблицаНачальныхСтатусов КАК ТаблицаНачальныхСтатусов

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

ВЫБРАТЬ
	ИсходныеДанные.Объект,
	ИсходныеДанные.Дата,
	ИсходныеДанные.Статус
ИЗ
	ИсходныеДанные КАК ИсходныеДанные
ГДЕ
	НЕ (ИсходныеДанные.Объект, ИсходныеДанные.Дата, ИсходныеДанные.Статус) В
				(ВЫБРАТЬ
					ТаблицаНачальныхСтатусов.Объект,
					ТаблицаНачальныхСтатусов.Дата,
					ТаблицаНачальныхСтатусов.Статус
				ИЗ
					ТаблицаНачальныхСтатусов КАК ТаблицаНачальныхСтатусов)
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ТаблицаАнализируемыхДанных.Объект КАК Объект,
	ТаблицаАнализируемыхДанных.Дата КАК Дата,
	ТаблицаАнализируемыхДанных.Статус КАК Статус,
	МИНИМУМ(ЕСТЬNULL(ТаблицаАнализируемыхДанныхДляСоединения.Дата, ДобавитьКДате(&ОкончаниеПериода, День, 1))) КАК ДатаСледующегоСтатуса
ПОМЕСТИТЬ ТаблицаПодготовленныхДанных
ИЗ
	ТаблицаАнализируемыхДанных КАК ТаблицаАнализируемыхДанных
		ЛЕВОЕ СОЕДИНЕНИЕ ТаблицаАнализируемыхДанных КАК ТаблицаАнализируемыхДанныхДляСоединения
		ПО ТаблицаАнализируемыхДанных.Объект = ТаблицаАнализируемыхДанныхДляСоединения.Объект
			И ТаблицаАнализируемыхДанных.Дата < ТаблицаАнализируемыхДанныхДляСоединения.Дата

СГРУППИРОВАТЬ ПО
	ТаблицаАнализируемыхДанных.Объект,
	ТаблицаАнализируемыхДанных.Дата,
	ТаблицаАнализируемыхДанных.Статус
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ТаблицаПодготовленныхДанных.Объект,
	ТаблицаПодготовленныхДанных.Статус,
	СУММА(РАЗНОСТЬДАТ(ТаблицаПодготовленныхДанных.Дата, ТаблицаПодготовленныхДанных.ДатаСледующегоСтатуса, ДЕНЬ)) КАК ДнейВСтатусе
ИЗ
	ТаблицаПодготовленныхДанных КАК ТаблицаПодготовленныхДанных

СГРУППИРОВАТЬ ПО
	ТаблицаПодготовленныхДанных.Объект,
	ТаблицаПодготовленныхДанных.Статус
Показать
20. spezc 587 28.11.16 11:43 Сейчас в теме
Комментарии:
- ИсходныеДанныеСрезПоследних - имитация среза последних на НачалоПериода
- ИсходныеДанные - имитация записей за период с НачалоПериода по ОкончаниеПериода
- Пакетный запрос для получения временной таблицы ТаблицаОбъектов на самом деле не нужен (не используется далее нигде).
- ТаблицаНачальныхДат нужна для тех объектов, которые появились в регистре после НачалоПериода (т.е. их нет в ИсходныеДанныеСрезПоследних).
- ТаблицаАнализируемыхДанных состоит из 1. ТаблицаНачальныхСтатусов и 2. ИсходныеДанные.Объект минус ТаблицаНачальныхСтатусов.
- В ТаблицаПодготовленныхДанных к ОкончаниеПериода добавляем один день, так как нам надо получить разницу с учетом этого последнего дня.
Прикрепленные файлы:
ВременныеТаблицы.xlsx
22. Sashares 18 28.11.16 20:49 Сейчас в теме
(20)не совсем понятно, зачем так сложно. В (10) приведено достаточно простое и элегантное решение. Попробуйте его осмыслить.
27. spezc 587 29.11.16 10:12 Сейчас в теме
(22) с Сергеем Ильдаровичем мне конечно не тягаться, но его запрос не покажет скважины, которые впервые появились в регистре в период с Дата1 по Дата2.
21. spezc 587 28.11.16 12:23 Сейчас в теме
32. spezc 587 29.11.16 12:43 Сейчас в теме
гы, действительно все работает) ну я же говорил не фиг с Ильдаровичем тягаться.
Оставьте свое сообщение
Новые вопросы с вознаграждением
Автор темы объявил вознаграждение за найденный ответ, его получит тот, кто первый поможет автору.

Вакансии

Программист 1С
Москва
зарплата от 150 000 руб. до 180 000 руб.
Полный день

Программист 1С
Москва
зарплата до 160 000 руб.
Полный день

Автор новостных обзоров на тему 1С и бухучета
Санкт-Петербург
По совместительству

Ведущий программист 1С
Санкт-Петербург
зарплата от 130 000 руб.
Полный день

Программист 1С
Москва
зарплата от 130 000 руб. до 200 000 руб.
Полный день