gifts2017

Прямые запросы: ускорение получения цен для типовой ТиС 7.7

Опубликовал Алексей Каменец (leshik) в раздел Программирование - Практика программирования

Первая статья из цикла статей "Прямые запросы:...". Рассказывается о применении класса ПрямойЗапрос и компоненты 1С++ для ускорения функции глВернутьЦену() в типовой конфигурации Торговля и склад. Платформа 7.7.

Для внедрения разработки нам потребуется:

1. Компонента 1С++ (последняя версия);

2. Класс ПрямойЗапрос;

3. Для работы разработки в DBF базах - компонента 1sqlite (не ниже 1.0.2.3)

Опишем порядок загрузки компонент и подключения класса.

1. Скачиваем по вышеуказанным ссылкам компоненты и класс ПрямойЗапрос.

2. Располагаем компоненты либо в каталоге ИБ либо в требуемом нам общем каталоге (чтобы все базы использовали одинаковые версии компонент). Описываем загрузку ВК в ГМ конфигурации. 1С++ должна быть загружена самой первой - до всех компонент. Также в последней версии 1С++ изменилась загрузка компоненты. Теперь не требуется наличия административных прав и доступа к ветке реестра HKLM.

Любителей загружать 1С++ не в ГМ прошу ознакомится с рекомендациями по загрузке компоненты из модуля отчета (обработки).

3. Создаем в каталоге ИБ каталог Classes (или же создаем общий каталог если планируем использовать для всех баз одни классы). Создаем в каталоге ИБ файл defcls.prm и в него добавляем следующую строчку

#include Classes\ПрямыеЗапросы\classes.prm

Результатом правильного выполнения описанных выше действий будет наличие в окне Помощь>О Программе вкладки 1С++ и наличия в ней строки о зарегистрированном классе ПрямойЗапрос.

 

Переходим к описанию изменений в ГМ.

1. Добавим глобальную переменную

 Перем глПрямойЗапросЦен Экспорт;

 2. Добавим в ГМ процедуру:

 

 Процедура глИнициализироватьЗапросЦен()
                        глПрямойЗапросЦен.Текст= "
                        |ВЫБРАТЬ
                        | СрезПоследнихЦен.ТекущийЭлемент КАК [ЦенаНоменклатуры $Справочник.Цены]
                        |,СрезПоследнихЦен.Цена КАК [Цена $Число]
                        |,СрезПоследнихЦен.Единица КАК [Единица $Справочник.Единицы]
                        |,СрезПоследнихЦен.Процент КАК [Процент $Число]
                        |ИЗ
                        | $СрезПоследних.Цены(:ТекДата
                        |,(Цена,Единица,Процент)
                        |,(($СпрЦен.Владелец = @Товар) И ($СпрЦен.ТипЦен = @ТипЦен))
                        |,ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Цены КАК СпрЦен $nolock
                        |ПО ($СпрЦен.ТекущийЭлемент = ТекущийЭлемент) И ($СпрЦен.ПометкаУдаления = 0)
                        |) КАК СрезПоследнихЦен
                        |";
                        
                        
                        
                        //глПрямойЗапросЦен.ОписаниеПараметра("ДатаЦены","Дата");
                        глПрямойЗапросЦен.УстановитьТекстовыйПараметр("ТекДата",РабочаяДата());
                        глПрямойЗапросЦен.ОписаниеПараметра("Товар","Справочник.Номенклатура");
                        глПрямойЗапросЦен.ОписаниеПараметра("ТипЦен","Справочник.ТипыЦен");
                        глПрямойЗапросЦен.ПодготовитьПараметризованныйЗапрос();
                        
КонецПроцедуры // глИнициализироватьЗапросЦен

 

3. В процедуре ПриНачалеРаботыСистемы() добавим следующие строки:

 

                        глПрямойЗапросЦен = СоздатьОбъект("ПрямойЗапрос");
                        
                        //Параметризированный запрос для получения цен
                        глПрямойЗапросЦен.БухгалтерскийУчет = 0;
                        глПрямойЗапросЦен.ОперативныйУчет = 0;
                        глПрямойЗапросЦен.ПериодическиеЗначения = 1;
                        глИнициализироватьЗапросЦен();

 

