Помогите сделать красиво.
Есть таблица значений с полями Контрагент , Итог, Итог2, Договор;
Надо свернуть таблицу, по поле договор это строка, ее надо конкатинировать, типа Договор +","+Договор.
Таблица.Свернуть("Контрагент" , "Итог, Итог2, Договор"); не подходит т.к. сворачиваются только числа,
и если договор повторяется получаем 0. Т.е. нужно вручную свернуть перебором, но как именно не соображу.
---
нужно вручную свернуть перебором, но как именно не соображу. М-да... Хотел было привычно понудеть: мол, нынешние 1Сники - не программисты, без "готовой функции" - никуда, а потом глянул на стаж автора - 13 лет с хвостиком!

Код писать принципиально не стану, а алгоритм может быть таким.
1. Сортируем ТЗ по Контрагенту
2. Запоминаем в переменной ТекущийКонтрагент Контрагента из последней строки, а в Итог, Итог2, Договор - в переменных ИтогоИтог, ИтогоИтог2, ИтогоДоговор.
3. В цикле перебираем строки ТЗ от конца к началу, с предпоследней строки.
4. Если Контрагент=ТекущийКонтрагент тогда к полям Итог, Итог2, Договор добавляем ИтогоИтог, ИтогоИтог2, ИтогоДоговор (с сохранением в полях ТЗ!), а предыдущую (лежащую ниже) строку ТЗ - удаляем.
5. Если Контрагент<>ТекущийКонтрагент тогда запоминаем в переменных ТекущийКонтрагентг, ИтогоИтог, ИтогоИтог2, ИтогоДоговор соответствующие поля.
6. Переходим к следующей (лежащей выше) строке.
---
1. Выделить контрагентов в отдельный список.
2. Обрабатывать таблицу по контрагентам
2а. Выгрузить договоры контрагента в массив
2б. свернуть копию таблицы по контрагенту
2в. получить конкатенацию договоров из массива и добавить результат в колонку таблицы
---
нужно вручную свернуть перебором, но как именно не соображу. М-да... Хотел было привычно понудеть: мол, нынешние 1Сники - не программисты, без "готовой функции" - никуда, а потом глянул на стаж автора - 13 лет с хвостиком!

Код писать принципиально не стану, а алгоритм может быть таким.
1. Сортируем ТЗ по Контрагенту
2. Запоминаем в переменной ТекущийКонтрагент Контрагента из последней строки, а в Итог, Итог2, Договор - в переменных ИтогоИтог, ИтогоИтог2, ИтогоДоговор.
3. В цикле перебираем строки ТЗ от конца к началу, с предпоследней строки.
4. Если Контрагент=ТекущийКонтрагент тогда к полям Итог, Итог2, Договор добавляем ИтогоИтог, ИтогоИтог2, ИтогоДоговор (с сохранением в полях ТЗ!), а предыдущую (лежащую ниже) строку ТЗ - удаляем.
5. Если Контрагент<>ТекущийКонтрагент тогда запоминаем в переменных ТекущийКонтрагентг, ИтогоИтог, ИтогоИтог2, ИтогоДоговор соответствующие поля.
6. Переходим к следующей (лежащей выше) строке.
---
По по поводу 1с ника- я не 1сник, я системщик. 1с для меня типа хобби, просят иногда мелкие задачи. Тут больше вопрос про программирование и ваш ответ ishelper правильный, потому что не стали писать код и потому что я просил красивое решение. Т.к. костыли которые предлагали коллеги, я и сам мог намудрить.
Судя по обсуждению задача не тривиальная. В общем код написал. Спасибо большое за подсказку.
---
(3) Можно еще в стиле брутфорса. Через получение массивов договоров каждого отдельного контрагента. Потом эти массивы нужно свернуть и СтрСоединить.
---
Потом эти массивы нужно свернуть и СтрСоединить. Алгоритмы решения могут быть очень разными, но позволю себе маааленькое уточнение: нигде в описании задачи не указана платформа 1С! То есть, это может быть даже 7.7, какие варианты будут работать в этом случае - смотрите сами.
---
Гхм;) Если маааленькое уточнение про СтрСоединить, то его аналог пишется не более, чем в 10 строк кода. И не люблю махинации с удалением первичных данных - это про "предыдущую (лежащую ниже) строку ТЗ - удаляем".
---
И не люблю махинации с удалением первичных данных - это про "предыдущую (лежащую ниже) строку ТЗ - удаляем". А штатная (средствами платформы) свертка не удаляет строки из сворачиваемой таблицы значений? Их количество остается неизменным? Интересненько...
---
Штатная свертка - нет, ничего не удаляет. Там свернутые строки по их ссылкам (указателям) совсем другие. Состав строк пересоздается в соответствии с критериями свертки и суммирования.
---
Там свернутые строки по их ссылкам (указателям) совсем другие. Состав строк пересоздается в соответствии с критериями свертки и суммирования. И что, исходный "состав строк" можно восстановить? Каким образом, расскажете?
---
Вроде бы я и не вел к тому, что исходный состав строк каким-то образом восстанавливается Нет, не вели. Вы всего лишь недвусмысленно и безапелляционно утверждали, что:
Штатная свертка - нет, ничего не удаляет.
Элементарно сравнивая количество строк в таблице значений до и после свертки задумываемся - а что случилось с теми строками, которых в свернутой ТЗ больше нет? Ушли в астрал? ;-)

А с учетом:
Свертка необратима, это факт. с удовольствием перечитываем процитированное выше. :-P
---
Аналогичная тема https://forum.infostart.ru/forum9/topic276612/
---
Вроде бы я и не вел к тому, что исходный состав строк каким-то образом восстанавливается. Свертка необратима, это факт. Если нужны исходные данные, то свертка делается на их копии.
---
Товарищ, вы меня троллите;) Хотите показаться умнее (меня, например) - ок, пусть так.
---
Можно ТЗ передать в запрос, в запросе итоги по контрагенту, числовые поля сразу просуммировать. Делаем пустую ТЗ с таким же набором колонок. Далее два цикла: первый по контрагентам (итоговые записи), в нем создаем новую строку в новой тз и заполняем контрагентом и числовыми итогами, потом второй цикл по детальным записям, т.е. по договорам. где собираем общую строку типа Договор = Договор+Выборка.Договор;. После цикла по детальным заполняем поле договора получившимся представлением в строке новой тз. На выходе получаем свернутую таблицу по контрагентам.
---
```1c
    таблицаРезультата = таблицаИсходная.Скопировать();
    таблицаРезультата.Свернуть("Контрагент", "Итог, Итог2");
    таблицаРезультата.Колонки.Добавить("Договор", Новый ОписаниеТипов("Строка"));
    таблицаИсходная.Индексы.Добавить("Контрагент"); // Не обязательно, это для ускорения поиска, если таблица большая
    Для каждого строкаРезультата Из таблицаРезультата Цикл
    Для каждого строкаИсходная Из таблицаИсходная.НайтиСтроки(Новый Структура("Контрагент", строкаРезультата.Контрагент)) Цикл
    строкаРезультата.Договор = строкаРезультата.Договор+?(строкаРезультата.Договор = ", ", ",")+строкаИсходная.Договор;
    КонецЦикла;
    КонецЦикла;
    // в результате 2 таблицы:
    // таблицаИсходная - начальная таблица
    // таблицаРезультата - свернутая таблица
```
---
а вот этот "шедевр" проще реализовать так:

