СКД

1. vdv1690500 12.03.25 16:21 Сейчас в теме
Здравствуйте. Как в СКД вывести строки в колонки.

Например:

Яблоко - Фрукт
Яблоко - Круглое
Яблоко - Красное
Огурец - Овощ
Огурец - Овальный

Должно быть:

Яблоко | Огурец
____________________ ____ ________________
Фрукт | Круглое | Краное | Овощ | Овальный

Как то так
По теме из базы знаний
Найденные решения
34. Torin57 41 20.03.25 21:42 Сейчас в теме
(29) На этот раз полностью доделал отчет. Тестовую базу с отчетом прикрепил.
Логисты в макете у меня объединяются следующим кодом:
// Выводим заголовки логистов в строке 4
Для Каждого ЛогистСсылка Из МассивЛогистов Цикл
    МассивВодителейЛогиста = СоответствиеДанных[ЛогистСсылка];
    КоличествоВодителей = МассивВодителейЛогиста.Количество();
    
    // Создаем ячейку для логиста программно в строке 4
    ТабДок.Область(4, НомерКолонки).Текст = СоответствиеЛогистов[ЛогистСсылка];
    
    // Форматирование: жирный шрифт и выравнивание по центру
    ТабДок.Область(4, НомерКолонки).Шрифт = Новый Шрифт(ТабДок.Область(4, НомерКолонки).Шрифт,,,Истина); // Жирный шрифт
    ТабДок.Область(4, НомерКолонки).ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
    ТабДок.Область(4, НомерКолонки).ШиринаКолонки = 20;
    
    // Линия вокруг
    ТабДок.Область(4, НомерКолонки).ГраницаСверху = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная,1);
    ТабДок.Область(4, НомерКолонки).ГраницаСлева = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная,1);
    ТабДок.Область(4, НомерКолонки).ГраницаСправа = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная,1);
    
    // Размещение текста                                                                                                             
    ТабДок.Область(4, НомерКолонки).РазмещениеТекста = ТипРазмещенияТекстаТабличногоДокумента.Переносить;
    
    // Устанавливаем цвет фона заголовка логиста (желтый)
    ТабДок.Область(4, НомерКолонки).ЦветФона = WebЦвета.Золотой;
    
    // Запоминаем начальную позицию для объединения
    НачальнаяКолонка = НомерКолонки;
    
    // Выводим пустые ячейки для остальных водителей
    Для Инд = 2 По КоличествоВодителей Цикл
        ТабДок.Область(4, НомерКолонки + Инд - 1).Текст = "";
        // Устанавливаем цвет фона для всех ячеек логиста
        ТабДок.Область(4, НомерКолонки + Инд - 1).ЦветФона = WebЦвета.Золотой;
    КонецЦикла;
    
    // Объединяем ячейки логиста над всеми его водителями
    Если КоличествоВодителей > 1 Тогда
        КонечнаяКолонка = НачальнаяКолонка + КоличествоВодителей - 1;
        ТабДок.Область(4, НачальнаяКолонка, 4, КонечнаяКолонка).Объединить();
        ТабДок.Область(4, КонечнаяКолонка).ГраницаСправа = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная,1);
    КонецЕсли;

    // Увеличиваем номер колонки для следующего логиста
    НомерКолонки = НомерКолонки + КоличествоВодителей;
КонецЦикла;
Показать


А группировка у меня происходит благодаря использованию конструкции ИТОГИ ПО в языке запросов. Далее я обхожу результат запроса по группировкам и создаю соответствие логистов и массива их водителей (это СоответствиеДанных). Эти данные я далее использую при выводе в табличный документ:
// Получаем выборку по логистам
ВыборкаЛогисты = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Логист");

// Создаем соответствия для хранения данных
СоответствиеЛогистов = Новый Соответствие;
СоответствиеВодителей = Новый Соответствие;
СоответствиеДанных = Новый Соответствие;

// Заполняем структуру данными
Пока ВыборкаЛогисты.Следующий() Цикл
    ЛогистСсылка = ВыборкаЛогисты.Логист;
    ЛогистНаименование = ВыборкаЛогисты.ЛогистНаименование;
    
    // Сохраняем информацию о логисте
    СоответствиеЛогистов.Вставить(ЛогистСсылка, ЛогистНаименование);
    
    // Получаем водителей для текущего логиста
    ВыборкаВодители = ВыборкаЛогисты.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Водитель");
    МассивВодителей = Новый Массив;
    
    // Собираем данные о водителях
    Пока ВыборкаВодители.Следующий() Цикл
        ВодительСсылка = ВыборкаВодители.Водитель;
        МассивВодителей.Добавить(ВодительСсылка);
        
        // Сохраняем имя водителя
        СоответствиеВодителей.Вставить(ВодительСсылка, ВыборкаВодители.ВодительНаименование);
        
        // Получаем детальные данные для водителя
        ВыборкаДетали = ВыборкаВодители.Выбрать();
        
        Если ВыборкаДетали.Следующий() Тогда
            // Создаем структуру для хранения показателей водителя
            ДанныеВодителя = Новый Структура;
            ДанныеВодителя.Вставить("ГосНомер", ВыборкаДетали.ГосНомер);
            ДанныеВодителя.Вставить("ЦветКузова", ВыборкаДетали.ЦветКузова);
            ДанныеВодителя.Вставить("Модель", ВыборкаДетали.Модель);
            ДанныеВодителя.Вставить("ГодВыпуска", ВыборкаДетали.ГодВыпуска);
            ДанныеВодителя.Вставить("КоличествоРейсов", ВыборкаДетали.КоличествоРейсов);
            ДанныеВодителя.Вставить("ПройденноеРасстояние", ВыборкаДетали.ПройденноеРасстояние);
            ДанныеВодителя.Вставить("СуммаВыручки", ВыборкаДетали.СуммаВыручки);
            ДанныеВодителя.Вставить("РасходТоплива", ВыборкаДетали.РасходТоплива);
            ДанныеВодителя.Вставить("ВремяВПути", ВыборкаДетали.ВремяВПути);
            
            // Сохраняем данные водителя
            СоответствиеДанных.Вставить(ВодительСсылка, ДанныеВодителя);
        КонецЕсли;
    КонецЦикла;
    
    // Сохраняем список водителей для логиста
    СоответствиеДанных.Вставить(ЛогистСсылка, МассивВодителей);
КонецЦикла;

// Получаем список всех логистов
МассивЛогистов = Новый Массив;
Для Каждого КлючИЗначение Из СоответствиеЛогистов Цикл
    МассивЛогистов.Добавить(КлючИЗначение.Ключ);
КонецЦикла;
Показать
Прикрепленные файлы:
1Cv8.dt
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
3. Torin57 41 12.03.25 17:42 Сейчас в теме
(1) Как найдете, отпишитесь пож-та. Тоже любопытно. У меня только так получилось.
Прикрепленные файлы:
15. Snigse 13.03.25 16:01 Сейчас в теме
(1) Свойства должны стать ресурсами
2. homer_ 79 12.03.25 17:19 Сейчас в теме
ищите по слову "кросс-таблица"
4. Serishev1s 13.03.25 04:06 Сейчас в теме
в выбранных полях добавить группы, у которых есть настройка - вертикально или горизонтально
Прикрепленные файлы:
5. vdv1690500 13.03.25 09:13 Сейчас в теме
(4) Пробовал не получается.

Суть в чем: Есть таблица водители, к ним прикреплены логисты. Необходимо чтобы была группировка по логистам вертикально. Под каждым логистом свои водители
Прикрепленные файлы:
10. Torin57 41 13.03.25 15:36 Сейчас в теме
(5) То есть должно типа такого получиться?

ОТЧЕТ: ГРУППИРОВКА ВОДИТЕЛЕЙ ПО ЛОГИСТАМ

===== ЛОГИСТ: Иванов Иван =====
Водитель: Петров Алексей
Водитель: Сидоров Николай
Водитель: Кузнецов Дмитрий

===== ЛОГИСТ: Смирнова Елена =====
Водитель: Васильев Сергей
Водитель: Морозов Андрей
Водитель: Новиков Игорь
Водитель: Федоров Михаил

