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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 13.08.2015, 11:05   #1  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
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, ....
понятно, что можно вставить в switch. но тогда код будет дублироваться. некрасиво. хотя везде в стандартной аксапте именно так и делается

понятно, что можно через DictField, но получается слишком длинный код, когда критериев (range) достаточно много.

есть еще какой-нибудь способ?

Последний раз редактировалось mazzy; 13.08.2015 в 11:07.
Старый 13.08.2015, 11:10   #2  
Dron AKA andy is offline
Dron AKA andy
Moderator
 
944 / 253 (10) ++++++
Регистрация: 27.03.2002
Адрес: Москва
MappingsInfo_RU::createMapWithFieldId(), и далее по мапу получать id по названию поля. Правда, способ не очень производительный по времени.
__________________
Андрей.

Последний раз редактировалось Dron AKA andy; 13.08.2015 в 11:17.
Старый 13.08.2015, 11:29   #3  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 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  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от gl00mie Посмотреть сообщение
В данном конкретном случае я бы лично, возможно, заложился на то, что названия используемых в запросе полей в CustTrans, VendTrans и CustVendTrans совпадают, и использовал бы конструкцию вида
X++:
fieldId = fieldName2Id(tableId, fieldStr(CustVendTrans, ExchRate));
не-а.
здесь есть кастомные поля. с разными названиями.

а без имен в стандарте можно?
Старый 13.08.2015, 11:40   #5  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Если имена полей отличаются, то из решений, лежащих на поверхности, - либо MappingsInfo_RU, либо иерархия классов с методами вида fieldId transFieldExchRate(), где наследники для нужной таблицы возвращают именно ее fieldId, по аналогии с RLedgerSheetEngine. Хотя по-моему, последнее - это overengineering для данной постановки задачи.
За это сообщение автора поблагодарили: mazzy (2).
Старый 13.08.2015, 11:47   #6  
raz is offline
raz
NavAx
Аватар для raz
NavAx Club
Лучший по профессии 2014
Лучший по профессии 2009
 
1,494 / 1065 (38) ++++++++
Регистрация: 22.07.2003
Адрес: МО
Можно попробовать пойти таким путем.
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  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от gl00mie Посмотреть сообщение
Хотя по-моему, последнее - это overengineering для данной постановки задачи.
угу.

Цитата:
Сообщение от raz Посмотреть сообщение
Можно попробовать пойти таким путем.
спасибо.

делаю предварительный вывод:
1. в стандарте из готовых методов только MappingsInfo_RU (но он работает медленно по именам)
2. делать свой служебный класс.
3. не выпендриваться, засунуть в switch-case ))

я думал, что забыл что-нибудь.
ок. спасибо.
Старый 13.08.2015, 12:11   #8  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Есть еще такой вариант Некорректное отражение map при пакетной обработке в Ax2009, и налоги в строках накладных/фактур
__________________
Axapta v.3.0 sp5 kr2
За это сообщение автора поблагодарили: mazzy (2).
Старый 13.08.2015, 12:17   #9  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
оооо, на том проекте, где я сейчас, уже создали служебные классы...

в двух словах:
- сначала парсится node-ветка mapping из map-объекта-AOT,
- значения складываются в map-класс
- потом используется.

причем уже есть синглтон, все дела... гут. буду юзать.

еще раз всем спасибо.
Старый 13.08.2015, 15:31   #10  
michel1971 is offline
michel1971
Участник
 
78 / 78 (3) ++++
Регистрация: 14.01.2011
если 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 is offline
DSPIC
Боец
 
1,077 / 1243 (44) ++++++++
Регистрация: 11.04.2008
До кучи готовый стандартный класс с поддержкей кеширования.

\Classes\VendDocumentUtil
Вложение 9369

Последний раз редактировалось DSPIC; 28.09.2017 в 01:50.
Теги
ax2012, map, законченный пример, как правильно

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Классы коллекций (инициализация, сериализация): List, Set, Map. petergunn DAX: База знаний и проекты 12 06.11.2024 18:38
Получить значение поля по TableId, FieldId, RecId bodeaux DAX: Программирование 8 08.07.2014 10:47
Некорректно отображается значение текстового поля их приджойненой таблицы в вэб-гриде... glibs DAX: Программирование 0 20.04.2009 19:13
Каким образом можно получить значение поля, зная fieldId? Lemming DAX: Программирование 10 19.06.2006 12:25
Не устанавливается EDT для поля таблицы Filip DAX: Программирование 3 29.10.2004 13:52
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 18:53.