Имя: Пароль:
1C
 
v8: Вопрос про Пакетный Режим запросов (выполнение Запроса в цикле)
0 nop
 
04.12.08
16:07
Результатом будет 1 таблица?
1 Mitriy
 
04.12.08
16:08
а сколько надо?
2 Fragster
 
гуру
04.12.08
16:09
нет
3 GenV
 
04.12.08
16:09
(0) Результат берется из последнего запроса с выборкой
4 nop
 
04.12.08
16:09
(1) столько отдельных таблиц, сколько запросов в пакете
5 Mitriy
 
04.12.08
16:10
(4) не взлетит, не для ентого енто...
6 nop
 
04.12.08
16:10
(3) где можно почитать, посмотреть примеры?
7 NULLL
 
04.12.08
16:11
Зависит от метода, которым выполнять запрос. Их два: Выполнить() и ВыполнитьПакет().
8 nop
 
04.12.08
16:12
(7) О! ВыполнитьПакет() - это похоже то что надо
9 GenV
 
04.12.08
16:14
(7) Точно. Давно я в AddDoc не заглядывал.
10 nop
 
04.12.08
16:22
можно простенький пример текста запроса?
11 nop
 
04.12.08
16:26
ап
12 AquaKosh
 
04.12.08
16:33
13 nop
 
04.12.08
16:50
(12) очень хорошая статья. Спасибо
14 Мелкий бес
 
04.12.08
16:58
добавлю:
1. использование МассиваРезультатов
МассивРезультатовЗапроса = Запрос.ВыполнитьПакет();
Если МассивРезультатовЗапроса[1].Пустой() Тогда
  ЧтоТо = МассивРезультатовЗапроса[2].Выгрузить().ВыгрузитьКолонку("ЧтоТо");
Иначе
  ТоТо = МассивРезультатовЗапроса[3].Выгрузить().ВыгрузитьКолонку("ТоТо");
КонецЕсли
2. в конце запроса всегда помнить о    УНИЧТОЖИТЬ ИмяВременнойТаблицы
15 AquaKosh
 
04.12.08
17:02
(13) Навеяно (14): Если не чистить за собой временные таблицы (или через менеджер временных таблиц, или непосредственно через УНИЧТОЖИТЬ), то в консоли сервера 1С будет висеть занятость базы SQL, как будто выполняется запрос (в серверном варианте, конечно).
16 Mitriy
 
04.12.08
17:02
(7) млин... тож пасиб :)
17 nop
 
04.12.08
17:10
у меня такая ситуация: текст запроса меняется в цикле и нужно получить результаты каждого из них. ВыполнитьПакет() не подойдет?
18 Fragster
 
гуру
04.12.08
17:12
(17) запихать все в 1 пакетный запрос через ";"... виды документов обходишь? объедини их в журнал... правда с блокировками возникнут косяки, если нагрузка большая...
19 Мелкий бес
 
04.12.08
17:12
1. возможно в тексте запроса есть постоянная часть и есть переменная часть
постоянную часть вынести во временную таблицу и в использовать ее в цикле
2. если цикл не бесконечный, то можно собрать пакетный запрос и выполнить его один раз. а потом в цикле просматривать результаты
20 nop
 
04.12.08
17:13
(18) вот пример

       "ВЫБРАТЬ
       |    ХозрасчетныйДвиженияССубконто.СубконтоКт1 КАК СубконтоКт1,
       |    ХозрасчетныйДвиженияССубконто.СубконтоКт2 КАК СубконтоКт2,
       |    СУММА(ХозрасчетныйДвиженияССубконто.КоличествоКт) КАК КоличествоКт,
       |    СУММА(ХозрасчетныйДвиженияССубконто.Сумма) КАК Сумма
       |ИЗ
       |    РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто(&ДатаНач, &ДатаКон, Регистратор = &Регистратор) КАК ХозрасчетныйДвиженияССубконто
       |
       |СГРУППИРОВАТЬ ПО
       |    ХозрасчетныйДвиженияССубконто.СубконтоКт1,
       |    ХозрасчетныйДвиженияССубконто.СубконтоКт2";
21 AquaKosh
 