```1c
    таблица.Сортировать("Контрагент");
    массивСтрокДляУдаления = Новый Массив;
    контрагент = Неопределено;
    Для каждого строка Из таблица Цикл
    Если контрагент <> строка.Контрагент Тогда
    контрагент = строка.Контрагент;
    строкаКонтрагента = строка;
    Иначе
    строкаКонтрагента.Договор = строкаКонтрагента.Договор+?(строкаКонтрагента.Договор = ", ", ",")+строка.Договор;
    строкаКонтрагента.Итог = строкаКонтрагента.Итог+строка.Итог;
    строкаКонтрагента.Итог2 = строкаКонтрагента.Итог2+строка.Итог2;
    массивСтрокДляУдаления.Добавить(строка);
    КонецЕсли;
    КонецЦикла;
    Для каждого строка Из массивСтрокДляУдаления Цикл
    таблица.Удалить(строка);
    КонецЦикла;
```
---
Если использовать СтрСоединить, то можно так:

```1c
    таблицаРезультата = таблицаИсходная.Скопировать();
    таблицаРезультата.Свернуть("Контрагент", "Итог, Итог2");
    таблицаРезультата.Колонки.Добавить("Договор", Новый ОписаниеТипов("Строка"));
    таблицаИсходная.Индексы.Добавить("Контрагент"); // Не обязательно, это для ускорения поиска, если таблица большая
    Для каждого строкаРезультата Из таблицаРезультата Цикл
    массивДоговоров = Новый Массив;
    Для каждого строкаИсходная Из таблицаИсходная.НайтиСтроки(Новый Структура("Контрагент", строкаРезультата.Контрагент)) Цикл
    массивДоговоров.Добавить(строкаИсходная.Договор);
    КонецЦикла;
    строкаРезультата.Договор = СтрСоединить(массивДоговоров, ",");
    КонецЦикла;
```

или

```1c
    таблица.Сортировать("Контрагент");
    массивСтрокДляУдаления = Новый Массив;
    контрагент = Неопределено;
    строкаКонтрагента = Неопределено; // Это нужно для синтакс-контроля, код отрабатывает без этой строки
    Для каждого строка Из таблица Цикл
    Если контрагент <> строка.Контрагент Тогда
    Если контрагент <> Неопределено Тогда
    строкаКонтрагента.Договор = СтрСоединить(массивДоговоров, ",");
    КонецЕсли;
    контрагент = строка.Контрагент;
    строкаКонтрагента = строка;
    массивДоговоров = Новый Массив;
    Иначе
    строкаКонтрагента.Итог = строкаКонтрагента.Итог+строка.Итог;
    строкаКонтрагента.Итог2 = строкаКонтрагента.Итог2+строка.Итог2;
    массивСтрокДляУдаления.Добавить(строка);
    КонецЕсли;
    массивДоговоров.Добавить(строка.Договор);
    КонецЦикла;
    Если контрагент <> Неопределено Тогда
    строкаКонтрагента.Договор = СтрСоединить(массивДоговоров, ",");
    КонецЕсли;
    Для каждого строка Из массивСтрокДляУдаления Цикл
    таблица.Удалить(строка);
    КонецЦикла;
```

Но СтрСоединить можно использовать только начиная с релиза 8.3.6.1977 или писать свою функцию. Считаю, что в данном алгоритме это избыточная функция.
---
Это можно решить через СКД:
Прописываем предопределенную процедуру в модуле отчета.
В строке "ВнешнийНаборДанных = Новый Структура("Таблица", Таблица);" передаем нашу таблицу.

```1c
    Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)

    СтандартнаяОбработка = Ложь;

    ВнешнийНаборДанных = Новый Структура("Таблица", Таблица);

    НастройкиКомпоновки = КомпоновщикНастроек.ПолучитьНастройки();

    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиКомпоновки);

    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешнийНаборДанных);

    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);

    КонецПроцедуры
```

Естественно, что это способ годится только для вывода отчета.
---
Да уж...
---
Да уж... ...страшно за человека, который в 5 часов утра воскресенья садится писать код в чужой ветке трехмесячной давности... все ли с ним в порядке? ;-)