|
v8: динамический запрос. | ☑ | ||
---|---|---|---|---|
0
zladenuw
28.02.13
✎
13:51
|
Есть справочник который хранит показатели. если формула пустаю то передаем в запрос показатель как параметр. если же у параметра есть формула. смотрим параметры формулы.
это сделал. вопрос только как сделать так. что если в формуле есть показатели. которые так же расчитываются. пока нет мысли как это сделать. Вот запрос. Функция ПостроениеЗапросаПоФормулеБюджета(Алгоритм,Год,МесяцК,МесяцН,Подразделение) Экспорт ТекстЗапросаОбщий = ""; ТекстЗапросаОбщий2 = ""; Если Алгоритм = Null или Алгоритм = Неопределено Тогда возврат 0; КонецЕсли; Попытка Формула = Алгоритм.Формула; ПараметрыФормулы = Алгоритм.ПараметрыФормулы; Исключение Возврат 0; КонецПопытки; Для каждого ПараметрФормулы из ПараметрыФормулы Цикл ТекстЗапроса = ПолучитьТекстЗапросаВложеннойФормулы(ПараметрФормулы); Если ПараметрыФормулы.Индекс(ПараметрФормулы)=0 тогда ТекстЗапросаОбщий = ТекстЗапроса; Иначе ТекстЗапросаОбщий2 = ТекстЗапросаОбщий2+", |("+ТекстЗапроса+")"+"КАК "+ПараметрФормулы.ПараметрИмя; КонецЕсли; КонецЦикла; ТекстПодмены = "ВЫБРАТЬ | "; ТекстПараметры = ""; Для каждого ПараметрФормулы из ПараметрыФормулы Цикл Формула = СтрЗаменить(Формула,ПараметрФормулы.ПараметрИмя,"ЕстьNull("+ПараметрФормулы.ПараметрИмя+".Первонач"+",0)"); КонецЦикла; ТекстПараметры = "("+Формула+") КАК "+"Итог"; ТекстПоиска = "ВЫБРАТЬ | "+ПараметрыФормулы[0].ПараметрИмя+".Первонач"; ТекстЗапросаОбщий = СтрЗаменить(ТекстЗапросаОбщий,ТекстПоиска,ТекстПодмены+ТекстПараметры); ТекстЗапросаОбщий =ТекстЗапросаОбщий+ТекстЗапросаОбщий2; ТекстЗапросаОбщий = ТекстЗапросаОбщий; Запрос = Новый Запрос(ТекстЗапросаОбщий); Для каждого ПараметрФормулы из ПараметрыФормулы Цикл Запрос.УстановитьПараметр(ПараметрФормулы.ПараметрИмя,ПараметрФормулы.ПараметрЗначение); КонецЦикла; Запрос.УстановитьПараметр("Год",Год); Запрос.УстановитьПараметр("МесяцК",МесяцК); Запрос.УстановитьПараметр("МесяцН",МесяцН); Запрос.УстановитьПараметр("Подразделение",Подразделение); Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл Возврат Выборка.Итог; КонецЦикла; Возврат 0; КонецФункции Функция ПолучитьТекстЗапросаВложеннойФормулы(Параметр) ТекстЗапроса = ""; Если ТипЗнч(Параметр.ПараметрЗначение) = Тип("Число") Тогда ТекстЗапроса = "ВЫБРАТЬ | "+Параметр.ПараметрИмя+".Первонач |ИЗ | (ВЫБРАТЬ | СУММА(&"+Параметр.ПараметрИмя+") КАК Первонач) КАК "+Параметр.ПараметрИмя+""; ИначеЕсли ТипЗнч(Параметр.ПараметрЗначение) = Тип("СправочникСсылка.СтатьиДоходовИРасходов") Тогда ДоходРасход = ?(Параметр.Доход,"Доходы","Расходы"); Доход = Параметр.Доход; ТекстЗапроса = "ВЫБРАТЬ | "+Параметр.ПараметрИмя+".Первонач |ИЗ | (ВЫБРАТЬ | СУММА(ВЫБОР | КОГДА ПланированиеБюджетаДоходыРасходы.Ссылка.Версия = 2 | ТОГДА ПланированиеБюджетаДоходыРасходы.Сумма | ИНАЧЕ 0 | КОНЕЦ) КАК Первонач, | СУММА(ВЫБОР | КОГДА ПланированиеБюджетаДоходыРасходы.Ссылка.Версия = 3 | ТОГДА ПланированиеБюджетаДоходыРасходы.Сумма | ИНАЧЕ 0 | КОНЕЦ) КАК Коррект | ИЗ | Документ.ПланированиеБюджета."+ДоходРасход+" КАК ПланированиеБюджетаДоходыРасходы | ГДЕ | ПланированиеБюджетаДоходыРасходы.Ссылка.Год = &Год | И ПланированиеБюджетаДоходыРасходы.Ссылка.Месяц МЕЖДУ &МесяцН И &МесяцК | И ПланированиеБюджетаДоходыРасходы.Ссылка.Проведен | И ПланированиеБюджетаДоходыРасходы.ПравилоДДС.Код <> ""000000027"" | И ПланированиеБюджетаДоходыРасходы.Сумма <> 0 | И ПланированиеБюджетаДоходыРасходы.Статья = &"+Параметр.ПараметрИмя+" | И ("+?(Доход,"","НЕ")+" ПланированиеБюджетаДоходыРасходы.Статья.Доход)) КАК "+Параметр.ПараметрИмя+""; ИначеЕсли НЕ ЗначениеЗаполнено(Параметр.ПараметрЗначение.Формула) Тогда ДоходРасход = ?(Параметр.Доход,"Доходы","Расходы"); Доход = Параметр.Доход; ТекстЗапроса = "ВЫБРАТЬ | "+Параметр.ПараметрИмя+".Первонач |ИЗ | (ВЫБРАТЬ | СУММА(ВЫБОР | КОГДА ПланированиеБюджетаДоходыРасходы.Ссылка.Версия = 2 | ТОГДА ПланированиеБюджетаДоходыРасходы.Сумма | ИНАЧЕ 0 | КОНЕЦ) КАК Первонач, | СУММА(ВЫБОР | КОГДА ПланированиеБюджетаДоходыРасходы.Ссылка.Версия = 3 | ТОГДА ПланированиеБюджетаДоходыРасходы.Сумма | ИНАЧЕ 0 | КОНЕЦ) КАК Коррект | ИЗ | Документ.ПланированиеБюджета."+ДоходРасход+" КАК ПланированиеБюджетаДоходыРасходы | ГДЕ | ПланированиеБюджетаДоходыРасходы.Ссылка.Год = &Год | И ПланированиеБюджетаДоходыРасходы.Ссылка.Месяц МЕЖДУ &МесяцН И &МесяцК | И ПланированиеБюджетаДоходыРасходы.Ссылка.Проведен | И ПланированиеБюджетаДоходыРасходы.ПравилоДДС.Код <> ""000000027"" | И ПланированиеБюджетаДоходыРасходы.Сумма <> 0 | И ПланированиеБюджетаДоходыРасходы.Статья.Вид = &"+Параметр.ПараметрИмя+" | И ("+?(Доход,"","НЕ")+" ПланированиеБюджетаДоходыРасходы.Статья.Доход)) КАК "+Параметр.ПараметрИмя+""; Иначе ТекстЗапроса = ПолучитьТекстЗапросаВложеннойФормулы(Параметр); КонецЕсли; Возврат ТекстЗапроса; КонецФункции |
|||
1
zladenuw
28.02.13
✎
13:53
|
(1) вот тут цикл по вложенной формуле сделать ?
Иначе ТекстЗапроса = ПолучитьТекстЗапросаВложеннойФормулы(Параметр); КонецЕсли; Или как лучше ? |
|||
2
zladenuw
28.02.13
✎
13:58
|
(1) на сколько я понимаю. мне нужно повторить полностью формирование запроса. сделать его вложенным и добавить к основному. получается что все формирование запроса копировать. или все таки может есть у кого то идеи ? может по другому надо ? Может построителем будет лучше или нет ?
|
|||
3
John D
28.02.13
✎
13:59
|
По идее, рекурсия напрашивается...
|
|||
4
zladenuw
28.02.13
✎
14:00
|
(3) это уже понял. но все равно спасибо
|
|||
5
zladenuw
28.02.13
✎
14:54
|
есть загвостка. как определить или данное имя вложеного запроса уже используется ?
для показателей формулы могут содержать одинаковые символы. например а и б. как во вложенных добавить префикс, количество вложенний не известно. и еще надо где то их запомнить и передавать в общий запрос для заполнение параметров. |
|||
6
zladenuw
28.02.13
✎
14:56
|
(5) есть 1 показатель. который расчитывается по формуле а+б.
а расчитывается так же по вложенной формуле (а+б) как а и (а+б) как б. |
|||
7
MSII
28.02.13
✎
14:57
|
(5) А ты передавай все нужные тебе данные в параметры функции.
|
|||
8
НЕА123
28.02.13
✎
15:01
|
почти офф.
может все это сначало в дерево значений сувать, а потом уж запрос делать. |
|||
9
zladenuw
28.02.13
✎
15:02
|
(8) а подробней ?
|
|||
10
zladenuw
28.02.13
✎
15:05
|
пока сделал изварот. добавлю наименование показателя. но как то не по феншую :)
|
|||
11
НЕА123
28.02.13
✎
15:05
|
(9)
честно говоря, я не понял задачи(устал, плохо соображаю). что-то аналогичное делал (не запрос). пока дерева не построил для наглядности, нихрена не получалось. |
|||
12
zladenuw
28.02.13
✎
15:09
|
(11) есть справочник разделы бюджета, делаю запрос к 2 ТЧ документа. вывожу все в одну таблицу запроса . если нет формулы то вывожу в таблицу1. если есть формула то в таблицу 2.
вот пляски с дополнительными показателями. |
|||
13
zladenuw
28.02.13
✎
15:11
|
(12) я думал не выбирать показатели где есть формула, тогда проблем нет. но начальник сказал, что бы можно было выбрать любой раздел. вот мучаюсь.
|
|||
14
zladenuw
28.02.13
✎
16:12
|
Сделал дерево.
http://ximage.ru/index.php?id=1362053287 Я так понимаю что нужно будет делать обход дерева. и на основание его строить запрос ? может все таки есть у кого примеры ? |
|||
15
zladenuw
28.02.13
✎
16:18
|
(14) так красивее http://ximage.ru/index.php?id=1362053758
Думаю к Имени параметру добавлять число по нарастающей. Но как быть дальше с запросом. делать подзапросы и выполнять а+б, для вложенной функции. или же формировать просто вложенные запросы. а потом вычитать уже по новой формуле где будет (а1+б1)-(а2+б2) так что ли ? |
|||
16
vde69
28.02.13
✎
16:19
|
(14) дерево и динамический список жутко тормозят, на списке из 10к строк любое действие занимает около 5 минут, даже скролинг....
динамический список нормально работает только с иерхическими списками, но не с деревом |
|||
17
zladenuw
28.02.13
✎
16:20
|
какой подход более правильный будет ?
Какое ограничение на количество вложенных запросов ? Если что платформа 8.1.13..41 (16) так мне для отчета. я это дело в СКД подставую как вычисляемое поле. и вывожу во вторую таблицу. |
|||
18
vde69
28.02.13
✎
16:21
|
||||
19
zladenuw
28.02.13
✎
16:24
|
http://ximage.ru/index.php?id=1362054229
вот отчет. внизу допольняю показателими у которых формула. (18)И как это поможет мне ? |
|||
20
zladenuw
28.02.13
✎
16:27
|
(18) я дерево вывел для наглядности. и для хранение,заполнение параметров. так как не известно изначально сколько в показатели может быть вложенных формул.
+ надо где то хранить имена вложенных таблиц, из за того что в формуле могут быть повторение имен параметров. |
|||
21
zladenuw
28.02.13
✎
16:29
|
(20) думаю использовать уровень дерева. тогда точно будут уникальные имена вложенных таблиц.
|
|||
22
vde69
28.02.13
✎
16:30
|
(20) да, это я тупанул, не вьехал в сабж...
|
|||
23
zladenuw
28.02.13
✎
16:31
|
(22) а можно как то в дереве узнать, какой уровень строки у нее или нет ?
|
|||
24
zladenuw
28.02.13
✎
16:45
|
(23) Мда. http://ximage.ru/index.php?id=1362055463
Все равно не так. |
|||
25
mishgan75
28.02.13
✎
16:50
|
не надо казаться самым умным. Найди более простое(понятное) решение проблемы.
|
|||
26
zladenuw
28.02.13
✎
16:51
|
(25) ну так подскажи :)
|
|||
27
vde69
28.02.13
✎
16:59
|
(24) у тебя класический подход функционально програмирования, в принцепе нормально...
как вариант перейти к процедурному подходу, многим 1с никам будет более понятно |
|||
28
zladenuw
28.02.13
✎
17:01
|
вот так заполняю дерево.
как мне проверить что владелец тот же и индекс его строки считать ненадо. Процедура КнопкаВыполнитьНажатие(Кнопка) ДеревоПоказателей.Колонки.Очистить(); СоздатьСтруктуруДерева(ДеревоПоказателей); ЗаполнитьДеревоПоказателей(ДеревоПоказателей,Алгоритм); ЭлементыФормы.ДеревоПоказателей.Значение = ДеревоПоказателей; ЭлементыФормы.ДеревоПоказателей.СоздатьКолонки(); КонецПроцедуры Процедура ЗаполнитьДеревоПоказателей(Дерево,Показатель) СтрокаДерева = Дерево.Строки.Добавить(); СтрокаДерева.Показатель = Показатель; СтрокаДерева.Формула = Показатель.Формула; Если Показатель.ПараметрыФормулы.Количество() > 0 Тогда Для каждого СтрПокФормулы из Показатель.ПараметрыФормулы цикл // СтрФормулы = СтрокаДерева.Строки.Добавить(); ЗаполнитьПараметрамиФункции(СтрФормулы,СтрПокФормулы,); КонецЦикла; // Иначе // СтрокаДерева.ЗначениеФормулы = Показатель.ЗначениеФормулы; КонецЕсли; КонецПроцедуры Процедура ЗаполнитьПараметрамиФункции(СтрокиФ,Показатель,пУровень = 0) Если Показатель.ПараметрЗначение.Формула = "" Тогда СтрокиФ.ПараметрФормулы = Показатель.ПараметрИмя; СтрокиФ.ПараметрФормулыЗапрос = Строка(СтрокиФ.Уровень()+пУровень)+Показатель.ПараметрИмя; СтрокиФ.ЗначениеФормулы = Показатель.ПараметрЗначение; СтрокиФ.Доход = Показатель.Доход; СтрокиФ.Расход = Показатель.Расход; Иначе //Для каждого //ВложФормулаСтрока = СтрФормулы.Строки.Добавить(); СтрокиФ.Показатель = Показатель.ПараметрЗначение; СтрокиФ.Формула = Показатель.ПараметрЗначение.Формула; Для каждого СтрПокФормулы из Показатель.ПараметрЗначение.ПараметрыФормулы цикл СтрокиВложФ = СтрокиФ.Строки.Добавить(); ЗаполнитьПараметрамиФункции(СтрокиВложФ,СтрПокФормулы,СтрокиФ.Строки.Индекс(СтрокиВложФ)); КонецЦикла; КонецЕсли; КонецПроцедуры Процедура СоздатьСтруктуруДерева(Дерево) Дерево.Колонки.Добавить("Показатель"); Дерево.Колонки.Добавить("Формула"); Дерево.Колонки.Добавить("ПараметрФормулы"); Дерево.Колонки.Добавить("ПараметрФормулыЗапрос"); Дерево.Колонки.Добавить("ЗначениеФормулы"); Дерево.Колонки.Добавить("Доход"); Дерево.Колонки.Добавить("Расход"); КонецПроцедуры |
|||
29
zladenuw
28.02.13
✎
17:08
|
(28) мда. надо было уровень брать с 0 уровня дерева,а не с его строк.с этим разобрался.
Теперь надо это чудо подставить в запрос. и потом подставить параметры :). вроде просто. вопрос как :) |
|||
30
zladenuw
28.02.13
✎
17:10
|
(27) а чем плох или харош такой подход ? только как меня тут будут понимать или не только ?
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |