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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 27.07.2015, 19:34   #1  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,860 / 3109 (111) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
SysReportRun - засада
Привет всем.
Обнаружил интересную особенность класса SysReportRun.
Перекрыли метод send
(описываю случай ax2009)
дописали свою логику.

Часть отчетов отвалилась - молча безо всяких ошибок.
Стали разбираться, оказалось, что в 2009-й метод reportRun.send() имеет 4 параметра.
А во многих репортах он перекрыт так что там их всего 3.
Например
\Reports\AssetBarcode\Methods\send
X++:
public boolean send(Common cursor, int level=1, boolean triggerOffBody=true)
{
    boolean     ret = true;
    AssetTable  tmp;
    ;
...
    ret = super(cursor, level, triggerOffBody);
    return ret;
}
При запуске работа отчета просто прерывается безо всяких сообщений об ошибках.
Примеры таких репортов (все со стандартных слоев) :
AssetBalances
AssetBalancesPeriod
AssetBarcode
AssetBasis
AssetDisposal
AssetDisposal_LV
AssetFutureValue
AssetInsurance
AssetTransactionListing
BOMConsistOf
BOMPartOf
CustSalesItemGroupStatistics_NA
CustTransList
CustTurnover_RU
CzAssetTableReport
EmplAdvance_RU
ForecastPurch
ForecastPurchActual
ForecastSales
ForecastSalesActual
InventBatchExpired
InventGroupPhys
InventGroupPosted
InventLedgerConciliation
InventSpecPhys
InventSpecPosted
InventSumCritical
LvAssetTableReport
PBAConfiguratedItem
PBAConsistOf
PBAPartOf
ProdDelay
ProdLedgerConciliation
ProdPicklist
ProjMissingHourReg
PurchLinesExtended
RouteOpr
SalesLinesExtended
SalesSupplyCapacity
smmActivityPerQuotation
TaxDeviation
TaxDeviation_BE
TaxTransCode
TaxTransDetail
TaxTransDetail_BE
TaxTransDetail_HU
VendTransList
VendTurnover_RU
WMSBillOfLading
WMSLocationLabel
WMSPickingList
WMSShipmentAddresses
WMSShipmentAddressesTransferOrders
WMSShipmentList
WorkCalendar

Лечится примерно так :
Для sysReportRun пишем свои методы

X++:
    // GRD_FixReports_pkoz,  pkoz, 27.07.2015