4. Приведем функцию ГМ глВернутьЦену() к следующему виду:

 

Функция глВернутьЦену(Номенклатура, ТипЦены, ДатаЦены=0, ЦенаЦены=0, ЕдЦены=0, ВалЦены=0, НаценкаЦены=0, НайденнаяЦена=0) Экспорт
Перем ЦеныНоменклатуры;
Перем НужныйТипЦен;
Перем ЕстьУдаленные;
 
                        Рез=1; НайденнаяЦена=ПолучитьПустоеЗначение("Справочник.Цены");
 
                        Если ПустоеЗначение(ДатаЦены)=1 Тогда ДатаЦены=РабочаяДата();           КонецЕсли;
 
                        // Найдет или нужную цену в справочнике, если она рассчитывается, то найдем базовую цену
                        Рассчетная=ТипЦены.Рассчитывается;
                        НужныйТипЦен=?(ПустоеЗначение(Рассчетная)=1, ТипЦены, ТипЦены.БазовыйТипЦен);
                        глПрямойЗапросЦен.ПодставлятьПараметры("ТипЦен",НужныйТипЦен);
                        глПрямойЗапросЦен.ПодставлятьПараметры("Товар",Номенклатура);
                        ТзЦен = глПрямойЗапросЦен.ВыполнитьПараметризованныйЗапрос();
                        ТзЦен.ВыбратьСтроки();
                        Пока ТзЦен.ПолучитьСтроку()=1 Цикл
                                               НайденнаяЦена = ТзЦен.ЦенаНоменклатуры;
                                               ЦенаЦены = ТзЦен.Цена;
                                               ЕдЦены = ТзЦен.Единица;
                                               ВалЦены = НайденнаяЦена.Валюта;
                                               НаценкаЦены = НайденнаяЦена.Процент;
                                               Прервать;
                        КонецЦикла;
                        
                        Если ПустоеЗначение(НайденнаяЦена)=1 Тогда Возврат 0; КонецЕсли;
 
                        // Заполним все ценовые характериситики
 
                        // если не задана единица цены на эту дату, то потом придется обрабатывать случай нулевого коэффициента у пустой единицы
 
                        Если ПустоеЗначение(Рассчетная)=1 Тогда
                                               
                        Иначе
                                               //Если цена рассчитывается
                                               ПроцентНаценки = ТипЦены.Процент;
                                               БазоваяЦена=ЦенаЦены;
                                               БазоваяВалюта=ВалЦены;
                                               // Цены у базового типа могут отличаться
                                               ЦенаЦены=глПересчет(БазоваяЦена, БазоваяВалюта, ДатаЦены, ТипЦены.Валюта, ДатаЦены);
                                               ЦенаЦены=глОкруглить(ЦенаЦены*(100+ПроцентНаценки)/100, ТипЦены.ПорядокОкругления);
                                               // элемент справочника Цены не существует (расчетный). Валюту и Наценку возьмем из типа цены
                                               ВалЦены=ТипЦены.Валюта;
                                               НаценкаЦены=ПроцентНаценки;
                        КонецЕсли;
                        Возврат Рез;
КонецФункции

 