===== ЛОГИСТ: Козлов Антон =====
Водитель: Соколов Владимир
Вод
11. vdv1690500 13.03.25 15:44 Сейчас в теме
(10)
Прикрепленные файлы:
12. Torin57 41 13.03.25 15:52 Сейчас в теме
(11) То есть нужно чтобы результат был точно как на картинке? Уж больно на СКД похожа картинка. Так что я предположил, что это картинка существующего у вас отчета на СКД, но вам нужно что-то другое.
14. vdv1690500 13.03.25 16:00 Сейчас в теме
(12) Да примерно кака на картинке. Это в Эксель
18. Torin57 41 13.03.25 16:04 Сейчас в теме
(14) М-да. Как все сложно...
Прикрепленные файлы:
19. vdv1690500 13.03.25 16:38 Сейчас в теме
20. Torin57 41 13.03.25 16:56 Сейчас в теме
(19) Да, это не то. А почему на СКД отчет? Интересуюсь из любопытства. ИМХО, СКД нужна, когда пользователь может захотеть что-то переделать в отчете. Отборы какие-то свои добавить. Если же ему четко нужен отчет как на картинке, то овчинка выделки не стоит. Чтобы выяснить какой-нибудь простой вопрос по созданию отчета на СКД нужно спрашивать на форуме. И так постоянно. Слишком много в СКД возможностей, слишком много переключателей, которые ты никогда не запомнишь и не выучишь. Выучишь если ты занимаешься ТОЛЬКО написанием отчетов на СКД, причем постоянно.
Хорошо. Если я не прав, то пусть фанаты СКД меня посрамят. Придут и расскажут как добиться нужного автору результата.
24. Vseznaika 13.03.25 20:47 Сейчас в теме
(20) Вы программист? Это мнение программиста. Я тоже программист и с этим мнением согласен.
Но есть и другое мнение. У меня есть знакомый - ученый-физик. Он постоянно выступает с докладами на всяких их физических конференциях. У него есть целый набор всяких программ для построения отчетов, диаграм, немыслимых математических вычислений.
Каждая из них больше, мощнее, сложнее на два порядка, чем СКД. Как по количеству галочек, так и по своим возможностям. Но вот умеет ведь ими пользоваться. А для него это всего лишь вспомогательный рабочий инструмент к основному виду деятельности (физике).
Каждому своё.
Я не фанат СКД и написал всё это не для того, чтобы кого-то посрамить. Просто описал ситуацию, которую видел сам. Дальше тут писать про это не имеет смысла, т.к. топик про другое совсем. Не будем флудить.

Тут больше вопрос к топикстартеру. А вот почему именно нужен такой длиииииинный отчет по-горизонтали и прям вот в таком виде?
Я понимаю, что может быть:
1. кто-то сказал "так надо и точка!" (бывает...)
2. захотелось поупражняться в создании нетрадиционных отчетов (похвально)

Ведь можно упростить... Зачем пытаться из палок и глины строить современный истребитель? Ну не может СКД этого с полпинка и не надо себя мучать.
Смысл финансовых отчетов - донести до их потребителя полезную информацию, а не в красотульках и навороченности.
Я не критикую и не пытаюсь тут умничать. Мне правда интересно: а зачем?

Пытаюсь сделать такой отчет. Правда, по преподавателям и ученикам вместо водителей и логистов. Но смысл тот же. Если времени хватит, то сюда выложу.
25. vdv1690500 13.03.25 21:29 Сейчас в теме
(24) Руководство такой именно отчет захотело.
26. Vseznaika 13.03.25 21:37 Сейчас в теме
(25)
Руководство такой именно отчет захотело

Ясно. Сочувствую. Не буду развивать мысль на темы: "а что это руководство будет делать с таким отчетом?" и "почему бы руководству нормальные отчет(ы) не захотеть?". Захотело - значит захотело. У меня руководства нет, мне проще)
28. Torin57 41 14.03.25 21:16 Сейчас в теме
(25) Ну как у вас, работа над отчетом движется?
29. vdv1690500 18.03.25 15:06 Сейчас в теме
(28) Пока никак. В итоге делаю в макете. На СКД не получается.

Необходимо Объединить логистов. Как это сделать в макете?
И сгруппировать
Прикрепленные файлы:
30. vdv1690500 18.03.25 15:09 Сейчас в теме
(28) Вот так чтоб было
Прикрепленные файлы:
31. Torin57 41 18.03.25 22:39 Сейчас в теме
(30) Создал тестовую базу, заполнил данными, создал отчет "Данные по логистам и водителям", но не довел до ума. Все сделал с помощью ИИ claude-3.7-sonnet. До создания макета уже не хватило времени. Код процедуры ПриКомпоновкеРезультата (уже вставлен в отчет):
// Модуль объекта отчета "ОтчетПоЛогистамИВодителям"

// Процедура формирования отчета
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    // Отключаем стандартную обработку СКД
    СтандартнаяОбработка = Ложь;
    
    // Получаем параметры отчета из настроек компоновщика
    КомпоновщикНастроек.ЗагрузитьНастройки(КомпоновщикНастроек.ПолучитьНастройки());
    Параметры = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы;
    
    // Получаем параметр периода
    ПериодПараметр = Параметры.Найти("Период");
    Если ПериодПараметр <> Неопределено Тогда
        Период = ПериодПараметр.Значение;
        НачалоПериода = Период.ДатаНачала;
        КонецПериода = Период.ДатаОкончания;
    Иначе
        НачалоПериода = ДобавитьМесяц(НачалоМесяца(ТекущаяДата()), -12);
        КонецПериода = КонецМесяца(ТекущаяДата());
    КонецЕсли;
    
    // Получаем параметр отбора по логисту
    ОтборЛогист = Неопределено;
    ЛогистПараметр = Параметры.Найти("Логист");
    Если ЛогистПараметр <> Неопределено И ЗначениеЗаполнено(ЛогистПараметр.Значение) Тогда
        ОтборЛогист = ЛогистПараметр.Значение;
    КонецЕсли;
    
    // Формируем табличный документ
    ТабДок = СформироватьОтчет(НачалоПериода, КонецПериода, ОтборЛогист);
    
    // Передаем табличный документ для вывода
    ДокументРезультат.Очистить();
    ДокументРезультат.Вывести(ТабДок);
КонецПроцедуры

// Функция формирования отчета
Функция СформироватьОтчет(НачалоПериода, КонецПериода, ОтборЛогист = Неопределено)
    // Создаем табличный документ
    ТабДок = Новый ТабличныйДокумент;
    
    // Устанавливаем параметры печати ДО установки ключа параметров печати
    ТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Ландшафт;
    ТабДок.АвтоМасштаб = Истина;
    ТабДок.ТолькоПросмотр = Истина;
    ТабДок.ОтображатьСетку = Ложь;
    ТабДок.ОтображатьЗаголовки = Ложь;
     
    // Теперь устанавливаем ключ параметров печати
    ТабДок.КлючПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_ОтчетПоЛогистамИВодителям";
    
    // Получаем макет отчета
    Макет = ПолучитьМакет("Макет");
    
    // Получаем области макета
    ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
    ОбластьЛогист = Макет.ПолучитьОбласть("Логист");
    ОбластьВодитель = Макет.ПолучитьОбласть("Водитель");
    ОбластьПоказатели = Макет.ПолучитьОбласть("Показатели");
    ОбластьИтогоПоЛогисту = Макет.ПолучитьОбласть("ИтогоПоЛогисту");
    ОбластьИтого = Макет.ПолучитьОбласть("Итого");
    
    // Заполняем заголовок
    ОбластьЗаголовок.Параметры.НачалоПериода = Формат(НачалоПериода, "ДЛФ=DD");
    ОбластьЗаголовок.Параметры.КонецПериода = Формат(КонецПериода, "ДЛФ=DD");
    
    // Добавляем информацию об отборе по логисту в заголовок
    Если ЗначениеЗаполнено(ОтборЛогист) Тогда
        ОбластьЗаголовок.Параметры.ОтборЛогист = "Логист: " + ОтборЛогист;
    Иначе
        ОбластьЗаголовок.Параметры.ОтборЛогист = "";
    КонецЕсли;
    
    ТабДок.Вывести(ОбластьЗаголовок);
    
    // Запрос для получения данных о логистах и их водителях
    Запрос = Новый Запрос;
    Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);
    Запрос.УстановитьПараметр("КонецПериода", КонецПериода);
    
    // Формируем текст запроса с учетом отбора по логисту
    ТекстЗапроса = 
    "ВЫБРАТЬ
    |   РегистрНакопления.ПоказателиРейсов.Логист КАК Логист,
    |   РегистрНакопления.ПоказателиРейсов.Логист.Наименование КАК ЛогистНаименование,
    |   РегистрНакопления.ПоказателиРейсов.Водитель КАК Водитель,
    |   РегистрНакопления.ПоказателиРейсов.Водитель.Наименование КАК ВодительНаименование,
    |   РегистрНакопления.ПоказателиРейсов.ТранспортноеСредство КАК ТранспортноеСредство,
    |   РегистрНакопления.ПоказателиРейсов.ТранспортноеСредство.Наименование КАК ТСНаименование,
    |   РегистрНакопления.ПоказателиРейсов.ТранспортноеСредство.ЦветКузова КАК ЦветКузова,
    |   СУММА(РегистрНакопления.ПоказателиРейсов.КоличествоРейсов) КАК КоличествоРейсов,
    |   СУММА(РегистрНакопления.ПоказателиРейсов.ПройденноеРасстояние) КАК ПройденноеРасстояние,
    |   СУММА(РегистрНакопления.ПоказателиРейсов.СуммаВыручки) КАК СуммаВыручки,
    |   СУММА(РегистрНакопления.ПоказателиРейсов.РасходТоплива) КАК РасходТоплива
    |ИЗ
    |   РегистрНакопления.ПоказателиРейсов КАК РегистрНакопления.ПоказателиРейсов
    |ГДЕ
    |   РегистрНакопления.ПоказателиРейсов.Период МЕЖДУ &НачалоПериода И &КонецПериода";
    
    // Добавляем условие отбора по логисту, если он указан
    Если ЗначениеЗаполнено(ОтборЛогист) Тогда
        Запрос.УстановитьПараметр("ОтборЛогист", ОтборЛогист);
        ТекстЗапроса = ТекстЗапроса + "
        |   И РегистрНакопления.ПоказателиРейсов.Логист = &ОтборЛогист";
    КонецЕсли;
    
    // Добавляем группировки и итоги
    ТекстЗапроса = ТекстЗапроса + "
    |
    |СГРУППИРОВАТЬ ПО
    |   РегистрНакопления.ПоказателиРейсов.Логист,
    |   РегистрНакопления.ПоказателиРейсов.Логист.Наименование,
    |   РегистрНакопления.ПоказателиРейсов.Водитель,
    |   РегистрНакопления.ПоказателиРейсов.Водитель.Наименование,
    |   РегистрНакопления.ПоказателиРейсов.ТранспортноеСредство,
    |   РегистрНакопления.ПоказателиРейсов.ТранспортноеСредство.Наименование,
    |   РегистрНакопления.ПоказателиРейсов.ТранспортноеСредство.ЦветКузова
    |
    |ИТОГИ ПО
    |   Логист,
    |   Водитель";
    
    Запрос.Текст = ТекстЗапроса;
    
    РезультатЗапроса = Запрос.Выполнить();
    
    // Проверяем, есть ли данные в результате запроса
    Если РезультатЗапроса.Пустой() Тогда
        // Если данных нет, выводим сообщение
        ОбластьПустойРезультат = Макет.ПолучитьОбласть("ПустойРезультат");
        ТабДок.Вывести(ОбластьПустойРезультат);
        Возврат ТабДок;
    КонецЕсли;
    
    // Цвета для выделения логистов
    ЦветаЛогистов = Новый Массив;
    ЦветаЛогистов.Добавить(WebЦвета.LightYellow);
    ЦветаЛогистов.Добавить(WebЦвета.LightGreen);
    ЦветаЛогистов.Добавить(WebЦвета.LightPink);
    ЦветаЛогистов.Добавить(WebЦвета.LightBlue);
    ЦветаЛогистов.Добавить(WebЦвета.LightCyan);
    
    // Определяем количество логистов для расчета ширины секций
    ВыборкаЛогистовКол = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Логист");
    КоличествоЛогистов = 0;
    
    Пока ВыборкаЛогистовКол.Следующий() Цикл
        КоличествоЛогистов = КоличествоЛогистов + 1;
    КонецЦикла;
    
    // Создаем таблицу с горизонтальными секциями
    // Первая строка - заголовки секций (логисты)
    СтрокаЛогистов = ТабДок.ПолучитьОбласть(1, 1, 1, 1).СкопироватьОбласть();
    ИндексЦвета = 0;
    
    // Обходим результат запроса по логистам
    ВыборкаЛогист = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Логист");
    
    // Создаем горизонтальные секции для каждого логиста
    Пока ВыборкаЛогист.Следующий() Цикл
        ИндексЦвета = ?(ИндексЦвета >= ЦветаЛогистов.Количество() - 1, 0, ИндексЦвета + 1);
        ТекущийЦвет = ЦветаЛогистов[ИндексЦвета];
        
        // Создаем секцию для логиста
        ОбластьЛогист.Параметры.Логист = ВыборкаЛогист.ЛогистНаименование;
        
        // Если это первый логист, выводим область
        Если ВыборкаЛогист.Номер() = 1 Тогда
            НачалоОбласти = ТабДок.НачалоОбласти();
            ТабДок.Вывести(ОбластьЛогист);
            КонецОбласти = ТабДок.КонецОбласти();
        Иначе
            // Иначе присоединяем горизонтально
            НачалоОбласти = ТабДок.НачалоОбласти();
            ТабДок.Присоединить(ОбластьЛогист);
            КонецОбласти = ТабДок.КонецОбласти();
        КонецЕсли;
        
        // Устанавливаем цвет фона для строки логиста
        ТабДок.УстановитьОбластьФона(НачалоОбласти, КонецОбласти, ТекущийЦвет);
        
        // Получаем водителей для текущего логиста
        ВыборкаВодитель = ВыборкаЛогист.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Водитель");
        
        // Определяем максимальное количество водителей для вертикального размера секции
        МаксСтрок = ВыборкаВодитель.Количество();
        
        // Сбрасываем выборку и обходим заново
        ВыборкаВодитель = ВыборкаЛогист.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Водитель");
        
        // Выводим заголовки для водителей
        ОбластьВодитель.Параметры.Водитель = "Водитель-ФИО";
        ОбластьВодитель.Параметры.ТС = "НомерТС";
        ОбластьВодитель.Параметры.ЦветКузова = "Цвет";
        
        // Если это первый логист, выводим область
        Если ВыборкаЛогист.Номер() = 1 Тогда
            НачалоОбласти = ТабДок.НачалоОбласти();
            ТабДок.Вывести(ОбластьВодитель);
            КонецОбласти = ТабДок.КонецОбласти();
        Иначе
            // Иначе присоединяем горизонтально
            НачалоОбласти = ТабДок.НачалоОбласти();
            ТабДок.Присоединить(ОбластьВодитель);
            КонецОбласти = ТабДок.КонецОбласти();
        КонецЕсли;
        
        // Устанавливаем цвет фона для заголовка водителей
        ТабДок.УстановитьОбластьФона(НачалоОбласти, КонецОбласти, ТекущийЦвет);
        
        // Выводим данные по водителям
        ТекНомерСтроки = 0;
        
        Пока ВыборкаВодитель.Следующий() Цикл
            ТекНомерСтроки = ТекНомерСтроки + 1;
            
            // Получаем детальные данные для водителя
            ВыборкаДетали = ВыборкаВодитель.Выбрать();
            
            // Если есть данные, заполняем параметры
            Если ВыборкаДетали.Следующий() Тогда
                ОбластьВодитель.Параметры.Водитель = ВыборкаВодитель.ВодительНаименование;
                ОбластьВодитель.Параметры.ТС = ВыборкаДетали.ТСНаименование;
                ОбластьВодитель.Параметры.ЦветКузова = ВыборкаДетали.ЦветКузова;
                
                // Если это первая строка для водителя и первый логист
                Если ТекНомерСтроки = 1 И ВыборкаЛогист.Номер() = 1 Тогда
                    ТабДок.Вывести(ОбластьВодитель);
                ИначеЕсли ТекНомерСтроки = 1 Тогда
                    // Если это первая строка для водителя, но не первый логист
                    ТабДок.Присоединить(ОбластьВодитель);
                ИначеЕсли ВыборкаЛогист.Номер() = 1 Тогда
                    // Если это не первая строка для водителя, но первый логист
                    ТабДок.ВывестиГоризонтальныйРазделительСтрок();
                    ТабДок.Вывести(ОбластьВодитель);
                Иначе
                    // Если это не первая строка для водителя и не первый логист
                    // Присоединяем по горизонтали к последней строке
                    ТабДок.Присоединить(ОбластьВодитель);
                КонецЕсли;
                
                // Выводим показатели для водителя
                ОбластьПоказатели.Параметры.КоличествоРейсов = ВыборкаДетали.КоличествоРейсов;
                ОбластьПоказатели.Параметры.ПройденноеРасстояние = ВыборкаДетали.ПройденноеРасстояние;
                ОбластьПоказатели.Параметры.СуммаВыручки = ВыборкаДетали.СуммаВыручки;
                ОбластьПоказатели.Параметры.РасходТоплива = ВыборкаДетали.РасходТоплива;
                
                // Выводим показатели под строкой водителя
                Если ТекНомерСтроки = 1 И ВыборкаЛогист.Номер() = 1 Тогда
                    ТабДок.Вывести(ОбластьПоказатели);
                ИначеЕсли ТекНомерСтроки = 1 Тогда
                    ТабДок.Присоединить(ОбластьПоказатели);
                ИначеЕсли ВыборкаЛогист.Номер() = 1 Тогда
                    ТабДок.ВывестиГоризонтальныйРазделительСтрок();
                    ТабДок.Вывести(ОбластьПоказатели);
                Иначе
                    ТабДок.Присоединить(ОбластьПоказатели);
                КонецЕсли;
            КонецЕсли;
        КонецЦикла;
        
        // Выводим итоги по логисту
        ОбластьИтогоПоЛогисту.Параметры.ИтогоКоличествоРейсов = ВыборкаЛогист.КоличествоРейсов;
        ОбластьИтогоПоЛогисту.Параметры.ИтогоПройденноеРасстояние = ВыборкаЛогист.ПройденноеРасстояние;
        ОбластьИтогоПоЛогисту.Параметры.ИтогоСуммаВыручки = ВыборкаЛогист.СуммаВыручки;
        ОбластьИтогоПоЛогисту.Параметры.ИтогоРасходТоплива = ВыборкаЛогист.РасходТоплива;
        
        // Выводим итоги под водителями
        Если ВыборкаЛогист.Номер() = 1 Тогда
            ТабДок.ВывестиГоризонтальныйРазделительСтрок();
            НачалоОбласти = ТабДок.НачалоОбласти();
            ТабДок.Вывести(ОбластьИтогоПоЛогисту);
            КонецОбласти = ТабДок.КонецОбласти();
        Иначе
            НачалоОбласти = ТабДок.НачалоОбласти();
            ТабДок.Присоединить(ОбластьИтогоПоЛогисту);
            КонецОбласти = ТабДок.КонецОбласти();
        КонецЕсли;
        
        // Устанавливаем цвет фона для итогов
        ТабДок.УстановитьОбластьФона(НачалоОбласти, КонецОбласти, ТекущийЦвет);
    КонецЦикла;
    
    // Выводим общие итоги в нижней части отчета
    ТабДок.ВывестиГоризонтальныйРазделительСтрок();
    
    // Получаем общие итоги из корневой выборки запроса
    ВыборкаИтоги = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
    
    Если ВыборкаИтоги.Следующий() Тогда
        ОбщееКоличествоРейсов = ВыборкаИтоги.КоличествоРейсов;
        ОбщееПройденноеРасстояние = ВыборкаИтоги.ПройденноеРасстояние;
        ОбщаяСуммаВыручки = ВыборкаИтоги.СуммаВыручки;
        ОбщийРасходТоплива = ВыборкаИтоги.РасходТоплива;
        
        ОбластьИтого.Параметры.ОбщееКоличествоРейсов = ОбщееКоличествоРейсов;
        ОбластьИтого.Параметры.ОбщееПройденноеРасстояние = ОбщееПройденноеРасстояние;
        ОбластьИтого.Параметры.ОбщаяСуммаВыручки = ОбщаяСуммаВыручки;
        ОбластьИтого.Параметры.ОбщийРасходТоплива = ОбщийРасходТоплива;
        
        ТабДок.Вывести(ОбластьИтого);
    КонецЕсли;
    
    // Настройка параметров фиксации областей
    ТабДок.ФиксацияСверху = 2;
    
    Возврат ТабДок;
КонецФункции
Показать
Прикрепленные файлы:
ТестБазаСОтчетомПоЛогистамИВодителям.dt
33. Torin57 41 19.03.25 10:00 Сейчас в теме
Что-то мне Клод не то посоветовал по поводу макета. Это я про пост 32. Ладно, попробую вечером опять с ним поговорить. Объяснить еще раз, что нам нужно. Пост 32 игнорируем.
34. Torin57 41 20.03.25 21:42 Сейчас в теме
(29) На этот раз полностью доделал отчет. Тестовую базу с отчетом прикрепил.
Логисты в макете у меня объединяются следующим кодом:
// Выводим заголовки логистов в строке 4
Для Каждого ЛогистСсылка Из МассивЛогистов Цикл
    МассивВодителейЛогиста = СоответствиеДанных[ЛогистСсылка];
    КоличествоВодителей = МассивВодителейЛогиста.Количество();
    
    // Создаем ячейку для логиста программно в строке 4
    ТабДок.Область(4, НомерКолонки).Текст = СоответствиеЛогистов[ЛогистСсылка];
    
    // Форматирование: жирный шрифт и выравнивание по центру
    ТабДок.Область(4, НомерКолонки).Шрифт = Новый Шрифт(ТабДок.Область(4, НомерКолонки).Шрифт,,,Истина); // Жирный шрифт
    ТабДок.Область(4, НомерКолонки).ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
    ТабДок.Область(4, НомерКолонки).ШиринаКолонки = 20;
    
    // Линия вокруг
    ТабДок.Область(4, НомерКолонки).ГраницаСверху = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная,1);
    ТабДок.Область(4, НомерКолонки).ГраницаСлева = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная,1);
    ТабДок.Область(4, НомерКолонки).ГраницаСправа = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная,1);
    
    // Размещение текста                                                                                                             
    ТабДок.Область(4, НомерКолонки).РазмещениеТекста = ТипРазмещенияТекстаТабличногоДокумента.Переносить;
    
    // Устанавливаем цвет фона заголовка логиста (желтый)
    ТабДок.Область(4, НомерКолонки).ЦветФона = WebЦвета.Золотой;
    
    // Запоминаем начальную позицию для объединения
    НачальнаяКолонка = НомерКолонки;
    
    // Выводим пустые ячейки для остальных водителей
    Для Инд = 2 По КоличествоВодителей Цикл
        ТабДок.Область(4, НомерКолонки + Инд - 1).Текст = "";
        // Устанавливаем цвет фона для всех ячеек логиста
        ТабДок.Область(4, НомерКолонки + Инд - 1).ЦветФона = WebЦвета.Золотой;
    КонецЦикла;
    
    // Объединяем ячейки логиста над всеми его водителями
    Если КоличествоВодителей > 1 Тогда
        КонечнаяКолонка = НачальнаяКолонка + КоличествоВодителей - 1;
        ТабДок.Область(4, НачальнаяКолонка, 4, КонечнаяКолонка).Объединить();
        ТабДок.Область(4, КонечнаяКолонка).ГраницаСправа = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная,1);
    КонецЕсли;

    // Увеличиваем номер колонки для следующего логиста
    НомерКолонки = НомерКолонки + КоличествоВодителей;
КонецЦикла;
Показать


А группировка у меня происходит благодаря использованию конструкции ИТОГИ ПО в языке запросов. Далее я обхожу результат запроса по группировкам и создаю соответствие логистов и массива их водителей (это СоответствиеДанных). Эти данные я далее использую при выводе в табличный документ:
// Получаем выборку по логистам
ВыборкаЛогисты = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Логист");

// Создаем соответствия для хранения данных
СоответствиеЛогистов = Новый Соответствие;
СоответствиеВодителей = Новый Соответствие;
СоответствиеДанных = Новый Соответствие;

