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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 04.02.2013, 16:23   #1  
plumbum is offline
plumbum
Участник
Соотечественники
 
182 / 86 (3) ++++
Регистрация: 07.12.2007
Адрес: Vienna, AT
DataMembers для DataContract автоматически
Вот набросал простой скрипт, создающий методы аннотированные [DataMemberAttribute] для всех переменных класса:

X++:
static void GenerateDataMembers(Args _args)
{
    #define.classDeclaration('classDeclaration')
    str strAttributeMethodLine1 = '[DataMemberAttribute]\n';
    str strAttributeMethodLine2 = 'public %1 parm%2(%1 _%2 = %2)\n';
    str strAttributeMethodLine3 = '{\n';
    str strAttributeMethodLine4 = '\t%2 = _%2;\n';
    str strAttributeMethodline5 = '\treturn %2;\n';
    str strAttributeMethodLine6 = '}';
    
    str strAttributeMethod      = strAttributeMethodLine1 +
                                  strAttributeMethodLine2 +
                                  strAttributeMethodLine3 +
                                  strAttributeMethodLine4 +
                                  strAttributeMethodLine5 +
                                  strAttributeMethodLine6;        
    str                         lstrAttributeMethodSource;
        
    ClassId                     lclsClassId             = classNum(<MyClassName>); //change this paramter
    
    SysDictClass                lclsDictclass           = new SysDictClass(lclsClassId);
    ClassBuild                  lclsClassBuild          = new ClassBuild(lclsDictclass.name(), true);
    
    Set                         lsetMethods             = lclsDictClass.methods(true, false, false);
    SetEnumerator               lsenMethods             = lsetMethods.getEnumerator();
    Map                         lmapMethods             = new Map(Types::String, Types::Class);
    MapEnumerator               lmenMethods;
    SysDictMethod               lclsMethod;
    str                         lstrClassDeclaration    = lclsDictclass 
                                                          ? TreeNode::findNode(strFmt('\\Classes\\%1\\classDeclaration', lclsDictclass.name())).AOTgetSource()
                                                          : '';
    
    Map                         lmapMemberVariableParm  = new Map(Types::String, Types::String);
    
    str                         lstrMemberVarPare;
    str                         lstrMemberVarType;    
    str                         lstrMemberVarName;
    str                         lstrMemberVarMName;
    str                         lstrMemberVarPrefName;
    
    int                         lintStrLen, 
                                lintMemberVarStartPos, 
                                lintMemberVarEndPos;
    container                   lconMemberVars;
    
    int                         lintConLen, i;
    
    
    ;    
    
    if (!lstrClassDeclaration) 
        return;
    
    while (lsenMethods.moveNext())
    {
        lclsMethod = lsenMethods.current();
        lmapMethods.insert(lclsMethod.name(), lclsMethod);
    }
    
    lintStrLen                  = strLen(lstrClassDeclaration);
    lintMemberVarStartPos       = strFind(lstrClassDeclaration, '{' ,1, lintStrLen);
    lintMemberVarEndPos         = strFind(lstrClassDeclaration, '}',1, lintStrLen);
 
    lstrClassDeclaration        = subStr(
                                    lstrClassDeclaration, 
                                    lintMemberVarStartPos+1, 
                                    lintMemberVarEndPos - lintMemberVarStartPos - 1);
    
    lstrClassDeclaration        = strReplace(lstrClassDeclaration, '\n', '');
    lstrClassDeclaration        = strReplace(lstrClassDeclaration, '\t', '');
    lstrClassDeclaration        = strReplace(lstrClassDeclaration, ';', ',');
    lstrClassDeclaration        = subStr(lstrClassDeclaration, 1, strLen(lstrClassDeclaration) - 1);
    
    lconMemberVars              = str2con(lstrClassDeclaration);
    lintConLen                  = conLen(lconMemberVars);
    
    for (i = 1; i <= lintConLen; i++)
    {
        lstrMemberVarPare       = conPeek(lconMemberVars, i);
        lstrMemberVarPare       = strLRTrim(lstrMemberVarPare);
        lstrMemberVarType       = subStr(lstrMemberVarPare, 1, strFind(lstrMemberVarPare, ' ', 1, strLen(lstrMemberVarPare))-1);
        lstrMemberVarName      = strLTrim(subStr(lstrMemberVarPare, strLen(lstrMemberVarType) +1 , strLen(lstrMemberVarPare) - strLen(lstrMemberVarType)));                
        
        if (! lmapMethods.exists('parm'+lstrMemberVarName))
        {
            lstrAttributeMethodSource = strFmt(strAttributeMethod, lstrMemberVarType, lstrMemberVarName);
            lclsClassBuild.addMethod('parm' + lstrMemberVarName, lstrAttributeMethodSource);            
        }
    }
    lclsClassBuild.classNode().AOTcompile();
    
}
уже существующие методы пересоздаваться не будут.

P.S.
а то уже совсем надоело все это "руками" делать.
Надеюсь еще кому-то пригодиться
__________________
http://www.axdevposts.blogspot.com
Пришел, уведел.... отойди, дай другому увидеть!
За это сообщение автора поблагодарили: mazzy (2), trud (1), Logger (1), gl00mie (2).
Старый 04.02.2013, 16:55   #2  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
1. So drop the Hungarian

2.

