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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 25.06.2022, 00:22   #1  
DesparioN is offline
DesparioN
Участник
 
86 / 15 (1) ++
Регистрация: 21.10.2014
Подсчет количества строк в Query (DAX2012)
Добрый день!

Обычно для подсчета количества строк всегда использовал queryRun::getQueryRowCount, однако появилась необходимость сделать тоже самое на темповой таблице, и тут возникла проблема.

Как я не пытался написать, всегда в результате получаю 0.

Есть какая то хитрость, или это невозможно?
Старый 25.06.2022, 10:25   #2  
axm2017 is offline
axm2017
Участник
 
1,937 / 317 (14) ++++++
Регистрация: 15.05.2017
Каковы правильно заметили дело наверное во временных таблицах. Наверное стоит это учесть и доработать Академ найти корректный метод
Старый 25.06.2022, 12:13   #3  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1296 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Да, этот метод принимает Query и поэтому в случае временной таблицы не знает какую именно из временных таблиц (их курсоров) обрабатывать.

Есть методы, которые принимают QueryRun. А вот уже в QueryRun можно подсунуть конкретный курсор заполненной временной таблицы (методом setCursor).

Это два метода класса SysQuery из AOT:
  • countTotal
  • countLoops

Они имеют особенности если запрос "многоэтажный". Если поищете по форуму эти методы, то будет понятно когда какой использовать (и использовать ли именно их).
Старый 25.06.2022, 23:17   #4  
DesparioN is offline
DesparioN
Участник
 
86 / 15 (1) ++
Регистрация: 21.10.2014
Их я тоже пробовал, и с setcursor, и с setrecord, и они тоже дают 0.
Старый 25.06.2022, 23:59   #5  
axm2017 is offline
axm2017
Участник
 
1,937 / 317 (14) ++++++
Регистрация: 15.05.2017
Цитата:
Сообщение от DesparioN Посмотреть сообщение
Их я тоже пробовал, и с setcursor, и с setrecord, и они тоже дают 0.
Значит делаете что то не так.
Покажите код - пример
Старый 26.06.2022, 00:08   #6  
DesparioN is offline
DesparioN
Участник
 
86 / 15 (1) ++
Регистрация: 21.10.2014
X++:
queryRun = new QueryRun(query);
queryRun.setRecord(tmpTable);
i = SysQuery::countTotal(queryRun);
Причем если написать while(queryRun.next()), то цикл отрабатывает.
Старый 26.06.2022, 08:03   #7  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,324 / 3548 (125) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Всё правильно. Особенность временных таблиц состоит в том, чтобы не терять курсор. Т.е. если можно объявить переменную постоянной таблицы, чего-то в ней сделать, а затем объявить новую переменную и она уже увидит сделанные изменения, то в случае с временными таблицами такой подход не работает.
В случае с временными таблицами нужно ту переменную, которую наполнили данными - "таскать за собой" и пользоваться методами setTmpData() / linkToPhysicalInstance(), чтобы новую переменную привязывать к буферу той переменной, в которой лежат данные.

Соответственно, в метод QueryRun::getQueryRowCount() действительно нельзя передать буфер временной таблицы, поэтому он работать для временных таблиц не будет
Но и метод SysQuery::countTotal() внутри себя занимается перепаковкой Query и т.о. теряет исходный курсор.

Поэтому, чтобы метод SysQuery::countTotal() работал корректно для временных таблиц - нужно сделать несколько изменений:
1. В метод countTotal нужно добавить параметр, через который будет передаваться буфер временной таблицы:
X++:
public client server static Integer countTotal(QueryRun _queryRun, Common _tmpBuffer = null)// VSUH, Корректный подсчет кол-ва записей во временной таблице, 06.04.2009
{
    container c = SysQuery::countPrim(_queryRun.pack(false), _tmpBuffer);

    return conpeek(c,1);
}
2. В метод countPrim также нужно добавить аналогичный параметр и уже его дальше использовать в методе setCursor
X++:
private server static container countPrim(container _queryPack, Common _tmpBuffer = null) // VSUH, Корректный подсчет кол-ва записей во временной таблице, 06.04.2009
{
    Query                   countQuery;
    QueryRun                countQueryRun;
    QueryBuildDataSource    qbds;
    QueryBuildFieldList     qbfl;
    Common                  common;
    Integer                 counter;
    Integer                 loops;
    ;
    countQueryRun   = new QueryRun(_queryPack);
    // VSUH, Корректный подсчет кол-ва записей во временной таблице, 06.04.2009 -->
    if (_tmpBuffer)
    {
        countQueryRun.setCursor(_tmpBuffer);
    }
    // VSUH, Корректный подсчет кол-ва записей во временной таблице, 06.04.2009 <--
    countQuery      = countQueryRun.query();
    qbds            = countQuery.dataSourceNo(1);
    qbds.update(false);
    qbds.sortClear();
    countQuery.clearGroupBy();
    countQuery.clearOrderBy();
    qbfl = qbds.fields();
    qbfl.dynamic(false);
    qbfl.clearFieldList();
    if (countQuery.dataSourceCount() == 1)
        qbds.addSelectionField(fieldNum(Common,RecId),SelectionField::Count);

    countQueryRun   = new QueryRun(countQuery);
    // VSUH, Корректный подсчет кол-ва записей во временной таблице, 06.04.2009 -->
    if (_tmpBuffer)
    {
        countQueryRun.setCursor(_tmpBuffer);
    }
    // VSUH, Корректный подсчет кол-ва записей во временной таблице, 06.04.2009 <--

    while (countQueryRun.next())
    {
        common  = countQueryRun.get(countQuery.dataSourceNo(1).table());
        counter += common.RecId;
        loops++;
    }

    return [counter,loops];
}
Само собой, можно еще сделать дополнительную проверку, что передаваемый буфер действительно является временной таблицей (tmpBuffer.isTmp() || tmpBuffer.isTempDB())
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 26.06.2022 в 09:00.
За это сообщение автора поблагодарили: Raven Melancholic (2), DesparioN (1).
Старый 26.06.2022, 08:14   #8  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1296 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Цитата:
Сообщение от axm2017 Посмотреть сообщение
Значит делаете что то не так.
Покажите код - пример
Не, всё нормально, это я ввел человека в заблуждение.
В стандарте действительно, не работает.
У меня примерно тоже, что указал sukhanchik, правда уже внутри countPrim проверка посильнее:
X++:
    if (_bufferTmp &&
        _bufferTmp.isTmp() &&
        countQuery.dataSourceCount() == 1)
    {        
        countQueryRun.setCursor(_bufferTmp);
    }
В итоге выглядит вот так (там еще параметры, но они не влияют в данном случае):
X++:
static void Job1(Args _args)
{
    TmpABC                  tmpABC;
    QueryRun                queryRun;
    Query                   query;
    QueryBuildDataSource    qbds;
    Counter                 recordCount;
    ;
    
    tmpABC.clear();
    tmpABC.initValue();
    
    tmpABC.ItemId   = 'ItemId1';
    tmpABC.RefRecId = 1;
    tmpABC.insert();
    
    tmpABC.ItemId   = 'ItemId2';
    tmpABC.RefRecId = 2;
    tmpABC.insert();
    
    query       = new Query();
    qbds        = query.addDataSource(tableNum(TmpABC));
    queryRun    = new QueryRun(query);
    
    recordCount = SysQuery::countTotal(queryRun, false, 0, tmpABC);
    info(strFmt("Всего записей %1.", recordCount));
}
Старый 26.06.2022, 08:26   #9  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1296 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
Само собой, можно еще сделать дополнительную проверку, что передаваемый буфер действительно является временной таблицей (tmpBuffer.isTmp() || tmpBuffer.isTemDB())
О, точно. сейчас еще добавлю isTemDB. Как-то кочует эта модификация с времен, когда этого не было.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
alirazazaidi: Build Dynamics Query in Dynamics 365 for Finance and Operations – Video Webcast MsDyn365FO Blog bot DAX Blogs 0 11.10.2018 08:12
emeadaxsupport: Microsoft Dynamics AX general performance analysis scripts page 5 Blog bot DAX Blogs 0 01.09.2014 14:11
Количество строк в Query Владимир Максимов DAX: Программирование 19 11.08.2014 18:27
Глюки с созданием большого количества строк. DDA DAX: Программирование 3 06.03.2003 12:36
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

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