Свертка таблицы значений по заданному условию

1. idw 344 22.08.19 15:19 Сейчас в теме
Задача стоит вот такая:
есть таблица значений из колонок: этаж, площадь и количество продаж.
Надо свернуть эту ТЗ хитрым способом по этажам и площадям,
а именно, есть некая другая ТЗ в которой забиты интвервалы свертки по этажам, например:
1-3, 4-6, 7-14 этаж.
По этой ТЗ надо свернуть основную таблицу, то есть все этажи с 1 по 3 объединить в одну строку и так далее.
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Найденные решения
21. KVIKS 400 23.08.19 09:40 Сейчас в теме +1 $m
Тогда
МасКУдалению=Новый Массив;
новтз= тз2.скопировать();
новтзграницаэтажей.свернуть("ИнтервалНиз,ИнтервалВерх");
//новтзграницаэтажей.сортировать("ИнтервалНиз убыв");
Для каждого стр из тз1 цикл
   Для каждого интервал из новтзграницаэтажей цикл
        если стр.этаж>=интервал.ИнтервалНиз и стр.этаж>=интервал.ИнтервалВерх тогда
               стр.этаж=интервал.ИнтервалНиз;
               Прервать;
        КонецЕсли;
        //если не наш интервал то ставим удалим потом 
          МасКУдалению.Добавить(Стр);
   КонецЦикла;
КонецЦикла;     
и еще 1 цикл чтобы выбросить лишнее
для Каждого стр из МасКУдалению Цикл
     Тз1.Удалить(стр);
Конеццикла;
тз1.Свернуть("Этаж","КоличествоПродаж") ;
Показать
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. VmvLer 22.08.19 15:24 Сейчас в теме
способ 1: Тз завернуть в ВТ и делать все запросом
спобос 2: Отборами разбить ТзИсточник на части, затем рукоблудить выполнять некоторые действия с множеством таблиц в коде
споосб 3: написать красивый и большой код обработки одной Тз, потом выкинуть его на помойку и зря потратить время.

я за способ 1
YannikAlx; +1 1 Ответить
3. Sashares 34 22.08.19 15:24 Сейчас в теме
И в чем именно сложность?
4. YannikAlx 43 22.08.19 15:25 Сейчас в теме
так и в чем проблема соединяйте в запросе 2 таблицы, ведь в параметрах связи не обязательны знаки равенства...
установите связь
ПО ТЗ1.Этаж>ТЗ2.НижнийИнтервал
И ТЗ1.Этаж<ТЗ2.ВерхнийИнтервал
5. SlavaKron 22.08.19 15:31 Сейчас в теме
Добавьте в ТЗ колонку ИнтервалЭтажа. Заполните ее по всем строкам ТЗ. Сверните ТЗ методом Свернуть()
6. idw 344 22.08.19 15:38 Сейчас в теме
(5) интервал этажа заранее не известен, он задается пользователем во второй ТЗ.
8. herfis 499 22.08.19 15:51 Сейчас в теме
Торможу, в (5) уже предложено
7. herfis 499 22.08.19 15:45 Сейчас в теме
1) Добавляешь колонку "КатегорияЭтажности"
2) Обходишь таблицу, определяя категорию этажности по данным второй таблицы
3) Сворачиваешь по этой колонке - профит.

Если нужна оптимизация производительности для второго этапа (чтобы не искать по второй таблице каждый раз), тогда создаешь соответствие "КатегорииЭтажности" по данным второй таблицы вида
1 (этаж) - 1 (категория)
2 - 1
3 - 1
4 - 2
5 - 2
6 - 2
7 - 3
.....

Тогда категория для пункта два будет вычисляться строкой кода, отрабатывающей мгновенно:
ТаблицаПродаж.КатегорияЭтажности = КатегорииЭтажности[ТаблицаПродаж.Этаж];
9. herfis 499 22.08.19 16:17 Сейчас в теме
Меня всегда смущает, когда люди предлагают решать простейшие задачи запросами.
Не, я понимаю - задача неплохо ложится на запрос, если бы эти таблицы были бы у нас в БД.
Но все данные у нас уже вот - в руках, в памяти. И обработать их требуемым образом можно быстро и дешево. Зачем запихивать их на сервер БД для этого? Почему людям кажется, что это проще и эффективнее? Вспоминается древний-древний фантастический рассказик "Последнее испытание".
Тут он второй по счету: https://knigogid.ru/books/530792-perekrestok-dalnih-dorog/toread
10. Akuji 22 22.08.19 16:21 Сейчас в теме
Просто перебрал бы все строки 1й таблицы в цикле и по условию отправлял бы во вторую.
11. herfis 499 22.08.19 16:23 Сейчас в теме
(10) Забыл про накопление итогов. И дедупликацию.
12. Akuji 22 22.08.19 16:26 Сейчас в теме
(11)
Ищем строки по условию интервала во второй таблице.

