Имя: Пароль:
1C
1C 7.7
v7: Можно ли ускорить глВернутьЦену()
,
0 zenon46
 
05.04.19
12:25
Доброго дня!
Снова немного некрофилии, начал притормаживать справочник Номенклатура, и в частности выборка цен, через глВернутьЦену, там реализован тупо перебор справочника ТипыЦен по владельцу, короче долго. Наткнулся вот на это http://catalog.mista.ru/public/76337/, но не завелась, спится в ошибку.
Идея типы не использовать выборку "Пока ЦеныНоменклатуры.ПолучитьЭлемент()  = 1 Цикл", за менить на НайтиПоРеквизиту, думаю не даст выигрыша. Может есть у кого рабочий пример этой функции ?
1 1Сергей
 
05.04.19
12:27
Для списка лучше сделать функцию получения всех цен за одно обращение к базе
2 Kigo_Kigo
 
05.04.19
12:27
Запрос к переодике?
3 VladZ
 
05.04.19
12:28
(0) переход на НайтиПоРеквизиту улучшит ситуацию. Если нужно еще быстрее - переходи на прямые запросы.
4 Garykom
 
гуру
05.04.19
12:28
Эээ в 77 как бы есть запросы, конечно они очень специфичные но при правильном употреблении работают сильно шустрее чем прямой доступ через курсоры.
5 1Сергей
 
05.04.19
12:28
Ну, и текст ошибки не конфиденциальная информация же :)
6 Вафель
 
05.04.19
12:28
на прямом скл если написать, то можно
7 Вафель
 
05.04.19
12:29
а ну собственно это и есть в (0)
8 Garykom
 
гуру
05.04.19
12:30
(0) Код "глВернутьЦену" в студию
9 Холст
 
05.04.19
12:33
(0) если сложно через объект "ПрямойЗапрос", то попробуй "обычный" запрос через компоненту 1CPP
используя $ПоследнееЗначение.Цены.Цена(СпрЦ.id,:КонДата)  [Цена$Число.15.2]
10 zenon46
 
05.04.19
12:36
(8) код штатный
Функция глВернутьЦену(Номенклатура, ТипЦены, ДатаЦены = 0, ЦенаЦены = 0, ЕдЦены = 0, ВалЦены = 0, НаценкаЦены = 0, НайденнаяЦена = 0) Экспорт
    Перем ЦеныНоменклатуры;
    Перем Рассчетная;
    Перем НужныйТипЦен;
    Перем ЕстьУдаленные;
    
    Рез = 1;
    НайденнаяЦена = ПолучитьПустоеЗначение("Справочник.Цены");
    
    Если ПустоеЗначение(ДатаЦены) = 1 Тогда
        ДатаЦены = РабочаяДата();
    КонецЕсли;

    // Найдет или нужную цену в справочнике
    // если она рассчитывается, то найдем базовую цену
    Рассчетная        = ТипЦены.Рассчитывается;
    НужныйТипЦен    = ?(ПустоеЗначение(Рассчетная) = 1, ТипЦены, ТипЦены.БазовыйТипЦен);
    
    ЦеныНоменклатуры= СоздатьОбъект("Справочник.Цены");
    ЦеныНоменклатуры.ИспользоватьВладельца(Номенклатура);
    
    ЦеныНоменклатуры.ВыбратьЭлементы();
    
    Пока ЦеныНоменклатуры.ПолучитьЭлемент()  = 1 Цикл    
        Если ЦеныНоменклатуры.ТипЦен <> НужныйТипЦен Тогда
            Продолжить;
        КонецЕсли;
        
        НайденнаяЦена = ЦеныНоменклатуры.ТекущийЭлемент();
        
        Если ЦеныНоменклатуры.ПометкаУдаления() = 1 Тогда
            Рез = - 1; // Цена есть, но помечена на удаление
            Продолжить;
        Иначе
            Прервать;
        КонецЕсли;
        
    КонецЦикла;      
    
    Если ПустоеЗначение(НайденнаяЦена) = 1 Тогда
        
        // Нет такой цены
        Возврат 0;
    КонецЕсли;
    
    // Заполним все ценовые характериситики
    
    // если не задана единица цены на эту дату, то потом придется обрабатывать случай нулевого коэффициента у  пустой единицы
    ЕдЦены        = НайденнаяЦена.Единица.Получить(ДатаЦены);
    
    Если ПустоеЗначение(Рассчетная) = 1 Тогда
        
        //Если цена не рассчитывается
        ЦенаЦены    = НайденнаяЦена.Цена.Получить(ДатаЦены);
        
        // элемент справочника существует Валюту и Наценку возьмем из него
        ВалЦены        = НайденнаяЦена.Валюта;
        НаценкаЦены    = НайденнаяЦена.Процент;
    Иначе
        
        //Если цена рассчитывается
        БазоваяЦена     = НайденнаяЦена.Цена.Получить(ДатаЦены);
        БазоваяВалюта    = НайденнаяЦена.Валюта;
        
        // Цены у базового типа могут отличаться
        ЦенаЦены    = глПересчет(БазоваяЦена, БазоваяВалюта, ДатаЦены, ТипЦены.Валюта, ДатаЦены);
        ЦенаЦены    = глОкруглить(ЦенаЦены * (100 + ТипЦены.Процент) / 100, ТипЦены.ПорядокОкругления);
        
        // элемент справочника Цены не существует (расчетный). Валюту и Наценку возьмем из типа цены
        ВалЦены        = ТипЦены.Валюта;
        НаценкаЦены    = ТипЦены.Процент;
    КонецЕсли;
    
    Возврат Рез;
