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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 21.01.2004, 20:51   #21  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
итак, предлагаю код метода SysQuery::countPrim для 3.0
Код:
private server static container countPrim(container _queryPack)
{
...
  ;
    countQueryRun   = new QueryRun(_queryPack);
    countQuery      = countQueryRun.query();
    for (k = 1; k <= countQuery.dataSourceCount();k++)
    {
        qbds = countQuery.dataSourceNo(k);
        qbds.update(false);
        //qbds.sortClear(); // Вот этот метод сильно мешал!
        qbfl = qbds.fields();
        qbfl.dynamic(false);
        qbfl.clearFieldList();
        qbfl.addField(FieldNum(Common,recId),SelectionField::COUNT);
    }

    countQueryRun   = new QueryRun(countQuery);
    while (countQueryRun.next())
    {
        common  = countQueryRun.getNo(1);
        counter += common.recId;
        loops++;
    }
    return [counter,((loops > 1)? loops : counter)];
}
Вложения
Тип файла: xpo SysQuery30.xpo (1.9 Кб, 291 просмотров)
__________________
полезное на axForum, github, vk, coub.
Старый 21.01.2004, 20:52   #22  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
код метода SysQuery::countPrim для 2.5
Код:
server static container countPrim(QueryRun _queryRun)
{
...
    con             = _queryRun.pack();
    countQueryRun   = new QueryRun(con);
    countQuery      = countQueryRun.query();
    for (k = 1; k <= countQuery.dataSourceCount();k++)
    {
        qbds            = countQuery.dataSourceNo(k);
        qbds.update(false);
        //qbds.sortClear(); // Мешал вот этот метод!
        qbfl = qbds.fields();
        qbfl.dynamic(false);
        qbfl.clearFieldList();
        qbfl.addField(FieldNum(Common,recId),SelectionField::COUNT);
    }

    countQueryRun   = new QueryRun(countQuery);
    while (countQueryRun.next())
    {
        common  = countQueryRun.getNo(1);
        counter += common.recId;
        loops++;
    }

    return [counter,((loops > 1)? loops : counter)];
}
Вложения
Тип файла: xpo SysQuery25.xpo (2.0 Кб, 296 просмотров)
__________________
полезное на axForum, github, vk, coub.
Старый 21.01.2004, 20:53   #23  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
проверочный job. подходит для обеих версий

Код:
static void testSysQuery_CountLoops_rnr(Args _args)
{
    Query                q = new Query();
    QueryRun             qr;
    QueryBuildDataSource qbds;
    QueryBuildDataSource qbds2;
    LedgerTable          lt;
    LedgerTrans          ltrans;
    Integer              loops;
    Integer              Total;

    qbds = q.addDataSource(tablenum(LedgerTable));
    qbds.addSortField(fieldnum(LedgerTable,AccountPlType));
    qbds.orderMode(0);

    qbds2 = qbds.addDataSource(tablenum(LedgerTrans));
    qbds2.joinMode(JoinMode::INNERJOIN);
    qbds2.addLink(fieldnum(LedgerTable,AccountNum),fieldnum(LedgerTrans,AccountNum));
    qbds2.addSortField(fieldnum(LedgerTrans,TransDate));
    qbds2.orderMode(0);

    info(q.dataSourceNo(1).toString());

    qr = new QueryRun(q);

    info(strfmt('Total: %1',SysQuery::countTotal(qr)));
    info(strfmt('Loops: %1',SysQuery::countLoops(qr)));

}
Вложения
Тип файла: xpo testSysQuery_CountLoops_rnr.xpo (1.4 Кб, 289 просмотров)
__________________
полезное на axForum, github, vk, coub.
Старый 21.01.2004, 21:05   #24  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
посмотрите, поиграйтесь orderMode(0) или orderMode(1) для обеих таблиц.

Обратите внимание, какие параметры и когда передаются между клиентом и сервером. Обратите внимание, как соптимизировали трафик в 3.0.

Что мешало в старой версии? В старой версии жутко мешал qbds.sortClear().

В целом был взят метод Максима. Единственно, что было исправлено в его методе, ставим Count(RecID) не только в первой таблице, но и во всех остальных.

Что получаем?
countTotal всегда достаточно быстро возвращает ОБЩЕЕ количество ЗАПИСЕЙ.
countLoops всегда достаточно быстро возвращает количество ГРУППИРОВОК.

интересно поведение countLoops, когда начинаете играться с OrderMode в проверочном примере. (для того, чтобы получить полную картину, раскоментарьте метод info в CountPrim)