Если строку нашли то прибавляем итог.

Итог = Итог + данныеСтроки
13. herfis 499 22.08.19 16:35 Сейчас в теме
(12) Перечитал условие задачи. Если нет дополнительных измерений, то получается что итоговое измерение будет одно - по интервалу.
Тогда решение в самом деле можно предельно упростить для решения за один проход.
14. herfis 499 22.08.19 16:40 Сейчас в теме
Я бы тогда добавил итоговые колонки в таблицу интервалов, заполнил бы соответствие номера этажа - строке таблицы интервалов и в цикле по основной таблице:
СтрокаИнтервала = СоответствиеИнтервалов[СтрокаПродажПоЭтажам.Этаж];
СтрокаИнтервала.Площадь = СтрокаИнтервала.Площадь + СтрокаПродажПоЭтажам.Площадь;
СтрокаИнтервала.КвоПродаж = СтрокаИнтервала.КвоПродаж + СтрокаПродажПоЭтажам.КвоПродаж;
15. KVIKS 400 22.08.19 17:22 Сейчас в теме
а интервалы во второй таблице задаются строкой? "1-3"? или все таки двумя числами в разных колонках?
16. idw 344 22.08.19 19:08 Сейчас в теме
(15) двумя числами в колонках.
17. KVIKS 400 22.08.19 19:43 Сейчас в теме
новтз= тз2.скопировать();
новтзграницаэтажей.свернуть("ИнтервалНиз");
новтзграницаэтажей.сортировать("ИнтервалНиз убыв");
Для каждого стр из тз1 цикл
   Для каждого интервал из новтзграницаэтажей цикл
        если стр.этаж>=интервал.ИнтервалНиз тогда
               стр.этаж=интервал.ИнтервалНиз;
               Прервать;
        КонецЕсли;
   КонецЦикла;
КонецЦикла;     
тз1.Свернуть("Этаж","КоличествоПродаж") ;
Показать

Суть в том что нам не нужен интервал, а нужна одна из границ интервала, отсортированная по убыванию. И в цикле по тз1 идет проверка если этаж больше максимальной границы, ставим нужную границу, если нет то мы автоматом спустимся в следующий интервал и тд. и в конце уже просто свернуть тз по нужным колонкам
20. idw 344 22.08.19 20:08 Сейчас в теме
(17) а если так:

Для каждого стр из ТЗ1 цикл
		Для каждого интервал из ТЗ2 цикл
			если (интервал.ИнтервалНиз <=стр.этаж) и (стр.этаж<=интервал.ИнтервалВерх) тогда
				стр.этаж=интервал.ИнтервалНиз;
				Прервать;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;  
тз1.Свернуть("Этаж","КоличествоПродаж") ;
Показать
18. KVIKS 400 22.08.19 19:45 Сейчас в теме
главное чтобы не было разрывов в интервалах к примеру выбрать 1-3 и 8-9, тогда все этажи с 1 по 7 попадут в первый интервал 1-3.
19. idw 344 22.08.19 19:47 Сейчас в теме
(18) как раз разрывы и могут быть. Типа смотреть не все этажи. )
21. KVIKS 400 23.08.19 09:40 Сейчас в теме +1 $m
Тогда
МасКУдалению=Новый Массив;
новтз= тз2.скопировать();
новтзграницаэтажей.свернуть("ИнтервалНиз,ИнтервалВерх");
//новтзграницаэтажей.сортировать("ИнтервалНиз убыв");
Для каждого стр из тз1 цикл
   Для каждого интервал из новтзграницаэтажей цикл
        если стр.этаж>=интервал.ИнтервалНиз и стр.этаж>=интервал.ИнтервалВерх тогда
               стр.этаж=интервал.ИнтервалНиз;
               Прервать;
        КонецЕсли;
        //если не наш интервал то ставим удалим потом 
          МасКУдалению.Добавить(Стр);
   КонецЦикла;
КонецЦикла;     
и еще 1 цикл чтобы выбросить лишнее
для Каждого стр из МасКУдалению Цикл
     Тз1.Удалить(стр);
Конеццикла;
тз1.Свернуть("Этаж","КоличествоПродаж") ;
Показать
23. idw 344 23.08.19 11:33 Сейчас в теме
(21) не совсем правильно сработает на удаление:
ТЗ1 - данный, ТЗ2 - условие по этажам.
Допустим ТЗ1: 1,2,3 этажи,
ТЗ2: с 1 по 1, с 2 по 3 этаж