04.12.08
17:14
(17) Дык зависит от методики построения...
Если используется ПАКЕТНЫЙ запрос, т.е. в одном тексте запроса много запросов, которые делают временные таблицы (ПОМЕСТИТЬ врТаб), то тогда ВыполнитьПакет().
А если каждый запрос, который создаётся в цикле тут же выполняется, а потом делается Выборка/Выгрузить, тогда Выполнить().
22 nop
 
04.12.08
17:15
(20) + грубо говоря мне надо выполнить этот запрос 2 раза: 1 раз по РегистрБухгалтерии.Хозрасчетный, 2ой - РегистрБухгалтерии.Управленческий и получить результаты обоих запросов, и вернуть их из функции в Соответствие (с ключами)

Функция ПолучитьСуммуСписанияАктивов().
23 nop
 
04.12.08
17:17
(21) Вот пока что я использую второй способ с циклом и Выполнить(). Где понятные запросы - переписываю под ОБЪЕДЕНИТЬ, СОЕДИНЕНИЕ. Иначе выполняю запрос в цикле.
Но есть мысль что с ВыполнитьПакет() производительность будет больше.
24 AquaKosh
 
04.12.08
17:19
(22) Так если всего два запроса, да ещё и по разным регистрам, да ещё и не срощенные вместе... зачем пакетный запрос? Обычные два запроса...
25 AquaKosh
 
04.12.08
17:20
(24) Не увидел 22... :)
26 nop
 
04.12.08
17:21
(24) ну потому что во первых надо разобраться с пакетным режимом, во вторых, по моему, будет все же немного быстрее, потому что текст передается серверу 1 раз, и результат будет возвращен 1 куском.
27 AquaKosh
 
04.12.08
17:27
(26) Не, затраты времени на передачу текста запроса по сравнению с временем выполнения оного - ничтожны, поэтому если два запроса по разным регистрам, то выигрыша, имхо, на глаз не заметить.
28 nop
 
04.12.08
17:28
(27) Возможно. Но для практики (понимания) сделаю с ВыполнитьПакет()
29 Живой Ископаемый
 
04.12.08
17:29
2(28) Главное сами тексты запросов в коде нужно разделить, а то констурктор будет хавать только последний запрос из пакета...
30 AquaKosh
 
04.12.08
17:30
(26) Лично я юзаю временные таблицы только в больших запросах, в которых есть более-менее одинаковые куски, перевод которых на временные таблицы даёт СУЩЕСТВЕННОЕ ускорение, т.к. запросы к регистрам делаются 1 раз, а дальше идёт юзанье уже временных таблиц.
31 nop
 
04.12.08
17:34
я вот не пойму из статьи:

"После выполнения запроса в переменную «МассивРезультатов» у нас попадет 3 элемента. Первые два будут содержать число характеризующее количество записей помещенных во временные таблицы ДокТЧ и СписокТоваров, а третий будет содержать выборку с полями «Номенклатура», «Док_Количество» и «Рег_Количество»."

Почему первые 2 будут содержать только число? Из-за слова ПОМЕСТИТЬ ?
32 Fragster
 
гуру
04.12.08
17:35
(23) лучше через "Объединить Все" делай - оно у тебя сразу одну таблицу вернет
33 AquaKosh
 
04.12.08
17:37
(31) Эм... Не я автор и, честно говоря, уже не помню подробности... Сейчас почитаю...
ПОМЕСТИТЬ - это признак того, что требуется создать виртуальную таблицу.
34 AquaKosh
 
04.12.08
17:44
(31) Вот описание ВыполнитьПакет() из СП:
Запрос (Query)
ВыполнитьПакет (ExecuteBatch)
Синтаксис:
ВыполнитьПакет()
Возвращаемое значение:
Тип: Массив.
Описание:
Последовательно выполняет все запросы и возвращает массив результатов для каждого запроса из пакета. Результаты помещаются в массив в последовательности расположения запросов в тексте пакета. Результатом выполнения запроса на уничтожение временной таблицы является значение Неопределено, которое также помещается в массив результатов.

Верить, соответственно, лучше СП. :)
35 Живой Ископаемый
 
04.12.08
17:45
+(34) стопроцентов - так и есть
36 AquaKosh
 
04.12.08
17:57
(31) Посмотри ещё про "МенеджерВременныхТаблиц" у запроса. Иногда его очень удобно использовать.
37 nop
 
04.12.08
17:59
(36) это просто оболочка что бы помещать в неё запросы и иметь доступ к временным талицам?
38 AquaKosh
 
04.12.08
18:05
(36) Ну типа того. Но у этой фишки есть плюс: текст запроса не обязательно должен включать сразу все временные таблицы, т.е. можно ОДНОМУ И ТОМУ ЖЕ экземпляру объекта ЗАПРОС, передавать различные тексты и выполнять их (через Выполнить()) сколько угодно раз - менеджер будет запоминать эти временные таблицы и по ним ПОЗЖЕ можно будет строить запросы, например если на данный момент не известны какие-либо параметры или ещё чего...
39 nop
 
04.12.08
18:11
вот что было
-----------------

Функция ПолучитьСуммуСписанияАктивов(ТекДокумент, ВидУчета = Неопределено) Экспорт
   
   
   ПроводкиДокумента = Новый ТаблицаЗначений;
   ПроводкиДокумента.Колонки.Добавить("Номенклатура");
   ПроводкиДокумента.Колонки.Добавить("Количество");
   ПроводкиДокумента.Колонки.Добавить("Сумма");
   ТаблицаСуммСписания = Новый ТаблицаЗначений;
   ТаблицаСуммСписания.Колонки.Добавить("Номенклатура");
   ТаблицаСуммСписания.Колонки.Добавить("Количество");
   ТаблицаСуммСписания.Колонки.Добавить("Сумма");
   Если ТекДокумент.Проведен Тогда
       ТекстЗапроса =
       "ВЫБРАТЬ
       |    ХозрасчетныйДвиженияССубконто.СубконтоКт1 КАК СубконтоКт1,
       |    ХозрасчетныйДвиженияССубконто.СубконтоКт2 КАК СубконтоКт2,
       |    СУММА(ХозрасчетныйДвиженияССубконто.КоличествоКт) КАК КоличествоКт,
       |    СУММА(ХозрасчетныйДвиженияССубконто.Сумма) КАК Сумма
       |ИЗ
       |    РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто(&ДатаНач, &ДатаКон, Регистратор = &Регистратор) КАК ХозрасчетныйДвиженияССубконто
       |
       |СГРУППИРОВАТЬ ПО
       |    ХозрасчетныйДвиженияССубконто.СубконтоКт1,
       |    ХозрасчетныйДвиженияССубконто.СубконтоКт2";
       
       Запрос = Новый Запрос;
       Запрос.Текст = ТекстЗапроса;
       Запрос.УстановитьПараметр("ДатаНач", ТекДокумент.Дата);
       Запрос.УстановитьПараметр("ДатаКон", ТекДокумент.Дата);
       Запрос.УстановитьПараметр("Регистратор", ТекДокумент.Ссылка);
       
       
       ПроводкиДокумента = Запрос.Выполнить().Выгрузить();
       Для Каждого ПроводкаДокумента Из ПроводкиДокумента Цикл
           Если ТипЗнч(ПроводкаДокумента.СубконтоКт1) = Тип("СправочникСсылка.Номенклатура") Тогда
               Строка = ТаблицаСуммСписания.Добавить();
               Строка.Номенклатура = ПроводкаДокумента.СубконтоКт1;
               Строка.Количество   = ПроводкаДокумента.КоличествоКт;
               Строка.Сумма        = ПроводкаДокумента.Сумма;
           КонецЕсли;
           Если ТипЗнч(ПроводкаДокумента.СубконтоКт2) = Тип("СправочникСсылка.Номенклатура") Тогда
               Строка = ТаблицаСуммСписания.Добавить();
               Строка.Номенклатура = ПроводкаДокумента.СубконтоКт2;
               Строка.Количество   = ПроводкаДокумента.КоличествоКт;
               Строка.Сумма        = ПроводкаДокумента.Сумма;
           КонецЕсли;
       КонецЦикла;
       ТаблицаСуммСписания.Свернуть("Номенклатура","Количество,Сумма");
   КонецЕсли;
   
 Возврат  ТаблицаСуммСписания;
 
КонецФункции

-----------------
Вот что стало
-----------------

Функция ПолучитьСуммуСписанияАктивов(ТекДокумент, ВидУчета = Неопределено) Экспорт
   
   Если ВидУчета = Неопределено Тогда
       ВидУчета = ТекДокумент.мВУ;
   КонецЕсли;
   ВидУчета = ВидУчетаВМассивУчетов(ВидУчета);
   
   ТекстПакета = "";
   
   ПроводкиДокумента = Новый ТаблицаЗначений;
   ПроводкиДокумента.Колонки.Добавить("Номенклатура");
   ПроводкиДокумента.Колонки.Добавить("Количество");
   ПроводкиДокумента.Колонки.Добавить("Сумма");
   шТаблицаСуммСписания = Новый ТаблицаЗначений;
   шТаблицаСуммСписания.Колонки.Добавить("Номенклатура");
   шТаблицаСуммСписания.Колонки.Добавить("Количество");
   шТаблицаСуммСписания.Колонки.Добавить("Сумма");
   
   
   Если ТекДокумент.Проведен Тогда
       Для каждого ву из ВидУчета Цикл
           
           ТекстЗапроса =
           "ВЫБРАТЬ
           |    %%ПланСчетов%%ДвиженияССубконто.СубконтоКт1 КАК СубконтоКт1,
           |    %%ПланСчетов%%ДвиженияССубконто.СубконтоКт2 КАК СубконтоКт2,
           |    СУММА(%%ПланСчетов%%ДвиженияССубконто.КоличествоКт) КАК КоличествоКт,
           |    СУММА(%%ПланСчетов%%ДвиженияССубконто.Сумма) КАК Сумма
           |ИЗ
           |    РегистрБухгалтерии.%%ПланСчетов%%.ДвиженияССубконто(&ДатаНач, &ДатаКон, Регистратор = &Регистратор) КАК %%ПланСчетов%%ДвиженияССубконто
           |
           |СГРУППИРОВАТЬ ПО
           |    %%ПланСчетов%%ДвиженияССубконто.СубконтоКт1,
           |    %%ПланСчетов%%ДвиженияССубконто.СубконтоКт2
           |";
           
           ТекстЗапроса = ОбработатьШаблонЗапроса(ТекстЗапроса, ву);            
           ТекстПакета = ТекстПакета + ";"+ Символы.ПС +ТекстЗапроса;
       КонецЦИкла;
       
       Запрос = Новый Запрос;
       Запрос.Текст = ТекстПакета;
       Запрос.УстановитьПараметр("ДатаНач", ТекДокумент.Дата);
       Запрос.УстановитьПараметр("ДатаКон", ТекДокумент.Дата);
       Запрос.УстановитьПараметр("Регистратор", ТекДокумент.Ссылка);

       
       мРез = Запрос.ВыполнитьПакет();
       Рез = Новый Соответствие;
       
       шаг = 0;
       Для каждого ву из ВидУчета Цикл
           ПроводкиДокумента = мРез[шаг].Выгрузить();
           ТаблицаСуммСписания = Новый  ТаблицаЗначений;
           ТаблицаСуммСписания = шТаблицаСуммСписания.СкопироватьКолонки();
           
           Для Каждого ПроводкаДокумента Из ПроводкиДокумента Цикл
               Если ТипЗнч(ПроводкаДокумента.СубконтоКт1) = Тип("СправочникСсылка.Номенклатура") Тогда
                   Строка = ТаблицаСуммСписания.Добавить();
                   Строка.Номенклатура = ПроводкаДокумента.СубконтоКт1;
                   Строка.Количество   = ПроводкаДокумента.КоличествоКт;
                   Строка.Сумма        = ПроводкаДокумента.Сумма;
               КонецЕсли;
               Если ТипЗнч(ПроводкаДокумента.СубконтоКт2) = Тип("СправочникСсылка.Номенклатура") Тогда
                   Строка = ТаблицаСуммСписания.Добавить();
                   Строка.Номенклатура = ПроводкаДокумента.СубконтоКт2;
                   Строка.Количество   = ПроводкаДокумента.КоличествоКт;
                   Строка.Сумма        = ПроводкаДокумента.Сумма;
               КонецЕсли;
               
           КонецЦикла;
           
           ТаблицаСуммСписания.Свернуть("Номенклатура","Количество,Сумма");
           Рез.Вставить(ву.ВидУчета, ТаблицаСуммСписания);
       КонецЦикла;        
   КонецЕсли;
   
   Если рез.Количество() = 1 и ВидУчета.Количество() = 1 Тогда
       Для каждого х из рез Цикл
           рез = х.Значение;
       КонецЦикла;
   КонецЕсли;
   
   Возврат  Рез;
КонецФункции
40 AquaKosh
 
04.12.08
18:18
(39) Ох, ё.... А где переносы? :))
41 nop
 
04.12.08
18:19
(40) О_О какие переносы? Пост криво отображается?
42 AquaKosh
 
04.12.08
18:23
(39) После беглого осмотра того, что СТАЛО, скажу вот что: я не знаю, сколько видов учёта, но это будет ОЧЕНЬ медленно, т.к. у тебя, предположительно, туча однотипных запросов к одному регистру.
Лучше сделай так: создай ОДИН запрос к ОДНОМУ регистру с минимальным отбором и помести его во временную таблицу + про индекс на вид учёта не забудь. А далее выбирай данные уже из этой виртуальной таблицы, накладывая отбор по виду учёта.
43 AquaKosh
 
04.12.08
18:24
(41) У меня 39-ый пост отобразился одной ОООООЧЕНЬ длинной строкой.
44 nop
 
04.12.08
18:26
(43) а щас?
45 AquaKosh
 
04.12.08
18:27
+ к (42): у тебя там ещё отбор по регистратору? Хм... Его тоже в индекс.
46 AquaKosh
 
04.12.08
18:27
(44) О, сейчас ок.
47 nop
 
04.12.08
18:27
до завтра, надо бежать
48 Serg_1960
 
04.12.08
18:28
(0) Прочитал вопрос - понял, что ничего не понял :( Почитал ответы - понял, что ничего не знал :( Спасибо nop за "хороший" вопрос :)
49 nop
 
05.12.08
10:09
(48) :)
50 NULLL
 
05.12.08
10:34
(39) Посоветую на угад. Я бы это выполнял в запросе:

Если ТипЗнч(ПроводкаДокумента.СубконтоКт1) = Тип("СправочникСсылка.Номенклатура") Тогда
               Строка = ТаблицаСуммСписания.Добавить();
               Строка.Номенклатура = ПроводкаДокумента.СубконтоКт1;
               Строка.Количество   = ПроводкаДокумента.КоличествоКт;
               Строка.Сумма        = ПроводкаДокумента.Сумма;
           КонецЕсли;
           Если ТипЗнч(ПроводкаДокумента.СубконтоКт2) = Тип("СправочникСсылка.Номенклатура") Тогда
               Строка = ТаблицаСуммСписания.Добавить();
               Строка.Номенклатура = ПроводкаДокумента.СубконтоКт2;
               Строка.Количество   = ПроводкаДокумента.КоличествоКт;
               Строка.Сумма        = ПроводкаДокумента.Сумма;
           КонецЕсли;
51 nop
 
05.12.08
10:36
(50) О_о как?
52 NULLL
 
05.12.08
10:39
Для опеределения типпа данных в запросе можна сипользовать логический оператор ССылка.
53 nop
 
05.12.08
10:45
(52) можно простой пример? Я вообще ничего не понял, что за оператор?
54 NULLL
 
05.12.08
10:50
ВЫБРАТЬ
           |    ДвиженияССубконто.СубконтоКт1 КАК СубконтоКт1,
           |    ДвиженияССубконто.СубконтоКт2 КАК СубконтоКт2,
           |    СУММА(ДвиженияССубконто.КоличествоКт) КАК КоличествоКт,
           |    СУММА(ДвиженияССубконто.Сумма) КАК Сумма
           |ИЗ
           |    РегистрБухгалтерии.%%ПланСчетов%%.ДвиженияССубконто(&ДатаНач, &ДатаКон, Регистратор = &Регистратор) КАК ДвиженияССубконто
           |
           |  где ДвиженияССубконто.СубконтоКт1 ССылка Справочник.Номенклатура ИЛИ  ДвиженияССубконто.СубконтоКт2 ССылка Справочник.Номенклатура
           |СГРУППИРОВАТЬ ПО
           |    ДвиженияССубконто.СубконтоКт1,
           |    ДвиженияССубконто.СубконтоКт2

И используйте псевдонимы.