X++:
lintMemberVarStartPos       = strFind(lstrClassDeclaration, '{' ,1, lintStrLen);
    lintMemberVarEndPos         = strFind(lstrClassDeclaration, '}',1, lintStrLen);
 
    lstrClassDeclaration        = subStr(
                                    lstrClassDeclaration, 
                                    lintMemberVarStartPos+1, 
                                    lintMemberVarEndPos - lintMemberVarStartPos - 1);
-->
X++:
System.Text.RegularExpression.Regex::replace(@'^.*\{(.*)\}.*$','$1')
За это сообщение автора поблагодарили: mazzy (2), gl00mie (2).
Старый 04.02.2013, 17:43   #3  
plumbum is offline
plumbum
Участник
Соотечественники
 
182 / 86 (3) ++++
Регистрация: 07.12.2007
Адрес: Vienna, AT
1. Ну это такие требования у нас на проекте - я их тоже не любил, но ИМХО при автоподстановке в AX2012 очень удобно

2. А это Вы к чему? Я собственно собирался середину выудить, там мне заменять только потом надо было.
__________________
http://www.axdevposts.blogspot.com
Пришел, уведел.... отойди, дай другому увидеть!
Старый 05.02.2013, 09:50   #4  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
1. Приношу свои соболезнования
2. Это и есть выудить середину - только короче
Старый 05.02.2013, 09:56   #5  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от plumbum Посмотреть сообщение
2. А это Вы к чему?
Это, наверно, к тому, что при наличии строк вида
X++:
    MyType   myVar;
можно сгенерить код соотв. методов с помощью регулярных выражений, заменив
Код:
^\s*(\w+)\s+(\w+);.*
на
Код:
[DataMemberAttribute]\npublic $1 parm\u$2($1 _$2 = $2)\n{\n    $2 = _$2;\n    return $2;\n}
За это сообщение автора поблагодарили: plumbum (1).
Старый 05.02.2013, 10:25   #6  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Не - тут просто заменой не обойтись - надо же еще удалить чего-то там. Я бы просто прошелся по матчам этого регекспа и сформировал код методов при помощи

X++:
strFmt(@'
%1 parm%2(%1 _value=%3)
{
      %3 = _value;
      return %3;
}
',  type, upperCaseName, lowerCaseName);
Старый 05.02.2013, 19:04   #7  
plumbum is offline
plumbum
Участник
Соотечественники
 
182 / 86 (3) ++++
Регистрация: 07.12.2007
Адрес: Vienna, AT
Понял насчет регулярных выражений, не обратил внимание на то, что под $* имелись в виду параметры - извиняюсь.

В дополнение еще, конечно, надо было бы вставить код, выуживающий комментарии и макросы из classDeclaration. Ну что ж, в следующем релизе

Собственно код метода и формируется с помощью strFmt.
__________________
http://www.axdevposts.blogspot.com
Пришел, уведел.... отойди, дай другому увидеть!
Старый 06.02.2013, 09:58   #8  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Если взять ScannerClass то комментарии макросы и прочее оно учтёт само.

Поит был не в strFmt а в использовании многострочных строк и в матчах регекспов
Старый 06.02.2013, 17:31   #9  
Evgeniy2020 is offline
Evgeniy2020
Участник
 
309 / 68 (3) ++++
Регистрация: 10.04.2007
Адрес: Москва, САО, СЗАО
в приведенной ссылке
Цитата:
Если взять ScannerClass
на сайте http://erpkb.com/Axapta/Klass/ScannerClass указана ссылка
http://erpkb.com/Axapta/Klass/ParserClass?v=1cfk а в ней ссылка (Перед чтением этой статьи рекомендуется изучить БНФ грамматику X++ )
http://msdn.microsoft.com/library/en...X++grammar.asp

ссылка не рабочая... можете указать рабочую ссылку на msdn?

Последний раз редактировалось Evgeniy2020; 06.02.2013 в 17:34.
Старый 06.02.2013, 19:11   #10  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от Evgeniy2020 Посмотреть сообщение
в приведенной ссылке на сайте http://erpkb.com/Axapta/Klass/ScannerClass указана ссылка [...]ссылка не рабочая... можете указать рабочую ссылку на msdn?
Рабочую ссылку на msdn можно найти тут:
Старый 06.02.2013, 21:07   #11  
Evgeniy2020 is offline
Evgeniy2020
Участник
 
309 / 68 (3) ++++
Регистрация: 10.04.2007
Адрес: Москва, САО, СЗАО
http://msdn.microsoft.com/en-us/library/dd261486.aspx

спасибо но эта ссылка имнно то шо искал
Старый 06.02.2013, 23:19   #12  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Кстати, code upgrade tool содержит в себе парзер X++ на C#
Теги
ax2012, datamemberattribute, sysoperation framework

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Автоматически пересчет цен/скидок в заказах Starling DAX: Функционал 2 11.04.2009 15:37
MAP автоматически George Nordic DAX: Программирование 2 05.07.2004 16:49
как автоматически выполнить код при импорте? puz DAX: Программирование 4 01.10.2003 10:54
Как автоматически заполнить поле InventDimId в таблице PriceDiscTable при импорте? Mike12345 DAX: Функционал 6 06.08.2003 11:29
AOS - не стартует автоматически при перезапуске системы Irvine DAX: Администрирование 7 28.07.2003 17:58

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

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

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