Показать сообщение отдельно
Старый 27.06.2008, 13:08   #17  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Подручные средства для облегчения создания рутинных фрагментов кода
Во загнул, скажете, но на самом деле все очень просто. То тут, то там приходится выписывать последовательности операторов присваивания для перевалки данных из одного места в другое, например, пересылать значения из несвязанных контролов формы в поля таблицы. Для оформления подобных операций желательно иметь выстроенный список полей с одной и с другой стороны, которые в коде необходимо "совместить" друг с другом посредством знака равенства.

Такое совмещение можно приготовить в любом редакторе текста, позволяющем блочные вставки, например, в MultiEdit или в текстовом редакторе программы FAR (выделение прямоугольника при помощи Alt+стрелка), и затем вставить в текст конкретного метода в Axapta. Еще проще подготовить присваивания при помощи таблиц Excel, вставив наборы полей в соседние колонки, связав их формулами и наконец скопировав вычисленные значения формул в код X++.

Пусть, например, имееется набор полей таблицы:
Table1.StrField1
Table1.StrField2
Table1.StrField3

и набор контролов формы (подразумевается AutoDeclaration = Yes):
StringEditControl1
StringEditControl2
StringEditControl3

Допустим, что код должен выглядеть следующим образом:
Table1.Field1 = StringEditControl1.valueStr();
Table1.Field2 = StringEditControl2.valueStr();
Table1.Field3 = StringEditControl3.valueStr();

Создадим эти операторы присваивания при помощи Excel. Для этого:
- скопируем набор полей в столбец A Excel, начиная с ячейки A1;
- скопируем набор контролов в столбец B Excel, начиная с ячейки B1;
- в ячейку C1 введем формулу: =A1 & " = " & B1 & ".valueStr();" и распространим ее вниз копированием на все необходимые строки;
- далее из столбца C забираем строки кода X++ для вставки в Axapta.

Всё неплохо. Дело осталось за малым - автоматизировать получение самих списков полей (не вручную их же набирать в самом деле! ).

Вот два коротеньких джобика, которые могут помочь в этом. Первый - получение списка полей таблицы:
X++:
static void Job_getTableFieldList(Args _args)
{
    str         tableName = 'RAssetTable'; // подставь здесь свою таблицу
    treeNode    treeNode = new xInfo()
                            .rootNode()
                            .AOTfindChild('Data Dictionary')
                            .AOTfindChild('Tables')
                            .AOTfindChild( tableName )
                            .AOTfindChild('Fields');
    ;
    treeNode = treeNode.AOTfirstChild();
    while ( treeNode )
    {
        info( strfmt('%1.%2', tableName, treeNode.treeNodeName()) );
        treeNode = treeNode.AOTnextSibling();
    }
}
Из инфолога список забираем операцией "Копировать как список в буфер обмена" и вставляем в Excel. Очевидно, что если табличная переменная в коде отличается от имени исходной таблицы, то достаточно соответствующим образом подправить параметры вызова функции strfmt. Например: strfmt('%1.%2', 'myTable', treeNode.treeNodeName()). Можно еще сразу включить знак равенства: '%1.%2 = ' (чтобы упростить формулу Excel или вообще обойтись без нее, если используется редактор с блочными вставками ).

Второй джоб - получение списка контролов формы:
X++:
static void Job_getFormControlList(Args _args)
{
    str         formName = 'RAssetTable';  // подставь здесь свою форму
    int         row, hLevel; // служебные поля на случай вывода сквозной нумерации строк или уровней иерархии
    TreeNode    treeNode = new xInfo()
                            .rootNode()
                            .AOTfindChild('Forms')
                            .AOTfindChild( formName )
                            .AOTfindChild('Designs')
                            .AOTfindChild('Design');
    str controlType;
    str controlName;

    void nextNode( treeNode _tn)
    {
        ;
        hLevel++;
        _tn = _tn.AOTfirstChild();
        while (_tn )
        {
            if (strscan(_tn.treeNodeName(), ':', 1, 10000))
            {
                row++;
                [controlType, controlName] = str2con(_tn.treeNodeName(), ':');

                if (substr(controlType,1,1)=='[') // Tab, TabPage, Group, Grid, ButtonGroup
                {
                    controlType = substr(controlType, 2, strlen(controlType)  );
                    controlName = substr(controlName, 1, strlen(controlName)-1);
                }
                info( strfmt('%1.valueStr();', controlName) );
            }
            nextNode(_tn );
            _tn = _tn.AOTnextSibling();
        }
        hLevel--;
    }
    ;
    nextNode( treeNode );
}
В целях примера к имени контрола при выводе в инфолог сразу добавлена подстрока '.valueStr();'.