Имя: Пароль:
1C
1С v8
Один запрос всегда лучше трех?
0 Мисти
 
09.03.14
11:02
У меня сначала находятся товары из накладных за период, они мне нужны вместе с количеством (запрос долго работает, перебор накладных быстрее, ну да ладно). Потом к списку товаров ищутся спецификации, они тоже нужны в явном виде, потом ищется номенклатура из спецификаций - в остатках, чтобы узнать себестоимость.
Есть вероятность, что в одном запросе это работало бы быстрее?
1 zak555
 
09.03.14
11:05
может тебе надо посмотреть, как делается разузлование ?
2 Сниф
 
09.03.14
11:06
Запрос долго работает, перебор накладных быстрее - у меня этот пункт вызывает смущение.
3 XLife
 
09.03.14
11:06
(0) >запрос долго работает, перебор накладных быстрее

враки
4 Сниф
 
09.03.14
11:10
Запрос даже как-то неудобно просить - вдруг там что-то личное?
5 Мисти
 
09.03.14
11:24
Вот вся история:
    ДокОтчет = Документы.ОтчетПроизводстваЗаСмену.ПустаяСсылка();    
    
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    РеализацияТоваровУслугТовары.Номенклатура КАК Номенклатура,
    |    РеализацияТоваровУслугТовары.Количество КАК Количество,
    |    РеализацияТоваровУслугТовары.Ссылка.Дата
    |ИЗ
    |    Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
    |ГДЕ
    |    РеализацияТоваровУслугТовары.Ссылка.Дата МЕЖДУ &ВыбНачПериода И &ВыбКонПериода
    |    И НЕ РеализацияТоваровУслугТовары.Ссылка.ПометкаУдаления
    |ИТОГИ
    |    СУММА(Количество)
    |ПО
    |    Номенклатура";
    
    Запрос.УстановитьПараметр("ВыбНачПериода", НачалоДня(ВыбНачПериода));
    Запрос.УстановитьПараметр("ВыбКонПериода", КонецДня(ВыбКонПериода));
    ЕстьСтроки = Ложь;
    ТабЗапрос = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Номенклатура");

    ДокОтчет = Документы.ОтчетПроизводстваЗаСмену.СоздатьДокумент();
        ДокОтчет.Дата = НачалоДня(ВыбНачПериода);
        ДокОтчет.Комментарий   = "Создан автоматически";
        ДокОтчет.Ответственный = Пользователи.ТекущийПользователь();
        ДокОтчет.ДляСписанияНДСиспользоватьСчетИАналитикуУчетаЗатрат = Истина;
        ДокОтчет.Организация = БухгалтерскийУчетПереопределяемый.ПолучитьЗначениеПоУмолчанию("ОсновнаяОрганизация");
        ДокОтчет.Склад       = БухгалтерскийУчетПереопределяемый.ПолучитьЗначениеПоУмолчанию("ОсновнойСклад");
        //ДокОтчет.ПодразделениеОрганизации = БухгалтерскийУчетПереопределяемый.ПолучитьЗначениеПоУмолчанию("ОсновноеПодразделениеОрганизации");
        Пока ТабЗапрос.Следующий() Цикл
            ЕстьСтроки = Истина;
            НоваяСтрока                  = ДокОтчет.Продукция.Добавить();
            НоваяСтрока.Счет             = ПланыСчетов.Хозрасчетный.НайтиПоКоду("43");
            НоваяСтрока.Номенклатура     = ТабЗапрос.Номенклатура;
            НоваяСтрока.Количество       = ТабЗапрос.Количество;
            НоваяСтрока.НоменклатурнаяГруппа = НоваяСтрока.Номенклатура.НоменклатурнаяГруппа;
            НоваяСтрока.ЕдиницаИзмерения =   НоваяСтрока.Номенклатура.ЕдиницаИзмерения;
        КонецЦикла;
        
    Если ЕстьСтроки Тогда
        ДокОтчет.Записать();
    КонецЕсли;
    СписокНомен = ДокОтчет.Продукция.Выгрузить(,"Номенклатура");
    ЗапросПоСпецификациям = Новый Запрос;
    ЗапросПоСпецификациям.Текст =
    "ВЫБРАТЬ
    |    СпецификацииНоменклатурыИсходныеКомплектующие.Номенклатура,
    |    СпецификацииНоменклатурыИсходныеКомплектующие.Количество,
    |    СпецификацииНоменклатурыИсходныеКомплектующие.Ссылка,
    |    СпецификацииНоменклатурыИсходныеКомплектующие.Ссылка.Владелец
    |ИЗ
    |    Справочник.СпецификацииНоменклатуры.ИсходныеКомплектующие КАК СпецификацииНоменклатурыИсходныеКомплектующие
    |ГДЕ
    |    СпецификацииНоменклатурыИсходныеКомплектующие.Ссылка.Владелец В(&СписокНомен)
    |    И СпецификацииНоменклатурыИсходныеКомплектующие.Ссылка.ПометкаУдаления = &Ложь";
    ЗапросПоСпецификациям.УстановитьПараметр("СписокНомен", СписокНомен);
    ЗапросПоСпецификациям.УстановитьПараметр("Ложь", Ложь);
    СписокСпецификаций =  ЗапросПоСпецификациям.Выполнить().Выгрузить();
    ТаблицаМат = Новый ТаблицаЗначений;
    ТаблицаМат.Колонки.Добавить("НоменклатураВладелец");
    ТаблицаМат.Колонки.Добавить("КоличествоВладелец");
    ТаблицаМат.Колонки.Добавить("Номенклатура"); // Это материал
    ТаблицаМат.Колонки.Добавить("Количество");
    ТаблицаМат.Колонки.Добавить("НоменклатурнаяГруппа");
    ТаблицаМат.Колонки.Добавить("СебестоимостьЕд");
    ТаблицаМат.Колонки.Добавить("Себестоимость");
    Для каждого СтрПрод из ДокОтчет.Продукция Цикл
        СтрокиСпец = СписокСпецификаций.НайтиСтроки(Новый Структура ("Владелец",СтрПрод.Номенклатура));
        Если СтрокиСпец.Количество()>0 Тогда
            СтрПрод.Спецификация = СтрокиСпец[0].ссылка;
            Для ии = 0 по СтрокиСпец.Количество()-1 Цикл
                Если  (СтрПрод.Спецификация = СтрокиСпец[ии].ссылка)и(СтрокиСпец[ии].Количество>0) Тогда
                    СтрТаблицаМат = ТаблицаМат.Добавить();
                    СтрТаблицаМат.Номенклатура = СтрокиСпец[ии].Номенклатура;
                    СтрТаблицаМат.Количество   = СтрокиСпец[ии].Количество;
                    СтрТаблицаМат.НоменклатурнаяГруппа = СтрПрод.Номенклатура.НоменклатурнаяГруппа;
                    СтрТаблицаМат.НоменклатураВладелец =  СтрПрод.Номенклатура;
                    СтрТаблицаМат.КоличествоВладелец   = СтрПрод.Количество;
                КонецЕсли;
                                
            КонецЦикла;
        КонецЕсли;
    КонецЦикла;
    ТабПром = ТаблицаМат.Скопировать();
    ТабПром.Свернуть("Номенклатура","Количество");
    СписокМат = ТабПром.ВыгрузитьКолонку("Номенклатура");
    ЗапросПоМат = Новый Запрос;
    ЗапросПоМат.Текст =
    "ВЫБРАТЬ
    |    ХозрасчетныйОстатки.Счет,
    |    ХозрасчетныйОстатки.Субконто1,
    |    ХозрасчетныйОстатки.СуммаОстатокДт,
    |    ХозрасчетныйОстатки.КоличествоОстатокДт
    |ИЗ
    |    РегистрБухгалтерии.Хозрасчетный.Остатки(&ВыбКонПериода, Счет = &ВыбСчет, ,Субконто1 В (&СписокМат)) КАК ХозрасчетныйОстатки"; //    
    ЗапросПоМат.УстановитьПараметр("ВыбКонПериода", КонецДня(ВыбКонПериода));
    ЗапросПоМат.УстановитьПараметр("СписокМат", СписокМат);
    ЗапросПоМат.УстановитьПараметр("ВыбСчет", ПланыСчетов.Хозрасчетный.СырьеИМатериалы);
    РезультатМат = ЗапросПоМат.Выполнить().Выгрузить();
    
    Для каждого СтрМат из ТаблицаМат Цикл
        СтрокиМат = РезультатМат.НайтиСтроки(Новый Структура ("Субконто1",СтрМат.Номенклатура));
        Если СтрокиМат.Количество()>0 Тогда
            Если СтрокиМат[0].КоличествоОстатокДт<>0 Тогда
                СтрМат.СебестоимостьЕд = СтрокиМат[0].СуммаОстатокДт/СтрокиМат[0].КоличествоОстатокДт;
            Иначе
                СтрМат.СебестоимостьЕд = 0;
            КонецЕсли;
        Иначе
            СтрМат.СебестоимостьЕд = 0;
        КонецЕсли;
    СтрМат.Себестоимость = СтрМат.СебестоимостьЕд*СтрМат.Количество*СтрМат.КоличествоВладелец;    
    КонецЦикла;
    ТабПром = ТаблицаМат.Скопировать();
    ТабПром.Свернуть("Номенклатура,НоменклатурнаяГруппа","Количество,Себестоимость");
    ДокОтчет.Материалы.Загрузить(ТабПром);
    Для каждого СтрМат из ДокОтчет.Материалы Цикл
           СтрМат.ЕдиницаИзмерения = СтрМат.Номенклатура.ЕдиницаИзмерения;
           СтрМат.Счет = ПланыСчетов.Хозрасчетный.СырьеИМатериалы;
    КонецЦикла;
    ТабПром = ТаблицаМат.Скопировать();
    ТабПром.Свернуть("НоменклатураВладелец","Себестоимость");
    Для каждого СтрПрод из ДокОтчет.Продукция Цикл
        СтрокиСпец = ТабПром.НайтиСтроки(Новый Структура ("НоменклатураВладелец",СтрПрод.Номенклатура));
        Если СтрокиСпец.Количество()>0 Тогда
            СтрПрод.ПлановаяСтоимость = СтрокиСпец[0].Себестоимость/СтрПрод.Количество;
            СтрПрод.СуммаПлановая = СтрокиСпец[0].Себестоимость;
        КонецЕсли;
    КонецЦикла;
    ДокОтчет.Записать();
    СтрВозврата = Новый Структура;
    СтрВозврата.Вставить("Док",ДокОтчет.Ссылка);
    Возврат(СтрВозврата);
