AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 14.11.2005, 13:11   #1  
rkrivov is offline
rkrivov
Участник
Аватар для rkrivov
 
31 / 10 (1) +
Регистрация: 18.02.2005
Адрес: Москва
Post Очередной вопрос про Query
Доброго времени суток!

У меня очередной вопрос про Query. Как можно программно создать запрос, который реализовал бы следующий код на X++ :
PHP код:
// . . .
LedgerBalancesDimTrans lb,lbBuf;
// . . .
while select lb
    group by dimension
        where 
(
                    (
lb.AccountNum == LedgerDistribByAlg.OffsetAccountNum) ||
                    (
lb.AccountNum == LedgerDistribByAlg.BaseAccountNum)
                 ) 
                 &&
                 ( 
lb.TransDate <= dateEndMth(ledgerJournalDistribTable.Period)) 
    
notexists join lbbuf                                                                 
        where 
(
                     (
lbbuf.AccountNum == LedgerDistribByAlg.OffsetAccountNum) ||
                     (
lbbuf.AccountNum == LedgerDistribByAlg.BaseAccountNum)
                 )
                 &&
                 ( 
lbbuf.TransDate <= dateEndMth(ledgerJournalDistribTable.Period))    &&
                 (                                                                         
                     (
lbbuf.Dimension[_dimensionNumber] !=lb.Dimension[_dimensionNumber] )
                 )                                                                 
                 &&
                 (
lbbuf.Dimension[_dimensionNumber] ==lb.Dimension[_dimensionNumber
                 || 
lB.Dimension[_dimensionNumber]=='')
{
// . . .
}
// . . . 
Я дулаю следующее:

PHP код:
// . . .
= new Query();
 
fieldName =strfmt("dimension[%1]"_dimensionNumber)
fieldId fieldName2Id(tableNum(LedgerBalancesDimTrans), fieldName);
qbds_lb q.addDataSource(tableNum(LedgerBalancesDimTrans), 'A');
qbds_lb.orderMode(OrderMode::GroupBy);
qbds_lb.addSortField(fieldId);
qbr qbds_lb.addRange(fieldNum(LedgerBalancesDimTransTransDate));
qbr.value(SysQuery::range(DateNull(), dateEndMth(ledgerJournalDistribTable.Period)));
if (
LedgerDistribByAlg.OffsetAccountNum)
{
    
qbr qbds_lb.addRange(fieldNum(LedgerBalancesDimTransAccountNum));
    
qbr.value(SysQuery::value(LedgerDistribByAlg.OffsetAccountNum));
}
 
if (
LedgerDistribByAlg.BaseAccountNum)
{
    
qbr qbds_lb.addRange(fieldNum(LedgerBalancesDimTransAccountNum));
    
qbr.value(SysQuery::value(LedgerDistribByAlg.BaseAccountNum));
}
 
qbds_lbbuf qbds_lb.addDataSource(tableNum(LedgerBalancesDimTrans), 'B');
qbds_lbbuf.relationsfalse );
qbr qbds_lbbuf.addRange(fieldNum(LedgerBalancesDimTransTransDate));
qbr.value(SysQuery::range(DateNull(), dateEndMth(ledgerJournalDistribTable.Period)));
if (
LedgerDistribByAlg.OffsetAccountNum)
{
    
qbr qbds_lbbuf.addRange(fieldNum(LedgerBalancesDimTransAccountNum));
    
qbr.value(SysQuery::value(LedgerDistribByAlg.OffsetAccountNum));
}
 
if (
LedgerDistribByAlg.BaseAccountNum)
{
    
qbr qbds_lbbuf.addRange(fieldNum(LedgerBalancesDimTransAccountNum));
    
qbr.value(SysQuery::value(LedgerDistribByAlg.BaseAccountNum));
}
 
qbds_lbbuf.joinMode(JoinMode::NoExistsJoin);
ds1 strfmt("%1.%2"qbds_lb.name(), fieldName);
ds2 strfmt("%1.%2"qbds_lbbuf.name(), fieldName);
queryExression strfmt("(%2 != %1) && ((%2 == %1) || (!%1))"ds1ds2 );
qbr qbds_lbbuf.addRange(fieldId);
qbr.value(queryExression);
qR = new QueryRun(q);
 
