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

15.11.11

Разработка - Запросы

Первая статья из цикла статей "Прямые запросы:...". Рассказывается о применении класса ПрямойЗапрос и компоненты 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С v7.7 Платформа 1С v8.3 Бесплатно (free)

Очень часто нужно при работе с HTTP сервисами или сайтами использовать Асинхронные HTTP запросы, отправку на сервер нескольких файлов, использование сжатия трафика. Эта статья про то, как этого легко добиться.

09.03.2016    38266    Serginio    22    

44

Универсальные функции Запросы Программист Платформа 1С v7.7 Платформа 1С v8.3 Бесплатно (free)

На эту тему уже есть статьи, но этот способ нигде не описан. Хотя я его использую с тех пор, как занимаюсь программированием. Его преимущество в простоте и универсальности: можно применять на 1С, SQL, а также в любом другом языке программирования.

05.07.2015    21955    json    3    

22

Запросы Программист Платформа 1С v7.7 Конфигурации 1cv7 Абонемент ($m)

Пример получения остатков по складу по запросу по почте из программы 1С 7.7. Для получения остатков необходимо пользователю с любого почтовика (с любого "мыла") отправить текст сообщения GiveMyStockBalance_ForAnalize на почтовый адрес определенный в Константа.СерверПолучения. Программа выдаст остатки (можно переписать функцию для выдачи любых данных) в формате xls на почту указанную в константе Константа.СерверОтправки. Программа может быть полезна в тех организациях где трудно или невозможно осуществить прямой доступ к 1С сотрудников для просмотра необходимых данных. Также можно организовать некий почтамт - запрос для клиентов - при посылке определенного логина клиентом на его почту будет автоматически выслана информация, например, акт сверки с клиентов, или процент выполнения его заказа и т.д.

3 стартмани

25.03.2014    25303    5    protexprotex    3    

5

Зарплата Запросы Программист Расчет 7.7 1С:Зарплата и кадры 7.7 Абонемент ($m)

Обзор методов реализации условий и функций с условиями в обращениях к журналу расчетов при помощи прямого запроса.

1 стартмани

06.12.2012    14214    nicotin    5    

9

Запросы Платформа 1С v7.7 Оперативный учет 7.7 Бухгалтерский учет 7.7 Расчет 7.7 Конфигурации 1cv7 Абонемент ($m)

Универсальный отчет для конфигураций на платформе 1С 7.7. Умеет обращатся к справочникам, документам, регистрам и журналам расчетов. Удобен для быстрого получения каких либо данных, которые можно получить посредствам запроса. Предусмотренна возможность сохранения настроек.

1 стартмани

14.04.2012    34141    305    set2333    16    

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

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

Периодические значения в ПрямомЗапросе имеет смысл использовать только для массового получения значений. Вот тогда он идеально и быстро отрабатывает.
Оставьте свое сообщение