static client server int GRD_getMethodParamsCount( str _reportName, str _reportMethodName )
{
    xrefPath        locPath;
    #AOT
    #Define.GRD_ReportMethodsCache("GRD_ReportMethodsCache")
    #Define.GRD_conNotDefinedValue([-1])
    container           con;
    SysDictMethod       SysDictMethod;
    int                 parms;
    ;
    locPath = #ReportsPath +  // #define.ReportsPath('\\Reports')
        @"\" + _reportName + @"\" + @"Methods" + @"\" + _reportMethodName;
        
    con = ClassFactory.globalCache().get(#GRD_ReportMethodsCache, locPath, #GRD_conNotDefinedValue);
    if ( con == #GRD_conNotDefinedValue ) // число параметров ни разу не рассчитывалось и не закешировано
    {
        SysDictMethod = SysDictMethod::newTreenodePath( locPath );
        if (SysDictMethod)
        {
            parms = SysDictMethod.parameterCnt();
        }
        else
        {
            parms = -2; // число параметров определить не удалось
            // либо такого метода нет
            // либо он в данном отчете не перекрыт
        }
        
        ClassFactory.globalCache().set(#GRD_ReportMethodsCache, locPath, [parms]);
    }
    else
    {
        parms = conPeek(con, 1);
    }
    
    return parms;
}

public boolean send(Common _cursor, int _level=1, boolean _triggerOffBody=TRUE, boolean _newPageBeforeBody=FALSE)
{
    boolean ret;
    int     GRD_parms;
    ;

    // GRD_FixReports_pkoz,  pkoz, 27.07.2015 -->
    // Столкнулись с тем, что в репортах метод Send може иметь меньшее число параметров (см. репорт InventOnhand).
    GRD_parms = SysReportRun::GRD_getMethodParamsCount(this.name(), methodstr(SysReportRun, send));

    switch (GRD_Parms)
    {
    case -2 : // метод в отчете не перекрыт
            ret = super(_cursor, _level, _triggerOffBody, _newPageBeforeBody);
            break;
    case  4 :
            ret = super( _cursor, _level, _triggerOffBody, _newPageBeforeBody );
            break;
    case  3 :
            ret = super( _cursor, _level, _triggerOffBody );
            break;
    case  2 :
            ret = super( _cursor, _level );
            break;
    case  1 :
            ret = super( _cursor );
            break;
    case  0 : // такого не должно быть ! // не может быть 0 параметров у этого метода
            //ret = super();
            throw error("  ");
            break;
    case -1 : // значение не рассчитано - такого не должно быть
            //ret = super(_cursor, _level, _triggerOffBody, _newPageBeforeBody);
            throw error("  ");
            break;

    default :
            ret = super( _cursor, _level, _triggerOffBody, _newPageBeforeBody );
    }

    //ret = super(_cursor, _level, _triggerOffBody, _newPageBeforeBody);
    // GRD_FixReports_pkoz,  pkoz, 27.07.2015 <--

    return ret;
}

Последний раз редактировалось Logger; 27.07.2015 в 19:37.
За это сообщение автора поблагодарили: Ruff (5).
Старый 28.07.2015, 06:59   #2  
andiv is offline
andiv
Участник
 
16 / 34 (2) +++
Регистрация: 11.01.2007
лечится примерно так:
SysReportRun
public boolean send(Common _cursor, int _level=1, boolean _triggerOffBody=TRUE, boolean _newPageBeforeBody=FALSE)


+ инкрементная компиляция.

ООП никто не отменял.
Старый 28.07.2015, 08:21   #3  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,860 / 3109 (111) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Не работает предложенный вами способ. Собственно из-за этого и стали придумывать вышеописанный способ.
Вы описание внимательно читали ?

Или вы предлагаете в каждом отчете из процитированного списка менять send метод ?

Последний раз редактировалось Logger; 28.07.2015 в 09:11.
Старый 28.07.2015, 09:23   #4  
andiv is offline
andiv
Участник
 
16 / 34 (2) +++
Регистрация: 11.01.2007
Вы в классе SysReportRun метод Send перекрывали? Сколько параметров указали?
Старый 28.07.2015, 09:29   #5  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,860 / 3109 (111) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Да.
Перекрыли метод в классе SysReportRun

Ядро сгенерило такой код
X++:
public boolean send(Common _cursor, int _level=1, boolean _triggerOffBody=TRUE, boolean _newPageBeforeBody=FALSE)
{
    boolean ret;

    ret = super(_cursor, _level, _triggerOffBody, _newPageBeforeBody);

    return ret;
}
И именно он в случае вышеупомянутых отчетов - не работает. Работа отчета молча прерывается без каких-либо сообщений об ошибках.

P.S.
Странно, вроде подробно все расписал еще в первом сообщении темы.
Почему еще вопросы возникают.
Неужели сложно взять, проверить и убедиться.
Старый 28.07.2015, 12:09   #6  
Ruff is offline
Ruff
Дмитрий Ерин
Аватар для Ruff
1C
 
475 / 396 (14) ++++++
Регистрация: 18.09.2003
Адрес: Тула
Есть еще такой вариант (проверил, работает):

X++:
// SysReportRun
public boolean send(Common _cursor, int _level=1, boolean _triggerOffBody=TRUE, boolean _newPageBeforeBody=FALSE)
{
    if (prmisdefault(_newPageBeforeBody)) 
    {
        return super(_cursor, _level, _triggerOffBody);
    }
    
    return super(_cursor, _level, _triggerOffBody, _newPageBeforeBody);
}
Ну и можно по аналогии проверять "дефолтность" третьего и второго параметров для вызова укороченных super(). Кстати, не анализировали, есть такие send() в стандарте, в которых меньше 3 параметров?

Еще интересный момент. Если попытаться запустить отчет из списка Logger-а сразу после модификации SysReportRun, то ядро выводит-таки ошибку:
Цитата:
Трассировка стека: Метод был вызван с недопустимым числом параметров.



(C)\Reports\BOMConsistOf\Methods\send
(C)\Classes\SysReportRun\send - line 5
(C)\Classes\ReportRun\fetch
(C)\Classes\SysReportRun\fetch - line 6
(C)\Classes\ReportRun\run
(C)\Reports\BOMConsistOf\Methods\run - line 26
(C)\Classes\SysReportRun\run - line 35
Но стоит просто откомпилировать отчет исправлено: вывести что-то в инфолог, как начинает проявляться описанный эффект - молчаливое завершение.
__________________

Последний раз редактировалось Ruff; 28.07.2015 в 13:52.
Старый 28.07.2015, 12:21   #7  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,860 / 3109 (111) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
спс
Про prmisdefault я и не подумал. Возможно он работал бы быстрее.

Я проверял по перекрестным ссылкам в нашем приложении (добавил дисплей метод на грид - выводящий число параметров метода). Там были только 3 и 4 параметра. Но допускаю что могли повлиять наши модификации. Например, в штатном коде для отчета InventOnhand 3 параметра, а у нас уже было исправлено на 4 на usr слое и глюк не проявлялся.

Последний раз редактировалось Logger; 28.07.2015 в 14:15.
Старый 28.07.2015, 12:25   #8  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,860 / 3109 (111) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Ruff Посмотреть сообщение
Еще интересный момент. Если попытаться запустить отчет из списка Logger-а сразу после модификации SysReportRun, то ядро выводит-таки ошибку:

Но стоит просто откомпилировать отчет, как начинает проявляться описанный эффект - молчаливое завершение.
Погодите, по идее если сделать модификацию как я описал то должна сработать ветка кода
X++:
    case  3 :
            ret = super( _cursor, _level, _triggerOffBody );
            break;
и не должно быть ошибки времени выполнения, так как число параметров будет одинаковым в вызове метода и в его объявлении в отчете.

может под отладчиком пройтись - мало ли что сглючило и неверно отработал
SysReportRun::GRD_getMethodParamsCount

У меня все работало нормально.
Проверял на отчетах с 4 и 3 параметрами.
Старый 28.07.2015, 12:30   #9  
Ruff is offline
Ruff
Дмитрий Ерин
Аватар для Ruff
1C
 
475 / 396 (14) ++++++
Регистрация: 18.09.2003
Адрес: Тула
Я имел в виду запуск без модификации. То есть просто перекрыть send, оставив сгенерированный ядром код, и запустить отчет.
Старый 28.07.2015, 12:33   #10  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,860 / 3109 (111) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Ruff Посмотреть сообщение
Я имел в виду запуск без модификации. То есть просто перекрыть send, оставив сгенерированный ядром код, и запустить отчет.
А !
А вот это очень странно. Интересно было бы докопаться.
Барабашки нет !
Старый 28.07.2015, 13:50   #11  
Ruff is offline
Ruff
Дмитрий Ерин
Аватар для Ruff
1C
 
475 / 396 (14) ++++++
Регистрация: 18.09.2003
Адрес: Тула
Цитата:
Сообщение от Logger Посмотреть сообщение
Барабашки нет !
Действительно) Я был не прав насчет компиляции (не влияет она, это просто было совпадение). Правда понять изначальную причину пропадания сообщения так и не удалось. Заметил только, что текст ошибки НЕ выводится, если что-то вывести в инфолог перед некорректным вызовом супер. Могу лишь предположить, что ядро как-то нестандартно работает с инфологом в таких случаях.
Теги
ax2009, reportrun, sysformrun, sysreportrun, баг

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
SysReportRun и tmpTable Pat4kord DAX: Программирование 12 15.03.2013 16:44
Query sort field autoSum ist DAX in English 4 27.03.2008 16:48
Засада с позиционированием при переходе к основной таблице. В чем дело? AK9 DAX: Программирование 17 30.11.2007 14:42
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 07:29.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.