Использование Data Methods в SSRS (AX 2009, SSRS) (продолжение)
... так вот - описанные ранее метод получения таблицы из AX в SSRS-отчет в качестве источника данных не работает. После развертывания на сервер отчетов классы Аксапты отказываются работать:
Пришлось делать по другому. В принципе, на скорость работы отчета это никак не отразилось.
В C# я написал класс, который из AxaptaRecordWrapper делает System.Data.DataTable. По сути - тоже преобразование, которое я делал в предыдущем посте по этой теме, за тем отличием - делается оно теперь на сторонее отчета.
В Аксапте добавил еще один метод, который вызывается на стороне отчета. Метод выгружает структуру таблицы:
Вот как выглядит класс для SSRS (C#):
метод getTableStructure - формирует таблицу
метод FillingDataTable - наполняет эту таблицу
Data method выглядит теперь так:
в проекте есть еще namespace, в котором константами забиты имена классов аксапты, методов и TableId.
на-пример:
после развертывания все работает
- Fehler beim Clientrendering.
- Fehler bei der Berichtsverarbeitung. (rsProcessingAborted)
- Fehler beim Ausführen der Abfrage für das Dataset1-Dataset. (rsErrorExecutingCommand)
- Exception has been thrown by the target of an invocation.
- Fehler beim Dynamics-Adapter 'CallStaticClassMethod'.
- ClrObject static method invocation error.
- Fehler beim Dynamics-Adapter 'CallStaticClassMethod'.
- Exception has been thrown by the target of an invocation.
- Fehler beim Ausführen der Abfrage für das Dataset1-Dataset. (rsErrorExecutingCommand)
- Fehler bei der Berichtsverarbeitung. (rsProcessingAborted)
Пришлось делать по другому. В принципе, на скорость работы отчета это никак не отразилось.
В C# я написал класс, который из AxaptaRecordWrapper делает System.Data.DataTable. По сути - тоже преобразование, которое я делал в предыдущем посте по этой теме, за тем отличием - делается оно теперь на сторонее отчета.
В Аксапте добавил еще один метод, который вызывается на стороне отчета. Метод выгружает структуру таблицы:
X++:
public static container getAXTableFields(TableId _TableId) { DictTable dictTable; DictField dictField; int field; int fieldId; int fieldCnt; container conTableStructure; ; dictTable = new DictTable(_TableId); info(strfmt("Die Tabbele %1 hat %2 Felden", dictTable.name(), dictTable.fieldCnt())); fieldCnt = dictTable.fieldCnt(); for (field=1; field <= dictTable.fieldCnt(); field++) { fieldId = dictTable.fieldCnt2Id(field); dictField = new DictField(_TableId, fieldId); if (dictField.isSystem()) continue; conTableStructure = conins(conTableStructure, fieldId, dictField.name()); switch (dictField.baseType()) { case Types::Integer : conTableStructure = conins(conTableStructure, (field + fieldCnt), "System.Int32"); break; case Types::UtcDateTime : conTableStructure = conins(conTableStructure, (field + fieldCnt), "System.DateTime"); break; case Types::Date : conTableStructure = conins(conTableStructure, (field + fieldCnt), "System.DateTime"); break; case Types::Enum : conTableStructure = conins(conTableStructure, (field + fieldCnt), "System.Int32"); break; case Types::Real : conTableStructure = conins(conTableStructure, (field + fieldCnt), "System.Double"); break; case Types::String : conTableStructure = conins(conTableStructure, (field + fieldCnt), "System.String"); break; default : conTableStructure = conins(conTableStructure, (field + fieldCnt), "System.String"); break; } } return conTableStructure; }
PHP код:
public class UNG_AxTables
{
AxaptaRecordWrapper axRecordWrapper;
Int32 TableId;
DataTable axTable;
public Int32 parmTableId(Int32 _TableId)
{
if (_TableId != 0)
this.TableId = _TableId;
return this.TableId;
}
public AxaptaRecordWrapper parmAxRecordWrapper(AxaptaRecordWrapper _axRecordWrapper)
{
if (_axRecordWrapper != null)
this.axRecordWrapper = _axRecordWrapper;
return this.axRecordWrapper;
}
private DataTable getTableStructure()
{
DataTable tmpTab = new DataTable("tmpTab");
DataColumnCollection columns = tmpTab.Columns;
DataColumn column;
var ax = SessionManager.GetSession();
AxaptaContainerWrapper axContainer = ax.CreateAxaptaContainer(ax.CallStaticClassMethod(UNG_ReportsClasses.UNG_SSRSTEST, UNG_ReportsClassesMethods.getAXTableFields, this.TableId));
for (Int32 i = 1; i < axContainer.Count; )
{
column = new DataColumn(axContainer[i].ToString(), Type.GetType(axContainer[i + 1].ToString()));
columns.Add(column);
i = i + 2;
}
return tmpTab;
}
private void FillingDataTable()
{
DataRowCollection rows = this.axTable.Rows;
DataRow row;
DataColumnCollection columns = this.axTable.Columns;
while (this.axRecordWrapper.Found)
{
row = this.axTable.NewRow();
for(int i=0; i < columns.Count; i++)
{
row.SetField(i, this.axRecordWrapper.GetField(columns[i].ColumnName));
}
rows.Add(row);
this.axRecordWrapper.Next();
}
}
public DataTable getDataTable()
{
this.axTable = this.getTableStructure();
this.FillingDataTable();
return this.axTable;
}
}
метод FillingDataTable - наполняет эту таблицу
Data method выглядит теперь так:
PHP код:
[DataMethod(), AxSessionPermission(SecurityAction.Assert)]
public static System.Data.DataTable DataMethod2(DateTime _OnDate, Boolean ShowZeroLines)
{
UNG_AxTables axTable = new UNG_AxTables();
AxaptaWrapper ax = SessionManager.GetSession();
AxaptaRecordWrapper axRecWr = ax.CreateAxaptaRecord(ax.CallStaticClassMethod(UNG_ReportsClasses.InventSumDateEngine, UNG_ReportsClassesMethods.getInventTransFinValueQtySSRS, _OnDate, ShowZeroLines));
axTable.parmTableId(UNG_TableId.UNG_tmpInventTransValueQty);
axTable.parmAxRecordWrapper(axRecWr);
return axTable.getDataTable();
}
на-пример:
PHP код:
public class UNG_TableId
{
public const Int32 SalesTable = 366;
public const Int32 InventTrans = 177;
public const Int32 UNG_tmpInventTransValueQty = 50249;
}
Всего комментариев 0