6 Мисти
 
09.03.14
11:24
Долго работает только первая честь, всё остальное быстро.
7 zak555
 
09.03.14
11:25
(5) упп ?
8 ДенисЧ
 
09.03.14
11:26
Так как называется, говорите, франч?
9 Мимохожий Однако
 
09.03.14
11:27
Пакетным запросом пробовала? Теория отвечает просто - сервер надо трясти пореже. Поэтому один запрос лучше, чем три на ту же тему.
10 Мисти
 
09.03.14
11:27
бухгалтерия 3.0
11 Мисти
 
09.03.14
11:28
Про теорию я знаю! Но если разница в доли секунды, то не вижу смысла - так-то писать гораздо легче.
Не представляю себе, как это всё упихнуть в один.
12 Мимохожий Однако
 
09.03.14
11:28
Регистры придумали для того, чтобы не трясти документы от царя Гороха.
13 Мимохожий Однако
 
09.03.14
11:29
Зачем учитывать не проведенные документы?
14 m-serg74
 
09.03.14
11:32
(12) реализации в регистры не пишут уже? или не проведенные нужны?
15 m-serg74
 
09.03.14
11:32
(12) сорри... к (10) писал
16 Мисти
 
09.03.14
11:32
Именно в этом идея. Накладные выписываются по сути вместо заявок, потом делают выпуск продукции, потом уже отгрузку на основании этого выпуска.
Трясем не от царя гороха, а за один день обычно.
17 XLife
 
09.03.14
11:33
(5)
1. зачем тебе непроведенные документы?
2. зачем тебе итоги?
3. вместо "Пока ТабЗапрос.Следующий() Цикл" сделать ДокОтчет.Продукция.Загрузить(Запрос.Выполнить().Выгрузить()); недостающие поля вытянуть в запросе
18 Мисти
 
09.03.14
11:36
Непроведенные нужны.
Итоги - потому что иначе у меня одна и та же номенклатура встречалась 10 раз.
3. Наверное, можно, но так нагляднее. Это влияет на скорость?
19 m-serg74
 
09.03.14
11:37
(18) сгруппировать тогда может
20 XLife
 
09.03.14
11:37
(18) 2. про группировку не слышала?

а вот за это надо сразу увольнять

    |    И СпецификацииНоменклатурыИсходныеКомплектующие.Ссылка.ПометкаУдаления = &Ложь";
    ЗапросПоСпецификациям.УстановитьПараметр("Ложь", Ложь);
21 Sj
 
09.03.14
11:38
Ага!

В цикле
    НоваяСтрока.Счет             = ПланыСчетов.Хозрасчетный.НайтиПоКоду("43");

Вот это
Если ЕстьСтроки Тогда
        ДокОтчет.Записать();
    КонецЕсли;

=
Если Докотчет.товары.количество() тогда

Да и ДокОтчет.Записать() есть в самом конце.
22 Мисти
 
09.03.14
11:40
|    И  Не СпецификацииНоменклатурыИсходныеКомплектующие.Ссылка.ПометкаУдаления"; ?
23 Мисти
 
09.03.14
11:40
Да и ДокОтчет.Записать() есть в самом конце. - это уже поправила.
24 XLife
 
09.03.14
11:41
(22) уже лучше)
25 Мисти
 
09.03.14
11:41
НоваяСтрока.Счет             = ПланыСчетов.Хозрасчетный.ГотоваяПродукция; - а так?
26 Kookish
 
09.03.14
11:41
(20) Вы не поверите, но я такой код нашел в штатной бухгалтерии 3.0. Форма документа УстановкаЦенНоменклатуры, процедура ЗаполнитьТоварыСервер. :)
27 Мисти
 
09.03.14
11:42
(24) Только вчера в книжке именно так прочитала!
28 XLife
 
09.03.14
11:43
(25) сделай через объявление переменной перед циклом
29 Лаврентий Берия
 
09.03.14
11:43
(0) Всё равно в трейсере SQL Server'а надо смотреть.
30 zak555
 
09.03.14
11:44
(26) действительно
31 m-serg74
 
09.03.14
11:44
(25) а однажды заполнить и потом использовать
[Справочник.Номенклатура.Реквизит.ОсновнаяСпецификацияНоменклатуры]

не предлагать?
32 Sj
 
09.03.14
11:44
(25) см (17) п. 3 - в запросе сразу вытягивать все требуемые поля, чтобы через точку ничего не было.
33 Мисти
 
09.03.14
11:45
(28) Вот прямо принципиально что-то изменится?
34 m-serg74
 
09.03.14
11:46
(33) - (31) глянь
35 XLife
 
09.03.14
11:47
(33) карма повысится
36 Мисти
 
09.03.14
11:48
(31)а однажды заполнить и потом использовать  - счет??
У них почему-то не выбрана как основная.
37 Мисти
 
09.03.14
11:50
(19) Чем сгруппировать лучше, чем итоги?
Почему за "Ложь = Ложь" увольнять, если так в книжке и на скорость не влияет?
38 Мисти
 
09.03.14
11:50
Вы пишите! Я попробую перестроиться. Надо же, чтоб хоть простой код не приводил в ужас программистов.
39 Kookish
 
09.03.14
11:53
(37) http://lurkmore.to/Индусский_код
40 m-serg74
 
09.03.14
11:53
(36) так заполни...
что значит "счет??"

и номенклатура + количество предлагаю брать из проводок 90 - 4101
41 m-serg74
 
09.03.14
11:54
(37) гораздо лучше... просто поверь
42 m-serg74
 
09.03.14
11:55
(18) [Непроведенные нужны]

зачем?
43 Sj
 
09.03.14
11:55
(40) документы могут быть не проведены.
44 m-serg74
 
09.03.14
11:56
(43) - (42) ???
45 XLife
 
09.03.14
11:57
(37) >Чем сгруппировать лучше, чем итоги?

это разные вещи... в твоем случае надо именно группировать
46 Sj
 
09.03.14
11:57
(37) лучше сгруппировать.
47 Sj
 
09.03.14
11:58
(44) а я откуда знаю?  Это больше вопрос к (0).
48 m-serg74
 
09.03.14
11:59
(47) ну ты же (42) писал
49 m-serg74
 
09.03.14
11:59
а (0) на (42) молчит почему то
50 m-serg74
 
09.03.14
12:00
(48) извиняюсь (43) писал
51 zak555
 
09.03.14
12:09
(43) проведение это просто флаг
52 Мимохожий Однако
 
09.03.14
12:34
(51)Проведение не просто флаг, а  с методической точки зрения  - окончательное подтверждение завершения операций. При формировании документов на основании проведенных я бы добавил проверку на проведенные документы и если есть непроведенные за выбранный период, то отказ от дальнейших действий. Это прежде всего избавление от бомбы замедленного действия.
53 Мисти
 
09.03.14
12:35
Я уже 2 раза написала - обрабатываемые документы не проведены, для них моей программой готовится выпуск продукции, а после проведения выпуска будут проведены накладные.
54 Мисти
 
09.03.14
12:36
Напишите, как надо было сгруппировать  (и почему)
55 zak555
 
09.03.14
12:38
(52) надо движения смотреть, а не флаги
56 Мисти
 
09.03.14
12:39
Хорошо, что никто не сказал, что всё можно засунуть в один запрос.
57 m-serg74
 
09.03.14
12:42
(56) нужно после того как сделаешь обязательным (31)
58 m-serg74
 
09.03.14
12:43
(54) ппц, а переключиться в конструкторе на вкладку группировка не проще чем спрашивать на мисте?
59 Мисти
 
09.03.14
12:46
Вкладка не ответит на вопрос - почему!
60 m-serg74
 
09.03.14
12:47
(59) ну хотя бы отпадет часть вопроса "как"
61 m-serg74
 
09.03.14
12:49
(59) по итогам будут все строки + итоговые строки по номенклатуре

по группировке будут только сгруппированные строки по номенклатуре и ссуммированное количество

думаю тебе нужно второе
62 H A D G E H O G s
 
09.03.14
12:55
Автору сменить специальность.
Ну не шмогла.
63 m-serg74
 
09.03.14
12:56
(5) кстати не бывает что продукция состоит из другой продукции, если бывает тогда вообще читать до посинения (1)
64 m-serg74
 
09.03.14
12:56
(62) да не... ну хоть пытается что то делать, а не просто "памагите, не могу"
65 Мисти
 
09.03.14
12:59
(61) Спасибо!
(63) Не бывает.
(64) Да наоборот! Всё получилось, достаточно быстро, лично мне всё нравится, хотела посмотреть, как это выглядит со стороны, а то я давно сама в своем бульоне варюсь и вижу кроме своего только текст разработчиков.
66 m-serg74
 
09.03.14
13:01
(65) так в итоге 1 или 3 запроса?
67 Мисти
 
09.03.14
13:08
Три. Пусть пока будет три в меру прилично написанных.
68 m-serg74
 
09.03.14
13:12
(67) мудрое решение... 3>1... пусть будет больше)))
69 mulmulya
 
09.03.14
13:14
(56) я скажу: можно засунуть в один запрос, он станет пакетным
70 m-serg74
 
09.03.14
13:15
(69) докажи :)
71 mulmulya
 
09.03.14
13:17
(70) что именно?
72 m-serg74
 
09.03.14
13:18
(71) и то что можно и то что "будет пакетным"
73 mulmulya
 
09.03.14
13:26
(72) сп:
ВыполнитьПакет (ExecuteBatch)
Синтаксис:

ВыполнитьПакет()
Возвращаемое значение:

Тип: Массив.

Описание:

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

Доступность:

Сервер, толстый клиент, внешнее соединение.
74 m-serg74
 
09.03.14
13:28
(73) уволить :)
как пакет пригодиться (0)
75 mulmulya
 
09.03.14
13:30
(74) уволить сп?
76 mulmulya
 
09.03.14
13:31
(74) пусть тс сам решает, что и как пригодится
77 m-serg74
 
09.03.14
13:31
(76) если бы ТС "сам" могла, не было бы топика
78 m-serg74
 
09.03.14
13:32
(75) уволить пейсателя (73)
79 mulmulya
 
09.03.14
13:33
(78) а за временные таблицы сжечь?
80 m-serg74
 
09.03.14
13:34
(79) другое дело... а пакет как то не в тему вовсе
81 mulmulya
 
09.03.14
13:35
(80)а временные таблицы в пакетном запросе кощунство?
82 m-serg74
 
09.03.14
13:36
(81) не путайте использование временных таблиц и ВыполнитьПакет
83 mulmulya
 
09.03.14
13:43
(82) с использованием ВТ запрос пакетный, либо нужно определить менеджера ВТ, но сейчас не тот случай. А уж просто Выполнить() или ВыполнитьПакет(), тс разберется.
что вам мешало подсказать нормально? Надо меня подкалывать?
84 mulmulya
 
09.03.14
13:45
(82) Про соединения в запросе вы наверняка знаете. Но это же такой секрет
85 m-serg74
 
09.03.14
13:50
(83) еще раз повторю именно "ВыполнитьПакет" в случае ТСа никак не лучше

[что вам мешало подсказать нормально?]

почитайте внимательно все посты... там есть несколько подсказок причем без [Надо меня подкалывать?]
86 m-serg74
 
09.03.14
13:50
(84) про наличие конструктора запроса тоже подсказать... это секрет?
87 Мисти
 
09.03.14
14:17
Там каждый следующий запрос зависит от предыдущего, так что это не может быть пакетом, разве нет?
88 m-serg74
 
09.03.14
14:21
(87) вполне достаточно соединений, можно даже без ВТ
89 Мисти
 
09.03.14
14:35
v8: Добавить в запрос еще один отбор - а вот эту мою тему кто-нибудь видит?
(88) С ВТ проще, наверное?
Теоретически я себе представляю, как соединять, но практически - в башке не укладывается. Даже не знаю, можно ли этому научиться.
Давайте в той теме - практически!
Тут уже всё работает, ну и фик с ним.
90 Torquader
 
09.03.14
16:43
(89) "Радость наша" вы уверены, что всё ПРАВИЛЬНО работает, а то иначе можно и с "поганой метлой" познакомится поближе.
Компьютер — устройство, разработанное для ускорения и автоматизации человеческих ошибок.