КонецФункции // глВернутьЦену()
11 Холст
 
05.04.19
12:40
(0) Засада в том, что цена может быть расчетной от другой цены, которая тоже расчетная и дальше длинная цепочка расчетных цен. И тогда функция сложная будет.
Если в базе нет цепочки расчетных цен или она короткая, то можно ограничиться
$ПоследнееЗначение.Цены.Цена(СпрЦ.id,:КонДата)  [Цена$Число.15.2]
или соединением с расчетной ценой

Также для ускорения можно один раз (при старте или время от времени) рассчитывать таблицу цен и хранить её или в глобальной ТЗ или в дополнительной SQL таблице (Наподобие идТовара/идТипЦены/Дата/Цена )
12 opus70
 
05.04.19
12:43
(11) сам провинциный и самый быстрый вариант отдельная таблица
так как4 не так уж часто цена меняется
13 Сияющий в темноте
 
05.04.19
12:45
(11)кеш цен в индексированной таблице-хорошая идея.
какие бы не были расчетные цены и т.п.обычно,цена нужна на сейчас,то есть действующая,кеш спасет,а для тех,кому нужна цена из истории,можно и подождать.
кстати,очень интересный вопрос,почему расчетные цены нужно пересчитывать каждый раз,а не только при изменении цены,от которой зависит расчет?
14 opus70
 
05.04.19
12:45
и если человек задумался об ускорении глВернутьЦену , то уж точно перепилить под отдельную таблицу или расчет цен в справочник другой и так далее уже не стоит такой уж не выполнимой задачей,
так как значит товаров много клиентов тоже
15 Базис
 
naïve
05.04.19
12:51
Флаг изменения цены и таблица с текущими ценами, обновляемая по сбросу флага.

Сколько пользователей, сколько документов в день, сколько типов цен фактически используются?
16 Kigo_Kigo
 
05.04.19
12:51
(13) Потому что есть у тебя 2 отдела, отдел закупок и отдел продаж, цена продажи строго + 30% на закупку, отдел продаж в душе не знает, что там делает отдел закупок, а цена нужна сейчас, а когда там приход вбивают ХЗ
17 zenon46
 
05.04.19
12:55
(15) пользователей 40, документов по разному, не считал если честно, отдел закупок обновляет цены через документы "Установка цен", цен расчетных нет (в классическом понимании), они рассчитываются при записи в документе "установка цен", 8 типов цен всего.
18 opus70
 
05.04.19
12:56
(16)тогда в расходной накладной добавить одну кнопку
РАСЧЕТ ЦЕНЫ и работа строиться вот так

Набили по остатку нажали кнопку рассчитать цену, рассчитать 100 позиций всегда быстрей чем бежать по подбору и считать на лету
19 zenon46
 
05.04.19
12:56
Иногда цены необходимо получать на предыдущую дату, а не на текущую. Главный тормоз это отоброжение списка номенклатуры в котором выведены 3 колонки с "базовыми" ценами и их хотят видеть он-лайн.
20 Злопчинский
 
05.04.19
12:56
все уже сделано до вас
http://catalog.mista.ru/public/76287/
21 Базис
 
naïve
05.04.19
12:56
Пора слезать с файловой :)

Найди Павла Шемякина, ToyPaul - он переделывал типовую ТиС на быстрые запросы.
22 zenon46
 
05.04.19
12:57
(21) так база SQL, 40 гигов
23 1Сергей
 
05.04.19
12:57
(22) текст ошибки будет или нет?
24 zenon46
 
05.04.19
12:58
(23) да тот код уже похерил, но ради инетреса верну назад, и скину ошибку.
25 opus70
 
05.04.19
12:58
(22) тодда тем более ищи как тебе посоветовали самый быстрый способ все ускорить
26 opus70
 
05.04.19
13:02
(22)ну или пуст кто нибуть поделиться у кого осталось эта библиотека с обработками там полный комплект для ТИС очень удобно и отчеты и модули проведения
27 Aleksey
 
05.04.19
13:06
Переходи на эмуляцию рс средствами рн
28 opus70
 
05.04.19
13:06
(22) у меня к несчастью она канула на умершем ноутбуке а организации которым покупал канули за данностью лет нет ничего вечного
29 uno-group
 
05.04.19
13:54
Пиши свою функцию в справочник ТМЦ. При Открытии создай справочник цен. у раз рассчитай коэффициент пересчета исходя из курсов, если конечно цены не в разных валютах. Можно пихать в сам справочник ТМЦ последние актуальную цену при изменение справочника цен. А если дата не актуальная лесть в справочник цен. В основном будет все летать, а любящие лазить в прошлое подождут.
30 Злопчинский
 
05.04.19
23:09
(22) и чего? у меня файловая на 10 гигов почти. из прямых запросов в оперативной работе - ничего нет. и все нормально работают.
.
проблемы зависят не столько от объема базы сколько от текущей интенсивности работы. хочешь мощность - много за короткое время - база начгет потеть точно так как человек.
31 Сияющий в темноте
 
05.04.19
23:36
Можно в кеше держать не одно значение,а несколько на нужный период,а остальное в историю и подчиненный справочник,чтобы периодику не трясти.
Компьютеры — прекрасное средство для решения проблем, которых до их появления не было.