Вход | Регистрация


Формула ЧИСТВНДОХ в запросе

Формула ЧИСТВНДОХ в запросе
Я
   alekosansey
 
19.11.18 - 08:40
Добрый день. Есть конфигурация на 8.1 Бух для Казахстана. Есть обработка которая выполняет подсчет ГЭСВ(годовой эфективной ставки) и есть очень большой объем данных для которых нужно выполнить расчет. Подскажите как можно ускорить процесс
 
 
   alekosansey
 
1 - 19.11.18 - 08:41
Процедура КнопкаВыполнитьНажатие(Кнопка)
УсловиеПункт ="";    
Запрос = Новый Запрос;
МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос.МенеджерВременныхТаблиц = МенеджерВт;
Если Подразделение.Пустая() Тогда

Иначе 
    УсловиеПункт = "И ФинДвиженияПоЗБ.Пункт = &Пункт";
КонецЕсли; 
Запрос.Текст = "ВЫБРАТЬ
               |    ФинДвиженияПоЗБ.Пункт КАК Пункт,
               |    ФинДвиженияПоЗБ.Регистратор.ЗБ КАК ЗБ,
               |    ФинДвиженияПоЗБ.Регистратор.Дата КАК ДатаВыдачи,
               |    ФинДвиженияПоЗБ.Регистратор.ДатаВозврата КАК ДатаВозврата,
               |    СУММА(ВЫБОР
               |            КОГДА ФинДвиженияПоЗБ.ДвижениеДС = &Выдача
               |                ТОГДА ФинДвиженияПоЗБ.Сумма
               |            ИНАЧЕ 0
               |        КОНЕЦ) КАК СуммаКредита,
               |    СУММА(ВЫБОР
               |            КОГДА ФинДвиженияПоЗБ.ДвижениеДС = &Вознаграждение
               |                    ИЛИ ФинДвиженияПоЗБ.ДвижениеДС = &КомСбор
               |                ТОГДА ФинДвиженияПоЗБ.Сумма
               |            ИНАЧЕ 0
               |        КОНЕЦ) КАК ДоходОтВыдачи
               |ПОМЕСТИТЬ ВтСырыеДанные
               |ИЗ
               |    РегистрНакопления.ФинДвиженияПоЗБ КАК ФинДвиженияПоЗБ
               |ГДЕ
               |    ФинДвиженияПоЗБ.Регистратор ССЫЛКА Документ.ВыдачаЗБ
               |    И ФинДвиженияПоЗБ.Период МЕЖДУ &НачДата И &КонДАта
               |    "+УсловиеПункт+"
               |
               |СГРУППИРОВАТЬ ПО
               |    ФинДвиженияПоЗБ.Пункт,
               |    ФинДвиженияПоЗБ.Регистратор.ЗБ,
               |    ФинДвиженияПоЗБ.Регистратор.Дата,
               |    ФинДвиженияПоЗБ.Регистратор.ДатаВозврата
               |;
               |
               ////////////////////////////////////////////////////////////////////////////////

               |ВЫБРАТЬ
               |    ВтСырыеДанные.Пункт,
               |    ВтСырыеДанные.ЗБ,
               |    ВтСырыеДанные.ДатаВыдачи,
               |    ВтСырыеДанные.ДатаВозврата,
               |    ВтСырыеДанные.СуммаКредита,
               |    ВтСырыеДанные.ДоходОтВыдачи,
               |    ВтСырыеДанные.СуммаКредита + ВтСырыеДанные.ДоходОтВыдачи КАК СуммаГашения
               |ПОМЕСТИТЬ ВтДанныеБезГЭСВ
               |ИЗ
               |    ВтСырыеДанные КАК ВтСырыеДанные
               |;
               |
               ////////////////////////////////////////////////////////////////////////////////

               |ВЫБРАТЬ
               |    ВтДанныеБезГЭСВ.Пункт,
               |    ВтДанныеБезГЭСВ.ЗБ,
               |    ВтДанныеБезГЭСВ.ДатаВыдачи,
               |    ВтДанныеБезГЭСВ.ДатаВозврата,
               |    ВтДанныеБезГЭСВ.СуммаКредита,
               |    ВтДанныеБезГЭСВ.ДоходОтВыдачи,
               |    ВтДанныеБезГЭСВ.СуммаГашения
               |ИЗ
               |    ВтДанныеБезГЭСВ КАК ВтДанныеБезГЭСВ";
               
Запрос.УстановитьПараметр("Вознаграждение",Справочники.СтатьиДвиженияДенежныхСредств.НайтиПоКоду("000000074"));
Запрос.УстановитьПараметр("КомСбор",Справочники.СтатьиДвиженияДенежныхСредств.НайтиПоКоду("000000073"));
Запрос.УстановитьПараметр("Выдача",Справочники.СтатьиДвиженияДенежныхСредств.НайтиПоКоду("000000072"));
Запрос.УстановитьПараметр("Пункт",Подразделение);
Запрос.УстановитьПараметр("НачДАта",НачДата);
Запрос.УстановитьПараметр("КОнДата",КонДата);
Выборка = Запрос.Выполнить().Выбрать();
ТабДок = Новый ТаблицаЗначений;
ТабДок.Колонки.Добавить("ЗБ",Новый ОписаниеТипов("СправочникССылка.ЗалоговыеБилеты"));
ТабДок.Колонки.Добавить("ГЭСВ",Новый ОписаниеТипов("Число"));

Пока Выборка.Следующий() Цикл
      ТекСтрока = ТабДок.Добавить();
      ТекСтрока.ЗБ = Выборка.ЗБ;
      ТекСтрока.ГЭСВ = ЧистВнДох(Выборка.ДатаВыдачи,Выборка.СуммаКредита,Выборка.ДатаВозврата,Выборка.ДоходОтВыдачи);
КонецЦикла; 

Запрос2 = Новый ЗАпрос;
Запрос2.Текст =  "ВЫБРАТЬ
                 |    ЗБСГЭСВ.ЗБ,
                 |    ЗБСГЭСВ.ГЭСВ
                 |ПОМЕСТИТЬ ВТЗБСГЭСВ
                 |ИЗ
                 |    &ЗБСГЭСВ КАК ЗБСГЭСВ
                 |;
                 |
                 ////////////////////////////////////////////////////////////////////////////////

                 |ВЫБРАТЬ
                 |    ВтДанныеБезГЭСВ.Пункт,
                 |    ВтДанныеБезГЭСВ.ЗБ КАК ЗБ,
                 |    ВтДанныеБезГЭСВ.ДатаВыдачи,
                 |    ВтДанныеБезГЭСВ.ДатаВозврата,
                 |    ВтДанныеБезГЭСВ.СуммаКредита,
                 |    ВтДанныеБезГЭСВ.ДоходОтВыдачи,
                 |    ВтДанныеБезГЭСВ.СуммаГашения,
                 |    ВТЗБСГЭСВ.ГЭСВ
                 |ИЗ
                 |    ВтДанныеБезГЭСВ КАК ВтДанныеБезГЭСВ
                 |        ЛЕВОЕ СОЕДИНЕНИЕ ВТЗБСГЭСВ КАК ВТЗБСГЭСВ
                 |        ПО ВтДанныеБезГЭСВ.ЗБ = ВТЗБСГЭСВ.ЗБ
                 |
                 |УПОРЯДОЧИТЬ ПО
                 |    ЗБ";
Запрос2.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос2.УстановитьПараметр("ЗБСГЭСВ",ТабДок);
ТЗ = Запрос2.Выполнить().Выгрузить();

Печать(ТЗ);

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

//Описание:

//Входные параметры:
// ДатаВыдачи,

// СуммаКредита (СуммаК),
// ДатаВозврата,

// СтавкаВознаграждение,
// Срок,

