секции в макете 1с 7.7

  • Автор темы maxgross
  • Дата начала
M

maxgross

#1
Подскажите, как поправить макет или же запрос и его вывод в макет, чтобы все получилось правильно.
Скрины вложил. Там вся суть проблемы.

Код:
Код:
Процедура Запрос()
Перем Запрос, ТекстЗапроса, Таб;
//Создание объекта типа Запрос
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса =
"//{{ЗАПРОС(Запрос)
|Период с ВыбНачПериода по ВыбКонПериода;
|Номенклатура = Регистр.Продажи.Номенклатура;
|Контрагент = Регистр.Продажи.Контрагент;
|Количество = Регистр.Продажи.Количество;
|Функция КоличествоСумма = Сумма(Количество);
|Группировка Номенклатура упорядочить по Номенклатура.Наименование;
|Группировка Контрагент упорядочить по Контрагент.Наименование;
|"//}}ЗАПРОС
;
// Если ошибка в запросе, то выход из процедуры
Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
Возврат;
КонецЕсли;

// Подготовка к заполнению выходных форм данными запроса
Таб = СоздатьОбъект("Таблица");
Таб.ИсходнаяТаблица("Запрос");
// Заполнение полей "Заголовок"
Таб.ВывестиСекцию("Заголовок");
Состояние("Заполнение выходной таблицы...");
Таб.Опции(0, 0, Таб.ВысотаТаблицы(), 0);
Пока Запрос.Группировка(1) = 1 Цикл
// Заполнение полей Номенклатура
Пока Запрос.Группировка(2) = 1 Цикл
Таб.ВывестиСекцию("Номенклатура");

// Заполнение полей Контрагент
Таб.ВывестиСекцию("Контра");
КонецЦикла;
КонецЦикла;
// Заполнение полей "Итого"
Таб.ВывестиСекцию("Итого");
// Вывод заполненной формы
Таб.ТолькоПросмотр(1);
Таб.Показать("Запрос", "");
КонецПроцедуры
 

Вложения

U

User1C

#2
Предполажу что надо присоединить секцию "Контра"

Код:
Пока Запрос.Группировка(1) = 1 Цикл
// Заполнение полей Номенклатура
Таб.ВывестиСекцию("Номенклатура");
Пока Запрос.Группировка(2) = 1 Цикл  
// Заполнение полей Контрагент
Таб.Присоединить("Номенклатура|Контра");
КонецЦикла;
КонецЦикла;
 
M

maxgross

#3
Предполажу что надо присоединить секцию "Контра"

Код:
Пока Запрос.Группировка(1) = 1 Цикл
// Заполнение полей Номенклатура
Таб.ВывестиСекцию("Номенклатура");
Пока Запрос.Группировка(2) = 1 Цикл  
// Заполнение полей Контрагент
Таб.Присоединить("Номенклатура|Контра");
КонецЦикла;
КонецЦикла;

Не выходит.
 

Вложения

Paume

Well-known member
15.12.2010
107
0
#4
Поместить столбцы 1 и 2 в отдельную секцию, например Секция_1

Все Таб.ВывестиСекцию() заменить на
1.
Таб.ВывестиСекцию("Заголовок|Секция_1");
Цикл по попавшим в запрос Контрагентам
Таб.ПрисоединитьСекцию("Заголовок|Контра");
КонецЦикла;
2.
Пока Запрос.Группировка(1)=1 Цикл
Таб.ВывестиСекцию("Номенклатура|Секция_1");
Пока Запрос.Группировка(2)=1 цикл
Таб.присоединитьСекцию("Номенклатура|Контра");
КонецЦикла;
КонецЦикла;
3.
Таб.ВывестиСекцию("Итого|Секция_1");
Цикл по попавшим в запрос Контрагентам
Таб.ПрисоединитьСекцию("Итого|Контра");
КонецЦикла;
 
M

maxgross

#5
Цикл по попавшим в запрос Контрагентам
иначе: Пока Запрос.Группировка("Контрагент") = 1 Цикл
Правильно понимаю?

А в целом, это разве правильно? Ведь группировка по контрагентам - ниже уровнем,чем по номенклатуре. Правильно ли - обращаться сразу ко второму уровню?

пс. с семеркой знаком 3 дня, поэтому прошу извинить за, возможно, глупые вопросы.
 
M

maxgross

#6
Как и говорил (если правильно Вас понял), возникает следующая ошибка:

Код:
Пока Запрос.Группировка("Контрагент") = 1 Цикл 
{Отчет.новый2.Форма.Модуль(40)}: Не было обращения к старшим уровням выборки.
 

Paume

Well-known member
15.12.2010
107
0
#7
Ведь группировка по контрагентам - ниже уровнем,чем по номенклатуре. Правильно ли - обращаться сразу ко второму уровню?
Совершенно верно - обращаемся сначала к первому уровню и только потом ко второму.

Обычно в таких задачах предварительно пользуются выгрузкой результата запроса в таблицу значений
Запрос.Выгрузить(ТЗ);
ТЗ.Свернуть("Контрагент","КоличествоСумма");
Цикл в шапке и итогах делается по таблице значений.
 
M

maxgross

#8
В итоге, у меня получилось следующее:

Код:
Процедура Запрос()
Перем Запрос, ТекстЗапроса, Таб;
//Создание объекта типа Запрос
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса = 
"//{{ЗАПРОС(Запрос)
|Период с ВыбНачПериода по ВыбКонПериода;
|Номенклатура = Регистр.Продажи.Номенклатура;
|Контрагент = Регистр.Продажи.Контрагент;
|Количество = Регистр.Продажи.Количество;
|Функция КоличествоСумма = Сумма(Количество);
|Группировка Номенклатура упорядочить по Номенклатура.Наименование;
|Группировка Контрагент упорядочить по Контрагент.Наименование;
|"//}}ЗАПРОС
;

Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
Возврат;
КонецЕсли;
ТЗ = СоздатьОбъект("ТаблицаЗначений");
Запрос.Выгрузить(ТЗ);
ТЗ.Свернуть("Контрагент","КоличествоСумма");


Таб = СоздатьОбъект("Таблица");
Таб.ИсходнаяТаблица("Запрос");

Пока ТЗ.ПолучитьСтроку() = 1 Цикл 
Таб.ВывестиСекцию("Заголовок|Секция_1");
КонецЦикла; 

Состояние("Заполнение выходной таблицы...");

Таб.Опции(0, 0, Таб.ВысотаТаблицы(), 0);

Пока Запрос.Группировка(1) = 1 Цикл
Таб.ВывестиСекцию("Номенклатура|Секция_1");
Пока Запрос.Группировка(2)=1 Цикл
Таб.присоединитьСекцию("Номенклатура|Контра");
КонецЦикла;
КонецЦикла;

Таб.ВывестиСекцию("Итого|Секция_1");
Пока ТЗ.ПолучитьСтроку() = 1 Цикл
Таб.ПрисоединитьСекцию("Итого|Контра");
КонецЦикла;
Таб.ТолькоПросмотр(1);
Таб.Показать("Запрос", "");
КонецПроцедуры

Результат и макет прикреплены.
 

Вложения

Paume

Well-known member
15.12.2010
107
0
#9
Ох, ну ты и чудо в перьях. :)

Секций в макете теперь две.
Одна "Секция_1" - выводится первой и один раз для каждой из горизонтальных секций процедурой Таб.ВывестиСекцию.
А вторая "Контра" - выводится в цикле по ТЗ, где у тебя собраны все контрагенты, вошедшие в запрос, процедурой Таб.ПрисоединитьСекцию.

ВывестиСекцию(Область) - выводит указанную область с новой строки
ПрисоединитьСекцию(Область) - добавляет к последней выведенной области, рядышком ее рисует...
Хелп почитай, плиз.
 

Paume

Well-known member
15.12.2010
107
0
#10
Сорри за пред. ответ, вот это
Пока ТЗ.ПолучитьСтроку() = 1 Цикл
Таб.ВывестиСекцию("Заголовок|Секция_1");
КонецЦикла;
ввело в заблуждение.

Давай так - условие задачи: вывести отчет о продажах таким образом, чтобы в строках был товар, а в столбцах - контрагенты, которые этот товар купили?
Если да - то проверяй себя в отладчике.
Если нет, то уточняй условие.
 
M

maxgross

#11
Да, условие именно такое.

т.е. мой предыдущий код правильный?
 

Paume

Well-known member
15.12.2010
107
0
#12
т.е. мой предыдущий код правильный?
Ну, более-менее похоже на то, о чем я пытаюсь рассказать.

Теперь - понятно, что когда ты выводишь секцию "Итого|Контра", то к запросу ты уже не обращаешься - значит, это значение нужно брать хотя бы из той же ТЗ, куда ты выгрузил результат запроса.
Точно так же - названия контрагентов в заголовке.

Еще один нюанс - когда ты обходишь группировку, у тебя Товар1 может быть отгружен только Контрагенту1, а Товар2 - Контрагенту2, соответственно и таблица сформируется кривовато.

В отладчике ты видел, какие значения у тебя перебираются?
 
M

maxgross

#13
Код:
Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
Возврат;
КонецЕсли;
ТЗ = СоздатьОбъект("ТаблицаЗначений");
Запрос.Выгрузить(ТЗ);
ТЗ.Свернуть("Контрагент","КоличествоСумма");

Таб = СоздатьОбъект("Таблица");	
Таб.ИсходнаяТаблица("Запрос"); 
Таб.ВывестиСекцию("Заголовок|Секция_1"); 
Для й =1 по ТЗ.КоличествоСтрок() Цикл 
ТЗ.ПолучитьСтрокуПоНомеру(й);		
Таб.ПрисоединитьСекцию("Заголовок|Контра");	
КонецЦикла;
 
M

maxgross

#15
На данный момент имею следующее:

Код:
Процедура Запрос()
Перем Запрос, ТекстЗапроса, Таб;
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса = 
"//{{ЗАПРОС(Запрос)
|Период с ВыбНачПериода по ВыбКонПериода;
|Номенклатура = Регистр.Продажи.Номенклатура;
|Контрагент = Регистр.Продажи.Контрагент;
|Количество = Регистр.Продажи.Количество;
|Функция КоличествоСумма = Сумма(Количество);
|Группировка Номенклатура упорядочить по Номенклатура.Наименование;
|Группировка Контрагент упорядочить по Контрагент.Наименование;
|"//}}ЗАПРОС
;
Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
Возврат;
КонецЕсли;
ТЗ = СоздатьОбъект("ТаблицаЗначений");
Запрос.Выгрузить(ТЗ,,0);
ТЗ.Свернуть("Контрагент","КоличествоСумма");
Таб = СоздатьОбъект("Таблица");	
Таб.ИсходнаяТаблица("Запрос"); 
Таб.ВывестиСекцию("Заголовок|Секция_1"); 
Для й =1 по ТЗ.КоличествоСтрок() Цикл 
ТЗ.ПолучитьСтрокуПоНомеру(й);		
Таб.ПрисоединитьСекцию("Заголовок|Контра");	
КонецЦикла; 
Состояние("Заполнение выходной таблицы...");
Таб.Опции(0, 0, Таб.ВысотаТаблицы(), 0);
Пока Запрос.Группировка(1) = 1 Цикл
Таб.ВывестиСекцию("Номенклатура|Секция_1"); 
Пока Запрос.Группировка(2)=1 Цикл 
Для й=1 по ТЗ.КоличествоСтрок() цикл 
ТЗ.ПолучитьСтрокуПоНомеру(й);		 
Если ТЗ.Контрагент = Запрос.Контрагент тогда 
Сумма = Запрос.КоличествоСумма; 
Иначе Сумма =0; 
КонецЕсли;
Таб.присоединитьСекцию("Номенклатура|Контра"); 
КонецЦикла; 
КонецЦикла;	
КонецЦикла;
Таб.ВывестиСекцию("Итого|Секция_1"); 
Пока ТЗ.ПолучитьСтроку() = 1 Цикл 
Таб.ПрисоединитьСекцию("Итого|Контра");
КонецЦикла;
Таб.ТолькоПросмотр(1);
Таб.Показать("Запрос", "");
КонецПроцедуры

Откуда берутся лишние колонки с нулями?
У покупателя2 должны стоять "1" напротив каждого товара
 

Вложения

Paume

Well-known member
15.12.2010
107
0
#16
|Группировка Контрагент упорядочить по Контрагент.Наименование;
Могу предположить, что здесь требуется поставить Без Групп.
Т.е. запрос.Группировка(2) внчале получает значение группы контрагентов, а на следующем шаге цикла уже самого контрагента.
 
M

maxgross

#17
Как это сделать синтаксически? Как поставить Без Групп?
это нужно делать в конструкторе запросов?
или Без групп означает убрать группировку вообще?
 

KiR

НЕ шибка опытный програмер)
11.09.2007
1 581
0
#18
maxgross зайди в конструктор запросов и там на вкладке группировка выбери для нужной группировки флаг Без групп
(ну или ручками это дописать можно, только я не помню - перед или после упорядочивания)
 

vbs

Well-known member
18.02.2007
1 708
1
#19
Имея в виду какое-либо предприятие, помысли, точно ли оно тебе удастся.

К.Прутков :lamer: