Всем доброго дня!
Пытаюсь создать Отчет (не на СКД), но начал тупить, видимо мозгов не хватает, наставьте пожалуйста на путь истинный. Получаю из документов Таблицу значений, мне нужно ее "развернуть" из вертикальной в горизонтальную (образец прилагаю).
P.S. Шапку "развернуть" у меня получается, не соображу, как заполнить строки?
Заранее Спасибо!
Пытаюсь создать Отчет (не на СКД), но начал тупить, видимо мозгов не хватает, наставьте пожалуйста на путь истинный. Получаю из документов Таблицу значений, мне нужно ее "развернуть" из вертикальной в горизонтальную (образец прилагаю).
P.S. Шапку "развернуть" у меня получается, не соображу, как заполнить строки?
Заранее Спасибо!
Прикрепленные файлы:
ТабЗначений.xlsx
По теме из базы знаний
- Печать сгруппированной индексированной таблицы значений
- Управляемая форма 1С 8.2(8.3) – работа с деревом значений и таблицей значений. Часть II (Реализация DRAG and DROP)
- Восстановление развернутых строк ДереваЗначений после его обновления (управляемая форма)
- Удобный выбор из таблицы/дерева в УФ
- Здравствуй, дерево! Продолжение разбора особенностей поведения таблицы формы
Найденные решения
Остальные ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
Массив уникальных значений начислений, массив уникальных сотрудников.
Сперва цикл по начислениям - формируем шапку.
Дальше - в цикл по сотрудникам вложен цикл по начислениям, формируем структуру "Сотрудник, Начисление", дальше - НайтиСтроки. Если строки есть - берем нулевую, получаем значение, присоединяем область. Если строк нет - очищаем ячейку и тоже присоединяем область. Вот, собственно, и все, строк пятнадцать.
Сперва цикл по начислениям - формируем шапку.
Дальше - в цикл по сотрудникам вложен цикл по начислениям, формируем структуру "Сотрудник, Начисление", дальше - НайтиСтроки. Если строки есть - берем нулевую, получаем значение, присоединяем область. Если строк нет - очищаем ячейку и тоже присоединяем область. Вот, собственно, и все, строк пятнадцать.
(3)
1. Запоминаем в переменной ТекущийСотр ФИО сотрудника из первой строки ТЗ, создаем МассивДанных по числу колонок в шапке, которую вы "развернули", и заполняем его нулями.
2. В цикле перебираем ТЗ.
3. Если текущее значение ФИО совпадает с запомненным в переменной ТекущийСотр, то помещаем значение в соответствующий элемент МассивДанных - как его определить, дело хозяйское, можно через список значений или соответствия, созданные при формировании шапки.
4. Если ФИО не совпадает с переменной ТекущийСотр (сменился сотрудник), то:
- выводим в макет строку с данными: ТекущийСотр и МассивДанных;
- заполняем МассивДанных нулями;
- запоминаем в переменной ТекущийСотр ФИО сотрудника;
5. После окончания цикла один раз выполняем п.4 - чтобы вывести данные по последнему сотруднику.
у меня нет заранее подготовленного макета (он формируется программно)
А что выводится в ячейках с данными каждой строки (J4-R4,J5-R5 и т.д)? Предположим, что значения из массива. Тогда можно использовать такой алгоритм:
1. Запоминаем в переменной ТекущийСотр ФИО сотрудника из первой строки ТЗ, создаем МассивДанных по числу колонок в шапке, которую вы "развернули", и заполняем его нулями.
2. В цикле перебираем ТЗ.
3. Если текущее значение ФИО совпадает с запомненным в переменной ТекущийСотр, то помещаем значение в соответствующий элемент МассивДанных - как его определить, дело хозяйское, можно через список значений или соответствия, созданные при формировании шапки.
4. Если ФИО не совпадает с переменной ТекущийСотр (сменился сотрудник), то:
- выводим в макет строку с данными: ТекущийСотр и МассивДанных;
- заполняем МассивДанных нулями;
- запоминаем в переменной ТекущийСотр ФИО сотрудника;
5. После окончания цикла один раз выполняем п.4 - чтобы вывести данные по последнему сотруднику.
(11)
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("НомСтроки");
ТЗ.Колонки.Добавить("Сотрудник");
ТЗ.Колонки.Добавить("Начисление");
ТЗ.Колонки.Добавить("Группа");
ТЗ.Колонки.Добавить("Размер");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТарификацияНСОТ.ТаблицаВР.(
| Начисление КАК Начисление,
| Размер КАК Размер,
| Сотрудник КАК Сотрудник,
| ИдентификаторСтрокиСотрудника КАК ИдентификаторСтрокиСотрудника
| ) КАК ТаблицаВР
|ИЗ
| Документ.ТарификацияНСОТ КАК ТарификацияНСОТ
|ГДЕ
| ТарификацияНСОТ.Организация = &Организация
| И ТарификацияНСОТ.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
| И ТарификацияНСОТ.Проведен = &Проведен
| И ТарификацияНСОТ.ТаблицаВР.НомерСтроки > 1
| И ТарификацияНСОТ.ТаблицаВР.Размер > 0";
Запрос.УстановитьПараметр("ДатаНачала", Отчет.ДатаНачала);
Запрос.УстановитьПараметр("ДатаОкончания", Отчет.ДатаОкончания);
Запрос.УстановитьПараметр("Организация", Отчет.Организация);
Запрос.УстановитьПараметр("Проведен", Истина);
//Запрос.УстановитьПараметр("Ссылка", Документ);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
ВыборкаСтрок = Выборка.ТаблицаВР.Выбрать();
Пока ВыборкаСтрок.Следующий() Цикл
НС = ТЗ.Добавить();
НС.НомСтроки = ВыборкаСтрок.ИдентификаторСтрокиСотрудника;
НС.Сотрудник = ВыборкаСтрок.Сотрудник;
НС.Начисление = ВыборкаСтрок.Начисление;
НС.Группа = Справочники.СоответствиеВР.НайтиПоНаименованию(НС.Начисление).ВходитВГруппу;
НС.Размер = ВыборкаСтрок.Размер;
КонецЦикла;
КонецЦикла;
ТЗ.Свернуть("Начисление","Размер");
ВТЗ = Новый ТаблицаЗначений;
Для Инд = 1 По ТЗ.Количество() Цикл
Индекс = Инд-1;
ВР = ТЗ[Индекс].Начисление;
//Сообщить(""+Инд+" "+ВР);
ВТЗ.Колонки.Добавить(,Новый ОписаниеТипов("Число"),ВР.Наименование,10);
КонецЦикла;
// Далее "рисуем" макет
Линия = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная,1);
ТолстаяЛиния = Линия;//Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 2);
Таб=Новый ТабличныйДокумент;
Таб.Область(1,1).Текст=Заголовок;
Таб.Область(1,1).ШиринаКолонки = 4;
Таб.Область(1,1).Обвести(ТолстаяЛиния,ТолстаяЛиния,ТолстаяЛиния,ТолстаяЛиния);
Для Кол=1 По ВТЗ.Колонки.Количество() Цикл
врЗаголовок = "";
Если СокрЛП(Строка(ВТЗ.Колонки[Кол-1].Заголовок)) <> "" Тогда
врЗаголовок = Строка(ВТЗ.Колонки[Кол-1].Заголовок);
Иначе
врЗаголовок = Строка(ВТЗ.Колонки[Кол-1].Имя)
КонецЕсли;
Таб.Область(2,Кол+1).Текст = врЗаголовок;
//Таб.Область(2,Кол+1).Шрифт = Новый Шрифт(,,Истина);// жирный
Таб.Область(2,Кол+1).Обвести(ТолстаяЛиния,ТолстаяЛиния,ТолстаяЛиния,ТолстаяЛиния);
врШир = ВТЗ.Колонки[Кол-1].Ширина;
Если врШир > 0 Тогда
Таб.Область(2,Кол+1).ШиринаКолонки = врШир;
КонецЕсли;
КонецЦикла;
i=0;
Для Каждого Ном ИЗ ВТЗ Цикл
i=i+1;
Таб.Область(i+2,1).Текст=Строка(i);
Таб.Область(i+2,1).Обвести(Линия, Линия, Линия, Линия);
Для Кол=1 По ТЗ.Колонки.Количество() Цикл
Таб.Область(i+2,Кол+1).Текст=Строка(ТЗ[i-1][кол-1]);
Таб.Область(i+2,Кол+1).Обвести(Линия, Линия, Линия, Линия);
КонецЦикла;
Если i/10=Цел(i/10) Тогда
//Состояние(Заголовок+", печать: "+Строка(i));
КонецЕсли;
КонецЦикла;
Таб.Вывести(Таб);
ПоказатьТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("НомСтроки");
ТЗ.Колонки.Добавить("Сотрудник");
ТЗ.Колонки.Добавить("Начисление");
ТЗ.Колонки.Добавить("Группа");
ТЗ.Колонки.Добавить("Размер");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТарификацияНСОТ.ТаблицаВР.(
| Начисление КАК Начисление,
| Размер КАК Размер,
| Сотрудник КАК Сотрудник,
| ИдентификаторСтрокиСотрудника КАК ИдентификаторСтрокиСотрудника
| ) КАК ТаблицаВР
|ИЗ
| Документ.ТарификацияНСОТ КАК ТарификацияНСОТ
|ГДЕ
| ТарификацияНСОТ.Организация = &Организация
| И ТарификацияНСОТ.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
| И ТарификацияНСОТ.Проведен = &Проведен
| И ТарификацияНСОТ.ТаблицаВР.НомерСтроки > 1
| И ТарификацияНСОТ.ТаблицаВР.Размер > 0";
Запрос.УстановитьПараметр("ДатаНачала", Отчет.ДатаНачала);
Запрос.УстановитьПараметр("ДатаОкончания", Отчет.ДатаОкончания);
Запрос.УстановитьПараметр("Организация", Отчет.Организация);
Запрос.УстановитьПараметр("Проведен", Истина);
//Запрос.УстановитьПараметр("Ссылка", Документ);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
ВыборкаСтрок = Выборка.ТаблицаВР.Выбрать();
Пока ВыборкаСтрок.Следующий() Цикл
НС = ТЗ.Добавить();
НС.НомСтроки = ВыборкаСтрок.ИдентификаторСтрокиСотрудника;
НС.Сотрудник = ВыборкаСтрок.Сотрудник;
НС.Начисление = ВыборкаСтрок.Начисление;
НС.Группа = Справочники.СоответствиеВР.НайтиПоНаименованию(НС.Начисление).ВходитВГруппу;
НС.Размер = ВыборкаСтрок.Размер;
КонецЦикла;
КонецЦикла;
ТЗ.Свернуть("Начисление","Размер");
ВТЗ = Новый ТаблицаЗначений;
Для Инд = 1 По ТЗ.Количество() Цикл
Индекс = Инд-1;
ВР = ТЗ[Индекс].Начисление;
//Сообщить(""+Инд+" "+ВР);
ВТЗ.Колонки.Добавить(,Новый ОписаниеТипов("Число"),ВР.Наименование,10);
КонецЦикла;
// Далее "рисуем" макет
Линия = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная,1);
ТолстаяЛиния = Линия;//Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 2);
Таб=Новый ТабличныйДокумент;
Таб.Область(1,1).Текст=Заголовок;
Таб.Область(1,1).ШиринаКолонки = 4;
Таб.Область(1,1).Обвести(ТолстаяЛиния,ТолстаяЛиния,ТолстаяЛиния,ТолстаяЛиния);
Для Кол=1 По ВТЗ.Колонки.Количество() Цикл
врЗаголовок = "";
Если СокрЛП(Строка(ВТЗ.Колонки[Кол-1].Заголовок)) <> "" Тогда
врЗаголовок = Строка(ВТЗ.Колонки[Кол-1].Заголовок);
Иначе
врЗаголовок = Строка(ВТЗ.Колонки[Кол-1].Имя)
КонецЕсли;
Таб.Область(2,Кол+1).Текст = врЗаголовок;
//Таб.Область(2,Кол+1).Шрифт = Новый Шрифт(,,Истина);// жирный
Таб.Область(2,Кол+1).Обвести(ТолстаяЛиния,ТолстаяЛиния,ТолстаяЛиния,ТолстаяЛиния);
врШир = ВТЗ.Колонки[Кол-1].Ширина;
Если врШир > 0 Тогда
Таб.Область(2,Кол+1).ШиринаКолонки = врШир;
КонецЕсли;
КонецЦикла;
i=0;
Для Каждого Ном ИЗ ВТЗ Цикл
i=i+1;
Таб.Область(i+2,1).Текст=Строка(i);
Таб.Область(i+2,1).Обвести(Линия, Линия, Линия, Линия);
Для Кол=1 По ТЗ.Колонки.Количество() Цикл
Таб.Область(i+2,Кол+1).Текст=Строка(ТЗ[i-1][кол-1]);
Таб.Область(i+2,Кол+1).Обвести(Линия, Линия, Линия, Линия);
КонецЦикла;
Если i/10=Цел(i/10) Тогда
//Состояние(Заголовок+", печать: "+Строка(i));
КонецЕсли;
КонецЦикла;
Таб.Вывести(Таб);
Показать
Несколько желтых сообщений смутили: так есть решение или нет?
Если "нет" - напишу, как у меня в ведомости выводится.
Правильно написал (4) antz. Распишу:
Шаг 1 Составить массивы (у меня это ТЗ):
Наверное, оба массива сортировать.
Вывод:
Потом два внутренних цикла. А внутри проход по ТЗ.
Текст набросан грубо. Пропущена фаза вывода шапки.
Еще, могут покритиковать за тупой перебор. Иногда можно, все дело в объеме.
Если "нет" - напишу, как у меня в ведомости выводится.
Правильно написал (4) antz. Распишу:
Шаг 1 Составить массивы (у меня это ТЗ):
В_Поля = Новый Массив;
В_Сотры = Новый Массив;
Для каждого Строка Из ТЗ Цикл
Если НЕ В_Поля.Найти(Строка.Начисление)
В_Поля.Добавить(Строка.Начисление);
КонецЕсли;
Если НЕ В_Сотры.Найти(Строка.Сотрудник)
В_Сотры.Добавить(Строка.Сотрудник);
КонецЕсли;
КонецЦикла;
ПоказатьНаверное, оба массива сортировать.
Вывод:
Потом два внутренних цикла. А внутри проход по ТЗ.
Для каждого ТекСотр Из В_Сотры Цикл
Таб.ВывестиОбласть("Строка|ФИО");
Для каждого ТекПоле Из В_Поля Цикл
Для каждого Строка Из ТЗ Цикл
Если Строка.Сотрудник <> ТекСотр ИЛИ Строка.Начисление <> ТекПоле Тогда
Продолжить;
КонецЕсли;
Таб.ПрисоединитьОюласть("Строка|Колонка");
КонецЦикла; // ТЗ
КонецЦикла; // Начи
КонецЦикла; // Сотр
ПоказатьТекст набросан грубо. Пропущена фаза вывода шапки.
Еще, могут покритиковать за тупой перебор. Иногда можно, все дело в объеме.
(24) Откровенно говоря, конкретного решения пока нет, меня "сбил" leosoft. Он сделал рабочий вариант, но на СКД, проблема в том, что СКД я не знаю, а эта задача является "скелетом" Отчета и здесь будет еще шапка и куча условий/вариантов. "Тупой перебор" - потому что в Отчет попадает максимум 30-60 документов и в каждом ТЧ максимум по 20 строк. В итоге в печатной форме должно быть максимум 20 колонок и максимум 60 строк.
А ваш вариант очень интересный и мне понравился, я попробую использовать его! Правда здесь используется готовый макет, а у меня макет формировался программно (но с готовым макетом наверняка мне будет проще и понятней). Пока Спасибо за ваш вариант. Отработаю его и напишу, буду рад, если еще что-нибудь "подкинете". А я постараюсь из своего остатка пару Sm подкинуть.
А ваш вариант очень интересный и мне понравился, я попробую использовать его! Правда здесь используется готовый макет, а у меня макет формировался программно (но с готовым макетом наверняка мне будет проще и понятней). Пока Спасибо за ваш вариант. Отработаю его и напишу, буду рад, если еще что-нибудь "подкинете". А я постараюсь из своего остатка пару Sm подкинуть.
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот