Имя: Пароль:
1C
1С v8
Обход результата запроса по группировкам
0 Cray12
 
03.11.12
15:33
Добрый день.
Сейчас работаю с запросом и наткнулся на необходимость использования обхода результата запроса. Уже наслышан об этом, но так и не научился его использовать.
В общем, проблема в следующем: есть печатная форма, в ней - табличная часть, куда выводятся данные о кредитах за месяц. При этом, если договор не указан, записи будут выглядеть одинаково, так как столбца "Договор" нет и не должно быть. Велено сделать так, чтобы вместо одной табличной части выводилось столько, сколько у контрагента договоров, соответственно, с заголовком.

Пока запрос в таком виде:

"ВЫБРАТЬ
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.Организация КАК Организация,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.Контрагенты КАК Контрагенты,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.Договоры КАК Договоры,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.Дата_До КАК Дата_До,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймамТабличнаяЧасть1.Период КАК Период,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймамТабличнаяЧасть1.СуммаКредита КАК СуммаКредита,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймамТабличнаяЧасть1.СтавкаПоДоговору КАК СтавкаПоДоговору,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймамТабличнаяЧасть1.СуммаПоДоговору КАК СуммаПоДоговору,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймамТабличнаяЧасть1.СтавкаЦБ КАК СтавкаЦБ,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймамТабличнаяЧасть1.Коэффициент КАК Коэффициент,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймамТабличнаяЧасть1.СуммаПоНУ КАК СуммаПоНУ,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.СубконтоДляСчета91,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.ПроцентНУ,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.Ответственный,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.ДолжностьОтветственного
   |ИЗ
   |    Документ.Рурешъ_НачислениеПроцентовПоКредитамИЗаймам КАК Рурешъ_НачислениеПроцентовПоКредитамИЗаймам
   |        ЛЕВОЕ СОЕДИНЕНИЕ Документ.Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.ТабличнаяЧасть1 КАК Рурешъ_НачислениеПроцентовПоКредитамИЗаймамТабличнаяЧасть1
   |        ПО (Рурешъ_НачислениеПроцентовПоКредитамИЗаймамТабличнаяЧасть1.Ссылка = Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.Ссылка)
   |ГДЕ
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.Ссылка = &Ссылка
   |
   |УПОРЯДОЧИТЬ ПО
   |    Период
   |ИТОГИ
   |    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Договоры)
   |ПО
   |    Период,
   |    СуммаКредита,
   |    СтавкаПоДоговору,
   |    СуммаПоДоговору,
   |    СтавкаЦБ,
   |    Коэффициент,
   |    СуммаПоНУ";
И дальше попытался так:

Результат = Запрос.Выполнить();
ВыборкаДоговор = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

Вот, в общем все, помогите, пожалуйста.

P.S.:  Знаю, что многословен, извините.
1 ДенисЧ
 
03.11.12
15:34
Итоги по Договоры будет достаточно...
2 zak555
 
03.11.12
15:34
покажи лучше макет
3 Cray12
 
03.11.12
15:40
zak555,
Как тут файлы добавлять?
4 Cray12
 
03.11.12
15:42
ДенисЧ,
Там же и так есть итоги по Договоры?
5 Cray12
 
03.11.12
16:16
up
6 zak555
 
03.11.12
17:19
ты сриншот макета выложишь ?
7 Cray12
 
03.11.12
17:33
Ладно, попробую так:
http://rghost.ru/41319948 - это заполненная таб часть, сейчас без заголовка, но тут видно, что столбца Договор нет.
Это то, что получается без итогов, если просто взять все.

Если поставить итоги и взять через обход результатов запроса, то вместо договора берется единица, а таб часть вообще не заполняется:

http://rghost.ru/41319983
8 Cray12
 
03.11.12
17:40
Да, еще вот сам макет, мб надо:

http://rghost.ru/41320166
9 zak555
 
03.11.12
17:40
> При этом, если договор не указан, записи будут выглядеть одинаково, так как столбца "Договор" нет и не должно быть.

что-то я не пойму:
1. что за кредит без договора
2. ставка договора может меняться раз в месяц
3. что такое коэффициент
4. вы банк
?
10 Cray12
 
03.11.12
17:44
1. Я имел в виду, если договор не указан.
2,3. Ставка и коэффициент - вообще не суть, да я, если честно, и не очень вникал.
4. Нет, я физ. лицо.

Основной вопрос - как сделать несколько таб. частей и взять для них заголовки? Вот клочок текста, который я еще не скинул:

Результат = Запрос.Выполнить();
   
   Макет                    = ПолучитьМакет("Макет");
   ОбластьШапка            = Макет.ПолучитьОбласть("Шапка");
   ОбластьДоговор            = Макет.ПолучитьОбласть("Договор");
   ОбластьЗаголовокТаблицы = Макет.ПолучитьОбласть("ЗаголовокТаблицы");
   ОбластьСтрока            = Макет.ПолучитьОбласть("Строка");
   ОбластьПодвал            = Макет.ПолучитьОбласть("Подвал");
   ОбластьПодвал1            = Макет.ПолучитьОбласть("Подвал1");
   
   ОбластьШапка.Параметры.Период              = Строка(Формат(Дата_От, "ДЛФ = Д") + " - " + Формат(Дата_До, "ДЛФ = Д"));
   ОбластьШапка.Параметры.Организация          = Организация;
   ОбластьШапка.Параметры.Вид                  = Строка(ПолучитьСкидку(Договоры)) + "%";
   ОбластьШапка.Параметры.Контрагент          = Контрагенты;
   ОбластьШапка.Параметры.ДоговорКонтрагента = Договоры;
   
   ТабДок.Вывести(ОбластьШапка);
   
   ВыборкаПоДоговору = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
   
   ИтогоСуммаПоНУ = 0;
   ИтогоСуммаПоДоговору = 0;
   
   Пока ВыборкаПоДоговору.Следующий() Цикл
       
       ОбластьДоговор.Параметры.Договор = ВыборкаПоДоговору.Договоры;
       ТабДок.Вывести(ОбластьДоговор);
       ТабДок.Вывести(ОбластьЗаголовокТаблицы);
       
       Если ЗначениеЗаполнено(ВыборкаПоДоговору.Период) Тогда
           ОбластьСтрока.Параметры.Значение1 = ВыборкаПоДоговору.Период;
           ОбластьСтрока.Параметры.Значение2 = ВыборкаПоДоговору.СуммаКредита;
           ОбластьСтрока.Параметры.Значение3 = ВыборкаПоДоговору.СтавкаПоДоговору;
           ОбластьСтрока.Параметры.Значение4 = ВыборкаПоДоговору.СуммаПоДоговору;
           ОбластьСтрока.Параметры.Значение5 = ВыборкаПоДоговору.СтавкаЦБ;
           ОбластьСтрока.Параметры.Значение6 = ВыборкаПоДоговору.Коэффициент;
           ОбластьСтрока.Параметры.Значение7 = ВыборкаПоДоговору.СуммаПоНУ;
           ИтогоСуммаПоНУ                      = ИтогоСуммаПоНУ + ВыборкаПоДоговору.СуммаПоНУ;
           ИтогоСуммаПоДоговору              = ИтогоСуммаПоДоговору + ВыборкаПоДоговору.СуммаПоДоговору;
           ТабДок.Вывести(ОбластьСтрока);
       КонецЕсли;

   КонецЦикла;

И он приводит к результату, показанном на втором скрине. Еще погуглил по обходу результата запроса, но того, что надо, все никак не найду =(
11 zak555
 
03.11.12
17:51
так и что не выводится ?
12 Cray12
 
03.11.12
17:53
Ну, "1" - это не название договора - это раз.
И таб часть совсем пустая =(
А должна быть как на 1 скрине.
13 zak555
 
03.11.12
18:45
Процедура Печать(ТабДок, Ссылка) Экспорт
   //{{_КОНСТРУКТОР_ПЕЧАТИ(Печать)
   Макет = Документы.Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.ПолучитьМакет("Печать");
   Запрос = Новый Запрос;
   Запрос.Текст =
   "ВЫБРАТЬ
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.Договоры,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.ДолжностьОтветственного,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.Контрагенты,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.Ответственный,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.СубконтоДляСчета91,
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.ТабличнаяЧасть1.(
   |        Период,
   |        СуммаКредита,
   |        СтавкаПоДоговору,
   |        СуммаПоДоговору,
   |        СтавкаЦБ,
   |        Коэффициент,
   |        СуммаПоНУ
   |    )
   |ИЗ
   |    Документ.Рурешъ_НачислениеПроцентовПоКредитамИЗаймам КАК Рурешъ_НачислениеПроцентовПоКредитамИЗаймам
   |ГДЕ
   |    Рурешъ_НачислениеПроцентовПоКредитамИЗаймам.Ссылка В (&Ссылка)";
   Запрос.Параметры.Вставить("Ссылка", Ссылка);
   Выборка = Запрос.Выполнить().Выбрать();

   ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
   Шапка = Макет.ПолучитьОбласть("Шапка");
   ОбластьТабличнаяЧасть1Шапка = Макет.ПолучитьОбласть("ТабличнаяЧасть1Шапка");
   ОбластьТабличнаяЧасть1 = Макет.ПолучитьОбласть("ТабличнаяЧасть1");
   Подвал = Макет.ПолучитьОбласть("Подвал");

   ТабДок.Очистить();

   ВставлятьРазделительСтраниц = Ложь;
   Пока Выборка.Следующий() Цикл
       Если ВставлятьРазделительСтраниц Тогда
           ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
       КонецЕсли;

       ТабДок.Вывести(ОбластьЗаголовок);

       Шапка.Параметры.Заполнить(Выборка);
       ТабДок.Вывести(Шапка, Выборка.Уровень());

       ТабДок.Вывести(ОбластьТабличнаяЧасть1Шапка);
       ВыборкаТабличнаяЧасть1 = Выборка.ТабличнаяЧасть1.Выбрать();
       Пока ВыборкаТабличнаяЧасть1.Следующий() Цикл
           ОбластьТабличнаяЧасть1.Параметры.Заполнить(ВыборкаТабличнаяЧасть1);
           ТабДок.Вывести(ОбластьТабличнаяЧасть1, ВыборкаТабличнаяЧасть1.Уровень());
       КонецЦикла;

       Подвал.Параметры.Заполнить(Выборка);
       ТабДок.Вывести(Подвал);

       ВставлятьРазделительСтраниц = Истина;
   КонецЦикла;
   //}}
КонецПроцедуры
14 Cray12
 
04.11.12
17:10
Ну, это уже явно ближе к решению, и я, похоже, снова неправильно выразился.
При использовании этого кода получается вот это:

http://rghost.ru/41340182

Удивляет даже не то, что таб часть пустая, а то, что записей 26, а должно быть 28. Вот этого я совсем не понял.
И еще я не понял несколько строк. Например, область "Заголовок" (на самом деле, "ЗаколовокТаблицы", но этого на скрине не видно, тут я налажал) - это и есть шапка таблицы, поэтому я не очень понял, зачем ты просто ее вывел.
Но это все легко можно доработать, в основном меня волнует, почему таб часть не заполняется, как создать столько таблиц, сколько всего договоров и как имена договоров выводить перед таблицами, вот там область для этого, а как ее заполнить - я так и не понял

http://rghost.ru/41320166

Но в целом огромное спасибо за то, что уже сделал для меня. Я уже совсем запутался.
15 zak555
 
04.11.12
17:44
открой для себя конструктор печати
16 Cray12
 
04.11.12
18:37
Да сроки поджимают, чтобы что-то открывать
17 zak555
 
05.11.12
00:55
какие сроки ?
это кнопка
18 Cray12
 
05.11.12
01:21
С ней еще разбираться надо, а времени на самообучение нет пока
19 Cray12
 
05.11.12
15:20
Все в твоем коде было в порядке, просто в макете параметры названы не совсем правильно, поэтому "Параметры.Заполнить" не работало. Но когда я чуть-чуть поменял код:

ОбластьШапка                = Макет.ПолучитьОбласть("Шапка");
   ОбластьДоговор                = Макет.ПолучитьОбласть("Договор");
   ОбластьТабличнаяЧасть1Шапка = Макет.ПолучитьОбласть("ЗаголовокТаблицы");
   ОбластьТабличнаяЧасть1        = Макет.ПолучитьОбласть("Строка");
   ОбластьПодвал                = Макет.ПолучитьОбласть("Подвал");
   ОбластьПодвал1                = Макет.ПолучитьОбласть("Подвал1");

   ТабДок.Очистить();
   
   ОбластьШапка.Параметры.Период              = Строка(Формат(Дата_От, "ДЛФ = Д") + " - " + Формат(Дата_До, "ДЛФ = Д"));
   ОбластьШапка.Параметры.Организация          = Организация;
   ОбластьШапка.Параметры.Вид                  = Строка(ПолучитьСкидку(Договоры)) + "%";
   ОбластьШапка.Параметры.Контрагент          = Контрагенты;
   ОбластьШапка.Параметры.ДоговорКонтрагента = Договоры;
   ТабДок.Вывести(ОбластьШапка);

   ВставлятьРазделительСтраниц = Ложь;
   Пока Выборка.Следующий() Цикл
       Если ВставлятьРазделительСтраниц Тогда
           ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
       КонецЕсли;
       
       ОбластьДоговор.Параметры.Договор = Выборка.Договоры;
       ТабДок.Вывести(ОбластьДоговор);
       
       ТабДок.Вывести(ОбластьТабличнаяЧасть1Шапка);
       ВыборкаТабличнаяЧасть1 = Выборка.ТабличнаяЧасть1.Выбрать();
       
       ИтогоСуммаПоНУ = 0;
       ИтогоСуммаПоДоговору = 0;

       Пока ВыборкаТабличнаяЧасть1.Следующий() Цикл
           ОбластьТабличнаяЧасть1.Параметры.Значение1 = ВыборкаТабличнаяЧасть1.Период;
           ОбластьТабличнаяЧасть1.Параметры.Значение2 = ВыборкаТабличнаяЧасть1.СуммаКредита;
           ОбластьТабличнаяЧасть1.Параметры.Значение3 = ВыборкаТабличнаяЧасть1.СтавкаПоДоговору;
           ОбластьТабличнаяЧасть1.Параметры.Значение4 = ВыборкаТабличнаяЧасть1.СуммаПоДоговору;
           ОбластьТабличнаяЧасть1.Параметры.Значение5 = ВыборкаТабличнаяЧасть1.СтавкаЦБ;
           ОбластьТабличнаяЧасть1.Параметры.Значение6 = ВыборкаТабличнаяЧасть1.Коэффициент;
           ОбластьТабличнаяЧасть1.Параметры.Значение7 = ВыборкаТабличнаяЧасть1.СуммаПоНУ;
           
           ИтогоСуммаПоНУ         = ИтогоСуммаПоНУ + ВыборкаТабличнаяЧасть1.СуммаПоНУ;
           ИтогоСуммаПоДоговору = ИтогоСуммаПоДоговору + ВыборкаТабличнаяЧасть1.СуммаПоДоговору;
           ТабДок.Вывести(ОбластьТабличнаяЧасть1, ВыборкаТабличнаяЧасть1.Уровень());
       КонецЦикла;

         ОбластьПодвал.Параметры.ИтогоСуммаПоДоговору = ИтогоСуммаПоДоговору;
       ОбластьПодвал.Параметры.ИтогоСуммаПоНУ         = ИтогоСуммаПоНУ;
       ТабДок.Вывести(ОбластьПодвал);

       ВставлятьРазделительСтраниц = Истина;
   КонецЦикла;
   
   ОбластьПодвал1.Параметры.Статья           = СубконтоДляСчета91;
   
   Если Флажок2 = Истина Тогда
       ОбластьПодвал1.Параметры.Порядок = "Со следующего дня";
   Иначе
       ОбластьПодвал1.Параметры.Порядок = "С первого дня";
   КонецЕсли;
   
   Если ПроцентНУ <> 0 Тогда
       ОбластьПодвал1.Параметры.ИзмененияСтавкиЦБ = Строка(ПроцентНУ) + "%";
   КонецЕсли;
   ОбластьПодвал1.Параметры.Должность           = ДолжностьОтветственного;
   ОбластьПодвал1.Параметры.Ответственный       = Ответственный;
   ОбластьПодвал1.Параметры.ДатаОтчета       = ТекущаяДата();
   
   ТабДок.Вывести(ОбластьПодвал1);
   //}}
   
   ТабДок.Показать();

Получилось так, что он не берет договор в выборке. То есть через отладчик поле "Договоры" у выборки просто пустое.
А из-за этого таб. часть всего одна и заголовка у нее нет:

http://rghost.ru/41360130

А я создал еще один договор и не указал его, чтобы проверить.
Главное, что обидно, я в коде уже почти разобрался, только условия в запросе не понял. И думал, что все сработает, ан нет. Помоги, пожалуйста, zak.
20 Cray12
 
05.11.12
15:22
Вот еще, на всякий случай:

http://rghost.ru/41360200
21 Cray12
 
05.11.12
15:26
Аааа, я понял. Если договор не указан, то запрос обращается к реквизиту документа "Договоры", а он пустой, т.к. значение попросту не выбрано. Логично, что не работает. Ладно, тут есть прогресс, буду думать
22 Cray12
 
05.11.12
16:37
Слушай, zak, у меня еще вопрос.
Вот есть таб. часть, в ней есть договоры:

http://rghost.ru/41361635

Я подумал взять их оттуда, тем более, что все равно работаю с таб. частью. Но тут встал такой вопрос: а как взять все договоры только по одному разу?
То есть, в этой таб. части, например, 2 договора, а строк всего 90. Я попытался как-то так:

ВспомогательныйМассив = Новый Массив;
       МассивДоговоров      = Новый Массив;
       
       Пока ВыборкаТабличнаяЧасть1.Следующий() Цикл
           ВспомогательныйМассив.Добавить(ВыборкаТабличнаяЧасть1.Договор);                
       КонецЦикла;
       
       Для Инд = 0 По ВспомогательныйМассив.Количество() Цикл
           Для Инд1 = Инд + 1 По ВспомогательныйМассив.Количество() Цикл
               Для Инд2 = 0 По МассивДоговоров.Количество() Цикл
                   Если ВспомогательныйМассив[Инд] <> ВспомогательныйМассив[Инд1] И ВспомогательныйМассив[Инд1] <> МассивДоговоров[Инд2] Тогда
                       МассивДоговоров.Добавить(ВспомогательныйМассив[Инд1]);
                   КонецЕсли;
               КонецЦикла;
           КонецЦикла;
       КонецЦикла;

Да, сложно, где не надо, но я пытался и еще сложнее, и все равно не удалось. Ты не поможешь?
23 Cray12
 
05.11.12
16:37
То есть вот так, я не совсем то скинул:

ВспомогательныйМассив = Новый Массив;
       МассивДоговоров      = Новый Массив;
       
       Пока ВыборкаТабличнаяЧасть1.Следующий() Цикл
           ВспомогательныйМассив.Добавить(ВыборкаТабличнаяЧасть1.Договор);                
       КонецЦикла;
       
       Для Инд = 0 По ВспомогательныйМассив.Количество() Цикл
           Для Инд1 = Инд + 1 По ВспомогательныйМассив.Количество() Цикл
               Для Инд2 = 0 По МассивДоговоров.Количество() Цикл
                   Если ВспомогательныйМассив[Инд] <> ВспомогательныйМассив[Инд1]
                       МассивДоговоров.Добавить(ВспомогательныйМассив[Инд1]);
                   КонецЕсли;
               КонецЦикла;
           КонецЦикла;
       КонецЦикла;
24 Cray12
 
05.11.12
16:43
Для Инд1 = Инд + 1 По ВспомогательныйМассив.Количество() Цикл

В этой строчке "+1" не надо
25 Cray12
 
05.11.12
16:48
И получается массив с 2025 элементами. Вот в такие моменты и понимаешь, что работает код не совсем так, как планировалось...
26 Cray12
 
05.11.12
16:58
А такой код:

ВспомогательныйМассив = Новый Массив;
       МассивДоговоров      = Новый Массив;
       
       Пока ВыборкаТабличнаяЧасть1.Следующий() Цикл
           ВспомогательныйМассив.Добавить(ВыборкаТабличнаяЧасть1.Договор);                
       КонецЦикла;
       
       МассивДоговоров.Добавить(ВспомогательныйМассив[0]);
       
       Для Инд = 0 По ВспомогательныйМассив.Количество() - 1 Цикл
           Для Инд1 = 0 По МассивДоговоров.Количество() - 1 Цикл
               Если ВспомогательныйМассив[Инд] <> МассивДоговоров[Инд1] Тогда
                   МассивДоговоров.Добавить(ВспомогательныйМассив[Инд]);
               КонецЕсли;
           КонецЦикла;
       КонецЦикла;

Дал всего 46 элементов. А надо бы два...
Черт, все же вроде нормально.
27 Cray12
 
05.11.12
17:08
Нет, не правильно =/
Нашел ошибку, но новые идеи вообще не идут. Вроде и ситуация несложная, а я вот заступорился. А в эту тему вообще еще кто-нибудь заглядывает, интересно?
28 Cray12
 
05.11.12
17:15
О, нашел функцию Выбрать различные. Кажись, то, что надо.
Я не хочу быть самым богатым человеком на кладбище. Засыпать с чувством, что за день я сделал какую-нибудь потрясающую вещь — вот что меня интересует. Стив Джобс