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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 08.10.2012, 16:25   #1  
Dimitry is offline
Dimitry
Участник
 
172 / 10 (1) +
Регистрация: 07.02.2003
Запрос одного отчета присутствует в другом
Надеюсь это в эту ветку.

Обнаружена следующая бага.

Имеются два класса, наследники RunBase, построения отчета.
Строят по одинаковым таблицам, но выводят разные данные.

При сохранении запроса в одно отчете, он виден в другом.
Не могу понять в чем причина.
Старый 08.10.2012, 16:44   #2  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
Цитата:
Сообщение от Dimitry Посмотреть сообщение
Надеюсь это в эту ветку.

Обнаружена следующая бага.

Имеются два класса, наследники RunBase, построения отчета.
Строят по одинаковым таблицам, но выводят разные данные.

При сохранении запроса в одно отчете, он виден в другом.
Не могу понять в чем причина.
так как в запросе используются одни и те же таблицы (и запрос скорее всего примерно один и тот же, я не про критерии выборки, а про структуру запроса), то скорее всего аксапта из кэша подхватывает последний сохраненный запрос. Что бы этого не было, в классе, при формировании запроса, нужно явно указать имя запроса:

например:
X++:
query.name(classstr(MyReportClass));
P.S. а как вы строите запросы, кстати?
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
За это сообщение автора поблагодарили: Dimitry (1).
Старый 08.10.2012, 17:02   #3  
Dimitry is offline
Dimitry
Участник
 
172 / 10 (1) +
Регистрация: 07.02.2003
Понял... Спасибо.
Придется создавать кверики, а то они у меня в классе прописаны.
Старый 08.10.2012, 17:12   #4  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
Цитата:
Сообщение от Dimitry Посмотреть сообщение
... а то они у меня в классе прописаны.
А можно поподробней? Как в классе прописаны?
Идеально было бы пример привести
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 08.10.2012, 17:16   #5  
Dimitry is offline
Dimitry
Участник
 
172 / 10 (1) +
Регистрация: 07.02.2003
Вот в одном классе:
(на подобии в другом)
X++:
public void initParmDefault()
{
    QueryBuildDataSource qbdsTrans, qbdsPosting;
    QueryBuildRange      qbr;
    ;

    super();

    query = new Query();

    qbdsTrans = query.addDataSource(tableNum(InventTrans));
    qbdsTrans.addRange(fieldNum(InventTrans,DateFinancial));

    qbr = qbdsTrans.addRange(fieldNum(InventTRans, TransType));
    qbr.value(queryValue(InventTransType::Sales));
    qbr.status(RangeStatus::Locked);

    qbdsTrans.addGroupByField(fieldNum(InventTRans,TransRefId));
    //qbdsTrans.addGroupByField(fieldNum(InventTRans,DatePhysical));
    qbdsTrans.addGroupByField(fieldNum(InventTRans,DateFinancial));
    qbdsTrans.addGroupByField(fieldNum(InventTRans,InvoiceId));
    qbdsTrans.addSelectionField(fieldNum(InventTRans,Qty), SelectionField::Sum);
    qbdsTrans.addSelectionField(fieldNum(InventTRans,TaxAmountPhysical), SelectionField::Sum);

    qbdsPosting = qbdsTrans.addDataSource(tableNum(InventTransPosting));
    //qbdsPosting.addRange(fieldNum(InventTransPosting, InventTransPostingType)).value(queryValue(InventTransPostingType::Physical));
    qbdsPosting.addRange(fieldNum(InventTransPosting, InventTransPostingType)).value(queryValue(InventTransPostingType::Financial));
    //qbdsPosting.addLink(fieldNum(InventTRans,DatePhysical), fieldNum(InventTransPosting, TransDate));
    qbdsPosting.addLink(fieldNum(InventTRans,DateFinancial), fieldNum(InventTransPosting, TransDate));
    qbdsPosting.addLink(fieldNum(InventTRans,Voucher), fieldNum(InventTransPosting, Voucher));
    qbdsPosting.addLink(fieldNum(InventTRans,InventTransId), fieldNum(InventTransPosting, InventTransId));

    qbdsPosting.addSelectionField(fieldId2ext(fieldNum(InventTransPosting, Dimension),1), SelectionField::Max);
    qbdsPosting.addSelectionField(fieldId2ext(fieldNum(InventTransPosting, Dimension),2), SelectionField::Max);
    qbdsPosting.addSelectionField(fieldId2ext(fieldNum(InventTransPosting, Dimension),8), SelectionField::Max);

    queryRun = new SysQueryRun(query);
}
Старый 08.10.2012, 17:24   #6  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
Цитата:
Сообщение от Dimitry Посмотреть сообщение
Вот в одном классе:
(на подобии в другом)
X++:
public void initParmDefault()
{
    QueryBuildDataSource qbdsTrans, qbdsPosting;
    QueryBuildRange      qbr;
    ;

    super();

    query = new Query();

    qbdsTrans = query.addDataSource(tableNum(InventTrans));
    qbdsTrans.addRange(fieldNum(InventTrans,DateFinancial));

    qbr = qbdsTrans.addRange(fieldNum(InventTRans, TransType));
    qbr.value(queryValue(InventTransType::Sales));
    qbr.status(RangeStatus::Locked);

    qbdsTrans.addGroupByField(fieldNum(InventTRans,TransRefId));
    //qbdsTrans.addGroupByField(fieldNum(InventTRans,DatePhysical));
    qbdsTrans.addGroupByField(fieldNum(InventTRans,DateFinancial));
    qbdsTrans.addGroupByField(fieldNum(InventTRans,InvoiceId));
    qbdsTrans.addSelectionField(fieldNum(InventTRans,Qty), SelectionField::Sum);
    qbdsTrans.addSelectionField(fieldNum(InventTRans,TaxAmountPhysical), SelectionField::Sum);

    qbdsPosting = qbdsTrans.addDataSource(tableNum(InventTransPosting));
    //qbdsPosting.addRange(fieldNum(InventTransPosting, InventTransPostingType)).value(queryValue(InventTransPostingType::Physical));
    qbdsPosting.addRange(fieldNum(InventTransPosting, InventTransPostingType)).value(queryValue(InventTransPostingType::Financial));
    //qbdsPosting.addLink(fieldNum(InventTRans,DatePhysical), fieldNum(InventTransPosting, TransDate));
    qbdsPosting.addLink(fieldNum(InventTRans,DateFinancial), fieldNum(InventTransPosting, TransDate));
    qbdsPosting.addLink(fieldNum(InventTRans,Voucher), fieldNum(InventTransPosting, Voucher));
    qbdsPosting.addLink(fieldNum(InventTRans,InventTransId), fieldNum(InventTransPosting, InventTransId));

    qbdsPosting.addSelectionField(fieldId2ext(fieldNum(InventTransPosting, Dimension),1), SelectionField::Max);
    qbdsPosting.addSelectionField(fieldId2ext(fieldNum(InventTransPosting, Dimension),2), SelectionField::Max);
    qbdsPosting.addSelectionField(fieldId2ext(fieldNum(InventTransPosting, Dimension),8), SelectionField::Max);

    queryRun = new SysQueryRun(query);
}
можете прям здесь после строки:
X++:
query = new Query();
добавить строку из моего примера:
X++:
query.name(classstr());
и будет Вам счастье

P.S. только это надо сделать и во втором классе... да и вообще лучше это делать во всех классах где формируете запросы в коде, что бы в будущем аксапта находила нужный запрос в кэше по имени
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем

Последний раз редактировалось lev; 08.10.2012 в 17:26.
Старый 08.10.2012, 17:34   #7  
Dimitry is offline
Dimitry
Участник
 
172 / 10 (1) +
Регистрация: 07.02.2003
Спасибо. Помогло.
Старый 08.10.2012, 17:43   #8  
ice is offline
ice
Участник
Аватар для ice
Лучший по профессии 2014
 
1,731 / 406 (17) +++++++
Регистрация: 23.03.2006
Цитата:
Сообщение от lev Посмотреть сообщение
можете прям здесь после строки:
X++:
query = new Query();
добавить строку из моего примера:
X++:
query.name(classstr());
и будет Вам счастье

P.S. только это надо сделать и во втором классе... да и вообще лучше это делать во всех классах где формируете запросы в коде, что бы в будущем аксапта находила нужный запрос в кэше по имени
очень странный совет
X++:
query.name(classstr());
никогда подобный код не использовал (да и по правде сказать примеров не видел) и проблем не испытывал.
Может быть все таки проблема в другом?
Старый 08.10.2012, 17:47   #9  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
Цитата:
Сообщение от ice Посмотреть сообщение
очень странный совет
X++:
query.name(classstr());
никогда подобный код не использовал (да и по правде сказать примеров не видел) и проблем не испытывал.
Может быть все таки проблема в другом?
в чем странность?

проверено на своем опыте.
всегда использовал, когда формировал в коде запросы, которые выводятся пользователям в диалоге.
проблема, которая возникает, если не именовать запросы, описана в первом посте автора темы.
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 08.10.2012, 20:53   #10  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Надеюсь, Вы в курсе, что initParmDefault() выполняется только в том случае, если в кеше ничего не было найдено. Это значит, что если Вы хотя бы раз выполнили Ваш отчет, то он попал в кеш и все последующие запуски запрос будет браться из кеша, а все то, что написано в initParmDefault() будет игнорироваться. Точнее, initParmDefault() просто не будет выполняться. Разумеется, если Вы реализовали кеширование Вашего запроса в методах pack/unpack.

Как следствие, в случае модификации структуры Query в методе initParmDefault() необходимо либо очистить кеш по данному классу, либо увеличить значение константы CurrentVersion в методе classDeclaration.

Кроме того, если Вы создали класс как наследнико от RunBaseReport, то возможны дополнительные "заморчки" связанные с кешированием собственно отчета.
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 08.10.2012, 21:26   #11  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от lev Посмотреть сообщение
проблема, которая возникает, если не именовать запросы, описана в первом посте автора темы.
Нет. Это проблема, которая возникает, если оставить кеширование на откуп автоматическим средствами кеширования запросов. Тогда идентификация запроса в кеше будет идти по именам, сгенеренным автоматически. А генератор имен в кеше строит их на основе имени или ID таблиц-источников. Вот и получаются одинаковые имена для разных классов/форм

Описанный прием просто явным образом присваивает уникальное имя Query и подобной не однозначности не возникает.

Если же сделать сохранение query в кеше явным образом в методах pack/unpack, то уже не имеет значения, будет ли query автоматически сохраняться или нет. Он будет браться из кеша класса, а не из кеша query. Вне зависимости от его имени.
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
За это сообщение автора поблагодарили: dn (1), Pustik (3), ice (1).
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Поймать SQL запрос при формировании отчета Qaz Qwerty DAX: Программирование 7 12.06.2008 01:46
Печать отчета Прокопьева DAX: Программирование 11 02.08.2006 08:15
Как изменить заголовок окна предв.просмотра отчета Владимир Максимов DAX: Программирование 6 03.07.2006 15:34
Русская локализация Axapta 3 ? SlavaK DAX: Администрирование 59 01.07.2003 22:38
Формирование отчета с динамически изменяемым числом столбцов. rumpleteazer DAX: Программирование 1 06.09.2002 11:25

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

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

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