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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 18.10.2016, 15:52   #1  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Разминка. Принять в метод map или таблицу
Чиста разминка для ума. Совершенно программистская задача.
для определенности, пусть будет https://github.com/mazzy-ax/SysCustVend

Хочу сделать некий метод, который принимает либо map, либо таблицу.
В этот метод хочу передать инициализированный или неинициализированный map.

что-то типа такого
X++:
str TheUltimateQuestionOfLifeTheUniverseAndEverything(anytype mapOrTable)
{
   if( /* Deep Thought question: mapOrTable is CustVendTable */ )
      return 'nirvana';
   return '42';
}

static void main(Arga args)
{
   CustTrans ctr;
   VendTrans vtr;
   CustVendTrans mapTr;
   CustVendTrans mapTrInit = vtr;
   CustTable ct;
   VendTable vt;
   CustVendTable mapT;
   CustVendTable mapTinit = ct;

   debug::assert('42' == TheUltimateQuestionOfLifeTheUniverseAndEverything (ctr));
   debug::assert('42' == TheUltimateQuestionOfLifeTheUniverseAndEverything (vtr));
   debug::assert('42' == TheUltimateQuestionOfLifeTheUniverseAndEverything (maptr));
   debug::assert('42' == TheUltimateQuestionOfLifeTheUniverseAndEverything (maptrInit));
   debug::assert('42' == TheUltimateQuestionOfLifeTheUniverseAndEverything (ct));
   debug::assert('42' == TheUltimateQuestionOfLifeTheUniverseAndEverything (vt));
   debug::assert('nirvana' == TheUltimateQuestionOfLifeTheUniverseAndEverything (mapTinit));
   debug::assert('nirvana' == TheUltimateQuestionOfLifeTheUniverseAndEverything (mapT));
}
что надо написать в условии для Величайшего компьютера, чтобы метод попадал в нирвану, когда ему передается map CustVendTable, и отвечал бы 42 для всех остальных аргументов?

какие минимальные действия нужно сделать в условии?
какой тип у аргумента метода будет достаточен? все-таки anytype - это как-то уж очень.

Последний раз редактировалось mazzy; 18.10.2016 в 17:13.
Старый 18.10.2016, 16:14   #2  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,651 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Нужно отличить именно НЕ инициализированный Map? Тогда Common и sysDictTable.isMap()

X++:
static void test(Args _args)
{
    CustVendTrans   custVendTrans;
    Common          common;
    SysDictTable    sysDictTable;
    CustTrans       custTrans;
    ;

    //custVendTrans = custTrans;
    common = custVendTrans;
    sysDictTable = new SysDictTable(common.TableId);
    if (sysDictTable)
    {
        info(strFmt('%1',sysDictTable.isMap()));
    }
    info(strFmt('%1', common.TableId));

}
Правда, для инициализированного Map это уже не подойдет
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 18.10.2016, 16:17   #3  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Нужно отличить именно НЕ инициализированный Map? Тогда Common и sysDictTable.isMap()
...
Правда, для инициализированного Map это уже не подойдет
1.
угу. поэтому и не уточнял.
а есть способ который работал бы и для инициализированного, и для неинициализированного?

2.
isMap хорош, когда метод четко знает какой именно мап в него приходит
а если допустимо передавать разные мапы? как узнать какой именно пришел в common? делать switch на tablenum?
Старый 18.10.2016, 16:30   #4  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,651 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от mazzy Посмотреть сообщение
2.
isMap хорош, когда метод четко знает какой именно мап в него приходит
а если допустимо передавать разные мапы? как узнать какой именно пришел в common? делать switch на tablenum?
Этот момент не понял.

Если нам надо знать, что именно мы получили, и от этого строить обработку, то именно что switch на tablenum. Нам же все-равно надо будет как-то организовать ветвление кода в зависимости от полученного параметра. Или о чем тогда речь?
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 18.10.2016, 16:41   #5  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Этот момент не понял.

Если нам надо знать, что именно мы получили, и от этого строить обработку, то именно что switch на tablenum. Нам же все-равно надо будет как-то организовать ветвление кода в зависимости от полученного параметра. Или о чем тогда речь?
))))
"для определенности, пусть будет https://github.com/mazzy-ax/SysCustVend"