// qR.reset();
 
while (qR.next())
{
    
// . . .
}
// . . . 
Но оно не работает. Выдает сообщение "Ошибка расширенного диапазона запроса: Ожидается правая круглая скобка рядом с 15"

Последний раз редактировалось rkrivov; 14.11.2005 в 13:14.
Старый 14.11.2005, 13:34   #2  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,319 / 3547 (125) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Напишите вместо
X++:
queryExression = strfmt("(%2 != %1) && ((%2 == %1) || (!%1))", ds1, ds2 );
X++:
queryExression = strfmt("((%2 != %1) && ((%2 == %1) || (!%1)))", ds1, ds2 );
__________________
Возможно сделать все. Вопрос времени
Старый 14.11.2005, 13:57   #3  
rkrivov is offline
rkrivov
Участник
Аватар для rkrivov
 
31 / 10 (1) +
Регистрация: 18.02.2005
Адрес: Москва
Такая же фигня... получил - Ошибка расширенного диапазона запроса: Ожидается правая круглая скобка рядом с 16.
Старый 14.11.2005, 14:45   #4  
Ruff is offline
Ruff
Дмитрий Ерин
Аватар для Ruff
1C
 
475 / 396 (14) ++++++
Регистрация: 18.09.2003
Адрес: Тула
Хм... Честно говоря, не вникал в суть того, что Вы пытаетесь сделать, но сдается мне, что в Ваш запрос закралась какая-то бяка... Попытка оптимизировать (по правилу поглощения, кажется) условие:

"(%2 != %1) && ((%2 == %1) || (!%1))"

привела к следующему:

"(%2 != %1) && (!%1)"

Что по сути означает "первый параметр всегда пустой, а второй - всегда непустой". Может быть это именно то, что Вам и нужно, но зачем тогда такие сложные сравнения?
Старый 14.11.2005, 17:05   #5  
rkrivov is offline
rkrivov
Участник
Аватар для rkrivov
 
31 / 10 (1) +
Регистрация: 18.02.2005
Адрес: Москва
Цитата:
Попытка оптимизировать (по правилу поглощения, кажется) условие:

"(%2 != %1) && ((%2 == %1) || (!%1))"

привела к следующему:

"(%2 != %1) && (!%1)"
Все равно не спасает... ошибка все таже
Старый 14.11.2005, 17:07   #6  
Hezl is offline
Hezl
Участник
Аватар для Hezl
 
138 / 16 (1) ++
Регистрация: 21.04.2004
Адрес: Moscow, Russia
Попробуй все выражение взять в скобки.
Код:
"((%2 != %1) && ((%2 == %1) || (!%1)))"

Последний раз редактировалось Hezl; 14.11.2005 в 17:11.
Старый 14.11.2005, 17:12   #7  
rkrivov is offline
rkrivov
Участник
Аватар для rkrivov
 
31 / 10 (1) +
Регистрация: 18.02.2005
Адрес: Москва
Цитата:
Попробуй все выражение взять в скобки.
Уже брал и не в одни... не берет
Старый 14.11.2005, 17:15   #8  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Скобки здесь не причем.

Разборщик Axapta'ы не понимает обращение к полям в виде массива ("A.dimension[1]"). Можно обратиться к первому полю массива просто указав его имя ("A.dimension"). К остальным достучаться не получается даже через имя поля в б/д ("dimension2_" или "dimension3_")
__________________
Axapta v.3.0 sp5 kr2
Старый 14.11.2005, 17:16   #9  
rkrivov is offline
rkrivov
Участник
Аватар для rkrivov
 
31 / 10 (1) +
Регистрация: 18.02.2005
Адрес: Москва
Цитата:
Разборщик Axapta'ы не понимает обращение к полям в виде массива ("A.dimension[1]"). Можно обратиться к первому полю массива просто указав его имя ("A.dimension"). К остальным достучаться не получается даже через имя поля в б/д ("dimension2_" или "dimension3_")
А как получить физическое имя поля (то, что в базе) по его коду или аксаптовскому имени?
Старый 14.11.2005, 17:17   #10  
Hezl is offline
Hezl
Участник
Аватар для Hezl
 
138 / 16 (1) ++
Регистрация: 21.04.2004
Адрес: Moscow, Russia
Если я правильно помню, то подобный "расширенный" фильтр нельзя использовать для элементов массива с индексом более 1. У тебя fieldName = dimension[...]

Немного опоздал

Последний раз редактировалось Hezl; 14.11.2005 в 17:32.
Старый 14.11.2005, 17:26   #11  
rkrivov is offline
rkrivov
Участник
Аватар для rkrivov
 
31 / 10 (1) +
Регистрация: 18.02.2005
Адрес: Москва
вот что аксапта выдала "Ошибка расширенного диапазона запроса: B.dimension_5 не является корректной парой datasource.field рядом с 21."
Старый 14.11.2005, 17:43   #12  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Цитата:
Сообщение от rkrivov
А как получить физическое имя поля (то, что в базе) по его коду или аксаптовскому имени?
X++:
DictTable.fieldName(filedid2ext(fieldnum(LedgerBalancesDimTrans, Dimension), 5),
    DBBackend::Sql);
Цитата:
Сообщение от rkrivov
вот что аксапта выдала "Ошибка расширенного диапазона запроса: B.dimension_5 не является корректной парой datasource.field рядом с 21."
Во-первых, поле называется dimension5_
Во-вторых, все равно не поможет
__________________
Axapta v.3.0 sp5 kr2
За это сообщение автора поблагодарили: Ace of Database (2).
Старый 14.11.2005, 17:48   #13  
rkrivov is offline
rkrivov
Участник
Аватар для rkrivov
 
31 / 10 (1) +
Регистрация: 18.02.2005
Адрес: Москва
Цитата:
Во-первых, поле называется dimension5_
Во-вторых, все равно не поможет
Исчерпывающий ответ... главное поможет
Старый 14.11.2005, 17:59   #14  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Цитата:
Сообщение от rkrivov
Исчерпывающий ответ... главное поможет
Извините.
Выше я уже писал, что можно обратиться только к первому полю массива. Не совсем понял какие ко мне претензии
__________________
Axapta v.3.0 sp5 kr2
Старый 14.11.2005, 18:05   #15  
rkrivov is offline
rkrivov
Участник
Аватар для rkrivov
 
31 / 10 (1) +
Регистрация: 18.02.2005
Адрес: Москва
Цитата:
Выше я уже писал, что можно обратиться только к первому полю массива. Не совсем понял какие ко мне претензии
К вам никаких притензий... спасибо за помощь... но мне нужно обратиться ко всем аналитикам, а не только к первой
Старый 14.11.2005, 18:42   #16  
rkrivov is offline
rkrivov
Участник
Аватар для rkrivov
 
31 / 10 (1) +
Регистрация: 18.02.2005
Адрес: Москва
Самое интересное что при обращение к первой аналитике (т.е. к полю DIMENSION, а не к DIMENSION5_) получаем сообщение "Ошибка расширенного диапазона запроса: Ожидается правая круглая скобка рядом с 36."
Называется от чего ушли к тому и пришли

Последний раз редактировалось rkrivov; 14.11.2005 в 19:08.
Старый 15.11.2005, 11:23   #17  
rkrivov is offline
rkrivov
Участник
Аватар для rkrivov
 