МасКУдалению=Новый Массив;
// новтз= тз2.скопировать(); //не понял для чего это
тз2.свернуть("ИнтервалНиз,ИнтервалВерх");
//новтзграницаэтажей.сортировать("ИнтервалНиз убыв");
Для каждого стр из тз1 цикл
   Для каждого интервал из тз2 цикл
        если стр.этаж>=интервал.ИнтервалНиз и стр.этаж>=интервал.ИнтервалВерх тогда
               стр.этаж=интервал.ИнтервалНиз;
               Прервать;
        КонецЕсли;
        //если не наш интервал то ставим удалим потом 
          МасКУдалению.Добавить(Стр);
   КонецЦикла;
КонецЦикла;     


для Каждого стр из МасКУдалению Цикл
     Тз1.Удалить(стр);
Конеццикла;
тз1.Свернуть("Этаж","КоличествоПродаж") ;
Показать


перебираем этажи 1,2,3.
Со 2-м этажом будет интересно во 2-м цикле:
2этаж условие с 1 по 1 не проходит и попадает в массив на удаление.
24. KVIKS 400 23.08.19 13:47 Сейчас в теме
(23)да, пардон, массив должен заполняться после второго цикла, в конце первого только надо еще условие добавить обработали строку или нет, если нет то в массив ее.
25. idw 344 23.08.19 14:53 Сейчас в теме
(24) вот так?

МасКУдалению=Новый Массив;
// новтз= тз2.скопировать(); //не понял для чего это
тз2.свернуть("ИнтервалНиз,ИнтервалВерх");
//новтзграницаэтажей.сортировать("ИнтервалНиз убыв");
Для каждого стр из тз1 цикл
   Для каждого интервал из тз2 цикл
         ПрошлаУсловие = Ложь;;
        если стр.этаж>=интервал.ИнтервалНиз и стр.этаж>=интервал.ИнтервалВерх тогда
               стр.этаж=интервал.ИнтервалНиз;
               Прервать;
               ПрошлаУсловие = Истина;
        КонецЕсли;
        Если НЕ ПрошлаУсловие  Тогда
              МасКУдалению.Добавить(Стр);
        КонецЕсли;
   КонецЦикла;
КонецЦикла;     


для Каждого стр из МасКУдалению Цикл
     Тз1.Удалить(стр);
Конеццикла;
тз1.Свернуть("Этаж","КоличествоПродаж") ;
Показать
22. DC 149 23.08.19 10:00 Сейчас в теме
ВЫБРАТЬ
	ТЗ.Этаж КАК Этаж,
	ТЗ.Количество КАК Количество
ПОМЕСТИТЬ ТЗ
ИЗ
	&ТЗ КАК ТЗ
;
ВЫБРАТЬ
	ТЗЭтажи.ПервыйЭтаж КАК ПервыйЭтаж,
	ТЗЭтажи.ПоследнийЭтаж КАК ПоследнийЭтаж
ПОМЕСТИТЬ ТЗЭтажи
ИЗ
	&ТЗЭтажи КАК ТЗЭтажи
;
ВЫБРАТЬ
	ТЗЭтажи.ПервыйЭтаж КАК ПервыйЭтаж,
	ТЗЭтажи.ПоследнийЭтаж КАК ПоследнийЭтаж,
	СУММА(ТЗ.Количество) КАК Количество
ИЗ
	ТЗЭтажи КАК ТЗЭтажи
		ЛЕВОЕ СОЕДИНЕНИЕ ТЗ КАК ТЗ
		ПО (ТЗ.Этаж МЕЖДУ ТЗЭтажи.ПервыйЭтаж И ТЗЭтажи.ПоследнийЭтаж)

СГРУППИРОВАТЬ ПО
	ТЗЭтажи.ПервыйЭтаж,
	ТЗЭтажи.ПоследнийЭтаж
Показать
26. KVIKS 400 23.08.19 15:21 Сейчас в теме
Вот так, условие за вторым циклом
МасКУдалению=Новый Массив;
// новтз= тз2.скопировать(); //не понял для чего это
тз2.свернуть("ИнтервалНиз,ИнтервалВерх");
//новтзграницаэтажей.сортировать("ИнтервалНиз убыв");
Для каждого стр из тз1 цикл
   ПрошлаУсловие = Ложь;;
   Для каждого интервал из тз2 цикл
        
        если стр.этаж>=интервал.ИнтервалНиз и стр.этаж>=интервал.ИнтервалВерх тогда
               стр.этаж=интервал.ИнтервалНиз;
               ПрошлаУсловие = Истина;
               Прервать;
        КонецЕсли;
       
   КонецЦикла;
   Если НЕ ПрошлаУсловие  Тогда
              МасКУдалению.Добавить(Стр);
        КонецЕсли;
КонецЦикла;     


для Каждого стр из МасКУдалению Цикл
     Тз1.Удалить(стр);
Конеццикла;
тз1.Свернуть("Этаж","КоличествоПродаж") ;
Показать
Оставьте свое сообщение

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