// Заполняем структуру данными
Пока ВыборкаЛогисты.Следующий() Цикл
    ЛогистСсылка = ВыборкаЛогисты.Логист;
    ЛогистНаименование = ВыборкаЛогисты.ЛогистНаименование;
    
    // Сохраняем информацию о логисте
    СоответствиеЛогистов.Вставить(ЛогистСсылка, ЛогистНаименование);
    
    // Получаем водителей для текущего логиста
    ВыборкаВодители = ВыборкаЛогисты.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Водитель");
    МассивВодителей = Новый Массив;
    
    // Собираем данные о водителях
    Пока ВыборкаВодители.Следующий() Цикл
        ВодительСсылка = ВыборкаВодители.Водитель;
        МассивВодителей.Добавить(ВодительСсылка);
        
        // Сохраняем имя водителя
        СоответствиеВодителей.Вставить(ВодительСсылка, ВыборкаВодители.ВодительНаименование);
        
        // Получаем детальные данные для водителя
        ВыборкаДетали = ВыборкаВодители.Выбрать();
        
        Если ВыборкаДетали.Следующий() Тогда
            // Создаем структуру для хранения показателей водителя
            ДанныеВодителя = Новый Структура;
            ДанныеВодителя.Вставить("ГосНомер", ВыборкаДетали.ГосНомер);
            ДанныеВодителя.Вставить("ЦветКузова", ВыборкаДетали.ЦветКузова);
            ДанныеВодителя.Вставить("Модель", ВыборкаДетали.Модель);
            ДанныеВодителя.Вставить("ГодВыпуска", ВыборкаДетали.ГодВыпуска);
            ДанныеВодителя.Вставить("КоличествоРейсов", ВыборкаДетали.КоличествоРейсов);
            ДанныеВодителя.Вставить("ПройденноеРасстояние", ВыборкаДетали.ПройденноеРасстояние);
            ДанныеВодителя.Вставить("СуммаВыручки", ВыборкаДетали.СуммаВыручки);
            ДанныеВодителя.Вставить("РасходТоплива", ВыборкаДетали.РасходТоплива);
            ДанныеВодителя.Вставить("ВремяВПути", ВыборкаДетали.ВремяВПути);
            
            // Сохраняем данные водителя
            СоответствиеДанных.Вставить(ВодительСсылка, ДанныеВодителя);
        КонецЕсли;
    КонецЦикла;
    
    // Сохраняем список водителей для логиста
    СоответствиеДанных.Вставить(ЛогистСсылка, МассивВодителей);
КонецЦикла;

// Получаем список всех логистов
МассивЛогистов = Новый Массив;
Для Каждого КлючИЗначение Из СоответствиеЛогистов Цикл
    МассивЛогистов.Добавить(КлючИЗначение.Ключ);
КонецЦикла;
Показать
Прикрепленные файлы:
1Cv8.dt
35. vdv1690500 24.03.25 08:39 Сейчас в теме
(34) Аот что у меня получилось. И часть кода который объединяет логистов в колонке

Долго разбираюсь как сделать группировку по логистам(колонки) и построчно. Пока не получается.
Прикрепленные файлы:
36. Torin57 41 24.03.25 11:28 Сейчас в теме
(35) А сможешь файл своего отчета выложить, или его код? Я тогда вечером его загружу в Клод Соннет, попрошу проконсультировать. По моим наблюдениям, ИИ консультирует получше чем я. Да и код на 1С ловко пишет.
В общем, будущее поступило. Коллега мой на прошлой работе смеялся "И что же Денис будет делать, когда код на 1С будет ИИ писать? гы гы гы ))". Вот ответ на вопрос коллеги. Буду скармливать ТЗ Клод Соннету и контролировать выполнение.
37. vdv1690500 24.03.25 16:08 Сейчас в теме
(36) Вот функция ТаблицаЗначений у тебя уже есть своя



 ТабДок = Новый ТабличныйДокумент;
	ОбработкаОб = РеквизитФормыВЗначение("Объект");
	НачалоПериода = НачалоДня(ЭтотОбъект.НачалоПериода);
	КонецПериода = КонецДня(ЭтотОбъект.КонецПериода);
	Если КонецПериода > ТекущаяДата() ИЛИ НЕ ЗначениеЗаполнено(ЭтотОбъект.КонецПериода) Тогда
		КонецПериода = ТекущаяДата();
	КонецЕсли;	
	
	Макет = ОбработкаОб.ПолучитьМакет("Макет");
	КолонкаРеквизиты = Макет.ПолучитьОбласть("Реквизиты");
	КолонкаРеквизиты.Параметры.НачалоПериода = Формат(НачалоПериода, "ДФ=dd.MM.yyyy");
	КолонкаРеквизиты.Параметры.КонецПериода = Формат(КонецПериода, "ДФ=dd.MM.yyyy");
    ТабДок.Вывести(КолонкаРеквизиты);
	
	ОбластьИтого  = Макет.ПолучитьОбласть("ОбластьИтого");
	ТабДок.Вывести(ОбластьИтого);
	
	ОбластьВодители = Макет.ПолучитьОбласть("ОбластьВодители");
	
	Таблица = СформироватьТаблицу ();
	Таблица.Сортировать("Логист");	
	
		
	НачКолонки = 3;
	КонКолонки = НачКолонки-1;
	ВспПерем = "";
	Для каждого Строка Из Таблица Цикл
		ОбластьВодители.Параметры.ПериодРасчета = Формат(Строка.ПериодНачалоРасчета,"ДФ=dd.MM.yyyy")+" - "+ Формат(Строка.ПериодКонецРасчета,"ДФ=dd.MM.yyyy");
		ОбластьВодители.Параметры.Заполнить(Строка);
		ТабДок.Присоединить(ОбластьВодители);
		
////////////////////////////////////////////////////////////­/////////	
		КонКолонки = КонКолонки + 1;
		Если ВспПерем = "" ИЛИ ВспПерем = Строка.Логист Тогда
			Если НачКолонки < КонКолонки Тогда
				ТабДок.Область("R3"+"c"+НачКолонки+":"+"R3"+"c"+КонКолонки).Объединить();
			КонецЕсли;
		Иначе	
			НачКолонки = КонКолонки;
		КонецЕсли;	
		ВспПерем = Строка.Логист;
////////////////////////////////////////////////////////////­//////////		
	КонецЦикла;	
			
	
	
	Возврат (ТабДок);
Показать
38. Torin57 41 24.03.25 16:41 Сейчас в теме
(37) А сможешь весь свой код целиком выложить, вместе с запросом?
39. vdv1690500 25.03.25 09:58 Сейчас в теме
(38) У меня сложный запрос, с последующим добавлением данных в ТабЗнач со множеством всяких условий. Полностью еще не готов.

