|
Формула ЧИСТВНДОХ в запросе | ☑ | ||
---|---|---|---|---|
0
alekosansey
19.11.18
✎
08:40
|
Добрый день. Есть конфигурация на 8.1 Бух для Казахстана. Есть обработка которая выполняет подсчет ГЭСВ(годовой эфективной ставки) и есть очень большой объем данных для которых нужно выполнить расчет. Подскажите как можно ускорить процесс
|
|||
1
alekosansey
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 Процедура Печать(ТЗ) ТабДокумент = Новый ТабличныйДокумент; Макет = ПолучитьМакет("Макет"); ОбластьШапка = Макет.ПолучитьОбласть("Шапка"); ОбластьШапка.Параметры.Пункт = Подразделение; ОбластьШапка.Параметры.НачДата = НачДата; ОбластьШапка.Параметры.КонДата = КонДата; ТабДокумент.Вывести(ОбластьШапка); ОбластьШапкаТЗ = Макет.ПолучитьОбласть("ШапкаТЗ"); ТабДокумент.Вывести(ОбластьШапкаТЗ); ОбластьДанныеТЗ= Макет.ПолучитьОбласть("ДанныеТЗ"); Для каждого Запись Из ТЗ Цикл ОбластьДанныеТЗ.Параметры.Заполнить(Запись); ТабДокумент.Вывести(ОбластьДанныеТЗ); Сообщить("Выведен в таблицу билет :"+Запись.ЗБ); КонецЦикла; ТабДокумент.Показать(); КонецПроцедуры; |
|||
2
alekosansey
19.11.18
✎
08:41
|
Как можно это реализовать в запросе. Если таковое возможно
|
|||
3
Один С
19.11.18
✎
08:55
|
//из метода золотого сечения
Вон оно чо. Почувствовал свою ущербность... |
|||
4
Один С
19.11.18
✎
08:57
|
Все не читал, но писать 365 в коде это не по пацански. Раз в 4 года будут вопросы.
|
|||
5
alekosansey
19.11.18
✎
09:02
|
Спасибо на счет 365 учту.
|
|||
6
Бубка Гоп
19.11.18
✎
09:08
|
(1) Пока (Шаг < -Точность) ИЛИ (Шаг > Точность) Цикл
вот тут то с запросом возникнет трудность |
|||
7
Мандалай
19.11.18
✎
09:33
|
Замер производительности что показывает?
Какие строки занимают больше всего времени? |
|||
8
alekosansey
22.11.18
✎
08:35
|
Он просто много делает итераций внутри крайнего цикла.
|
|||
9
alekosansey
22.11.18
✎
08:35
|
update
|
|||
10
alekosansey
22.11.18
✎
08:37
|
Знаю что проблема в функции ЧИСтВнДох но где не могу понять. Подскажите пожалуйста как укоротить количество итераций
|
|||
11
alekosansey
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.382//из метода золотого сечения КонецЕсли; КонецЦикла; //ГЭСВ = ПСК Возврат Формат(ПСК*100,"ЧЦ=10; ЧДЦ=2"); КонецФункции // -Sarge: 07/11/20 |
|||
12
alekosansey
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.382//из метода золотого сечения КонецЕсли; КонецЦикла; //ГЭСВ = ПСК Возврат Формат(ПСК*100,"ЧЦ=10; ЧДЦ=2"); КонецФункции // -Sarge: 07/11/20 |
|||
13
Asmody
22.11.18
✎
09:01
|
Я правильно понимаю, что ЧистВнДох() зависит от периода кредита и сумм кредита и вознаграждения? Причем, исходя из первого запроса, либо суммы равны, либо одна из них = 0, но в последнем случае страбатывает граничное условие.
Т.е. по факту у рассчета два параметра: сумма и период. Может закешировать результат расчета в таблице и повторно не рассчитывать для одинаковых значений параметров? |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |