8.х помогите оптимизировать запрос

Тема в разделе "Конфигурирование на платформе "1С:Предприятие 8"", создана пользователем Dmitrij, 13 июн 2010.

  1. TopicStarter Overlay
    Dmitrij
    Offline

    Dmitrij Опытный в 1С

    Регистрация:
    6 май 2008
    Сообщения:
    844
    Симпатии:
    1
    Баллы:
    26
    есть ПФ выводит последний остаток со *, если не последний то без *, но при печати уходит много времени на обработку помогите оптимизировать, вот код
    Код:
    Функция Печать() Экспорт
    Если ТипЗнч(СсылкаНаОбъект)=Тип("ДокументСсылка.ПеремещениеТоваров") Тогда
    Склад=СсылкаНаОбъект.СкладОтправитель;
    Иначе
    Склад=СсылкаНаОбъект.Склад;
    КонецЕсли; 
    Если ЗначениеЗаполнено(Склад) Тогда
    ТабДокумент = Новый ТабличныйДокумент;
    Макет       = ПолучитьМакет("Сертификат");
    
    Шапка = Макет.ПолучитьОбласть("Шапка");
    Шапка.Параметры.ТекстЗаголовка = ОбщегоНазначения.СформироватьЗаголовокДокумента(СсылкаНаОбъект, "Лист сборки");
    Если ТипЗнч(СсылкаНаОбъект)=Тип("ДокументСсылка.ПеремещениеТоваров") Тогда
    Шапка.Параметры.ПолноеНаименованиеЛицензиата = СсылкаНаОбъект.Организация.Наименование+" "+СсылкаНаОбъект.СкладПолучатель;
    Шапка.Параметры.ПолноеНаименованиеОтправителя = СсылкаНаОбъект.Организация.Наименование+" "+СсылкаНаОбъект.СкладОтправитель;
    Иначе
    СведенияОПокупателе = УправлениеКонтактнойИнформацией.СведенияОЮрФизЛице(СсылкаНаОбъект.Контрагент,       СсылкаНаОбъект.Дата);
    Шапка.Параметры.ПолноеНаименованиеЛицензиата = ФормированиеПечатныхФорм.ОписаниеОрганизации(СведенияОПокупателе, "ПолноеНаименование");
    СведенияОПоставщике = УправлениеКонтактнойИнформацией.СведенияОЮрФизЛице(СсылкаНаОбъект.Организация,        СсылкаНаОбъект.Дата);
    Шапка.Параметры.ПолноеНаименованиеОтправителя = ФормированиеПечатныхФорм.ОписаниеОрганизации(СведенияОПоставщике, "ПолноеНаименование");
    КонецЕсли;
    ТабДокумент.Вывести(Шапка);
    
    Таблица = Макет.ПолучитьОбласть("Таблица");
    ТабДокумент.Вывести(Таблица);
    
    СтрокаДанных = Макет.ПолучитьОбласть("СтрокаДанных");
    НомерСтроки=0;
    СуммаДокумента=0;
    Для Каждого Стр Из СсылкаНаОбъект.Товары Цикл
    НомерСтроки=НомерСтроки+1;
    ОпределитьВладельца(Стр.Номенклатура);
    
    Запрос = Новый Запрос;
    Запрос.Текст = ЗапросОбщий();	
    Запрос.УстановитьПараметр("Дата", СсылкаНаОбъект.Дата); 
    Если ТипЗнч(СсылкаНаОбъект)=Тип("ДокументСсылка.ПеремещениеТоваров") Тогда
    Запрос.УстановитьПараметр("Склад", СсылкаНаОбъект.СкладОтправитель); 
    Иначе
    Запрос.УстановитьПараметр("ТипЦен", СсылкаНаОбъект.ТипЦен);
    Запрос.УстановитьПараметр("Склад", СсылкаНаОбъект.Склад);  
    Запрос.УстановитьПараметр("Контрагент", СсылкаНаОбъект.Контрагент);
    КонецЕсли;
    Запрос.УстановитьПараметр("Товар", Стр.Номенклатура.Ссылка); 
    ТЗ=Запрос.Выполнить().Выгрузить();
    
    Для Каждого СтокаДанных Из ТЗ Цикл
    Остаток=СтокаДанных.ОстатокНаСкладе;
    КонецЦикла;
    // Сообщить(Остаток);
    СтрокаДанных.Параметры.НомерСтроки=НомерСтроки;
    СтрокаДанных.Параметры.Коэф=НормаУпаковки;
    СтрокаДанных.Параметры.Наименование=Стр.Номенклатура;
    СтрокаДанных.Параметры.Код=Стр.Номенклатура.КодОК;
    СтрокаДанных.Параметры.Артикул=Стр.Номенклатура.Артикул;
    СтрокаДанных.Параметры.ЕдИзм=Стр.ЕдиницаИзмерения;
    СтрокаДанных.Параметры.Кол=Стр.Количество;
    
    Если СсылкаНаОбъект.Проведен И Не ЗначениеЗаполнено(Остаток) Тогда
    СтрокаДанных.Параметры.Кол="* "+Стр.Количество;
    ИначеЕсли СсылкаНаОбъект.Проведен=Ложь И Остаток=Стр.Количество Тогда
    СтрокаДанных.Параметры.Кол="* "+Стр.Количество;
    КонецЕсли;
    
    Если ТипЗнч(СсылкаНаОбъект)=Тип("ДокументСсылка.ПеремещениеТоваров") Тогда
    Иначе
    СтрокаДанных.Параметры.Цена=Стр.Цена;
    СтрокаДанных.Параметры.Сумма=Стр.Сумма;
    СуммаДокумента=СуммаДокумента+Стр.Сумма;
    КонецЕсли;
    ТабДокумент.Вывести(СтрокаДанных);
    КонецЦикла;
    
    Подвал = Макет.ПолучитьОбласть("Подвал");
    Подвал.Параметры.Сумма=Окр(СуммаДокумента,2);
    ПарПредмета = "рубль, рубля, рублей, м, копейка, копейки, копеек, ж, 2";
    Подвал.Параметры.СуммаПрописью=ЧислоПрописью(СуммаДокумента,,ПарПредмета);
    ТабДокумент.Вывести(Подвал);
    
    ТабДокумент.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;
    ТабДокумент.ПолеСлева=0;
    ТабДокумент.ПолеСправа=0;
    ТабДокумент.АвтоМасштаб=Истина;
    Если ТипЗнч(СсылкаНаОбъект)<>Тип("ДокументСсылка.ЧекККМ") Тогда
    //УниверсальныеМеханизмы.НапечататьДокумент(ТабДокумент, 1, Ложь);
    Возврат ТабДокумент;
    Иначе
    УниверсальныеМеханизмы.НапечататьДокумент(ТабДокумент, 1, Истина);
    ТекДок=СсылкаНаОбъект.ПолучитьОбъект();
    ТекДок.Печать("Чек",1,Истина);
    КонецЕсли;
    Иначе
    Сообщить("Необходимо заполнить реквизит склад!", СтатусСообщения.ОченьВажное);
    КонецЕсли;
    КонецФункции // Печать
    
    
    
  2. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    1) А где собственно сам запрос, который надо помочь оптимизировать? (Кроме "Запрос.Текст = ЗапросОбщий();" - ничего не вижу)
    2) ваша ошибка в том что вы создаете и вызываете запрос в цикле ("Для Каждого Стр Из СсылкаНаОбъект.Товары Цикл"). Надо не так. Передавайте в запрос ссылку на ваш документ, а в запросе за начальную таблицу возьмите таблицу "ВашДокумент.Товары", и с ней работайте. Т.е. не делайте отдельный запрос для каждой строки ТЧ, работайте сразу со всем документом.
  3. TopicStarter Overlay
    Dmitrij
    Offline

    Dmitrij Опытный в 1С

    Регистрация:
    6 май 2008
    Сообщения:
    844
    Симпатии:
    1
    Баллы:
    26
    Да, сделал запрос производительности много времени уходит на выполнение запроса
    Код:
    Функция ЗапросОбщий()
    Возврат 
    "ВЫБРАТЬ
    |	Товары.Товар,
    |	ОстаткиНаСкладе.Остаток КАК ОстатокНаСкладе
    |ИЗ
    |	(ВЫБРАТЬ
    |		Номенклатура.Ссылка КАК Товар
    |	ИЗ
    |		Справочник.Номенклатура КАК Номенклатура
    |	ГДЕ
    |		Номенклатура.ЭтоГруппа = ЛОЖЬ
    |		И Номенклатура.Услуга = ЛОЖЬ
    |		И Номенклатура.ВидНоменклатуры.ТипНоменклатуры <> ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Услуга)) КАК Товары
    |		ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
    |			ОстаткиПоРегистрам.Товар КАК Товар,
    |			ОстаткиПоРегистрам.Характеристика КАК Характеристика,
    |			ОстаткиПоРегистрам.Серия КАК Серия,
    |			СУММА(ОстаткиПоРегистрам.Остаток) КАК Остаток
    |		ИЗ
    |			(ВЫБРАТЬ
    |				ТоварыНаСкладахОстатки.Номенклатура КАК Товар,
    |				ТоварыНаСкладахОстатки.ХарактеристикаНоменклатуры КАК Характеристика,
    |				ТоварыНаСкладахОстатки.СерияНоменклатуры КАК Серия,
    |				ТоварыНаСкладахОстатки.КоличествоОстаток КАК Остаток
    |			ИЗ
    |				РегистрНакопления.ТоварыНаСкладах.Остатки(КОНЕЦПЕРИОДА(&Дата, ДЕНЬ), ) КАК ТоварыНаСкладахОстатки
    |			
    |			ОБЪЕДИНИТЬ ВСЕ
    |			
    |			ВЫБРАТЬ
    |				ТоварыВРозницеОстатки.Номенклатура,
    |				ТоварыВРозницеОстатки.ХарактеристикаНоменклатуры,
    |				ТоварыВРозницеОстатки.СерияНоменклатуры,
    |				ТоварыВРозницеОстатки.КоличествоОстаток
    |			ИЗ
    |				РегистрНакопления.ТоварыВРознице.Остатки(&Дата, ) КАК ТоварыВРозницеОстатки
    |			
    |			ОБЪЕДИНИТЬ ВСЕ
    |			
    |			ВЫБРАТЬ
    |				ТоварыВНТТОстатки.Номенклатура,
    |				ТоварыВНТТОстатки.ХарактеристикаНоменклатуры,
    |				ТоварыВНТТОстатки.СерияНоменклатуры,
    |				ТоварыВНТТОстатки.КоличествоОстаток
    |			ИЗ
    |				РегистрНакопления.ТоварыВНТТ.Остатки КАК ТоварыВНТТОстатки) КАК ОстаткиПоРегистрам
    |		
    |		СГРУППИРОВАТЬ ПО
    |			ОстаткиПоРегистрам.Характеристика,
    |			ОстаткиПоРегистрам.Товар,
    |			ОстаткиПоРегистрам.Серия) КАК Остатки
    |			ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
    |				ТоварыНаСкладахОстатки.Номенклатура КАК Товар,
    |				ТоварыНаСкладахОстатки.ХарактеристикаНоменклатуры КАК Характеристика,
    |				ТоварыНаСкладахОстатки.СерияНоменклатуры КАК Серия,
    |				ТоварыНаСкладахОстатки.КоличествоОстаток КАК Остаток,
    |				0 КАК ЦенаСкладская
    |			ИЗ
    |				РегистрНакопления.ТоварыНаСкладах.Остатки(КОНЕЦПЕРИОДА(&Дата, ДЕНЬ), Склад = &Склад) КАК ТоварыНаСкладахОстатки
    |			
    |			ОБЪЕДИНИТЬ ВСЕ
    |			
    |			ВЫБРАТЬ
    |				ТоварыВРозницеОстатки.Номенклатура,
    |				ТоварыВРозницеОстатки.ХарактеристикаНоменклатуры,
    |				ТоварыВРозницеОстатки.СерияНоменклатуры,
    |				ТоварыВРозницеОстатки.КоличествоОстаток,
    |				ТоварыВРозницеОстатки.СуммаПродажнаяОстаток / ТоварыВРозницеОстатки.КоличествоОстаток
    |			ИЗ
    |				РегистрНакопления.ТоварыВРознице.Остатки(&Дата, Склад = &Склад) КАК ТоварыВРозницеОстатки
    |			
    |			ОБЪЕДИНИТЬ ВСЕ
    |			
    |			ВЫБРАТЬ
    |				ТоварыВНТТОстатки.Номенклатура,
    |				ТоварыВНТТОстатки.ХарактеристикаНоменклатуры,
    |				ТоварыВНТТОстатки.СерияНоменклатуры,
    |				ТоварыВНТТОстатки.КоличествоОстаток,
    |				ТоварыВНТТОстатки.ЦенаВРознице
    |			ИЗ
    |				РегистрНакопления.ТоварыВНТТ.Остатки(&Дата, Склад = &Склад) КАК ТоварыВНТТОстатки) КАК ОстаткиНаСкладе
    |			ПО Остатки.Товар = ОстаткиНаСкладе.Товар
    |				И Остатки.Характеристика = ОстаткиНаСкладе.Характеристика
    |				И Остатки.Серия = ОстаткиНаСкладе.Серия
    |			ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(КОНЕЦПЕРИОДА(&Дата, ДЕНЬ), ) КАК ЦеныНоменклатурыСрезПоследних
    |			ПО Остатки.Товар = ЦеныНоменклатурыСрезПоследних.Номенклатура
    |				И Остатки.Характеристика = ЦеныНоменклатурыСрезПоследних.ХарактеристикаНоменклатуры
    |		ПО Товары.Товар = Остатки.Товар
    |ГДЕ
    |	Товары.Товар = &Товар";
    КонецФункции
    
    
    
    :unsure:
  4. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    В сам запрос, не въезжал честно говоря, убегаю сейчас, может позже будет время гляну, но:
    1) неудивительно что долго, вы же берете весь(!!!) справочник номенклатура (сколько там у вас позиций то?), делаете из него выборку, левые соединения всякие, а потом в итоге ограничеваете выборку 1(!!!) позицией (Товары.Товар = &Товар";). Это же прошу прощения Ж. :) (передавайте тогда туда уж список номенклатуры из документа). (повторюсь что делать должен запрос не въезжал, вы лучше напишите словами что оно должно возвращать, и что должна делать процедура обработки запроса, тоже словами опишите).
    2) вместо объединения ТоварыНаСкладахОстатки, ТоварыВНТТОстатки, ТоварыВРозницеОстатки вам возможно нужен всего 1 регистр: ТоварыОрганизаций (если не ошибаюсь)
  5. TopicStarter Overlay
    Dmitrij
    Offline

    Dmitrij Опытный в 1С

    Регистрация:
    6 май 2008
    Сообщения:
    844
    Симпатии:
    1
    Баллы:
    26
    запрос должен возвращать остаток товара на складе
  6. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    P.S. Да и не нужен там справочник номенклатура, у вас же регистры есть, берите Номенклатуру оттуда. Зачем вам справочник то?
  7. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Код:
    "ВЫБРАТЬ
    ПеремещениеТоваровТовары.Номенклатура,
    ТоварыОрганизацийОстатки.КоличествоОстаток
    ИЗ
    Документ.ПеремещениеТоваров.Товары КАК ПеремещениеТоваровТовары
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыОрганизаций.Остатки КАК ТоварыОрганизацийОстатки
    ПО ПеремещениеТоваровТовары.Номенклатура = ТоварыОрганизацийОстатки.Номенклатура
    И ПеремещениеТоваровТовары.Ссылка.Организация = ТоварыОрганизацийОстатки.Организация
    И ПеремещениеТоваровТовары.ХарактеристикаНоменклатуры = ТоварыОрганизацийОстатки.ХарактеристикаНоменклатуры
    И ПеремещениеТоваровТовары.СерияНоменклатуры = ТоварыОрганизацийОстатки.СерияНоменклатуры
    И ПеремещениеТоваровТовары.Ссылка.СкладОтправитель = ТоварыОрганизацийОстатки.Склад
    ГДЕ
    ПеремещениеТоваровТовары.Ссылка = &ДокументПеремещение"
    
    будет типа такого, в консоли запросов посмотрите что получается, в обще в этом направлении вам надо двигаться.
  8. TopicStarter Overlay
    Dmitrij
    Offline

    Dmitrij Опытный в 1С

    Регистрация:
    6 май 2008
    Сообщения:
    844
    Симпатии:
    1
    Баллы:
    26
    Вот я сократил запрос до этого:
    Код:
         "ВЫБРАТЬ
    |    СУММА(ТоварыНаСкладах.КоличествоОстаток) КАК ОстатокНаСкладе,
    |    ТоварыНаСкладах.СерияНоменклатуры,
    |    ТоварыНаСкладах.ХарактеристикаНоменклатуры,
    |    ТоварыНаСкладах.Номенклатура,
    |    ТоварыНаСкладах.Склад
    |ИЗ
    | РегистрНакопления.ТоварыНаСкладах.Остатки(КОНЕЦПЕРИОДА(&Дата, ДЕНЬ), Склад = &Склад) КАК ТоварыНаСкладах
    |ГДЕ
    | ТоварыНаСкладах.Номенклатура = &Товар
    |
    |СГРУППИРОВАТЬ ПО
    |    ТоварыНаСкладах.СерияНоменклатуры,
    |    ТоварыНаСкладах.ХарактеристикаНоменклатуры,
    |    ТоварыНаСкладах.Номенклатура,
    |    ТоварыНаСкладах.Склад";
    
    
    
    А как мне передать всю таблицу товаров из документа у меня типы документов могут быть разные: чек, рту, перемещение
  9. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Так напишите:
    Код:
    ТоварыНаСкладах.Номенклатура В (&Товар)
    
    &Товар - у вас будет список номенклатуры.
    получить можно ну хотя бы так:
    Код:
    СписокНоменклатуры = Товары.Выгрузить( ,"Номенклатура");
    
    думаю это услови тоже можно засунуть в параметры виртуальной таблицы.

    Но мне это в том виде в котором у вас есть - не нравится. Вы потом что с этими остатками делать будете? Я в код вывода не вникал, спрашиваю к тому что, если при выводе у вас нужны данные не только по остаткам и из справочника номенклатура, а из самого документа тоже (из табличной его части) - вы как их выводить будете? я имею ввиду искать соответствие между строками полученной вами выборки и строками табличной части?. Если то что написал не имеет значения (т.е. кроме остатков при выводе ничего не нужно), то оставьте.
  10. TopicStarter Overlay
    Dmitrij
    Offline

    Dmitrij Опытный в 1С

    Регистрация:
    6 май 2008
    Сообщения:
    844
    Симпатии:
    1
    Баллы:
    26
    А есть возможность поставить условие в запрос если есть остаток то выводить кол-во из табл товаров иначе кол-во из табл товаров + *
  11. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Всмысле вам сам остаток не нужен? Ну можно, почему нельзя, используйте конструкцию ВЫБОР-КОГДА-ТОГДА-ИНАЧЕ-КОНЕЦ.
  12. TopicStarter Overlay
    Dmitrij
    Offline

    Dmitrij Опытный в 1С

    Регистрация:
    6 май 2008
    Сообщения:
    844
    Симпатии:
    1
    Баллы:
    26
    а пример можно
  13. Stack_G
    Offline

    Stack_G Опытный в 1С

    Регистрация:
    10 дек 2007
    Сообщения:
    786
    Симпатии:
    2
    Баллы:
    26
    Между прочим:
    условие - в параметры виртуальной таблицы зперенесите.

    А вообще - Вам нужно соединить табличную часть документа с регистром остатков.

    Вот небольшой примерчик:
    Код:
    "ВЫБРАТЬ
    ПеремещениеТоваровТовары.Номенклатура,
    ПеремещениеТоваровТовары.Количество,
    ТоварыНаСкладахОстатки.КоличествоОстаток
    ИЗ
    Документ.ПеремещениеТоваров.Товары КАК ПеремещениеТоваровТовары
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
    ПО ПеремещениеТоваровТовары.Номенклатура = ТоварыНаСкладахОстатки.Номенклатура
    ГДЕ
    ПеремещениеТоваровТовары.Ссылка = &ТекущийДокумент"
    
  14. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Сделайте допустим так:
    Код:
    ВЫБРАТЬ
    ТабличнаяЧастьТовары.Номенклатура КАК Номенклатура,
    ВЫБОР
    КОГДА ЕСТЬNULL(ТоварыНаСкладахОстатки.КоличествоОстаток, 0) >= 0
    ТОГДА ""
    ИНАЧЕ "*"
    КОНЕЦ КАК Суффикс,
    ТабличнаяЧастьТовары.Количество КАК Количество
    ИЗ
    Документ.ПеремещениеТоваров.Товары КАК ТабличнаяЧастьТовары
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата, ) КАК ТоварыНаСкладахОстатки
    ПО ТабличнаяЧастьТовары.Номенклатура = ТоварыНаСкладахОстатки.Номенклатура
    И ТабличнаяЧастьТовары.ХарактеристикаНоменклатуры = ТоварыНаСкладахОстатки.ХарактеристикаНоменклатуры
    И ТабличнаяЧастьТовары.СерияНоменклатуры = ТоварыНаСкладахОстатки.СерияНоменклатуры
    И ТабличнаяЧастьТовары.Ссылка.СкладПолучатель = ТоварыНаСкладахОстатки.Склад
    ГДЕ
    ТабличнаяЧастьТовары.Ссылка = &Документ
    
    
    далее при выводе напишите:
    Код:
    СтрокаДанных.Параметры.Кол = Строка(Выборка.Количество) + Выборка.Суффикс;
    
    По поводу того что у вас несколько документов - название табличной части же у них у всех одинаковое ("Товары"?). Ну так в тексте запроса просто заменяете строку, вместо:
    Код:
    "Документ.ПеремещениеТоваров.Товары КАК ТабличнаяЧастьТовары"
    
    будет что-то вроде:
    Код:
    "Документ." + ТипМоегоДокумента + ".Товары КАК ТабличнаяЧастьТовары"
    
  15. TopicStarter Overlay
    Dmitrij
    Offline

    Dmitrij Опытный в 1С

    Регистрация:
    6 май 2008
    Сообщения:
    844
    Симпатии:
    1
    Баллы:
    26
    Это я знаю проблема в следующем можно ли то же самое сделать из 3 документов чек, перемещение и рту в одном запросе или надо писать три запроса
  16. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Dmitrij я же написал как это можно сделать.

Поделиться этой страницей