Функция ЧистВнДох(ДатаВыдачи, СуммаКредита, ДатаВозврата, СуммаВознаграждения, Точность = 0.01) экспорт
    
    Если ДатаВыдачи = Null или СуммаКредита = 0 или ДатаВозврата = null или СуммаВознаграждения = 0  Тогда
        Возврат 0;
    КонецЕсли; 

    ТаблицаРасчета = Новый ТаблицаЗначений;
    ТаблицаРасчета.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата", новый КвалификаторыДаты(ЧастиДаты.Дата)));
    ТаблицаРасчета.Колонки.Добавить("РазностьДат");
    ТаблицаРасчета.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10,2)));
    
    НоваяСтрокаТаблицаРасчета = ТаблицаРасчета.Добавить();
    НоваяСтрокаТаблицаРасчета.Дата = НачалоДня(ДатаВыдачи);
    НоваяСтрокаТаблицаРасчета.РазностьДат = (НачалоДня(ДатаВыдачи) - НачалоДня(ДатаВыдачи)) / (24 * 60 * 60) / 365;
    НоваяСтрокаТаблицаРасчета.Сумма = -СуммаКредита;
    
    НоваяСтрокаТаблицаРасчета = ТаблицаРасчета.Добавить();
    НоваяСтрокаТаблицаРасчета.Дата = НачалоДня(ДатаВозврата);
    НоваяСтрокаТаблицаРасчета.РазностьДат = (НачалоДня(ДатаВозврата) - НачалоДня(ДатаВыдачи)) / (24 * 60 * 60) / 365;
    НоваяСтрокаТаблицаРасчета.Сумма = СуммаКредита+СуммаВознаграждения;
    
    //

    ПСК = 0.1;
    Сумма = 0;
    Для каждого СтрокаРасчета Из ТаблицаРасчета Цикл
        Сумма = Сумма + СтрокаРасчета.Сумма / Pow(1 + ПСК, СтрокаРасчета.РазностьДат)
    КонецЦикла; 
     
    Если Сумма > 0 Тогда
        Шаг = 0.382 * ПСК;
     Иначе
        Шаг = -0.382 * ПСК;
    КонецЕсли;

    Пока (Шаг < -Точность) ИЛИ (Шаг > Точность) Цикл
        ПСК = ПСК + Шаг;
        Сумма = 0;
        Для каждого СтрокаРасчета Из ТаблицаРасчета Цикл
            Сумма = Сумма + СтрокаРасчета.Сумма / Pow(1 + ПСК, СтрокаРасчета.РазностьДат)
            
        КонецЦикла;
        Если Сумма * Шаг < 0 Тогда
            Шаг = -Шаг * 0.382//из метода золотого сечения

        КонецЕсли;
    КонецЦикла;
    //ГЭСВ = ПСК

    Возврат Формат(ПСК*100,"ЧЦ=10; ЧДЦ=2");
    
КонецФункции
// -Sarge: 07/11/2018


Процедура Печать(ТЗ)
    ТабДокумент = Новый ТабличныйДокумент;
    
    Макет = ПолучитьМакет("Макет");
    ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
    
    ОбластьШапка.Параметры.Пункт = Подразделение;
    ОбластьШапка.Параметры.НачДата = НачДата;
    ОбластьШапка.Параметры.КонДата = КонДата;
    ТабДокумент.Вывести(ОбластьШапка);
    
    ОбластьШапкаТЗ = Макет.ПолучитьОбласть("ШапкаТЗ");
    ТабДокумент.Вывести(ОбластьШапкаТЗ);
    
    ОбластьДанныеТЗ= Макет.ПолучитьОбласть("ДанныеТЗ");
    
    Для каждого Запись Из ТЗ Цикл
    
        ОбластьДанныеТЗ.Параметры.Заполнить(Запись);
        ТабДокумент.Вывести(ОбластьДанныеТЗ);
        Сообщить("Выведен в таблицу билет :"+Запись.ЗБ);
    КонецЦикла;
    
    ТабДокумент.Показать();
    
КонецПроцедуры;
   alekosansey
 
2 - 19.11.18 - 08:41
Как можно это реализовать в запросе. Если таковое возможно
   Один С
 
3 - 19.11.18 - 08:55
//из метода золотого сечения


Вон оно чо. 
Почувствовал свою ущербность...
   Один С
 
4 - 19.11.18 - 08:57
Все не читал, но писать 365 в коде это не по пацански. Раз в 4 года будут вопросы.
   alekosansey
 
5 - 19.11.18 - 09:02
Спасибо на счет 365 учту.
   Бубка Гоп
 
6 - 19.11.18 - 09:08
(1)   Пока (Шаг < -Точность) ИЛИ (Шаг > Точность) Цикл

вот тут то с запросом возникнет трудность
   Мандалай
 
7 - 19.11.18 - 09:33
Замер производительности что показывает?
Какие строки занимают больше всего времени?
   alekosansey
 
8 - 22.11.18 - 08:35
Он просто много делает итераций внутри крайнего цикла.
   alekosansey
 
9 - 22.11.18 - 08:35
update
   alekosansey
 
10 - 22.11.18 - 08:37
Знаю что проблема в функции ЧИСтВнДох но где не могу понять. Подскажите пожалуйста как укоротить количество итераций
 
 Рекламное место пустует
   alekosansey
 
11 - 22.11.18 - 08:38
//Описание:


//Входные параметры:

// ДатаВыдачи,

// СуммаКредита (СуммаК),

// ДатаВозврата,

// СтавкаВознаграждение,

// Срок,

Функция ЧистВнДох(ДатаВыдачи, СуммаКредита, ДатаВозврата, СуммаВознаграждения, Точность = 0.01) экспорт
    
    Если ДатаВыдачи = Null или СуммаКредита = 0 или ДатаВозврата = null или СуммаВознаграждения = 0  Тогда
        Возврат 0;
    КонецЕсли; 

    ТаблицаРасчета = Новый ТаблицаЗначений;
    ТаблицаРасчета.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата", новый КвалификаторыДаты(ЧастиДаты.Дата)));
    ТаблицаРасчета.Колонки.Добавить("РазностьДат");
    ТаблицаРасчета.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10,2)));
    
    НоваяСтрокаТаблицаРасчета = ТаблицаРасчета.Добавить();
    НоваяСтрокаТаблицаРасчета.Дата = НачалоДня(ДатаВыдачи);
    НоваяСтрокаТаблицаРасчета.РазностьДат = (НачалоДня(ДатаВыдачи) - НачалоДня(ДатаВыдачи)) / (24 * 60 * 60) / 365;
    НоваяСтрокаТаблицаРасчета.Сумма = -СуммаКредита;
    
    НоваяСтрокаТаблицаРасчета = ТаблицаРасчета.Добавить();
    НоваяСтрокаТаблицаРасчета.Дата = НачалоДня(ДатаВозврата);
    НоваяСтрокаТаблицаРасчета.РазностьДат = (НачалоДня(ДатаВозврата) - НачалоДня(ДатаВыдачи)) / (24 * 60 * 60) / 365;
    НоваяСтрокаТаблицаРасчета.Сумма = СуммаКредита+СуммаВознаграждения;
    
    //


    ПСК = 0.1;
    Сумма = 0;
    Для каждого СтрокаРасчета Из ТаблицаРасчета Цикл
        Сумма = Сумма + СтрокаРасчета.Сумма / Pow(1 + ПСК, СтрокаРасчета.РазностьДат)
    КонецЦикла; 
     
    Если Сумма > 0 Тогда
        Шаг = 0.382 * ПСК;
     Иначе
        Шаг = -0.382 * ПСК;
    КонецЕсли;

    Пока (Шаг < -Точность) ИЛИ (Шаг > Точность) Цикл
        ПСК = ПСК + Шаг;
        Сумма = 0;
        Для каждого СтрокаРасчета Из ТаблицаРасчета Цикл
            Сумма = Сумма + СтрокаРасчета.Сумма / Pow(1 + ПСК, СтрокаРасчета.РазностьДат)
            
        КонецЦикла;
        Если Сумма * Шаг < 0 Тогда
            Шаг = -Шаг * 0.38//из метода золотого сечения


        КонецЕсли;
    КонецЦикла;
    //ГЭСВ = ПСК


    Возврат Формат(ПСК*100,"ЧЦ=10; ЧДЦ=2");
    
