27.07.2015, 19:34 | #1 |
Участник
|
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 |
Участник
|
лечится примерно так:
SysReportRun public boolean send(Common _cursor, int _level=1, boolean _triggerOffBody=TRUE, boolean _newPageBeforeBody=FALSE) + инкрементная компиляция. ООП никто не отменял. |
|
28.07.2015, 08:21 | #3 |
Участник
|
Не работает предложенный вами способ. Собственно из-за этого и стали придумывать вышеописанный способ.
Вы описание внимательно читали ? Или вы предлагаете в каждом отчете из процитированного списка менять send метод ? Последний раз редактировалось Logger; 28.07.2015 в 09:11. |
|
28.07.2015, 09:23 | #4 |
Участник
|
Вы в классе SysReportRun метод Send перекрывали? Сколько параметров указали?
|
|
28.07.2015, 09:29 | #5 |
Участник
|
Да.
Перекрыли метод в классе 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 |
Дмитрий Ерин
|
Есть еще такой вариант (проверил, работает):
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); } Еще интересный момент. Если попытаться запустить отчет из списка 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 |
Участник
|
спс
Про prmisdefault я и не подумал. Возможно он работал бы быстрее. Я проверял по перекрестным ссылкам в нашем приложении (добавил дисплей метод на грид - выводящий число параметров метода). Там были только 3 и 4 параметра. Но допускаю что могли повлиять наши модификации. Например, в штатном коде для отчета InventOnhand 3 параметра, а у нас уже было исправлено на 4 на usr слое и глюк не проявлялся. Последний раз редактировалось Logger; 28.07.2015 в 14:15. |
|
28.07.2015, 12:25 | #8 |
Участник
|
Цитата:
X++: case 3 : ret = super( _cursor, _level, _triggerOffBody ); break; может под отладчиком пройтись - мало ли что сглючило и неверно отработал SysReportRun::GRD_getMethodParamsCount У меня все работало нормально. Проверял на отчетах с 4 и 3 параметрами. |
|
28.07.2015, 12:30 | #9 |
Дмитрий Ерин
|
Я имел в виду запуск без модификации. То есть просто перекрыть send, оставив сгенерированный ядром код, и запустить отчет.
|
|
28.07.2015, 12:33 | #10 |
Участник
|
|
|
28.07.2015, 13:50 | #11 |
Дмитрий Ерин
|
Действительно) Я был не прав насчет компиляции (не влияет она, это просто было совпадение). Правда понять изначальную причину пропадания сообщения так и не удалось. Заметил только, что текст ошибки НЕ выводится, если что-то вывести в инфолог перед некорректным вызовом супер. Могу лишь предположить, что ядро как-то нестандартно работает с инфологом в таких случаях.
|
|
Теги |
ax2009, reportrun, sysformrun, sysreportrun, баг |
|
Похожие темы | ||||
Тема | Ответов | |||
SysReportRun и tmpTable | 12 | |||
Query sort field autoSum | 4 | |||
Засада с позиционированием при переходе к основной таблице. В чем дело? | 17 |
|