13.08.2015, 11:05 | #1 |
Участник
|
fieldnum и map custVendTrans - как получить идентификатор поля таблицы по мапу?
Дурной вопрос. Понял, что я не знаю красивого ответа. Может подскажете?
Есть: = код, в котором объявлена переменная типа map CustVendTrans = запрос, который содержит либо custTrans, либо vendTrans в зависимости от внешних = метод, который устанавливает range в этом запросе = для range нужно получить fieldnum вопрос: а как проще и красивше получить fieldnum? X++: CustVendTrans custVendTrans = custVendTransStatic.custVendTrans(); Query q; QueryBuildDataSource qbds; ; switch( _journalTable.JournalModule) { case ModuleCustVend::Cust: q = new Query(querystr(myCustQuery)); break; case ModuleCustVend::Vend: q = new Query(querystr(myVendQuery)); break; default: throw Error::unsupportedEnumValue(_journalTable.JournalModule); } qbds = q.dataSourceTable(custVendTrans.TableId); // здесь возвращает fieldid из мапа = 39, а нужно для CustTrans = 41, а для VendTrans = 78 SysQuery::findOrCreateRange(qbds, fieldnum(custVendTrans, ExchRate) ).value(myValue); // есть еще много критериев. как бы красиво оформить? SysQuery::findOrCreateRange(qbds, fieldnum(custVendTrans, .... SysQuery::findOrCreateRange(qbds, fieldnum(custVendTrans, .... SysQuery::findOrCreateRange(qbds, fieldnum(custVendTrans, .... SysQuery::findOrCreateRange(qbds, fieldnum(custVendTrans, .... понятно, что можно через DictField, но получается слишком длинный код, когда критериев (range) достаточно много. есть еще какой-нибудь способ? Последний раз редактировалось mazzy; 13.08.2015 в 11:07. |
|
13.08.2015, 11:10 | #2 |
Moderator
|
MappingsInfo_RU::createMapWithFieldId(), и далее по мапу получать id по названию поля. Правда, способ не очень производительный по времени.
__________________
Андрей. Последний раз редактировалось Dron AKA andy; 13.08.2015 в 11:17. |
|
13.08.2015, 11:29 | #3 |
Участник
|
Нужно быть очень аккуратным при работе с классом MappingsInfo_RU в AX 2009: метод findMappingTreeNode() в этой версии использует вызов infolog.getNode(), который сам выполняется и возвращает объект на клиенте. Затем по TreeNode'у в методе find() бегает TreeNodeIterator, который в общем случае может создаваться на сервере (если сам класс используется на сервере). В итоге можно словить труднодиагностируемые тормоза и нефиговый клиент-серверный трафик в чисто серверном, как может показаться, коде. В 2012-й реализацию findMappingTreeNode() с этой точки зрения исправили.
В данном конкретном случае я бы лично, возможно, заложился на то, что названия используемых в запросе полей в CustTrans, VendTrans и CustVendTrans совпадают, и использовал бы конструкцию вида X++: fieldId = fieldName2Id(tableId, fieldStr(CustVendTrans, ExchRate)); |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
13.08.2015, 11:33 | #4 |
Участник
|
Цитата:
здесь есть кастомные поля. с разными названиями. а без имен в стандарте можно? |
|
13.08.2015, 11:40 | #5 |
Участник
|
Если имена полей отличаются, то из решений, лежащих на поверхности, - либо MappingsInfo_RU, либо иерархия классов с методами вида fieldId transFieldExchRate(), где наследники для нужной таблицы возвращают именно ее fieldId, по аналогии с RLedgerSheetEngine. Хотя по-моему, последнее - это overengineering для данной постановки задачи.
|
|
|
За это сообщение автора поблагодарили: mazzy (2). |
13.08.2015, 11:47 | #6 |
NavAx
|
Можно попробовать пойти таким путем.
X++: protected FieldId fieldIdByExtendedType(TableId _tableId, int _extendedTypeNum) { DictTable dictTable = new DictTable(_tableId); DictField dictField; ExtendedTypeId extendedTypeId; FieldId fieldId, fieldIdRet; int i, n; ; fieldId = dictTable.fieldNext(0); while (fieldId && ! isSysId(FieldId)) { dictField = new DictField(DictTable.id(), fieldId); extendedTypeId = dictField.typeId(); if (extendedTypeId == _extendedTypeNum) { fieldIdRet = fieldId; break; } fieldId = dictTable.fieldNext(fieldId); } return fieldIdRet; } |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
13.08.2015, 12:04 | #7 |
Участник
|
Цитата:
спасибо. делаю предварительный вывод: 1. в стандарте из готовых методов только MappingsInfo_RU (но он работает медленно по именам) 2. делать свой служебный класс. 3. не выпендриваться, засунуть в switch-case )) я думал, что забыл что-нибудь. ок. спасибо. |
|
13.08.2015, 12:11 | #8 |
Участник
|
Есть еще такой вариант Некорректное отражение map при пакетной обработке в Ax2009, и налоги в строках накладных/фактур
__________________
Axapta v.3.0 sp5 kr2 |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
13.08.2015, 12:17 | #9 |
Участник
|
оооо, на том проекте, где я сейчас, уже создали служебные классы...
в двух словах: - сначала парсится node-ветка mapping из map-объекта-AOT, - значения складываются в map-класс - потом используется. причем уже есть синглтон, все дела... гут. буду юзать. еще раз всем спасибо. |
|
13.08.2015, 15:31 | #10 |
Участник
|
если 12-ка, то можно вот так
X++: public static FieldId getMappedField(TableId _mapId, TableId _mappedTableId, FieldId _mapFieldId) { FieldId ret; DictTable dictTable; DictTableMap dictTableMap; int i; if (_mapId && _mapFieldId && _mappedTableId) { dictTable = new DictTable(_mapId); if (dictTable && dictTable.isMap()) { for (i = dictTable.mapCnt(); i >= 1; i--) { dictTableMap = dictTable.mapObject(i); if (dictTableMap.table() == _mappedTableId) { break; } dictTableMap = null; } if (dictTableMap) { for (i = dictTableMap.fieldCnt(); i >= 1; i--) { if (dictTableMap.fieldCnt2FieldFrom(i) == _mapFieldId) { ret = dictTableMap.fieldCnt2FieldTo(i); break; } } } } } return ret; } |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
18.08.2015, 14:26 | #11 |
Боец
|
Последний раз редактировалось DSPIC; 28.09.2017 в 01:50. |
|
Теги |
ax2012, map, законченный пример, как правильно |
|
|