Вот функция которая формирует таблицу и возвращает в СформироватьТаблицу в предыдущем посте

Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|	вдвЛогистыВодителей.Период КАК ПериодНачалоРасчета,
	|	вдвЛогистыВодителей.КонецПериода КАК ПериодКонецРасчета,
	|	вдвЛогистыВодителей.Логист КАК Логист,
	|	вдвЛогистыВодителей.ТС КАК ТС,
	|	вдвЛогистыВодителей.Водитель КАК Водитель
	|ИЗ
	|	РегистрСведений.вдвЛогистыВодителей КАК вдвЛогистыВодителей
	|ГДЕ
	|	вдвЛогистыВодителей.КонецПериода > &КонецПериода
	|
	|ОБЪЕДИНИТЬ ВСЕ
	|
	|ВЫБРАТЬ
	|	вдвЛогистыВодителей.Период,
	|	вдвЛогистыВодителей.КонецПериода,
	|	вдвЛогистыВодителей.Логист,
	|	вдвЛогистыВодителей.ТС,
	|	вдвЛогистыВодителей.Водитель
	|ИЗ
	|	РегистрСведений.вдвЛогистыВодителей КАК вдвЛогистыВодителей
	|ГДЕ
	|	вдвЛогистыВодителей.КонецПериода = &Пустая
	|
	|УПОРЯДОЧИТЬ ПО
	|	ПериодНачалоРасчета";	 
	Запрос.УстановитьПараметр("КонецПериода", НачалоПериода);
	Запрос.УстановитьПараметр("Пустая", Дата("00010101"));

	Таблица = Запрос.Выполнить().Выгрузить();
	Для каждого стр из Таблица Цикл
		Если стр.ПериодКонецРасчета = Дата("00010101") Тогда 
			стр.ПериодКонецРасчета = КонецДня(ТекущаяДата());		
		КонецЕсли;	
		Если НачалоПериода > стр.ПериодНачалоРасчета Тогда		
			стр.ПериодНачалоРасчета = НачалоПериода;			
		КонецЕсли;	
	КонецЦикла;
	
	
		////////////////////////////////////////////////////////////­////////////
	////////////////////////////////Получить данные по топливу/////////////    
	Таблица.Колонки.Добавить("ВидТоплива");
	
	Таблица.Колонки.Добавить("БензРоснефть", Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("БензЛенуар", Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("БензЛукойл", Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("БензГазпром", Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("БензЭкспресс", Новый ОписаниеТипов("Число"));
		
	Таблица.Колонки.Добавить("ГазРоснефть", Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("ГазЛенуар", Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("ГазЛукойл", Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("ГазГазпром", Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("ГазЭкспресс", Новый ОписаниеТипов("Число"));

	Таблица.Колонки.Добавить("ДизРоснефть", Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("ДизЛенуар", Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("ДизЛукойл", Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("ДизГазпром", Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("ДизЭкспресс", Новый ОписаниеТипов("Число"));

	Таблица.Колонки.Добавить("ИтогоТопливо", Новый ОписаниеТипов("Число"));
	
		
	
	///////////////////////вид топлива
	ВыполнитьЗапросВидТоплива(Таблица);
	/////////////////////// топливо
	
	ВыполнитьЗапросТопливо("Топливо", "БензРоснефть", Таблица);
	ВыполнитьЗапросТопливо("Топливо", "БензЛенуар", Таблица);
	ВыполнитьЗапросТопливо("Топливо", "БензЛукойл", Таблица);
	ВыполнитьЗапросТопливо("Топливо", "БензГазпром", Таблица);
	ВыполнитьЗапросТопливо("Топливо", "БензЭкспресс", Таблица);
	
	ВыполнитьЗапросТопливо("Топливо", "ГазРоснефть", Таблица);
	ВыполнитьЗапросТопливо("Топливо", "ГазЛенуар", Таблица);
	ВыполнитьЗапросТопливо("Топливо", "ГазЛукойл", Таблица);
	ВыполнитьЗапросТопливо("Топливо", "ГазГазпром", Таблица);
	ВыполнитьЗапросТопливо("Топливо", "ГазЭкспресс", Таблица);
	
	ВыполнитьЗапросТопливо("Топливо", "ДизРоснефть", Таблица);
	ВыполнитьЗапросТопливо("Топливо", "ДизЛенуар", Таблица);
	ВыполнитьЗапросТопливо("Топливо", "ДизЛукойл", Таблица);
	ВыполнитьЗапросТопливо("Топливо", "ДизГазпром", Таблица);
	ВыполнитьЗапросТопливо("Топливо", "ДизЭкспресс", Таблица);
	
	РасчитатьИтогоТопливо(Таблица);
	
	///////////////////////пробег 
	Таблица.Колонки.Добавить("Пробег", Новый ОписаниеТипов("Число"));
	Для каждого стр из Таблица Цикл
		ТабПробег = ВыполнитьЗапросПробег(стр.ПериодНачалоРасчета, стр.ПериодКонецРасчета, стр.ТС);
		Если ТабПробег.Количество() > 0 Тогда
			стр.Пробег = ТабПробег[0].Количество;
		КонецЕсли;
	КонецЦикла;
		
	
	////////////////////////Ремонты
	Таблица.Колонки.Добавить("РемЗапчасти", Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("РемСторонний", Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("РемДоставка", Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("РемПрочее", Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("РемИтого", Новый ОписаниеТипов("Число"));
	
	ВыполнитьЗапросРемонты("РемЗапчасти", Таблица);
	ВыполнитьЗапросРемонты("РемСторонний", Таблица);
	
	РасчитатьИтогоРем(Таблица);
	
	//////////////////////////////Заказы
	Таблица.Колонки.Добавить("МСКСПБ", Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("СПБМСК", Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("Заказы", Новый ОписаниеТипов("Число"));
	
	ВыполнитьЗапросЗаказы("МСКСПБ", Таблица);
	ВыполнитьЗапросЗаказы("СПБМСК", Таблица);
	ВыполнитьЗапросЗаказы("Заказы", Таблица);
	
	/////////////////////////////
	
	
	
	Возврат (Таблица);
Показать
40. Torin57 41 26.03.25 09:38 Сейчас в теме
(35) Ответ ИИ claude-3.7-sonnet:

Вы правы в обоих замечаниях. Давайте адаптируем решение под существующий код автора, учитывая, что у него уже есть сформированная таблица значений.

Вариант решения с использованием существующей таблицы значений

Поскольку у автора уже есть готовая таблица значений (`Таблица`), мы можем использовать её для создания структуры данных по логистам, а затем применить эту структуру для правильного объединения ячеек. Вот как это можно реализовать:
ТабДок = Новый ТабличныйДокумент;
ОбработкаОб = РеквизитФормыВЗначение("Объект");
НачалоПериода = НачалоДня(ЭтотОбъект.НачалоПериода);
КонецПериода = КонецДня(ЭтотОбъект.КонецПериода);
Если КонецПериода > ТекущаяДата() ИЛИ НЕ ЗначениеЗаполнено(ЭтотОбъект.КонецПериода) Тогда
    КонецПериода = ТекущаяДата();
КонецЕсли;    

Макет = ОбработкаОб.ПолучитьМакет("Макет");
КолонкаРеквизиты = Макет.ПолучитьОбласть("Реквизиты");
КолонкаРеквизиты.Параметры.НачалоПериода = Формат(НачалоПериода, "ДФ=dd.MM.yyyy");
КолонкаРеквизиты.Параметры.КонецПериода = Формат(КонецПериода, "ДФ=dd.MM.yyyy");
ТабДок.Вывести(КолонкаРеквизиты);

ОбластьИтого = Макет.ПолучитьОбласть("ОбластьИтого");
ТабДок.Вывести(ОбластьИтого);

ОбластьВодители = Макет.ПолучитьОбласть("ОбластьВодители");

Таблица = СформироватьТаблицу();
Таблица.Сортировать("Логист");    

// Создаем структуру для группировки по логистам
СоответствиеЛогистов = Новый Соответствие; // Логист -> Количество водителей
МассивЛогистов = Новый Массив; // Для сохранения порядка логистов

// Заполняем структуру данных
Для каждого Строка Из Таблица Цикл
    Логист = Строка.Логист;
    
    Если СоответствиеЛогистов[Логист] = Неопределено Тогда
        СоответствиеЛогистов.Вставить(Логист, 1);
        МассивЛогистов.Добавить(Логист);
    Иначе
        СоответствиеЛогистов[Логист] = СоответствиеЛогистов[Логист] + 1;
    КонецЕсли;
КонецЦикла;

// Выводим данные
ТекущаяКолонка = 1;
Для каждого Строка Из Таблица Цикл
    ОбластьВодители.Параметры.ПериодРасчета = Формат(Строка.ПериодНачалоРасчета,"ДФ=dd.MM.yyyy") + " - " + Формат(Строка.ПериодКонецРасчета,"ДФ=dd.MM.yyyy");
    ОбластьВодители.Параметры.Заполнить(Строка);
    ТабДок.Присоединить(ОбластьВодители);
    
    ТекущаяКолонка = ТекущаяКолонка + 1;
КонецЦикла;

// Объединяем ячейки для логистов
ТекущаяКолонка = 1;
Для каждого Логист Из МассивЛогистов Цикл
    КоличествоВодителей = СоответствиеЛогистов[Логист];
    
    Если КоличествоВодителей > 1 Тогда
        // Объединяем ячейки для логиста в строке 3
        ТабДок.Область(3, ТекущаяКолонка, 3, ТекущаяКолонка + КоличествоВодителей - 1).Объединить();
    КонецЕсли;
    
    ТекущаяКолонка = ТекущаяКолонка + КоличествоВодителей;
КонецЦикла;

Возврат (ТабДок);
Показать

Объяснение решения:

1. Сначала мы создаем структуру данных:
- `СоответствиеЛогистов` - хранит количество водителей для каждого логиста
- `МассивЛогистов` - сохраняет порядок логистов для правильного обхода

2. При первом проходе по таблице заполняем эту структуру.

3. Затем выводим данные в табличный документ как обычно.

4. После вывода всех данных делаем второй проход по логистам и объединяем ячейки для каждого логиста, у которого больше одного водителя.

Важное замечание:

В коде я предполагаю, что логисты находятся в строке 3 табличного документа. Если это не так, нужно заменить число 3 на правильный номер строки (судя по скриншоту, это строка 3).

Также обратите внимание, что этот код предполагает, что водители одного логиста идут подряд в таблице (что должно выполняться благодаря сортировке `Таблица.Сортировать("Логист")`).

Если нужны дополнительные корректировки под конкретную структуру макета автора, дайте знать - я адаптирую решение.
13. Torin57 41 13.03.25 15:59 Сейчас в теме
(11) Или вот так?:

ОТЧЕТ: ГРУППИРОВКА ВОДИТЕЛЕЙ ПО ЛОГИСТАМ

===== ЛОГИСТ: Иванов Иван ===== ===== ЛОГИСТ: Смирнова Елена ===== ===== ЛОГИСТ: Козлов Антон
Водитель: Васильев Сергей Водитель: Петров Алексей Водитель: Соколов Владимир
Водитель: Морозов Андрей Водитель: Сидоров Николай Водитель: Стас Михайлов
Водитель: Новиков Игорь Водитель: Кузнецов Дмитрий Водитель: Сергей Кошкин
Водитель: Федоров Михаил
17. vdv1690500 13.03.25 16:02 Сейчас в теме
(13) Ответил выше на картинке как примерно
6. vdv1690500 13.03.25 09:15 Сейчас в теме
Что то типаа этого
В ТаблицуЗначений будут добавляться данные, и она будет вниз увеличиваться
Прикрепленные файлы:
7. Asgard90 13.03.25 11:05 Сейчас в теме
о, честно говоря если соединять 3+ таблицы то увы я сам пока в этим потерялся. А вот с двумя, вполне рабочий вариант, но вы можете попробовать сами. Есть такая штука как автономерзаписи() в запросе можно группировать таблицу по нему)
8. DirecTwiX 13.03.25 11:15 Сейчас в теме
ЗначениеВГруппировкеМассив + что-то про соединение
9. DirecTwiX 13.03.25 11:20 Сейчас в теме
(8) Как вариант - прям функция из общего модуля, если гуру скд не набегут
16. vdv1690500 13.03.25 16:01 Сейчас в теме
Что получается примерно у меня: Как переместить вторую табл горизонтально с группировкой?? Новой группой в выбранных полях с расположением горизонтально не получается
Прикрепленные файлы:
21. vdv1690500 13.03.25 16:58 Сейчас в теме
Как в макете можно сделать?

Запросом получил таблицу, макет сделал с областями по колонкам(скриншот), в цикле добавляю область колонку с водителями.
А как сгруппировать по логистам водителей ХЗ.
Прикрепленные файлы:
22. Torin57 41 13.03.25 17:08 Сейчас в теме
(21) Нашел статью на ИТС https://its.1c.ru/db/metod8dev/content/2658/hdoc

Вот что там пишут:
При обходе результата запроса нередко возникает необходимость получения всех значений группировок внутри какой-либо другой группировки. Такая возможность может понадобиться, например, при выводе кросс отчета. Для обеспечения такой возможности в объекте ВыборкаИзРезультатаЗапроса предусмотрен третий параметр функции Выбрать().

Рассмотрим пример. Пусть нам необходимо получить кросс-отчет по остаткам номенклатуры на различных складах. Номенклатуру необходимо вывести в строках, склады - в колонках. Запрос для получения остатков будет выглядеть так:

ВЫБРАТЬ
    УчетНоменклатурыОстатки.Номенклатура КАК Номенклатура,
    УчетНоменклатурыОстатки.Номенклатура.Представление,
    УчетНоменклатурыОстатки.Склад КАК Склад,
    УчетНоменклатурыОстатки.Склад.Представление,
    УчетНоменклатурыОстатки.КоличествоОстаток КАК КоличествоОстаток
ИЗ
    РегистрНакопления.УчетНоменклатуры.Остатки КАК УчетНоменклатурыОстатки
ИТОГИ СУММА(КоличествоОстаток) ПО 
    ОБЩИЕ,
    Номенклатура,
    Склад
Показать


Для обхода номенклатуры воспользуемся выборкой из результата запроса:
ВыборкаНоменклатура = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Номенклатура");
Пока ВыборкаНоменклатура.Следующий() Цикл
    ОбластьНоменклатура.Параметры.Заполнить(ВыборкаНоменклатура);
    ТабДок.Вывести(ОбластьНоменклатура);

Для обхода внутри номенклатуры всех складов, присутствующих в результате запроса, получим вложенную выборку от выборки номенклатуры, с указанием третьего параметра "ВСЕ":
ВыборкаСклад = ВыборкаНоменклатура.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Склад", "ВСЕ");
Пока ВыборкаСклад.Следующий() Цикл
    ОбластьСклад.Параметры.Заполнить(ВыборкаСклад);
    ТабДок.Присоединить(ОбластьСклад);
КонецЦикла;
27. Torin57 41 14.03.25 12:29 Сейчас в теме
(21) Есть еще вариант без использования ИТОГИ ПО, с помощью копирования и свертки таблицы значений. Вот пример:
// Определение типов данных
ТипСтрока50 = Новый ОписаниеТипов("Строка", , 
    Новый КвалификаторыСтроки(50, ДопустимаяДлина.Переменная));
ТипЧисло10_2 = Новый ОписаниеТипов("Число",
    Новый КвалификаторыЧисла(10, 2, ДопустимыйЗнак.Любой));
ТипДата = Новый ОписаниеТипов("Дата");

// Создание таблицы значений
ТаблицаЗначений = Новый ТаблицаЗначений;
ТаблицаЗначений.Колонки.Добавить("НомерДокумента", ТипСтрока50);
ТаблицаЗначений.Колонки.Добавить("ДатаДокумента", ТипДата);
ТаблицаЗначений.Колонки.Добавить("ИННКонтрагента", ТипСтрока50);
ТаблицаЗначений.Колонки.Добавить("Номенклатура", ТипСтрока50);
ТаблицаЗначений.Колонки.Добавить("Цена", ТипЧисло10_2);
ТаблицаЗначений.Колонки.Добавить("Количество", ТипЧисло10_2);
ТаблицаЗначений.Колонки.Добавить("СтавкаНДС", ТипЧисло10_2);
ТаблицаЗначений.Колонки.Добавить("Сумма", ТипЧисло10_2);

// Заполнение таблицы значений
ТаблицаЗначений.Добавить();
ТаблицаЗначений[0].НомерДокумента = "Документ1";
ТаблицаЗначений[0].ДатаДокумента = ТекущаяДата();
ТаблицаЗначений[0].ИННКонтрагента = "1234567890";
ТаблицаЗначений[0].Номенклатура = "Товар1";
ТаблицаЗначений[0].Цена = 1000;
ТаблицаЗначений[0].Количество = 5;
ТаблицаЗначений[0].СтавкаНДС = 20;
ТаблицаЗначений[0].Сумма = ТаблицаЗначений[0].Цена * ТаблицаЗначений[0].Количество;

ТаблицаЗначений.Добавить();
ТаблицаЗначений[1].НомерДокумента = "Документ2";
ТаблицаЗначений[1].ДатаДокумента = ТекущаяДата();
ТаблицаЗначений[1].ИННКонтрагента = "1234567890";
ТаблицаЗначений[1].Номенклатура = "Товар2";
ТаблицаЗначений[1].Цена = 1500;
ТаблицаЗначений[1].Количество = 3;
ТаблицаЗначений[1].СтавкаНДС = 10;
ТаблицаЗначений[1].Сумма = ТаблицаЗначений[1].Цена * ТаблицаЗначений[1].Количество;

ТаблицаЗначений.Добавить();
ТаблицаЗначений[2].НомерДокумента = "Документ3";
ТаблицаЗначений[2].ДатаДокумента = ТекущаяДата();
ТаблицаЗначений[2].ИННКонтрагента = "5432167890";
ТаблицаЗначений[2].Номенклатура = "Товар3";
ТаблицаЗначений[2].Цена = 2000;
ТаблицаЗначений[2].Количество = 2;
ТаблицаЗначений[2].СтавкаНДС = 20;
ТаблицаЗначений[2].Сумма = ТаблицаЗначений[2].Цена * ТаблицаЗначений[2].Количество;

ТаблицаЗначений.Добавить();
ТаблицаЗначений[3].НомерДокумента = "Документ4";
ТаблицаЗначений[3].ДатаДокумента = ТекущаяДата();
ТаблицаЗначений[3].ИННКонтрагента = "0987654321";
ТаблицаЗначений[3].Номенклатура = "Товар4";
ТаблицаЗначений[3].Цена = 3000;
ТаблицаЗначений[3].Количество = 1;
ТаблицаЗначений[3].СтавкаНДС = 10;
ТаблицаЗначений[3].Сумма = ТаблицаЗначений[3].Цена * ТаблицаЗначений[3].Количество;

// Сворачивание таблицы по документам
ТабДокументы = ТаблицаЗначений.Скопировать();
ТабДокументы.Свернуть("НомерДокумента, ДатаДокумента, ИННКонтрагента", "Сумма");

// Обработка документов
Для каждого ТекДокумент Из ТабДокументы Цикл
    
    // Здесь создаем документ
    НомерДок = ТекДокумент.НомерДокумента;
    ДатаДок = ТекДокумент.ДатаДокумента;
    ИННКонтрагента = ТекДокумент.ИННКонтрагента;
    ОбщаяСумма = ТекДокумент.Сумма;
    
    Сообщить("НомерДок " + НомерДок);
    Сообщить("ДатаДок " + Формат(ДатаДок, "ДФ=dd.MM.yyyy"));
    Сообщить("ИННКонтрагента " + ИННКонтрагента);
    Сообщить("ОбщаяСумма " + ОбщаяСумма);

    // Отбор строк текущего документа с учетом ИНН контрагента
    ОтборСтрокТекущегоДокумента = Новый Структура;
    ОтборСтрокТекущегоДокумента.Вставить("НомерДокумента", НомерДок);
    ОтборСтрокТекущегоДокумента.Вставить("ДатаДокумента", ДатаДок);
    ОтборСтрокТекущегоДокумента.Вставить("ИННКонтрагента", ИННКонтрагента);
    
    СтрокиДокумента = ТаблицаЗначений.НайтиСтроки(ОтборСтрокТекущегоДокумента);
    
    Для каждого СтрокаТЧДокумента Из СтрокиДокумента Цикл

        // Здесь заполняем табличную часть документа
        Номенклатура = СтрокаТЧДокумента.Номенклатура;
        Цена = СтрокаТЧДокумента.Цена;
        Количество = СтрокаТЧДокумента.Количество;
        СтавкаНДС = СтрокаТЧДокумента.СтавкаНДС;   
        
        Сообщить("Номенклатура " + Номенклатура);
        Сообщить("Цена " + Цена);
        Сообщить("Количество " + Количество);
        Сообщить("СтавкаНДС " + СтавкаНДС);
        
    КонецЦикла;  
    
    // Здесь записываем документ
    Сообщить("-------------------");
    
КонецЦикла;
Показать
23. Torin57 41 13.03.25 17:21 Сейчас в теме
Получается что-то типа:
ВыборкаЛогисты = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Логист");
Пока ВыборкаЛогисты .Следующий() Цикл
    ОбластьЛогисты.Параметры.Заполнить(ВыборкаЛогисты);
    ТабДок.Присоединить(ОбластьЛогисты);
 
   ВыборкаВодители = ВыборкаЛогисты.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Водитель", "ВСЕ");
   Пока ВыборкаВодители .Следующий() Цикл
    ОбластьЛогистыВодители.Параметры.Заполнить(ВыборкаВодители );
    ТабДок.Присоединить(ОбластьЛогистыВодители);
  КонецЦикла;
КонецЦикла;
Показать

Внутри каждого логиста перебираем его водителей. Если не получится, то можно в ИИ клод соннет 3.7 попробовать написать код. Но это уже завтра.
32. Torin57 41 18.03.25 22:43 Сейчас в теме
Но Клод мне рассказал как нарисовать макет. Вот его схематичная схема:
+-----------------------------------------------------+
| ЗАГОЛОВОК |
+-----------------------------------------------------+
| ЛОГИСТ 1 | ЛОГИСТ 2 | ЛОГИСТ 3 |
+-----------------------------------------------------+
| Водитель-ФИО | Водитель-ФИО | Водитель-ФИО |
| НомерТС | НомерТС | НомерТС |
| ЦветКузова | ЦветКузова | ЦветКузова |
+-----------------------------------------------------+
| Водитель 1 | Водитель 1 | Водитель 1 |
| ТС 1 | ТС 1 | ТС 1 |
| Цвет 1 | Цвет 1 | Цвет 1 |
+-----------------------------------------------------+
| Показатели 1 | Показатели 1 | Показатели 1 |
+-----------------------------------------------------+
| Водитель 2 | Водитель 2 | Водитель 2 |
| ТС 2 | ТС 2 | ТС 2 |
| Цвет 2 | Цвет 2 | Цвет 2 |
+-----------------------------------------------------+
| Показатели 2 | Показатели 2 | Показатели 2 |
+-----------------------------------------------------+
| ИТОГО ПО ЛОГИСТУ| ИТОГО ПО ЛОГИСТУ| ИТОГО ПО ЛОГИСТУ|
+-----------------------------------------------------+
| ИТОГО ПО ВСЕМ ЛОГИСТАМ |
+-----------------------------------------------------+

Создание и настройка областей макета:

Откройте конфигуратор и перейдите к отчету "ОтчетПоЛогистамИВодителям"

Создайте макет отчета:

В дереве объектов конфигурации найдите отчет
Перейдите на вкладку "Макеты"
Добавьте новый макет типа "Табличный документ" с именем "Макет"

Создайте области в макете:
a. Область "Заголовок" (1 строка x несколько колонок):

+----------------------------------------------+
| Отчет по логистам и водителям за период: |
| с [НачалоПериода] по [КонецПериода] |
| [ОтборЛогист] |
+----------------------------------------------+
Выделите область для заголовка (например, ячейки A1:G3)
Щелкните правой кнопкой мыши и выберите "Имя области" → "Определить"
Введите имя "Заголовок"
Настройте параметры: &НачалоПериода, &КонецПериода, &ОтборЛогист

b. Область "Логист" (1 строка x несколько колонок):
text+----------------+
[Логист]
+----------------+

Выделите область для логиста (например, ячейки A4:C4)
Определите имя области "Логист"
Настройте параметр: &Логист

c. Область "Водитель" (1 строка x несколько колонок):
text+----------------+
[Водитель]
[ТС]
[ЦветКузова]
+----------------+

Выделите область для водителя (например, ячейки A5:C7)
Определите имя области "Водитель"
Настройте параметры: &Водитель, &ТС, &ЦветКузова

d. Область "Показатели" (1 строка x несколько колонок):
text+----------------+
Рейсы: [КоличествоРейсов]
Расстояние: [ПройденноеРасстояние]
Выручка: [СуммаВыручки]
Топливо: [РасходТоплива]
+----------------+

Выделите область для показателей (например, ячейки A8:C11)
Определите имя области "Показатели"
Настройте параметры: &КоличествоРейсов, &ПройденноеРасстояние, &СуммаВыручки, &РасходТоплива

e. Область "ИтогоПоЛогисту" (1 строка x несколько колонок):
text+----------------+
ИТОГО:
Рейсы: [ИтогоКоличествоРейсов]
Расстояние: [ИтогоПройденноеРасстояние]
Выручка: [ИтогоСуммаВыручки]
Топливо: [ИтогоРасходТоплива]
+----------------+

Выделите область для итогов по логисту (например, ячейки A12:C16)
Определите имя области "ИтогоПоЛогисту"
Настройте параметры: &ИтогоКоличествоРейсов, &ИтогоПройденноеРасстояние, &ИтогоСуммаВыручки, &ИтогоРасходТоплива

f. Область "Итого" (1 строка x все колонки):
text+----------------------------------------------+
ИТОГО ПО ВСЕМ ЛОГИСТАМ:
Рейсы: [ОбщееКоличествоРейсов]
Расстояние: [ОбщееПройденноеРасстояние]
Выручка: [ОбщаяСуммаВыручки]
Топливо: [ОбщийРасходТоплива]
+----------------------------------------------+

Выделите область для общих итогов (например, ячейки A17:G21)
Определите имя области "Итого"
Настройте параметры: &ОбщееКоличествоРейсов, &ОбщееПройденноеРасстояние, &ОбщаяСуммаВыручки, &ОбщийРасходТоплива

g. Область "ПустойРезультат" (для случая отсутствия данных):
text+----------------------------------------------+
Нет данных для отображения по заданным
параметрам отчета
+----------------------------------------------+

Выделите область (например, ячейки A22:G23)
Определите имя области "ПустойРезультат"

Советы по созданию макета:

Размеры областей:

Сделайте области логиста, водителя и показателей одинаковой ширины, чтобы они красиво выстраивались горизонтально
Используйте объединение ячеек для создания удобного форматирования

Форматирование:

Для области "Логист" можно использовать жирный шрифт и выравнивание по центру
Для заголовков водителей также можно использовать жирный шрифт
Для числовых значений настройте формат ячеек с необходимым количеством десятичных знаков

Параметры:

Все параметры в макете должны начинаться с символа "&" (например, &Логист)
Проверьте, что имена параметров в макете совпадают с именами в коде

Цвета:

В самом макете не задавайте цвета фона для областей логистов - они будут установлены программно в коде

После создания и настройки всех областей макета, код отчета будет использовать их для формирования отчета, располагая секции логистов горизонтально и заполняя их данными о водителях и показателях.
Оставьте свое сообщение

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