Так, если оба OrderMode = 0, то CountLoop = 4110. Правильно все количество записей, вычисляется на сервере, сама Аксапта получает управление только один раз.

Если OrderMode = 1,0, то CountLoop = 5. Это количетсво группировок по типам счетов. Все правильно. У меня есть проводки по всем типам счетов, кроме загловков, итогов.

Если OrderMode = 0,1, то CountLoop = 116. Это количество различных дат в таблице финансовых проводок.

Если же OrderMode = 1,1, то CountLoop = 272. Это количество дат внутри каждого типа счета.

Т.е. можно теперь можно делать следующее (причем progress bar будет работать правильно для любого запроса!)
Код:
SysOperationProgress progress = new SysOperationProgress();

progress.setTotal(SysQuery::countLoops(qr));
while( qr.next() ){
     // ...do somthing...
     progress.incCount();
}
Посмотрите, пожалуйста. Если замечаний нет, то положим в FAQ.

wamr, я правильно понял идею насчет loops?
__________________
полезное на axForum, github, vk, coub.
Старый 22.01.2004, 13:11   #25  
Владимир Максимов_imported is offline
Владимир Максимов_imported
Участник
 
33 / 10 (1) +
Регистрация: 20.01.2004
Цитата:
progress bar будет работать правильно для любого запроса!
А как насчет связей между таблицами отличных от Inner Join? Т.е. OuterJoin, ExistsJoin или NoExistsJoin?
Старый 22.01.2004, 13:19   #26  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
также должно работать.
ближе к вечеру проверю.
__________________
полезное на axForum, github, vk, coub.
Старый 26.01.2004, 00:44   #27  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
в целом модификация работает правильно.

Бывают глюки на бессмысленные запросы. Например, если сделать NoExistsjoin с группировкой по подчиненной таблице... В нормальных случаях работает корректно.

Если сомневаетесь в работе, то используйте try/catch для обрамления вызова.

Вопрос помещен в FAQ Как подсчитать количество записей, возвращаемых Query
Спасибо участникам обсуждения
__________________
полезное на axForum, github, vk, coub.
Старый 06.05.2008, 18:49   #28  
gl00mie_imported is offline
gl00mie_imported
Участник
 
17 / 10 (1) +
Регистрация: 18.01.2006
Цитата:
Сообщение от mazzy Посмотреть сообщение
итак, предлагаю код метода SysQuery::countPrim для 3.0
Код:
private server static container countPrim(container _queryPack)
{
...
  ;
    countQueryRun   = new QueryRun(_queryPack);
    countQuery      = countQueryRun.query();
    for (k = 1; k <= countQuery.dataSourceCount();k++)
    {
        qbds = countQuery.dataSourceNo(k);
        qbds.update(false);
        qbfl = qbds.fields();
        qbfl.dynamic(false);
        qbfl.clearFieldList();
        qbfl.addField(FieldNum(Common,recId),SelectionField::COUNT);
    }
...
}
Давнишняя тема, но по ходу разбирательств обнаружилась небольшая неточность. В исходном сообщении говорилось следующее:
Цитата:
Сообщение от Maxim Gorbunov Посмотреть сообщение
Более правильный метод подсчета записей, возвращаемых Query см. в методе webTableLookup.run() Там есть вложенный метод computeRecordCount, который все и делает. Вкратце, суть метода такова. Сначала создается копия исходного Query. Для всех DataSource в Query отменяется динамическое создание списка выбираемых полей и добавляется только поле TableId (чтобы хоть что-то выбиралось). Далее, в самый главный DataSource добавляется Selection Field RecId с функцией агрегации COUNT
Тут же получается, что COUNT(RecId) добавляется для каждого датасорса вместо только первого. В свете этого корректнее было бы, наверно, написать так
Код:
    for (k = 1; k <= countQuery.dataSourceCount();k++)
    {
        qbds = countQuery.dataSourceNo(k);
        qbds.update(false);
        qbfl = qbds.fields();
        qbfl.dynamic(false);
        qbfl.clearFieldList();
        if (k == 1)
            qbfl.addField(fieldnum(Common, RecId), SelectionField::Count);
        else
            qbfl.addField(fieldnum(Common, TableId));
    }
Старый 20.09.2011, 15:35   #29  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
дальнейшее развитие и исправления здесь
http://axforum.info/forums/showthrea...047#post258047
__________________
полезное на axForum, github, vk, coub.
 


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

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

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