Ну вот собственно и все – разработка готова к работе на реальной базе.

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Александр Лыткин (TrinitronOTV) 15.11.11 14:08
очень нужная информация, спасибо большое
2. Олег Почекутов (PochekutovOleg) 15.11.11 14:26
3. Евгений Долиновский (Dolly_EV) 16.11.11 04:59
"Прямой запрос" и "Поставщик данных" - в массы!
4. vkr (vkr) 16.11.11 07:58
(0) Уважаемый автор, скажите, пожалуйста - можно ли с помощью описываемого Вами метода прямых запросов
каким-либо образом ускорить в ТиС 7.7 получение ГТД при подборе номенклатуры в расходную накладную?
А то мы имеем такой тормозище при запросе ГТД через партии - а партионный учет нам нафиг не сдался
(мы его не ведем)...
5. Алексей Каменец (leshik) 16.11.11 11:30
(4) vkr, Ускорить можно все.
Давайте обсудим через ICQ (201216980) вашу проблему и сделаем на основании её решения еще одну статью.
6. Евгений Долиновский (Dolly_EV) 16.11.11 11:59
(0) Автор, а почему "заремил" //глПрямойЗапросЦен.ОписаниеПараметра("ДатаЦены","Дата"); ?
И не используешь передаваемый в глВернутьЦену() параметр "ДатаЦены"?
Вобщем-то не только на РабочаяДата() нужны цены.
7. vkr (vkr) 16.11.11 12:42
(5) Спасибо, я в ближайшие пару дней обсужу с главбухом вопрос
вмешательства в конфу ТиС и, если что, с Вами свяжусь, ОК ?
8. Евгений Долиновский (Dolly_EV) 16.11.11 14:23
(6) понятно.."Параметры разрешено использовать только в секции «ДополнительныеУсловия».".. Как обойти?
9. Алексей Каменец (leshik) 16.11.11 17:33
(8) Dolly_EV,
На самом деле я на рабочей базе обошел проверкой изменения даты от предыдущей и переинициализацией запроса.
Вечером выложу этот вариант.
(7) Конечно можно.
10. marina ivanova (koffe) 16.11.11 20:40
11. Станислав Шепталов (sCHTASS) 18.11.11 10:18
А прирост какой вообще получается?
12. Максим Шуйский (maxpiter) 18.11.11 12:17
(9) Все еще ждем продолжения :)
Иначе реализация какая-то недоделанная.
13. Евгений Долиновский (Dolly_EV) 21.11.11 04:21
(9) Я тем же путем сначала пошел, но в итоге померил монитором время выполнения на одном отчете, где глВернутьЦену() сидит, как внешняя функция в запросе (штатном, 1С-ном). В итоге - не ускорение, а даже замедление получилось. Даже с учетом не переинициализации (смены даты не было)
14. Станислав Шепталов (sCHTASS) 21.11.11 19:29
(13) Мешать запросы 1с и 1с++ - это такое извращение!!!
Лучше массово получить цену на все товары, выгрузить в таблицу значений и тянуть их из нее.
dav405; maxpiter; +2 Ответить 1
15. Евгений Долиновский (Dolly_EV) 22.11.11 03:51
(14) Не вижу никакого извращения. Когда рабочая конфига, которая писалась 10 лет, переписывается на прямые запросы - одним махом ВСЕ СРАЗУ не перепишешь. Да и речь о том, что в данном конкретном случае (множественное получение цены) сей параметризованный запрос оказывается менее эффективным, чем штатный метод "Получить" и перебор по "ТипЦен"
16. Станислав Шепталов (sCHTASS) 22.11.11 19:59
(15) Я про частый случай, описанный в (13). Про то, что юзать функцию в запросе некошерно.

(0) Таки на мой вопрос никто не ответил. Прирост какой-нить есть? Самому проверить не на чем.
17. Максим Шуйский (maxpiter) 23.11.11 10:21
(16) прирост есть, но т.к. только на рабочую дату, то в живую не проверить, может на параметризированный запрос на 1cpp накидаете запрос?
18. Ольга Зверькова (Lyuba-Lyuba) 23.11.11 10:28
19. david (dav405) 28.11.11 08:23
Нет, только групповое получение цен поправляет. Замена в глВернутьЦену у меня (MSSQL2005, ТиС9.2, используя СрезПоследних ) привела к ЗАМЕДЛЕНИЮ.
20. Сергей (Che) Коцюра (CheBurator) 18.04.12 03:09
Прямо-таки родственный мой материал: http://infostart.ru/public/76287/
.
Помогал и учили меня признанные мэтры прямых запросов, за что им и спасибо.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа