Привет всем.
Обнаружил интересную особенность класса 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;
}