Медленная работа запроса

Тема в разделе "1C и всё что с ней связано", создана пользователем LEVENTENOK, 20 окт 2009.

  1. LEVENTENOK

    LEVENTENOK Гость

    1С 7.7

    есть регистр остатков "ОстаткиТоваров" с измерением "Товар" и ресурсом "ОстатокТовара".

    есть таблица значений - список отобранных товаров ТЗ

    нужно по каждому товару получить чило - количество дней в заданном периоде, когда ОстатокТовара был положительным.
    типа
    Если ОстатокТовара (за этот день) > 0 Тогда КолвоДней = КолвоДней + 1;

    решил так:

    РегОст1=СоздатьОбъект("Регистр.ОстаткиТоваров");
    РегОст1.ВременныйРасчет();

    ТЗ.ВыбратьСтроки();
    Пока ТЗ.ПолучитьСтроку() = 1 Цикл
    КД = 0;
    Дата1 = ВыбНачПериода -1;
    РегОст1.УстановитьФильтр("Товар",,);
    РегОст1.УстановитьЗначениеФильтра("Товар",ТЗ.Товар);
    Пока Дата1 < ВыбКонПериодаТА Цикл
    Дата1 = Дата1 + 1;
    РассчитатьРегистрыНа(Дата(Дата1));
    Колво = РегОст1.СводныйОстаток(ТЗскул.Товар, , , "ОстатокТовара");
    Если Число(Колво) > 0 Тогда
    КД = КД +1;
    КонецЕсли
    КонецЦикла;
    ТЗ.КолДН = КД;
    КонецЦикла;

    работает очень-очень медленно, да оно и понятно. на таблице в 2500 товаров и за период - месяц - не дождался...
    как ускорить? очень нужно!

    заранее спасибо.
     
  2. vbs

    vbs Well-Known Member

    Регистрация:
    18 фев 2007
    Сообщения:
    1.708
    Симпатии:
    3
    Работает у тебя медленно из-за постоянного пересчета регистров

    Попробуй примерно такой запрос :
    ТекстЗапроса =
    "//{{ЗАПРОС(Сформировать)
    |Период с ВыбНачПериода по ВыбКонПериода;
    |Товар = Регистр.ОстаткиТоваров.Товар;
    |ОстатокТовара = Регистр.ОстаткиТоваров.ОстатокТовара;
    |Условие (Товар в ТЗ.Товар);
    |Группировка Товар;
    |Группировка День;";
     
  3. puh14

    puh14 Well-Known Member
    1C Team

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


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


    ааа - не совсем так, надо учесть приходы. попозже напишу
     
  4. vbs

    vbs Well-Known Member

    Регистрация:
    18 фев 2007
    Сообщения:
    1.708
    Симпатии:
    3
    Ох, не уверен я, что этот кусок кода корректно написан )
     
  5. puh14

    puh14 Well-Known Member
    1C Team

    Регистрация:
    11 июл 2008
    Сообщения:
    1.412
    Симпатии:
    0
    корректно-корректно. я так всегда ТЗ сокращаю - работает без косяков. я же не с текущей строкой работаю а через получитьстрокупономеру()


    а вот запрос у меня неправильный, как и сокращение. Правильный скоро будет
     
  6. LEVENTENOK

    LEVENTENOK Гость

    Очень-очень жду. на самом деле - есть еще приходы...1-го было 10, потом 2-го ушло 2, потом 3-го ушло 8, потом 5-го пришло 10, потом 10-го ушло 10.
    количество дней = 9
     
  7. puh14

    puh14 Well-Known Member
    1C Team

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


    Иначе
    ТЗ2.ОстатокНач = ТекущийОстаток;
    ТЗ2.ДокКонца = Тз2.ПолучитьЗначение(ааа+1,"Док");
    ТЗ2.УдалитьСтроку(ааа+1);
    ААА = ааа-1;

    КонецЕсли;
    КонецЕсли;
    КонецЦикла;



    Вот как-то так. Посмотри на ТЗ2 до сворачивания.Там все движения.
    по идее алгоритм свертки тз правильный - но что-то я не учел , некорректно пашет. это ты уж сам.
    после свертки действия простые новая колонка с числодней заполняется разницей дат документов или разницей документов и периодов. а потом ТЗ сворачиваетсяпо колонкам товар и числодней.

    как время будет тож повожусь с сверткой - пока со временем худо
     
  8. puh14

    puh14 Well-Known Member
    1C Team

    Регистрация:
    11 июл 2008
    Сообщения:
    1.412
    Симпатии:
    0
    //*******************************************
    Процедура Сформировать()
    Запрос = СоздатьОбъект("Запрос");
    ТекстЗапроса =
    "//{{ЗАПРОС(Сформировать)
    |Период с ВыбНачПериода по ВыбКонПериода;
    |Без Итогов;
    |Товар = Регистр.ОстаткиТоваров.Товар;
    |ОстатокТовара = Регистр.ОстаткиТоваров.ОстатокТовара;
    |Док = Регистр.ОстаткиТоваров.ТекущийДокумент;
    |Группировка Товар Без Групп;
    |Группировка Док;
    |Функция ОстатокНач = НачОст(ОстатокТовара);
    |Функция ОстатокПр = Приход(ОстатокТовара);
    |Функция ОстатокРс = Расход(ОстатокТовара);
    |Условие (Товар в ТЗ.Товар);";
    Запрос.Выполнить(ТекстЗапроса);
    ТЗ2 = создатьОбъект("ТаблицаЗначений");
    запрос.Выгрузить(ТЗ2);
    ТЗ2.Свернуть("Товар,Док","ОстатокНач,ОстатокПр,ОстатокРс,ОстатокКон");
    Тз2.Сортировать("+Товар,+Док",1);
    Тз2.НоваяКолонка("ДокКонца");
    Тз2.НоваяКолонка("ЧислоДней");
    Тз2.ВыбратьСтроки();
    Текущийостаток =0;
    для ааа=1 по ТЗ2.КоличествоСтрок() Цикл
    ПОПЫТКА
    ТЗ2.ПолучитьСтрокуПоНомеру(ааа+1);
    иСКЛЮЧЕНИЕ
    Прервать;
    КонецПопытки;
    ТЗ2.ПолучитьСтрокуПоНомеру(ааа);
    Если Тз2.Товар <>Тз2.ПолучитьЗначение(ааа+1,"Товар") Тогда
    ТекущийОстаток = 0;
    Продолжить;
    Иначе
    Текущийостаток = ТекущийОстаток + ТЗ2.ОстатокНач+ТЗ2.ОстатокПр - ТЗ2.ОстатокРс + Тз2.ПолучитьЗначение(ааа+1,"ОстатокНач") + Тз2.ПолучитьЗначение(ааа+1,"ОстатокПр")-Тз2.ПолучитьЗначение(ааа+1,"ОстатокРс");
    Если ТекущийОстаток>0 Тогда
    ТЗ2.ОстатокНач = 0;
    ТЗ2.ОстатокПр =0;
    ТЗ2.ОстатокРс =0;
    ТЗ2.УдалитьСтроку(ааа+1);
    ААА = ааа-1;
    ИначеЕсли ТекущийОстаток=0 Тогда
    ТЗ2.ДокКонца = Тз2.ПолучитьЗначение(ааа+1,"Док");

    ТЗ2.ОстатокНач = 0;
    ТЗ2.ОстатокПр =0;
    ТЗ2.ОстатокРс =0;
    ТЗ2.УдалитьСтроку(ааа+1);
    Иначе
    ТЗ2.ОстатокНач = 0;
    ТЗ2.ОстатокПр =0;
    ТЗ2.ОстатокРс =0;
    ТЗ2.УдалитьСтроку(ааа);


    КонецЕсли;
    КонецЕсли;
    КонецЦикла;

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

    ИначеЕсли (ПустоеЗначение(ТЗ2.ДокКонца)=0) и (ПустоеЗначение(ТЗ2.Док)=1) Тогда

    ТЗ2.ЧислоДней = Число(ТЗ2.ДокКонца.ДатаДок - ВыбНачПериода);
    КонецЕсли;
    КонецЦикла;

    ТЗ2.Свернуть("Товар","ЧислоДней");



    КонецПроцедуры



    Вот так работает. Сам накосячил - при сортировке ТЗ с документами надо указывать доп параметр - иначе он сортирует по типу а потом по дате документа.
     
Загрузка...
Похожие Темы - Медленная работа запроса
  1. Andrey Kha
    Ответов:
    0
    Просмотров:
    23
  2. Hoasker
    Ответов:
    0
    Просмотров:
    64
  3. garri671
    Ответов:
    0
    Просмотров:
    54
  4. lelik200969
    Ответов:
    0
    Просмотров:
    50
  5. Kozolick
    Ответов:
    0
    Просмотров:
    138

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