AXForum  
Go Back   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Forgotten Your Password?
Register Forum Rules FAQ Members List Today's Posts Search

 
 
Thread Tools Search this Thread Display Modes
Old 04.02.2013, 16:23   #1  
plumbum is offline
plumbum
Участник
Соотечественники
 
182 / 86 (3) ++++
Join Date: 07.12.2007
Location: 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
Пришел, уведел.... отойди, дай другому увидеть!
This post has been rated by: mazzy (2), trud (1), Logger (1), gl00mie (2).
Old 04.02.2013, 16:55   #2  
belugin is offline
belugin
Участник
belugin's Avatar
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Join Date: 16.01.2004
Blog Entries: 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')
This post has been rated by: mazzy (2), gl00mie (2).
Old 04.02.2013, 17:43   #3  
plumbum is offline
plumbum
Участник
Соотечественники
 
182 / 86 (3) ++++
Join Date: 07.12.2007
Location: Vienna, AT
1. Ну это такие требования у нас на проекте - я их тоже не любил, но ИМХО при автоподстановке в AX2012 очень удобно

2. А это Вы к чему? Я собственно собирался середину выудить, там мне заменять только потом надо было.
__________________
http://www.axdevposts.blogspot.com
Пришел, уведел.... отойди, дай другому увидеть!
Old 05.02.2013, 09:50   #4  
belugin is offline
belugin
Участник
belugin's Avatar
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Join Date: 16.01.2004
Blog Entries: 5
1. Приношу свои соболезнования
2. Это и есть выудить середину - только короче
Old 05.02.2013, 09:56   #5  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5813 (201) ++++++++++
Join Date: 28.11.2005
Location: Москва
Blog Entries: 3
Quote:
Originally Posted by plumbum View Post
2. А это Вы к чему?
Это, наверно, к тому, что при наличии строк вида
X++:
    MyType   myVar;
можно сгенерить код соотв. методов с помощью регулярных выражений, заменив
Code:
^\s*(\w+)\s+(\w+);.*
на
Code:
[DataMemberAttribute]\npublic $1 parm\u$2($1 _$2 = $2)\n{\n    $2 = _$2;\n    return $2;\n}
This post has been rated by: plumbum (1).
Old 05.02.2013, 10:25   #6  
belugin is offline
belugin
Участник
belugin's Avatar
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Join Date: 16.01.2004
Blog Entries: 5
Не - тут просто заменой не обойтись - надо же еще удалить чего-то там. Я бы просто прошелся по матчам этого регекспа и сформировал код методов при помощи

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

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

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

Поит был не в strFmt а в использовании многострочных строк и в матчах регекспов
Old 06.02.2013, 17:31   #9  
Evgeniy2020 is offline
Evgeniy2020
Участник
 
309 / 68 (3) ++++
Join Date: 10.04.2007
Location: Москва, САО, СЗАО
в приведенной ссылке
Quote:
Если взять 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?

Last edited by Evgeniy2020; 06.02.2013 at 17:34.
Old 06.02.2013, 19:11   #10  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5813 (201) ++++++++++
Join Date: 28.11.2005
Location: Москва
Blog Entries: 3
Quote:
Originally Posted by Evgeniy2020 View Post
в приведенной ссылке на сайте http://erpkb.com/Axapta/Klass/ScannerClass указана ссылка [...]ссылка не рабочая... можете указать рабочую ссылку на msdn?
Рабочую ссылку на msdn можно найти тут:
Old 06.02.2013, 21:07   #11  
Evgeniy2020 is offline
Evgeniy2020
Участник
 
309 / 68 (3) ++++
Join Date: 10.04.2007
Location: Москва, САО, СЗАО
http://msdn.microsoft.com/en-us/library/dd261486.aspx

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

 

Similar Threads
Thread Thread Starter Forum Replies Last Post
Автоматически пересчет цен/скидок в заказах 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

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Рейтинг@Mail.ru
All times are GMT +3. The time now is 23:56.
Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Contacts E-mail, Advertising.