7.7 Оптимизация обработки ЗагрузкаККМ (SQL)

Тема в разделе "Конфигурирование на платформе "1С:Предприятие 7.7"", создана пользователем Александр Орлов, 3 окт 2012.

  1. TopicStarter Overlay
    Александр Орлов
    Offline

    Александр Орлов

    Регистрация:
    3 окт 2012
    Сообщения:
    6
    Симпатии:
    0
    Баллы:
    1
    Всем доброго дня. Есть такая обработка Загрузка ККМ. Сейчас у нас ТиС 7.7 на SQL2008 R2 и порядка 140 000 наименований номенклатуры. До перехода на SQL в файловой версии загрузка занимала порядка 3-4 минут. После перехода перебор справочника номенклатуры стал занимать 16-18 минут. Переписали на прямой запрос, стало порядка 8 минут. Можно еще что-то оптимизировать в нашем коде? Саму выборку получает мгновенно, а вот потом из этой выборки ВыбратьСтроки получается очччень долго. Подскажите люди добрые.






    Перем СписокСкладов;//ВыбФирма
    //******************************************************************************
    // Описание:
    // Получает список товаров выбранной фирмы на выбранном розничном складе,
    // формирует таблицу значений, в которую записывает полученную инфрмацию и
    // и вызывает функцию для загрузки этой информации в выбранную ККМ.
    //
    Процедура Выполнить()
    Перем ОписаниеОш,Поз;
    //ДН
    Если ТЦены.Выбран()=0 Тогда
    Предупреждение("Выберите тип цены для выгрузки!");
    Возврат;
    КонецЕсли;
    //
    СписокТоваров = СоздатьОбъект("ТаблицаЗначений");
    СписокТоваров.НоваяКолонка("Код");
    СписокТоваров.НоваяКолонка("Штрихкод");
    СписокТоваров.НоваяКолонка("Наименование");
    СписокТоваров.НоваяКолонка("Цена");
    СписокТоваров.НоваяКолонка("Количество");
    СписокТоваров.НоваяКолонка("Отдел");
    СписокТоваров.НоваяКолонка("Родитель");
    СписокТоваров.НоваяКолонка("Группа");
    СписокТоваров.НоваяКолонка("Уровень");
    СписокТоваров.НоваяКолонка("Признак");
    СписокТоваров.НоваяКолонка("СхемаВнутрАвтСкидки");
    СписокТоваров.НоваяКолонка("ТипТовСкидки");
    СписокТоваров.НоваяКолонка("ТовСкидка");




    СписокТоваровПоСтарому = СоздатьОбъект("ТаблицаЗначений");
    СписокТоваровПоСтарому.НоваяКолонка("Код");
    СписокТоваровПоСтарому.НоваяКолонка("Штрихкод");
    СписокТоваровПоСтарому.НоваяКолонка("Наименование");
    СписокТоваровПоСтарому.НоваяКолонка("Цена");
    СписокТоваровПоСтарому.НоваяКолонка("Количество");
    СписокТоваровПоСтарому.НоваяКолонка("Отдел");

    СпрТоваров = СоздатьОбъект("Справочник.Номенклатура");
    СпрПризнакЗагрузки = СоздатьОбъект("Справочник.ПризнакЗагрузки");
    СпрТоварВОтдел=СоздатьОбъект("Справочник.ТоварВОтдел");

    ВсегоТоваров=0;
    Отобрано=0;

    Сообщить("Начали"+текущеевремя());
    //

    СписокГрупп = СоздатьОбъект("СписокЗначений");
    Текст = "
    |SELECT
    | СпрН.ID as [Элемент $Справочник.Номенклатура],
    | $ПоследнееЗначение.Цены.Цена(СпрЦ.ID, :ВыбДата) Цена
    |FROM
    | $Справочник.Номенклатура as СпрН
    |LEFT JOIN
    | $Справочник.Цены СпрЦ ON СпрЦ.ParentExt = СпрН.ID AND
    | $СпрЦ.ТипЦен = :ТипЦен
    |WHERE
    | СпрН.IsFolder = 2 AND
    | СпрН.IsMark = 0
    |";
    RecordSet.УстановитьТекстовыйПараметр("ВыбДата",РабочаяДата());
    RecordSet.УстановитьТекстовыйПараметр("ТипЦен",ТЦены);
    ТЗТ = глПолучитьВыборку(, Текст);
    Ном=1;
    ТЗТ.ВыбратьСтроки();
    Пока ТЗТ.ПолучитьСтроку()=1 Цикл
    ВсегоТоваров=ВсегоТоваров+1;
    Состояние(Строка(ВсегоТоваров)+" ("+Отобрано+" )");
    Если (ТЗТ.Цена=0) Тогда Продолжить; КонецЕсли;
    НайденнаяСкидка = "";
    Отобрано=Отобрано+1;
    СпрЕд=СоздатьОбъект("Справочник.Единицы");
    СпрЕд.ИспользоватьВладельца(ТЗТ.Элемент);
    СпрЕд.ВыбратьЭлементы();
    Пока СпрЕд.ПолучитьЭлемент()=1 Цикл
    (СтрДлина(СокрЛП(СпрЕд.ТекущийЭлемент().Штрихкод))=12) Тогда
    (СтрДлина(СокрЛП(СпрЕд.ТекущийЭлемент().Штрихкод))=13) Тогда

    Склад = "";
    СпрТоварВОтдел.ИспользоватьВладельца(ТЗТ.Элемент);
    СпрТоварВОтдел.ВыбратьЭлементы();
    Пока СпрТоварВОтдел.ПолучитьЭлемент()=1 Цикл
    Если СписокСкладов.НайтиЗначение(СпрТоварВОтдел.Магазин_Отдел)<>0 Тогда
    Отдел = Число(СпрТоварВОтдел.Магазин_Отдел.НомерСекции);
    Склад = СпрТоварВОтдел.Магазин_Отдел;
    Прервать;
    КонецЕсли;
    КонецЦикла;

    КонецЦикла;
    Если (ПустоеЗначение(Склад)=1)и(БезОтдела=0) Тогда
    Отдел = 0;
    Продолжить;
    КонецЕсли;



    СписокТоваров.НоваяСтрока();
    СписокТоваров.Код = СокрЛП(ТЗТ.Элемент.Код);
    СписокТоваров.Код=ТЗТ.Элемент.Код;
    СписокТоваров.Признак = Признак;
    СписокТоваров.Штрихкод = СокрЛП(ТЗТ.Элемент.БазоваяЕдиница.Штрихкод);
    СписокТоваров.Наименование = СокрЛП(ТЗТ.Элемент.ПолнНаименование); //ТАНЕКО НаименованиеЦенника
    // СписокТоваров.Цена = НайденнаяЦена;
    СписокТоваров.Цена = ТЗТ.Цена;


    // СписокТоваров.Количество = глВернутьОстаток2(СпрТоваров.ТекущийЭлемент(),ВыбФирма,Склад);

    СписокТоваров.Отдел = Отдел;
    СписокТоваров.Родитель = ТЗТ.Элемент.Родитель.Код;
    СписокТоваров.Группа = 0;
    СписокТоваров.Уровень = ТЗТ.Элемент.Уровень();



    Родитель =ТЗТ.Элемент.Родитель;
    Пока ПустоеЗначение(Родитель)=0 Цикл
    Если СписокГрупп.НайтиЗначение(Родитель)=0 Тогда
    СписокГрупп.ДобавитьЗначение(Родитель);
    КонецЕсли;
    Родитель = Родитель.Родитель;
    КонецЦикла;
    КонецЦикла;
    //
    Сообщить("Подгодовили табл: "+текущеевремя());
    //
    ВсегоГрупп = СписокГрупп.РазмерСписка();
    i = 0;
    Для i = 1 По ВсегоГрупп Цикл
    Группа = СписокГрупп.ПолучитьЗначение(i);
    СписокТоваров.НоваяСтрока();
    СписокТоваров.Код = СокрЛП(Группа.Код);
    СписокТоваров.Признак = 1;
    СписокТоваров.Штрихкод = "";
    СписокТоваров.Наименование = СокрЛП(Группа.Наименование); //ТАНЕКО НаименованиеЦенника
    СписокТоваров.Родитель = ?(ПустоеЗначение(Группа.Родитель)=0,Группа.Родитель.Код,"");
    СписокТоваров.Группа = 1;
    СписокТоваров.Уровень = Группа.Уровень();

    //СписокТоваров.СхемаВнутрАвтСкидки = Группа.НайденнаяСкидка;
    КонецЦикла;

    СписокТоваров.Сортировать("Уровень+,Группа-");




    ЕстьПоСтарому=0;
    ТЗ_Кассы.ВыбратьСтроки();
    Пока ТЗ_Кассы.ПолучитьСтроку()=1 Цикл
    Если ТЗ_Кассы.Флаг=2 Тогда
    Продолжить;
    КонецЕсли;

    ВыбКасса = ТЗ_Кассы.Касса;
    Поз = 0;

    Если глККМOffLine.НайтиЗначение(ВыбКасса, Поз, "ККМ") = 1 Тогда
    глККМOffLine.ПолучитьСтрокуПоНомеру(Поз);
    КаталогОбмена = СокрЛП(ВыбКасса.КаталогОбмена);
    Иначе
    Сообщить("Настройте кассу "+Строка(ВыбКасса)+" !!!");
    Продолжить;
    КонецЕсли;

    Если Прав(КаталогОбмена,1)<>"\" Тогда
    КаталогОбмена=КаталогОбмена+"\";
    КонецЕсли;

    Если ВыбКасса.ПоНовому=1 Тогда
    Если глККМЗагрузитьТовары(ВыбКасса, ПерезаписыватьБазу, СписокТоваров, ОписаниеОш) = 1 Тогда
    ТекстСообщения="Загрузка номенклатуры со склада успешно завершена.";
    Сообщить(ТекстСообщения);
    Иначе
    Сообщить(ОписаниеОш);
    КонецЕсли;
    Иначе
    Если ЕстьПоСтарому = 0 Тогда
    Если глККМЗагрузитьТовары(ВыбКасса, 0, СписокТоваровПоСтарому, ОписаниеОш) = 1 Тогда
    ТекстСообщения="Загрузка номенклатуры со склада успешно завершена.";
    ЕстьПоСтарому = 1;
    Сообщить(ТекстСообщения);
    Иначе
    Сообщить(ОписаниеОш);
    КонецЕсли;
    КонецЕсли;
    КонецЕсли;

    КонецЦикла;

    Сообщить("Усе; "+текущеевремя());

    //КонецЦикла;
    КонецПроцедуры


    Процедура МеняемФирму()

    СпрКассы = СоздатьОбъект("Справочник.Кассы");
    СпрКассы.ВыбратьЭлементы();
    ТЗ_Кассы.УдалитьСтроки();
    Пока СпрКассы.ПолучитьЭлемент() = 1 Цикл
    Если (СпрКассы.Выбран() = 1) И (СпрКассы.РежимККМ = Перечисление.РежимыККМ.OffLine) Тогда
    Если ВыбФирма <> СпрКассы.Магазин Тогда
    Продолжить;
    КонецЕсли;

    ВыбКасса = СпрКассы.ТекущийЭлемент();
    ТЗ_Кассы.НоваяСтрока();
    ТЗ_Кассы.Флаг = 1;
    ТЗ_Кассы.Касса=СпрКассы.ТекущийЭлемент();
    ТЗ_Кассы.Номер=СпрКассы.ЗаводскойНомерККМ;
    ТЗ_Кассы.Каталог=СокрЛП(СпрКассы.КаталогОбмена);

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

    ТЗ_Склады.УдалитьСтроки();
    СписокСкладов.УдалитьВсе();
    Если ПустоеЗначение(ВыбКасса)=0 Тогда
    Если ПустоеЗначение(ВыбКасса.СкладКомпании)=0 Тогда
    СпрСклады = СоздатьОбъект("Справочник.Склады");
    СпрСклады.ВыбратьЭлементы();
    Пока СпрСклады.ПолучитьЭлемент()=1 Цикл
    Если
    (СпрСклады.СкладМагазина=ВыбКасса.СкладКомпании)или
    (СпрСклады.СкладМагазина2=ВыбКасса.СкладКомпании)
    Тогда
    ТЗ_Склады.НоваяСтрока();
    ТЗ_Склады.Флаг=1;
    ТЗ_Склады.Склад=СпрСклады.ТекущийЭлемент();
    СписокСкладов.ДобавитьЗначение(СпрСклады.ТекущийЭлемент());
    КонецЕсли;
    КонецЦикла;
    Иначе
    Сообщить("У кассы не задан магазин!");
    КонецЕсли
    КонецЕсли;

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

    //******************************************************************************
    // Предопределенная процедура.
    //
    Процедура ПриОткрытии(ФлагЧтенияНастройки)
    Перем ПозСтр;
    Выбдата = РабочаяДата();
    ТЗ_Склады.НоваяКолонка("Флаг",,,,,4,,);
    ТЗ_Склады.НоваяКолонка("Склад",,,,,,,);
    ТЗ_Склады.ВыводитьПиктограммы("Флаг");

    ТЗ_Кассы.НоваяКолонка("Флаг",,,,,4,,);
    ТЗ_Кассы.НоваяКолонка("Касса",,,,,12,,);
    ТЗ_Кассы.НоваяКолонка("Номер",,,,,8,,);
    ТЗ_Кассы.НоваяКолонка("Каталог",,,,,,,);
    ТЗ_Кассы.ВыводитьПиктограммы("Флаг");

    //ВыбФирма = Константа.Магазин;

    СпрКассы = СоздатьОбъект("Справочник.Кассы");
    СпрКассы.ВыбратьЭлементы();
    Пока СпрКассы.ПолучитьЭлемент() = 1 Цикл
    Если (СпрКассы.Выбран() = 1) И (СпрКассы.РежимККМ = Перечисление.РежимыККМ.OffLine) Тогда
    Если ВыбФирма <> СпрКассы.Магазин Тогда
    Продолжить;
    КонецЕсли;

    ВыбКасса = СпрКассы.ТекущийЭлемент();
    ТЗ_Кассы.НоваяСтрока();
    ТЗ_Кассы.Флаг = 1;
    ТЗ_Кассы.Касса=СпрКассы.ТекущийЭлемент();
    ТЗ_Кассы.Номер=СпрКассы.ЗаводскойНомерККМ;
    ТЗ_Кассы.Каталог=СокрЛП(СпрКассы.КаталогОбмена);

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

    ТЗ_Склады.УдалитьСтроки();
    СписокСкладов.УдалитьВсе();
    Если ПустоеЗначение(ВыбКасса)=0 Тогда
    Если ПустоеЗначение(ВыбКасса.СкладКомпании)=0 Тогда
    СпрСклады = СоздатьОбъект("Справочник.Склады");
    СпрСклады.ВыбратьЭлементы();
    Пока СпрСклады.ПолучитьЭлемент()=1 Цикл
    Если
    (СпрСклады.СкладМагазина=ВыбКасса.СкладКомпании)или
    (СпрСклады.СкладМагазина2=ВыбКасса.СкладКомпании)
    Тогда
    ТЗ_Склады.НоваяСтрока();
    ТЗ_Склады.Флаг=1;
    ТЗ_Склады.Склад=СпрСклады.ТекущийЭлемент();
    СписокСкладов.ДобавитьЗначение(СпрСклады.ТекущийЭлемент());
    КонецЕсли;
    КонецЦикла;
    Иначе
    Сообщить("У кассы не задан магазин!");
    КонецЕсли
    КонецЕсли;

    Если ТЗ_Склады.КоличествоСтрок()=0 Тогда
    //Форма.Сформировать.Доступность(0);
    КонецЕсли;
    КонецПроцедуры // ПриОткрытии()

    Процедура ПриВыбореЯчейкиСоставаКассы()
    Перем ТекСтрока, ТекКолонка;

    // ТекСтрока = ТЗ_Склады.ТекущаяСтрока();
    ТЗ_Кассы.ТекущаяКолонка(, ТекКолонка);
    Если ТекКолонка = 1 Тогда //
    Если ТЗ_Кассы.Флаг=1 Тогда
    ТЗ_Кассы.Флаг=2;
    Иначе
    ТЗ_Кассы.Флаг=1;
    КонецЕсли;
    КонецЕсли;

    КонецПроцедуры // ПриВыбореЯчейкиСостава()

    СписокСкладов = СоздатьОбъект("СписокЗначений");
    ПерезаписыватьБазу = 0;
  2. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    21.520
    Симпатии:
    407
    Баллы:
    104
    Все подчиненные справочники тоже выбирать запросом. "Хором". По владельцу. Думаю время сократится до 1-2 минут максимум
  3. TopicStarter Overlay
    Александр Орлов
    Offline

    Александр Орлов

    Регистрация:
    3 окт 2012
    Сообщения:
    6
    Симпатии:
    0
    Баллы:
    1
    Мы этот запрос писали очень долго, впервые столкнулись со скулем и прямыми запросами, помогите пожалуйста :blush:
  4. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    21.520
    Симпатии:
    407
    Баллы:
    104
    Да все по аналогии!! Только выгрузите результат запроса в СЗ. В справочнике цен используйте реквизит ВЛАДЕЛЕЦ и (условие Владелец В СЗ)
  5. TopicStarter Overlay
    Александр Орлов
    Offline

    Александр Орлов

    Регистрация:
    3 окт 2012
    Сообщения:
    6
    Симпатии:
    0
    Баллы:
    1
    Хорошо, будем пробовать. Отпишусь что получится. Спасибо.

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