31 / 10 (1) +
Регистрация: 18.02.2005
Адрес: Москва
Angry Ну не работает эта з(а)раза
В общем так... вот код, который формирует запрос (он несколько изменился) :
X++:
q = new Query();
qbds_lb = q.addDataSource(tableNum(LedgerBalancesDimTrans));
qbds_lbbuf = qbds_lb.addDataSource(tableNum(LedgerBalancesDimTrans));
qbds_lbbuf.relations( false );
qbds_lbbuf.joinMode(JoinMode::NoExistsJoin);
qbds_lb.orderMode(OrderMode::GroupBy);
qbds_lb.addSortField(fieldId);
qbr = qbds_lb.addRange(fieldNum(LedgerBalancesDimTrans, TransDate));
qbr.value(SysQuery::range(DateNull(), dateEndMth(ledgerJournalDistribTable.Period)));
qbr = qbds_lbbuf.addRange(fieldNum(LedgerBalancesDimTrans, TransDate));
qbr.value(SysQuery::range(DateNull(), dateEndMth(ledgerJournalDistribTable.Period)));
if (LedgerDistribByAlg.OffsetAccountNum)
{
    qbr = qbds_lb.addRange(fieldNum(LedgerBalancesDimTrans, AccountNum));
        qbr.value(SysQuery::value(LedgerDistribByAlg.OffsetAccountNum));
    qbr = qbds_lbbuf.addRange(fieldNum(LedgerBalancesDimTrans, AccountNum));
        qbr.value(SysQuery::value(LedgerDistribByAlg.OffsetAccountNum));
}
if (LedgerDistribByAlg.BaseAccountNum)
{
    qbr = qbds_lb.addRange(fieldNum(LedgerBalancesDimTrans, AccountNum));
        qbr.value(SysQuery::value(LedgerDistribByAlg.BaseAccountNum));
    qbr = qbds_lbbuf.addRange(fieldNum(LedgerBalancesDimTrans, AccountNum));
        qbr.value(SysQuery::value(LedgerDistribByAlg.BaseAccountNum));
}
switch (_dimensionNumber)
{
case 1:
    if (ledgerDistribByAlg.DimLedgerDistribByAlg[1])
    {
        qbr = qbds_lb.addRange(fieldName2Id(tableNum(LedgerBalancesDimTrans), "dimension[1]"));
            qbr.value(ledgerDistribByAlg.DimLedgerDistribByAlg[1]);
        qbr = qbds_lbbuf.addRange(fieldName2Id(tableNum(LedgerBalancesDimTrans), "dimension[1]"));
            qbr.value(ledgerDistribByAlg.DimLedgerDistribByAlg[1]);
    }
    break;
case 2:
    if (ledgerDistribByAlg.DimLedgerDistribByAlg[2])
    {
        qbr = qbds_lb.addRange(fieldName2Id(tableNum(LedgerBalancesDimTrans), "dimension[2]"));
            qbr.value(ledgerDistribByAlg.DimLedgerDistribByAlg[2]);
        qbr = qbds_lbbuf.addRange(fieldName2Id(tableNum(LedgerBalancesDimTrans), "dimension[2]"));
            qbr.value(ledgerDistribByAlg.DimLedgerDistribByAlg[2]);
    }
    break;
case 5:
    if (ledgerDistribByAlg.DimLedgerDistribByAlg[3])
    {
        qbr = qbds_lb.addRange(fieldName2Id(tableNum(LedgerBalancesDimTrans), "dimension[5]"));
            qbr.value(ledgerDistribByAlg.DimLedgerDistribByAlg[3]);
        qbr = qbds_lbbuf.addRange(fieldName2Id(tableNum(LedgerBalancesDimTrans), "dimension[5]"));
            qbr.value(ledgerDistribByAlg.DimLedgerDistribByAlg[3]);
    }
    break;
}
ds1 = strfmt("%1.%2", qbds_lb.name(), fieldName);
ds2 = strfmt("%1.%2", qbds_lbbuf.name(), fieldName);
queryExression = strfmt("((NOT(%2 = %1)) AND ((%2 = %1) OR (NOT(%1 = ''))))", ds1, ds2 );
qbr = qbds_lbbuf.addRange(fieldId);
qbr.value(queryExression);
qR = new QueryRun(q);
// qR.reset();
while (qR.next())
{    
    lb = qR.getNo(1);
    // . . .
    // Something to do
    // . . .
}
Вот полученый запрос:

Код:
SELECT * FROM LedgerBalancesDimTrans 
GROUP BY LedgerBalancesDimTrans.Dimension[5] ASC 
WHERE ((TransDate<=30.11.2005)) AND 
((AccountNum = 25.0200) OR (AccountNum = 20.0100)) 
NOTEXISTS JOIN * 
FROM LedgerBalancesDimTrans 
WHERE ((TransDate<=30.11.2005)) AND 
((AccountNum = 25.0200) OR (AccountNum = 20.0100)) AND 
((((NOT(LedgerBalancesDimTrans_1_1.dimension[5] = LedgerBalancesDimTrans_1.dimension[5])) AND 
	 ((LedgerBalancesDimTrans_1_1.dimension[5] = LedgerBalancesDimTrans_1.dimension[5]) OR 
						 (NOT(LedgerBalancesDimTrans_1.dimension[5] = ''))))))
И при этом не работает. получаю сообщения а-ля Ошибка расширенного диапазона запроса: Ожидается правая круглая скобка рядом с 0.
Попробовал практически все варинаты... так и не работает... Как это Аксапта парсит такие запросы.... или это вообще сделать не реально? (тогда нужно действовать напрямую)
Если убрать строки
X++:
qbr = qbds_lbbuf.addRange(fieldId);
qbr.value(queryExression);
- все работает... т.е. ошибки нет, но и запрос отрабатывает не корректно.

Последний раз редактировалось rkrivov; 15.11.2005 в 12:01.
Старый 15.11.2005, 12:08   #18  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
??
Я чего-то не пойму - вам же AndyD написал, что оно не будет работать с Dimension с index > 1

возможно попробуйте вместо попыток создания query убрать то условие, которое глючит, делать while (qr.next())
{
//и здесь проверять ваше условие через if(dimension[5] != '34') так далее
}

Это дольше понятно работать будет - но зато будет.
Старый 15.11.2005, 12:33   #19  
rkrivov is offline
rkrivov
Участник
Аватар для rkrivov
 
31 / 10 (1) +
Регистрация: 18.02.2005
Адрес: Москва
Цитата:
Сообщение от kashperuk
??
Я чего-то не пойму - вам же AndyD написал, что оно не будет работать с Dimension с index > 1

возможно попробуйте вместо попыток создания query убрать то условие, которое глючит, делать while (qr.next())
{
//и здесь проверять ваше условие через if(dimension[5] != '34') так далее
}

Это дольше понятно работать будет - но зато будет.
если я уберу строки
X++:
ds1 = strfmt([color=red]"%1.%2"[/color], qbds_lb.name(), fieldName);
ds2 = strfmt([color=red]"%1.%2"[/color], qbds_lbbuf.name(), fieldName);
queryExression = strfmt([color=red]"((NOT(%2 = %1)) AND ((%2 = %1) OR (NOT(%1 = ''))))"[/color], ds1, ds2 );
qbr = qbds_lbbuf.addRange(fieldId);
qbr.value(queryExression);
то все будет работать... и не смотря на Dimension с Index > 1

К тому же с Index = 1 тоже не работает... я уже писал об этом...

Последний раз редактировалось rkrivov; 15.11.2005 в 12:38.
Старый 15.11.2005, 12:44   #20  
oblin is offline
oblin
Участник
 
2 / 10 (1) +
Регистрация: 14.02.2005
Адрес: Москва
Вместо

queryExression = strfmt("((NOT(%2 = %1)) AND ((%2 = %1) OR (NOT(%1 = ''))))", ds1, ds2 );

Попробуйте

queryExression = strfmt('((NOT(%2 = %1)) AND ((%2 = %1) OR (NOT(%1 = ""))))', ds1, ds2 );

Часто помогает.
Теги
query, программно, фильтр, запрос (query)

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Вопрос по Query с агрегатной функцией Jarad DAX: Программирование 11 31.10.2006 21:10
Вопрос про Query 6apcyk DAX: Программирование 5 16.11.2005 19:08
Вопрос по query и join tischenko DAX: Программирование 2 20.07.2005 13:05
Вопрос по запросу (query) Александр_1975 DAX: Программирование 2 23.01.2004 17:35
Вопрос знатокам QBE и Query в AXAPTA Maxim Gorbunov DAX: Программирование 6 27.12.2002 13:19
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 23:22.