Задача стоит вот такая:
есть таблица значений из колонок: этаж, площадь и количество продаж.
Надо свернуть эту ТЗ хитрым способом по этажам и площадям,
а именно, есть некая другая ТЗ в которой забиты интвервалы свертки по этажам, например:
1-3, 4-6, 7-14 этаж.
По этой ТЗ надо свернуть основную таблицу, то есть все этажи с 1 по 3 объединить в одну строку и так далее.
МасКУдалению=Новый Массив;
новтз= тз2.скопировать();
новтзграницаэтажей.свернуть("ИнтервалНиз,ИнтервалВерх");
//новтзграницаэтажей.сортировать("ИнтервалНиз убыв");
Для каждого стр из тз1 цикл
Для каждого интервал из новтзграницаэтажей цикл
если стр.этаж>=интервал.ИнтервалНиз и стр.этаж>=интервал.ИнтервалВерх тогда
стр.этаж=интервал.ИнтервалНиз;
Прервать;
КонецЕсли;
//если не наш интервал то ставим удалим потом
МасКУдалению.Добавить(Стр);
КонецЦикла;
КонецЦикла;
и еще 1 цикл чтобы выбросить лишнее
для Каждого стр из МасКУдалению Цикл
Тз1.Удалить(стр);
Конеццикла;
тз1.Свернуть("Этаж","КоличествоПродаж") ;
способ 1: Тз завернуть в ВТ и делать все запросом
спобос 2: Отборами разбить ТзИсточник на части, затем рукоблудить выполнять некоторые действия с множеством таблиц в коде
споосб 3: написать красивый и большой код обработки одной Тз, потом выкинуть его на помойку и зря потратить время.
так и в чем проблема соединяйте в запросе 2 таблицы, ведь в параметрах связи не обязательны знаки равенства...
установите связь
ПО ТЗ1.Этаж>ТЗ2.НижнийИнтервал
И ТЗ1.Этаж<ТЗ2.ВерхнийИнтервал
1) Добавляешь колонку "КатегорияЭтажности"
2) Обходишь таблицу, определяя категорию этажности по данным второй таблицы
3) Сворачиваешь по этой колонке - профит.
Если нужна оптимизация производительности для второго этапа (чтобы не искать по второй таблице каждый раз), тогда создаешь соответствие "КатегорииЭтажности" по данным второй таблицы вида
1 (этаж) - 1 (категория)
2 - 1
3 - 1
4 - 2
5 - 2
6 - 2
7 - 3
.....
Тогда категория для пункта два будет вычисляться строкой кода, отрабатывающей мгновенно:
Меня всегда смущает, когда люди предлагают решать простейшие задачи запросами.
Не, я понимаю - задача неплохо ложится на запрос, если бы эти таблицы были бы у нас в БД.
Но все данные у нас уже вот - в руках, в памяти. И обработать их требуемым образом можно быстро и дешево. Зачем запихивать их на сервер БД для этого? Почему людям кажется, что это проще и эффективнее? Вспоминается древний-древний фантастический рассказик "Последнее испытание".
Тут он второй по счету: https://knigogid.ru/books/530792-perekrestok-dalnih-dorog/toread
(12) Перечитал условие задачи. Если нет дополнительных измерений, то получается что итоговое измерение будет одно - по интервалу.
Тогда решение в самом деле можно предельно упростить для решения за один проход.
Я бы тогда добавил итоговые колонки в таблицу интервалов, заполнил бы соответствие номера этажа - строке таблицы интервалов и в цикле по основной таблице:
новтз= тз2.скопировать();
новтзграницаэтажей.свернуть("ИнтервалНиз");
новтзграницаэтажей.сортировать("ИнтервалНиз убыв");
Для каждого стр из тз1 цикл
Для каждого интервал из новтзграницаэтажей цикл
если стр.этаж>=интервал.ИнтервалНиз тогда
стр.этаж=интервал.ИнтервалНиз;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
тз1.Свернуть("Этаж","КоличествоПродаж") ;
Показать
Суть в том что нам не нужен интервал, а нужна одна из границ интервала, отсортированная по убыванию. И в цикле по тз1 идет проверка если этаж больше максимальной границы, ставим нужную границу, если нет то мы автоматом спустимся в следующий интервал и тд. и в конце уже просто свернуть тз по нужным колонкам
Для каждого стр из ТЗ1 цикл
Для каждого интервал из ТЗ2 цикл
если (интервал.ИнтервалНиз <=стр.этаж) и (стр.этаж<=интервал.ИнтервалВерх) тогда
стр.этаж=интервал.ИнтервалНиз;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
тз1.Свернуть("Этаж","КоличествоПродаж") ;
МасКУдалению=Новый Массив;
новтз= тз2.скопировать();
новтзграницаэтажей.свернуть("ИнтервалНиз,ИнтервалВерх");
//новтзграницаэтажей.сортировать("ИнтервалНиз убыв");
Для каждого стр из тз1 цикл
Для каждого интервал из новтзграницаэтажей цикл
если стр.этаж>=интервал.ИнтервалНиз и стр.этаж>=интервал.ИнтервалВерх тогда
стр.этаж=интервал.ИнтервалНиз;
Прервать;
КонецЕсли;
//если не наш интервал то ставим удалим потом
МасКУдалению.Добавить(Стр);
КонецЦикла;
КонецЦикла;
и еще 1 цикл чтобы выбросить лишнее
для Каждого стр из МасКУдалению Цикл
Тз1.Удалить(стр);
Конеццикла;
тз1.Свернуть("Этаж","КоличествоПродаж") ;
(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 не проходит и попадает в массив на удаление.
(23)да, пардон, массив должен заполняться после второго цикла, в конце первого только надо еще условие добавить обработали строку или нет, если нет то в массив ее.
МасКУдалению=Новый Массив;
// новтз= тз2.скопировать(); //не понял для чего это
тз2.свернуть("ИнтервалНиз,ИнтервалВерх");
//новтзграницаэтажей.сортировать("ИнтервалНиз убыв");
Для каждого стр из тз1 цикл
Для каждого интервал из тз2 цикл
ПрошлаУсловие = Ложь;;
если стр.этаж>=интервал.ИнтервалНиз и стр.этаж>=интервал.ИнтервалВерх тогда
стр.этаж=интервал.ИнтервалНиз;
Прервать;
ПрошлаУсловие = Истина;
КонецЕсли;
Если НЕ ПрошлаУсловие Тогда
МасКУдалению.Добавить(Стр);
КонецЕсли;
КонецЦикла;
КонецЦикла;
для Каждого стр из МасКУдалению Цикл
Тз1.Удалить(стр);
Конеццикла;
тз1.Свернуть("Этаж","КоличествоПродаж") ;
ВЫБРАТЬ
ТЗ.Этаж КАК Этаж,
ТЗ.Количество КАК Количество
ПОМЕСТИТЬ ТЗ
ИЗ
&ТЗ КАК ТЗ
;
ВЫБРАТЬ
ТЗЭтажи.ПервыйЭтаж КАК ПервыйЭтаж,
ТЗЭтажи.ПоследнийЭтаж КАК ПоследнийЭтаж
ПОМЕСТИТЬ ТЗЭтажи
ИЗ
&ТЗЭтажи КАК ТЗЭтажи
;
ВЫБРАТЬ
ТЗЭтажи.ПервыйЭтаж КАК ПервыйЭтаж,
ТЗЭтажи.ПоследнийЭтаж КАК ПоследнийЭтаж,
СУММА(ТЗ.Количество) КАК Количество
ИЗ
ТЗЭтажи КАК ТЗЭтажи
ЛЕВОЕ СОЕДИНЕНИЕ ТЗ КАК ТЗ
ПО (ТЗ.Этаж МЕЖДУ ТЗЭтажи.ПервыйЭтаж И ТЗЭтажи.ПоследнийЭтаж)
СГРУППИРОВАТЬ ПО
ТЗЭтажи.ПервыйЭтаж,
ТЗЭтажи.ПоследнийЭтаж
МасКУдалению=Новый Массив;
// новтз= тз2.скопировать(); //не понял для чего это
тз2.свернуть("ИнтервалНиз,ИнтервалВерх");
//новтзграницаэтажей.сортировать("ИнтервалНиз убыв");
Для каждого стр из тз1 цикл
ПрошлаУсловие = Ложь;;
Для каждого интервал из тз2 цикл
если стр.этаж>=интервал.ИнтервалНиз и стр.этаж>=интервал.ИнтервалВерх тогда
стр.этаж=интервал.ИнтервалНиз;
ПрошлаУсловие = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если НЕ ПрошлаУсловие Тогда
МасКУдалению.Добавить(Стр);
КонецЕсли;
КонецЦикла;
для Каждого стр из МасКУдалению Цикл
Тз1.Удалить(стр);
Конеццикла;
тз1.Свернуть("Этаж","КоличествоПродаж") ;