КонецФункции
// -Sarge: 07/11/20
   alekosansey
 
12 - 22.11.18 - 08:41
точнее

//Описание:
//Входные параметры:

// ДатаВыдачи,

// СуммаКредита (СуммаК),

// ДатаВозврата,

// СтавкаВознаграждение,

// Срок,

Функция ЧистВнДох(ДатаВыдачи, СуммаКредита, ДатаВозврата, СуммаВознаграждения, Точность = 0.01) экспорт
    
    Если ДатаВыдачи = Null или СуммаКредита = 0 или ДатаВозврата = null или СуммаВознаграждения = 0  Тогда
        Возврат 0;
    КонецЕсли; 

    ТаблицаРасчета = Новый ТаблицаЗначений;
    ТаблицаРасчета.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата", новый КвалификаторыДаты(ЧастиДаты.Дата)));
    ТаблицаРасчета.Колонки.Добавить("РазностьДат");
    ТаблицаРасчета.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10,2)));
    
    НоваяСтрокаТаблицаРасчета = ТаблицаРасчета.Добавить();
    НоваяСтрокаТаблицаРасчета.Дата = НачалоДня(ДатаВыдачи);
    НоваяСтрокаТаблицаРасчета.РазностьДат = (НачалоДня(ДатаВозврата) - НачалоДня(ДатаВыдачи)) / (24 * 60 * 60) / 365;
    НоваяСтрокаТаблицаРасчета.Сумма = -СуммаКредита;
    
    НоваяСтрокаТаблицаРасчета = ТаблицаРасчета.Добавить();
    НоваяСтрокаТаблицаРасчета.Дата = НачалоДня(ДатаВозврата);
    НоваяСтрокаТаблицаРасчета.РазностьДат = (НачалоДня(ДатаВозврата) - НачалоДня(ДатаВыдачи)) / (24 * 60 * 60) / 365;
    НоваяСтрокаТаблицаРасчета.Сумма = СуммаКредита+СуммаВознаграждения;
    
    //


    ПСК = 0.1;
    Сумма = 0;
    Для каждого СтрокаРасчета Из ТаблицаРасчета Цикл
        Сумма = Сумма + СтрокаРасчета.Сумма / Pow(1 + ПСК, СтрокаРасчета.РазностьДат)
    КонецЦикла; 
     
    Если Сумма > 0 Тогда
        Шаг = 0.382 * ПСК;
     Иначе
        Шаг = -0.382 * ПСК;
    КонецЕсли;

    Пока (Шаг < -Точность) ИЛИ (Шаг > Точность) Цикл
        ПСК = ПСК + Шаг;
        Сумма = 0;
        Для каждого СтрокаРасчета Из ТаблицаРасчета Цикл
            Сумма = Сумма + СтрокаРасчета.Сумма / Pow(1 + ПСК, СтрокаРасчета.РазностьДат)
            
        КонецЦикла;
        Если Сумма * Шаг < 0 Тогда
            Шаг = -Шаг * 0.38//из метода золотого сечения


        КонецЕсли;
    КонецЦикла;
    //ГЭСВ = ПСК


    Возврат Формат(ПСК*100,"ЧЦ=10; ЧДЦ=2");
    
КонецФункции
// -Sarge: 07/11/20
   Asmody
 
13 - 22.11.18 - 09:01
Я правильно понимаю, что ЧистВнДох() зависит от периода кредита и сумм кредита и вознаграждения? Причем, исходя из первого запроса, либо суммы равны, либо одна из них = 0, но в последнем случае страбатывает граничное условие.
Т.е. по факту у рассчета два параметра: сумма и период.
Может закешировать результат расчета в таблице и повторно не рассчитывать для одинаковых значений параметров?

Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Рекламное место пустует