![]() |
![]() |
![]() |
|
v7: Проблемы с "внешней" функцией в запросе | ☑ | ||
---|---|---|---|---|
0
Umnov
26.03.10
✎
20:55
|
Не могу понять почему не происходит вызов функции
При прохождении под отладчиком туда как будто вообще не попадает и как результат СуммаНом пустое Перем ЗакупТипЦен, ВалютаРубли; Функция ВернутьСумму(Цена, Валюта, КолВо) возврат глПересчет(Цена*КолВо, Валюта, ТекущаяДата(), ВалютаРубли, ТекущаяДата()); КонецФункции //******************************************* // Процедура генерации запроса НоменклатураВГруппе. // Процедура НоменклатураВГруппе() Перем Запрос, ТекстЗапроса, Таб; //Создание объекта типа Запрос Запрос = СоздатьОбъект("Запрос"); ТекстЗапроса = "//{{ЗАПРОС(НоменклатураВГруппе) |Номенклатура = Регистр.ОстаткиТМЦ.Номенклатура, Справочник.Цены.Владелец, Регистр.Заказы.Номенклатура, Регистр.РезервыТМЦ.Номенклатура; |ОстатокНом = Регистр.ОстаткиТМЦ.Количество; |ТранзитНом = Регистр.Заказы.КоличествоПриход; |РезервНом = Регистр.РезервыТМЦ.Количество; |ТипЦен = Справочник.Цены.ТипЦен; |Цена = Справочник.Цены.Цена; |Валюта = Справочник.Цены.Валюта; |Индекс = Регистр.ОстаткиТМЦ.Склад.Индекс; |Функция Остаток = КонОст(ОстатокНом); |Функция Транзит = КонОст(ТранзитНом); |Функция Резерв = КонОст(РезервНом); |Функция СуммаНом = Сумма(ВернутьСумму(Цена,Валюта,ОстатокНом)); |Группировка Номенклатура без групп; |Условие(Номенклатура в ВыбНоменклатура); |Условие(ТипЦен = ЗакупТипЦен); |"//}}ЗАПРОС ; // Если ошибка в запросе, то выход из процедуры Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда Возврат; КонецЕсли; // Подготовка к заполнению выходных форм данными запроса Таб = СоздатьОбъект("Таблица"); Таб.ИсходнаяТаблица("НоменклатураВГруппе"); // Заполнение полей "Заголовок" Таб.ВывестиСекцию("Заголовок"); Состояние("Заполнение выходной таблицы..."); Таб.Опции(0, 0, Таб.ВысотаТаблицы(), 0); Пока Запрос.Группировка(1) = 1 Цикл // Заполнение полей Номенклатура Таб.ВывестиСекцию("Номенклатура"); КонецЦикла; // Заполнение полей "Итого" Таб.ВывестиСекцию("Итого"); // Вывод заполненной формы Таб.ТолькоПросмотр(1); Таб.Показать("НоменклатураВГруппе", ""); КонецПроцедуры Процедура ПриОткрытии() СпрТипыЦен = СоздатьОбъект("Справочник.ТипыЦен"); СпрТипыЦен.НайтиПоНаименованию("Базовые"); ЗакупТипЦен = СпрТипыЦен.ТекущийЭлемент(); СпрВалюты = СоздатьОбъект("Справочник.Валюты"); СпрВалюты.НайтиПоКоду(810,1); ВалютаРубли = СпрВалюты.ТекущийЭлемент(); КонецПроцедуры |
|||
1
dk
26.03.10
✎
20:58
|
1. отладчик в ф-ции из запроса не заходит
2. что там возвращает глПересчет? |
|||
2
dk
26.03.10
✎
20:59
|
чтобы убедиться, что заходит добавь сообщить в ф-цию
|
|||
3
Umnov
26.03.10
✎
21:03
|
спасибо... не знал что не заходит
поставил сообщить - все норм проблема с данными видимо - буду вычислять сейчас |
|||
4
Umnov
26.03.10
✎
21:09
|
Проблема найдена
|ОстатокНом = Регистр.ОстаткиТМЦ.Количество; тут 0 вот тут |Функция Остаток = КонОст(ОстатокНом); нужное значение ... но вызов функции в таком виде |Функция СуммаНом = Сумма(ВернутьСумму(Цена,Валюта,ОстатокНом)); выдает Функция СуммаНом = Сумма(ВернутьСумму(Цена,Валюта,Остаток <<?>> )); Запрос[13] : Ошибка в выражении 'Остаток' (((( есть ли решение? |
|||
5
dk
26.03.10
✎
21:13
|
не, с такими извратами в запросах - это к Ёпрст
|
|||
6
Umnov
26.03.10
✎
21:20
|
просто если писать просто в SQL то все просто и ясно а вот с 1с так не везет)
|
|||
7
NS
26.03.10
✎
21:20
|
нет решения. У тебя разные переменные запроса описывают разные структуры - регистр и справочник.
|
|||
8
NS
26.03.10
✎
21:23
|
что-то я заврался.
|Функция СуммаНом = Сумма(ВернутьСумму(Цена,Валюта,ОстатокНом)); выдает Функция СуммаНом = Сумма(ВернутьСумму(Цена,Валюта,Остаток <<?>> )); Каким образом на "ОстатокНом" ругается как на "остаток"? |
|||
9
NS
26.03.10
✎
21:25
|
Функция СуммаНом = Сумма(ВернутьСумму(Цена,Валюта,Запрос.Остаток));
|
|||
10
Umnov
26.03.10
✎
21:27
|
нет
ошибся конечно ошибку выдает вызов Функция СуммаНом = Сумма(ВернутьСумму(Цена,Валюта,Запрос.Остаток)); |
|||
11
Umnov
26.03.10
✎
21:30
|
т.е. как я понял невозможно в функции обратиться к значению которую возвращает другая функция
|
|||
12
Cthulhu
26.03.10
✎
22:37
|
//(4),(11): возможно. попробуй:
|Функция СуммаНом = Сумма(ВернутьСумму(Цена,Валюта,Запрос.Остаток)); |
|||
13
Cthulhu
26.03.10
✎
22:41
|
ЗЫ: кстати, подобным "финтом ушами" построил запрос, выдающий в результате список контрагентов + первых(!)документов, двинувших регистр... ))
|
|||
14
Umnov
27.03.10
✎
07:32
|
не спасает т сожалению....
при вызове конструктора выдает Функция СуммаНом = Сумма(ВернутьСумму(Цена,Валюта,Запрос.Остаток <<?>> )); Запрос[13] : Ошибка в выражении 'Запрос' Ошибок - 1, Предупреждений - 0. если просто выполнить ошибок нет но Запрос.Остаток = 0 ... хотя не 0 оно( видимо красиво не выйдет писать ... придется как всегда - через ... . |
|||
15
VladZ
27.03.10
✎
08:15
|
Ценой можно озадачится на этапе вывода информации.
|
|||
16
Umnov
27.03.10
✎
08:37
|
(15) безусловно.... но было бы красивей все в запросе....
|
|||
17
Umnov
27.03.10
✎
08:40
|
просто с Цена,Валюта проблем не возникает... все проблемы с Остаток )))
который является результатом тоже фанкции |
|||
18
VladZ
27.03.10
✎
09:50
|
(16) "Красивее" - не тот критерий, на который стоило бы ориентироваться.. :)
|
|||
19
Cthulhu
27.03.10
✎
11:51
|
(14): головой думай. И ставь в текст вместо Запрос имя твоей переменной (типа "Запрос").
если у других работает а у тебя не работает - это вовсе не значит, что у других ошибка в программе из-за которой оно у них работате, это значит что нужно подумать. |
|||
20
vcv
27.03.10
✎
11:53
|
(14) Ты выбери что-то одно. Или конструктором писать стандартные, рекомендованные нам свыше запросы, со всеми их ограничениями и недостатками. Или руками писать какие-то запросные извращения.
|
|||
21
Umnov
27.03.10
✎
12:03
|
(19) а текст выше посмотреть как??? ))))
Запрос = СоздатьОбъект("Запрос"); (20) ну насчет извращений я бы поспорил.... вот делать все руками - извращение... а запросом на МОЙ взгляд нет... не говорю что это правильно для всех) |
|||
22
Umnov
27.03.10
✎
12:11
|
(13) был бы счастлив увидеть кусочег кода)
заранее спасибо |
|||
23
vcv
27.03.10
✎
13:50
|
(21) Извращение - имеется в виду конструкция
Функция СуммаНом = Сумма(ВернутьСумму(Цена,Валюта,Запрос.Остаток)); в запросе. Точнее обращение к "Запрос.Остаток". Конструктор не позволяет такую написать. Но руками строчку запроса написать можно. Правда при этом нужно быть готовым к тому, что запрос может начать работать в несколько раз медленнее. |
|||
24
Cthulhu
27.03.10
✎
15:05
|
(23): я заюзав внешнюю функцию решил задачу получения запросом списка первых(!!!) документов, двинувших регистр - и сократив время запроса на порядки (перевод: в сотни(!) раз).
просто нужно думать - как и чем пользоваться. для чего. впрочем как и везде. |
|||
25
vcv
28.03.10
✎
11:20
|
Поделился бы примером запроса. Эффект "в сотни раз" - на это стоит посмотреть и проанализировать.
|
|||
26
Cthulhu
28.03.10
✎
13:46
|
(25): а самому не интересно? все ведь штатно.
|
|||
27
Cthulhu
28.03.10
✎
13:49
|
(24)+: (25): ну может и не в сотни, каюсь. ))) но значительно: на среднем ноуте 65+к записей регистра взаиморасчетов с покупателями лопатит за 5-6 секунд и вылает в результате первые документы с движениями по регистру по 1300+ покупателям.
|
|||
28
Umnov
28.03.10
✎
14:06
|
(26)аааа хачу посмотреть!!!!
|
|||
29
vcv
28.03.10
✎
19:01
|
(27) Ты бы все же поделился. Я тоже достигал с помощью извратов в штатных запросах хороших результатов, но интересен и чужой опыт. Особенно если нахаляву :-)
<РекламаON>Вот, например, моя полезняшка: http://infostart.ru/public/64620/ <РекламаOFF> Вдруг удастся приложить удачно к одной своей задачке. Хитрый анализ взаиморасчетов с аналитическим распределением по поставщикам, номенклатуре и прочим параметрам документов/партий, 20К контрагентов, полмиллиона движений в регистре. Минуты три запрос выполняется и минут 30 обработка результатов запроса. Есть слабая надежда, что приснится ночью идея, как часть обработки результатов запроса перенести в запрос, что бы SQL работал, а не клиент. |
|||
30
Cthulhu
28.03.10
✎
19:17
|
(29): "504 Gateway Time-out"
|
|||
31
Cthulhu
28.03.10
✎
19:18
|
// Да все просто.
// --- список обработанных покупателей и счетчик записей запроса - переменные модуля: Перем тПокупСЗ,кЗапросНомерЗаписи; // --- внешняя функция, используемая в запросе: Функция ФункФлЕсть(тПокуп) Перем флЕсть; флЕсть=тПокупСЗ.НайтиЗначение(тПокуп); кЗапросНомерЗаписи=кЗапросНомерЗаписи+1; // чтобы знать - сколько там записей из регистра перелопачено... //Состояние("Зап."+кЗапросНомерЗаписи+" / Покуп="+тПокупСЗ.РазмерСписка()+" ..."); // ... и чтобы не скучно было //Если флЕсть=0 Тогда тПокупСЗ.ДобавитьЗначение(тПокуп); Сообщить(""+тПокуп+" - добавлен...","i"); // отладка //Иначе Сообщить("Покуп."+тПокуп+"="+флЕсть+" - пропуск...",".") КонецЕсли; // отладка Если флЕсть=0 Тогда тПокупСЗ.ДобавитьЗначение(тПокуп) КонецЕсли; Возврат(флЕсть); КонецФункции //ФункЕсть // --- кусок процедуры, получающий запросом список первых документов по контрагентам // --- из регистра взаиморасчетов с покупателями: тПокупСЗ=СоздатьОбъект("СписокЗначений"); кЗапросНомерЗаписи=0; тТхт="Период с ВыбНачПериода по ВыбКонПериода; |Покуп=Регистр.ВзаиморасчетыПокупателей.Контрагент; |тСум=Регистр.ВзаиморасчетыПокупателей.ДолгОсн; |Функция ДолгПлюс=Приход(тСум); Функция ДолгМинус=Расход(тСум); |Группировка Покуп БЕЗ ГРУПП; Группировка Документ; |Функция ФлЕсть=Сумма(ФункФлЕсть(Покуп)); Условие (тВыб.ФлЕсть=0);"; // sic! Сообщить("["+ТекущаяДата()+"/"+ТекущееВремя()+"]: Выполнение запроса ...","."); тМилиСек=_GetPerformanceCounter(); тВыб=СоздатьОбъект("Запрос"); Если тВыб.Выполнить(тТхт)=0 Тогда Возврат КонецЕсли; тМилиСек=_GetPerformanceCounter()-тМилиСек; Сообщить("["+ТекущаяДата()+"/"+ТекущееВремя()+"]: Запрос по "+кЗапросНомерЗаписи +" записям регистра выполнен за "+(тМилиСек/1000)+" секунд - выбрано "+тПокупСЗ.РазмерСписка()+" покупателей ...","i"); тМилиСек=_GetPerformanceCounter(); кЗапросНомерЗаписи=тПокупСЗ.РазмерСписка(); тЗапросНомерЗаписи=0; Пока тВыб.Группировка("Покуп")=1 Цикл Пока тВыб.Группировка("Документ")=1 Цикл тЗапросНомерЗаписи=тЗапросНомерЗаписи+1; Состояние("Запрос("+тЗапросНомерЗаписи+"/"+кЗапросНомерЗаписи+"): "+тВыб.Покуп+" / "+тВыб.Докум+" ..."); Сообщить(" + Выборка: Покуп.="+тВыб.Покуп+" / Докум.="+тВыб.Докум,""); КонецЦикла; КонецЦикла; тМилиСек=_GetPerformanceCounter()-тМилиСек; Сообщить("["+ТекущаяДата()+"/"+ТекущееВремя()+"]: Выборка по "+кЗапросНомерЗаписи+" группировкам Запроса выполнена за "+(тМилиСек/1000)+" секунд ...","i"); // как-то так... с бантиками... ))) |
|||
32
vcv
28.03.10
✎
19:59
|
(30) Как обычно. Инфостарт с переменным успехом борется с пользователями. Ни как не может найти тонкую грань между желаемым (побольше активных пользователей) и своими возможностями это желаемое переварить.
(31) Гм. Элегантненько. Такое мне в голову не приходило. Респект. Кажется вижу, как и свой проблемный отчет ускорить. |
|||
33
Umnov
29.03.10
✎
20:52
|
да неплохо только с моей задачей не сходится!
|
|||
34
vcv
30.03.10
✎
09:41
|
(33) Мне кажется, что в твоем случае, гораздо проще не связываться с функцией, а расценить остатки при выводе отчета.
Или хотя бы убрать из запроса справочник цен. Если в функцию в запросе передавать номенклатуру и остаток, определять цену и считать сумму уже в функции. Для ускорения можно предварительно заполнить таблицу значений ценами и в функции быстро выбирать нужное из ТЗ. |
|||
35
Ёпрст
гуру
30.03.10
✎
09:51
|
(0) Функция сумма в останковых регистрах считает только тогда, когда вычисляются другие функции в тексте запроса (исключение - сумма по реквизиту регистра)
Соответственно, при функции КонОст функция сумма будет считать так: если запрос на начало/конец периодичности сохранения останков, то КонОст ничего не вычисляет, итоги сразу берет из таблички итогов - функция Сумма в запросе ничего не возвращает.. Иначе, конОст берет итоги с ближайшего периода и вычисляет останки конечный остаток как начОст(из таблички итогов)+(Приход-Расход)из таблички движений.. Вот при работе прихода и расхода будет выполнятся функция сумма... Ежели в тексте запроса добавить другие функции - Приход/расход, то Сумма будет вычисляться при вычислении и этих функций..+ для каждого "движения" регистра. |
|||
36
Ёпрст
гуру
30.03.10
✎
09:58
|
+35 хотя в дбф функция конОст будет вычисляться немного по-другому.. и Сумма будет работать всегда, в не зависимости от даты запроса.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |