29.01.2011, 16:06 | #1 |
Участник
|
Расширенный диапазон в Query range: вычесть число из даты
Никак не могу побороть один момент в запросе.
Нужно сделать аналог конструкции X++: where table1.Date < systemDateGet() - table2.Days X++: qbdsTable1.addRange(fieldNum(Table1, Date)).value( strfmt('(Date < %1 - %2.%3))', date2StrXpp(systemDateGet()), query.dataSourceTable(tableNum(Table2)).name(), fieldStr(Table2, Days))); X++: qbdsTable1.addRange(fieldNum(Table1, Date)).value( strfmt('(Date < dateadd(%1.%2, -%3.%4, %5))', query.dataSourceTable(tableNum(Table1)).name(), fieldStr(Table1, Date), query.dataSourceTable(tableNum(Table2)).name(), fieldStr(Table2, Days), date2StrXpp(systemDateGet()))); X++: qbdsTable1.addRange(fieldNum(Table1, Date)).value( strfmt('((%1 - %2.%3) > %4.%5)', date2StrXpp(systemDateGet()), query.dataSourceTable(tableNum(Table1)).name(), fieldStr(Table1, Date), query.dataSourceTable(tableNum(Table2)).name(), fieldStr(Table2, Days))); |
|
29.01.2011, 18:50 | #2 |
SAP
|
Цитата:
X++: where table1.Date < systemDateGet() - table2.Days X++: date = systemDateGet() - table2.Days where table1.Date < date |
|
29.01.2011, 18:57 | #3 |
Участник
|
Пару раз уже сталкивался с подобными штуками. Таки нужное значение лучше вычислить заранее, а потом уже использовать в запросе.
|
|
29.01.2011, 22:50 | #4 |
Участник
|
Дык, дело-то в том, что это значение получается в результате запроса. Table2 в данном случае - датасорс этого же Query. Иначе и не надо было бы расширенный диапазон заводить.
|
|
30.01.2011, 09:43 | #5 |
Участник
|
Почитайте еще вот эту тему Расширенный запрос по дате
|
|
30.01.2011, 18:42 | #6 |
Участник
|
Смотрел.
Опять-таки, там не рассматривается поставленная задача. Нужно в условиях для одного датасорса использовать сравнение с полями другого датасорса - задача, давно решаемая с помощью расширенного диапазона. Проблема именно в том, чтоб задать корректное для вычитание дней из даты в этом расширенном диапазоне. |
|
31.01.2011, 09:27 | #7 |
Участник
|
Цитата:
Нужно в условиях для одного датасорса использовать сравнение с полями другого датасорса - задача, давно решаемая с помощью расширенного диапазона.
Может попробовать использовать 1-ый вариант, но с использованием функции date2num(): X++: qbdsTable1.addRange(fieldNum(Table1, Date)).value(strfmt("date2num(Date) < (date2num(%1) - %2.%3)", systemDateGet(), query.dataSourceTable(tableNum(Table2)).name(), fieldStr(Table2, Days))); X++: qbdsTable1.addRange(fieldNum(Table1, Date)).value(strfmt("Date < num2date(date2num(%1) - %2.%3)", systemDateGet(), query.dataSourceTable(tableNum(Table2)).name(), fieldStr(Table2, Days)));
__________________
С уважением, Александр. Последний раз редактировалось samolalex; 31.01.2011 в 09:33. |
|
31.01.2011, 10:17 | #8 |
Участник
|
Ой, что-то вас совсем не туда понесло. Разве в SQL есть функции date2num и num2date?
Это ж, фактически, скулю скармливаться будет. Что он должен делать, получив такое? X++: "date2num(Date) < (date2num(%1) - %2.%3)" X++: qbdsTable1.addRange(fieldNum(Table1, Date)).value( strfmt('(%1.%2 < dateadd(day, -%1.%2, %5))', query.dataSourceTable(tableNum(Table1)).name(), fieldStr(Table1, Date), query.dataSourceTable(tableNum(Table2)).name(), fieldStr(Table2, Days), date2StrXpp(systemDateGet()))); |
|
31.01.2011, 10:24 | #9 |
Участник
|
Может, так попробовать
X++: qbdsTable2.addRange(fieldNum(Table2, Days)).value( strfmt('((%1 - %2.%3) > %4)', date2StrXpp(systemDateGet()), query.dataSourceTable(tableNum(Table1)).name(), fieldStr(Table1, Date), fieldStr(Table2, Days)));
__________________
Axapta v.3.0 sp5 kr2 |
|
31.01.2011, 10:53 | #10 |
северный Будда
|
Попробуйте сначала записать в какую-то переменную значение systemDateGet(), а потом в разнице использовать эту переменную
__________________
С уважением, Вячеслав |
|
31.01.2011, 11:08 | #11 |
Участник
|
Цитата:
Я сейчас эксперимент поставил: заменил текущую дату на 1 день позже даты записи, которая не должна попадать в запрос и стал менять в table2 кол-во дней, формируя отчёты. При значении в поле table2.Days 25105 данные, которые не должны попасть в отчёт по этому признаку перестают в него попадать. Но умножением числа дней на 25 тысяч, по-моему, мало что добьюсь - арифметическая ошибка переполнения будет на реальных цифрах. Смысл? Что функция возвратит дату, которую скуль нормально примет, что переменная - одинаково. Последний раз редактировалось Corel; 31.01.2011 в 11:14. |
|
31.01.2011, 11:33 | #12 |
Участник
|
Прошу прощение за настойчивость, но вы обратили внимание, что рейнж накладывается на поле не первого, а второго датасорса?
Вот такой запрос у меня корректно отрабатывает в журнале накладных поставщиков Вот так это условие отправляется на сервер {ts '2011-01-31 00:00:00.000'}-A.INVOICEDATE)<=B.RECVERSION Не судите за корректность запроса, это только проверка
__________________
Axapta v.3.0 sp5 kr2 |
|
31.01.2011, 11:58 | #13 |
Участник
|
Цитата:
Хм... Попробую так. Если у вас вычитание даты из даты корректно работает, значит, надежда есть. Upd: Попробовал. Ошибка расширенного диапазона: Ошибка расширенного диапазона запроса: Table1.Date не является корректной парой datasource.field рядом с 45. Видимо, из-за того, что датасорсы уж очень далеко отстоят друг от друга - table2 входит в запрос гораздо выше. Сейчас пробую так: делаю предварительный запрос, собрав в Map интересующие меня пары код - кол-во дней из table2, а затем в основном Query иду по этой мапе и ставлю условие X++: qbdsTable1.addRange(fieldNum(Table1, Date)).value(strfmt('((%2.%4 == %5) && (%6.%7 < %1))', date2StrXpp(systemDateGet() - any2int(mapIterator.value())), //%1 query.dataSourceTable(tableNum(Table2)).name(), //%2 fieldStr(Table2, Days), //%3 fieldStr(Table2, Id), //%4 SysQuery::value(mapIterator.key()), //%5 query.dataSourceTable(tableNum(Table1)).name(), //%6 fieldStr(Table1, Date))); //%7 Последний раз редактировалось Corel; 31.01.2011 в 12:23. |
|
31.01.2011, 12:38 | #14 |
Участник
|
Ну, по идее, это должно и в обратную строну работать
X++: qbdsTable1.addRange(fieldNum(Table1, Date)).value( strfmt('((%1 - %2) > %3.%4)', date2StrXpp(systemDateGet()), fieldStr(Table1, Date), query.dataSourceTable(tableNum(Table2)).name(), fieldStr(Table2, Days)));
__________________
Axapta v.3.0 sp5 kr2 |
|
31.01.2011, 14:28 | #15 |
Участник
|
По идее-то да. Но вот в таком варианте наблюдаю вываливание на QueryRun.next() в тарссировку стека с ошибкой "неверный параметр".
Цитата:
Хотя, вы бы привели запрос полностью, что бы было видно, как таблицы между собой соединяются
Запрос должен находить номенклатуры, относящиеся к выбранным Table2 (на Table2 накладывается пользовательский фильтр), у которых текущие остатки больше 0 и по которым есть приходные проводки с датой раньше, чем текущая минус кол-во дней, указанное в соответствующей Table2. X++: query = new Query(); qbdsTable2 = query.addDataSource(tableNum(Table2)); qbdsInventTable = qbdsTable2.addDataSource(tableNum(InventTable)); qbdsInventTable.addLink(fieldNum(Table2, Id), fieldNum(InventTable, Table2Id)); qbdsInventTable.addGroupByField(fieldNum(InventTable, ItemId)); qbdsInventSum = qbdsInventTable.addDataSource(tableNum(InventSum)); qbdsInventSum.relations(true); qbdsInventSum.addRange(fieldNum(InventSum, PostedQty)).value('(PostedQty>0)'); qbdsInventSum.addSelectionField(fieldNum(InventSum, PostedQty), SelectionField::Sum); qbdsInventTrans = qbdsInventSum.addDataSource(tableNum(InventTrans)); qbdsInventTrans.relations(true); qbdsInventTrans.addRange(fieldNum(InventTrans, StatusReceipt)).value(queryValue(StatusReceipt::Purchased)); qbdsInventTrans.addRange(fieldNum(InventTrans, DateFinancial)).value(strfmt('(((%1 - %2) > %3.%4))', date2StrXpp(systemDateGet()), fieldStr(InventTrans, DateFinancial), query.dataSourceTable(tableNum(Table2)).name(), fieldStr(Table2, Days))); qbdsInventTrans.joinMode(JoinMode::ExistsJoin); |
|
31.01.2011, 15:24 | #16 |
MCTS
|
Похожие ошибки бывают когда накладываемое значение ренджа очень длинное и попросту обрезается парсером (вроде в рендж входит значение не длиннее 255 символов). Хотя в Вашем случае условие и не выглядит длинным, но мало ли...
|
|
31.01.2011, 17:13 | #17 |
Участник
|
А такой вариант ?
X++: qbdsInventTrans.addRange(fieldNum(InventTrans, DateFinancial)).value(strfmt('(((%1.%2 + %3.%4 - %5) > 0))', query.dataSourceTable(tableNum(InventTrans)).name(), fieldStr(InventTrans, DateFinancial), query.dataSourceTable(tableNum(Table2)).name(), fieldStr(Table2, Days), date2StrXpp(systemDateGet())); |
|
31.01.2011, 17:28 | #18 |
Участник
|
Цитата:
Сообщение от Alexius
А такой вариант ?
X++: qbdsInventTrans.addRange(fieldNum(InventTrans, DateFinancial)).value(strfmt('(((%1.%2 + %3.%4 - %5) > 0))', query.dataSourceTable(tableNum(InventTrans)).name(), fieldStr(InventTrans, DateFinancial), query.dataSourceTable(tableNum(Table2)).name(), fieldStr(Table2, Days), date2StrXpp(systemDateGet())); Последний раз редактировалось Corel; 31.01.2011 в 17:32. |
|
31.01.2011, 17:29 | #19 |
Moderator
|
Цитата:
|
|
|
За это сообщение автора поблагодарили: PavelX (1), Corel (1). |
31.01.2011, 17:42 | #20 |
Участник
|
Цитата:
Код: SELECT TOP 1 DATEFINANCIAL, DATEFINANCIAL - 1 FROM INVENTTRANS WHERE DATEFINANCIAL <> '19000101' PS2. Городить полноценный полигон мне лень |
|
Теги |
querybuildrange, дата, расширенный фильтр |
|
|