предположим я хочу, чтобы метод возвратил признак "Клиент", если на вход поданы таблицы/мапы, связанные с клиентами, и возвратил "Поставщик", если на вход поданы таблицы/мапы связанные с поставщиками. пример вызова в разными объектами я написал выше.

как отличить один неинициализированный мап от другого в методе?

как отличить один инициализированный мап от другого, если они ссылаются на одни и те же таблицы. например, первый мап - на custTrans, vendTrans, а второй мап - на custTrans, vendTrans, emplTrans.

===================
повторюсь, что это всего лишь разминка для ума. и часть совсем другой задачи, из которой я и вытащил собственно вопрос. скорее всего, задачу я полностью переформулирую. но на вопрос хотелось бы знать ответ, если он есть конечно.
Старый 18.10.2016, 16:46   #6  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,651 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Ага. Но если Map еще не инициализирован, то мы никак не можем заранее сказать, какой именно таблицей он будет инициализирован. Клиентом или поставщиком. Нет данных

А вот если он инициализирован, то,... а нам действительно надо знать, что это именно map?
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 18.10.2016, 17:11   #7  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
а нам действительно надо знать, что это именно map?
нет конечно, реальную задачу я переформулирую, чтобы обойтись и без этого )))

а вот для себя хотелось бы понять - есть ли способ "действительно знать".
я чуток подправил псевдокод, чтобы было понятно где и какой именно результат хотелось бы получить

X++:
str TheUltimateQuestionOfLifeTheUniverseAndEverything(anytype mapOrTable)
{
   if( /* Deep Thought question: mapOrTable is CustVendTable */ )
      return 'nirvana';
   return '42';
}

static void main(Arga args)
{
   CustTrans ctr;
   VendTrans vtr;
   CustVendTrans mapTr;
   CustVendTrans mapTrInit = vtr;
   CustTable ct;
   VendTable vt;
   CustVendTable mapT;
   CustVendTable mapTinit = ct;

   debug::assert('42' == TheUltimateQuestionOfLifeTheUniverseAndEverything (ctr));
   debug::assert('42' == TheUltimateQuestionOfLifeTheUniverseAndEverything (vtr));
   debug::assert('42' == TheUltimateQuestionOfLifeTheUniverseAndEverything (maptr));
   debug::assert('42' == TheUltimateQuestionOfLifeTheUniverseAndEverything (maptrInit));
   debug::assert('42' == TheUltimateQuestionOfLifeTheUniverseAndEverything (ct));
   debug::assert('42' == TheUltimateQuestionOfLifeTheUniverseAndEverything (vt));
   debug::assert('nirvana' == TheUltimateQuestionOfLifeTheUniverseAndEverything (mapTinit));
   debug::assert('nirvana' == TheUltimateQuestionOfLifeTheUniverseAndEverything (mapT));
}

Последний раз редактировалось mazzy; 18.10.2016 в 17:15.
Старый 18.10.2016, 17:17   #8  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
870 / 637 (23) +++++++
Регистрация: 14.10.2004
В AX3.0 удалось сделать такой пример. В AX2009 он не работает.
Приведенный ниже джоб выдает представление объектов в виде xml.
Вызовите у объекта метод xml() и распарсите атрибут "name" в узле xml "Record". И войдите в "нирвану", если название узла будет "CustVendTrans"
См. рисунок.
http://www.axforum.info/forums/attac...4&d=1476800120

X++:
static void Job806(Args _args)
{
   CustTrans ctr;
   VendTrans vtr;
   CustVendTrans mapTr;
   CustVendTrans mapTrInit = vtr;
   CustTable ct;
   VendTable vt;
   CustVendTable mapT;
   CustVendTable mapTinit = ct;

    void ultimate(object mapOrTable)
    {
        ;
        info(mapOrTable.xml());
    }
    ;

   ultimate (ctr);
   ultimate (vtr);
   ultimate (maptr);
   ultimate (maptrInit);
   ultimate (ct);
   ultimate (vt);
   ultimate (mapTinit);
   ultimate (mapT);
}
Миниатюры
Нажмите на изображение для увеличения
Название: CustVendTrans.jpg
Просмотров: 368
Размер:	165.1 Кб
ID:	10994  

Последний раз редактировалось Ace of Database; 18.10.2016 в 17:23.
За это сообщение автора поблагодарили: mazzy (5).
Старый 18.10.2016, 17:22   #9  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Ace of Database Посмотреть сообщение
представление объектов в виде xml.
это мысль! уйти во внутреннее представление...

а есть ли способ уйти в нирванну, оставаясь в матрице и не переходя на внутреннее представление?
Старый 18.10.2016, 17:28   #10  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Ace of Database Посмотреть сообщение
В AX2009 он не работает.
я думаю, что внутреннее представление можно получить, если запаковать в контейнер.
кроме того, придется сделать поиск имени в AOT\maps...
в общем, можно. спасибо.

а есть ли более изящный способ?
Старый 18.10.2016, 17:36   #11  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,651 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от Ace of Database Посмотреть сообщение
В AX3.0 удалось сделать такой пример. В AX2009 он не работает.
Пример бесполезен

Для НЕ инициализированных Map имя вполне можно получить и через DictTable. А для инициализированных Map и Ваш пример возвращает имя таблицы, а не имя Map

PS: Чтобы пример заработал в старших версиях замените Object на Common
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 18.10.2016, 17:37   #12  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
870 / 637 (23) +++++++
Регистрация: 14.10.2004
Второй вариант, который работает в AX2009
Для CustVendTrans получается значение "Номер счета: ,"
X++:
static void Job806(Args _args)
{
   CustTrans ctr;
   VendTrans vtr;
   CustVendTrans mapTr;
   CustVendTrans mapTrInit = vtr;
   CustTable ct;
   VendTable vt;
   CustVendTable mapT;
   CustVendTable mapTinit = ct;

    void ultimate(common mapOrTable)
    {
        ;
        info(strfmt("%1", mapOrTable.caption()));
    }
    ;

   ultimate (ctr);
   ultimate (vtr);
   ultimate (maptr);
   ultimate (maptrInit);
   ultimate (ct);
   ultimate (vt);
   ultimate (mapTinit);
   ultimate (mapT);
}
Изображения
 
Старый 18.10.2016, 17:39   #13  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
870 / 637 (23) +++++++
Регистрация: 14.10.2004
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Пример бесполезен
PS: Чтобы пример заработал в старших версиях замените Object на Common
Уже пробовал. У меня AX2009 рушится при вызове метода xml() на полях с типом UTCDateTime
Старый 18.10.2016, 17:46   #14  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от mazzy Посмотреть сообщение
"для определенности, пусть будет https://github.com/mazzy-ax/SysCustVend"
предположим я хочу, чтобы метод возвратил признак "Клиент", если на вход поданы таблицы/мапы, связанные с клиентами, и возвратил "Поставщик", если на вход поданы таблицы/мапы связанные с поставщиками.
В моем понимании Map'ы в X++ - это своего рода реализация ООП для таблиц, причем не аналог наследования в AX 2012, а скорее аналог интерфейсов и разделяемых классов (partial classes) вместе взятых. Из этого следует, что код, работающий с Map'ами, в design time всегда работает с неким интерфейсом (в терминах ООП), а в run time всегда работает с некой конкретной реализацией этого интерфейса - таблицей.
Map проявляет свою сущность интерфейса через предоставление стороннему коду названий и базовых типов полей, а также сигнатур экземплярных табличных методов.
Map проявляет свою сущность разделяемого класса через реализацию логики экземплярных табличных методов.

Из вышесказанного следует несколько выводов:
  • если коду, работающему с Map, нужно как-то различать те реализации (таблицы), которые могут прийти под видом Map в run time, то либо в Map должно быть какое-то поле, которое в таблицах будет заполнено соотв. образом, либо в Map должен быть какой-то метод, возвращающий соотв. признак, а в таблицах - его реализация. Надо помнить, что вызов mapBuffer.method() в run time приводит к попытке вызова соотв. метода таблицы, и если она не реализует метод с такой сигнатурой, то вызов завершится ошибкой времени выполнения.
  • передача коду в run time неинициализированного Map'а - это своего рода форс-мажор, схожий с передачей null вместо объекта класса, реализующего определенный интерфейс.
  • если код предназначен для работы с разными Map'ами, то, видимо, он использует этот тип объектов приложения не как "ООП для таблиц", а совсем иначе, и тогда получается, что такому коду вообще должно быть без разницы, пришел ли ему на вход буфер таблицы, Map, View... Стало быть, такой код по идее должен работать с Common и механизмами отражения.
Цитата:
Сообщение от mazzy Посмотреть сообщение
как отличить один неинициализированный мап от другого в методе?
По значению поля TableId.
Цитата:
Сообщение от mazzy Посмотреть сообщение
как отличить один инициализированный мап от другого, если они ссылаются на одни и те же таблицы. например, первый мап - на custTrans, vendTrans, а второй мап - на custTrans, vendTrans, emplTrans.
Никак: исходя из идеологии Map, в run time всегда должна приходить реализация, т.е. буфер конкретной таблицы. Если вам на вход пришел буфер таблицы CustTrans, то не имеет значения, под видом какого Map этот буфер в design time указан в вызывающем коде и Map ли там вообще - может, Common, а может, anytype

Резюме: в представленной постановке задачи код должен работать не с anytype и не с Map, а с Common и использовать API отражения для получения нужной информации. Анализ Common.TableId в коде ничем не хуже анализа Map.TableId

Последний раз редактировалось gl00mie; 18.10.2016 в 19:43. Причина: стилистика
За это сообщение автора поблагодарили: mazzy (5).
Старый 18.10.2016, 17:47   #15  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
870 / 637 (23) +++++++
Регистрация: 14.10.2004
Цитата:
Сообщение от Ace of Database Посмотреть сообщение
Уже пробовал. У меня AX2009 рушится при вызове метода xml() на полях с типом UTCDateTime
Сейчас в другой своей AX2009 попробовал - там нормально отрабатывает метод xml().
Старый 18.10.2016, 17:47   #16  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,651 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Может, я чего-то не понимаю, но почему нельзя "по старинке"

X++:
static void test(Args _args)
{
    CustTrans ctr;
    VendTrans vtr;
    CustVendTrans mapTr;
    CustVendTrans mapTrInit = vtr;
    CustTable ct;
    VendTable vt;
    CustVendTable mapT;
    CustVendTable mapTinit = ct;

    void ultimate(common mapOrTable)
    {
        DictTable   dictTable;
        ;
        dictTable = new dictTable(mapOrTable.TableId);
        info(dictTable.name());
        //info(dictTable.label());
    }
    ;

    ultimate (ctr);
    ultimate (vtr);
    ultimate (maptr);
    ultimate (maptrInit);
    ultimate (ct);
    ultimate (vt);
    ultimate (mapTinit);
    ultimate (mapT);
}
Чем это отличается от XML() и caption()?
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
За это сообщение автора поблагодарили: mazzy (2).
Старый 18.10.2016, 17:55   #17  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
870 / 637 (23) +++++++
Регистрация: 14.10.2004
Цитата:
Чем это отличается от XML() и caption()?
Согласен, через dictTable удобнее. Но через caption() получается на 2 строки кода меньше. Mazzy же написал в условии задачи "какие минимальные действия нужно сделать"

Последний раз редактировалось Ace of Database; 18.10.2016 в 17:58. Причина: поправил оформление цитаты
Старый 18.10.2016, 17:59   #18  
ice is offline
ice
Участник
Аватар для ice
Лучший по профессии 2014
 
1,689 / 405 (17) +++++++
Регистрация: 23.03.2006
А есть ли возможность модифицировать Mapы? если да, то можно, например, перекрыть "бесполезный" метод toString() и возвращать "nirvana"
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Классы коллекций (инициализация, сериализация): List, Set, Map. petergunn DAX: База знаний и проекты 10 04.06.2018 18:45
Не корректная сортировка в Map-e и Set-е. AX2009 RU5 Pustik DAX: Программирование 12 03.05.2016 21:28
Dynamics AX: Map Object Sorting - a real issue Blog bot DAX Blogs 7 15.10.2008 12:02
Как вызвать один метод при записи в любую таблицу Dimitry DAX: Программирование 23 25.05.2007 11:38
Русская локализация Axapta 3 ? SlavaK DAX: Администрирование 59 01.07.2003 22:38
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 15:02.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.