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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 25.05.2007, 15:53   #1  
Damn is offline
Damn
Участник
 
436 / 154 (6) ++++++
Регистрация: 28.05.2003
Адрес: в глуши
Лукап, отображающий список полей определённой таблицы
Изучая метод pickField() наткнулся на метод findFields() таблицы TmpSysTableField.
Есть там такой вот участок
X++:
                    field       = new SysDictField(dictTable.id(), dictTable.fieldCnt2Id(i), j);

                    if ((field.flags()      &  #DBF_VISIBLE) &&
                        (field.flags()      &  #DBF_STORE) &&
                        (field.baseType()   != Types::CONTAINER) &&
                        (field.name()       != fieldStr(Common, dataAreaId)) &&
                        (field.name()       != fieldStr(Common, sequenceNum)) &&
                        (field.name()       != fieldStr(Common, tableId)) &&
                        (field.baseType()   != Types::VARSTRING))
                    {
                        elements++;
                        pack = conIns(pack, elements, [dictTable.fieldCnt2Id(i),
                                                       field.extendedFieldId(),
                                                       field.name(),
                                                       field.label(),
                                                       field.help(j),
                                                       field.extendedTypeId(),
                                                       field.baseType()]);
                    }
Ну вот почему в случае поля с типом Dimension метод field.name() возвращает просто "Dimension", причём несколько (кол-во аналитик) раз ? Вроде как ожидается что-то типа "Dimension[1]", "Dimension[2]" и т.д. Конечно можно легко заменить field.name() методом fieldid2name() или ещё как-то, чтобы добиться требуемого результата, но почему изначально-то правильно не работает ...
Вобщем вот, высказался
P.S. Проверено в 3.0 SP5 и 4.0 SP1
__________________
Дмитрий
Старый 25.05.2007, 17:51   #2  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
на самом деле, думаю работает все правильно.
Поле в АОТ одно. Но оно является массивом. Поэтому перебираются все элементы массива. Но название поля то одно и то же.

Другое дело, что в базе данных это поле хранится как отдельные поля.
Но при просмотре поля в базе данных все отрабатывает как положено

X++:
static void tutorial_SysDictFieldDimension(Args _args)
{
    SysDictField fld = new SysDictField(tableNum(LedgerJournalTable), fieldNum(LedgerJournalTable, Dimension));
    ;
    info(fld.name());

    info(fld.name(DbBackend::Sql, 1));
    info(fld.name(DbBackend::Sql, 2));
    info(fld.name(DbBackend::Sql, 3));
}
Или я чего-то недопонял?
Старый 25.05.2007, 18:22   #3  
Damn is offline
Damn
Участник
 
436 / 154 (6) ++++++
Регистрация: 28.05.2003
Адрес: в глуши
И в итоге метод pickField() отобразит на экране окошко типа
...
AccountNum
CurrencyCode
Dimension
Dimension
Dimension
...
не очень как-то удобно видеть дименшны без номеров
__________________
Дмитрий
Старый 25.05.2007, 18:26   #4  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Да, согласен. Может возникнуть непонятка.

Поэтому стоит делать так: (в смысле, выводить кроме названия поля еще и его метку)
http://www.axaptapedia.com/Image:SelectFields.PNG

Старый 16.09.2009, 15:50   #5  
propeller is offline
propeller
Участник
Аватар для propeller
 
359 / 29 (1) +++
Регистрация: 25.07.2007
pickField() ?
Есть ли в аксапте метод вроде pickField() только чтобы выпадал список не name а label полей таблицы ?
или как можно создать такой метод?
Старый 16.09.2009, 17:42   #6  
tricky is offline
tricky
Участник
 
140 / 64 (3) ++++
Регистрация: 03.05.2005
Адрес: Гуково
Я такого метода не знаю. Но если программировать, придется чуток покорежить парочку классов.
Можно сделать более "тактичнее", но если делать "в лоб", то примерно вот так.
1. В BaseEnum SysPickListType добавить еще один элемент. Пусть он будет называться FieldsLabels.
2. В классе Global добавить еще один метод, почти такой же, как и метод pickField
X++:
static int pickFieldLabel(tableId tableId)
{
    Object  formRun;
    Args    args;
    ;
    args = new Args(formstr(SysPick));
    args.parm(strRFix(int2str(SysPickListType::FieldsLabels),2)+int2str(tableId));
    formRun = classfactory.formRunClass(args);
    formRun.init();
    formRun.run();
    formRun.wait();
    if (formRun.selection())
        return formRun.selection();
    return 0;
}
3. В класс sysPickList, по аналогии с методом fillFieldsMap, добавить еще один метод:
X++:
public static client container fillFieldsLabelsMap(str _argsParm)
{
    TmpSysTableField    tmpSysTableField;
    DictTable           dictTable       = new DictTable(str2int(_argsParm));
    Map                 map             = new Map(Types::Integer, Types::String);
    ;
    if (dictTable &&
        dictTable.rights() > AccessType::NoAccess)
    {
        tmpSysTableField = TmpSysTableField::findTableFields(tmpSysTableField, dictTable.id());

        while select tmpSysTableField
        {
            map.insert(tmpSysTableField.ExtendedFieldId, tmpSysTableField.FieldLabel);
        }
    }
    return map.pack();
}
4. В методе init этого же класса добавить примерно такие строки (в блоке switch(sysPickListType)):
X++:
//-------------
        case SysPickListType::FieldsLabels :
            imageRes    = #imageField;
            caption     = "@SYS3852";
            designWidth = #designLargeWidth;
            if (!map)
            {
                map = Map::create(sysPickList::fillFieldsLabelsMap(parmTxt));
            }
            break;
//-------------
5. Теперь можно попробовать вызвать наш новый метод:
X++:
    Global::pickFieldLabel(tableNum(InventTable));
За это сообщение автора поблагодарили: mazzy (2), lev (3), Poleax (5), propeller (1), abri (1), MazZzDaI (1).
Старый 17.09.2010, 17:46   #7  
Poleax is offline
Poleax
Модератор
Аватар для Poleax
MCP
MCBMSS
Злыдни
 
1,353 / 595 (22) +++++++
Регистрация: 17.02.2005
Адрес: msk
Записей в блоге: 34
Post
По аналогии с выше приведенным постом tricky, я сделал для себя выпадающий список (Lookup) для всех полей таблицы не являющимися системными:
Результат:
Название: fieldsUser.png
Просмотров: 1547

Размер: 40.5 Кб
  1. В \Data Dictionary\Base Enums\SysPickListType добавить элемент, назовем его к примеру FieldsUsersLabels (Пользовательские поля с названием)
  2. В классе создадим метод \Classes\Global\pickFieldUserLabel
    X++:
    static int pickFieldUserLabel(tableId tableId)
    {
        Object  formRun;
        Args    args;
        ;
        args = new Args(formstr(SysPick));
        args.parm(strRFix(int2str(SysPickListType::FieldsUsersLabels),2)+int2str(tableId));
        formRun = classfactory.formRunClass(args);
        formRun.init();
        formRun.run();
        formRun.wait();
        if (formRun.selection())
            return formRun.selection();
        return 0;
    }
  3. В класс создадим метод \Classes\sysPickList\fillFieldsUserLabesMap:
    X++:
    public static client container fillFieldsUserLabesMap(str _argsParm)
    {
        TmpSysTableField    tmpSysTableField;
        DictTable           dictTable       = new DictTable(str2int(_argsParm));
        Map                 map             = new Map(Types::Integer, Types::String);
        
        //Variables
        DictField               dictField;
        SysDimension            dim;
        str                     num = '';
        
        ;
        if (dictTable &&
            dictTable.rights() > AccessType::NoAccess)
        {
            tmpSysTableField = TmpSysTableField::findTableFields(tmpSysTableField, dictTable.id());
    
            while select tmpSysTableField
            {
                dictField  = new dictField(dictTable.id(), tmpSysTableField.ExtendedFieldId);
                
                if(!dictField.isSystem())
                {
                    if(tmpSysTableField.FieldName LIKE "*Dimension*")
                        num = "[" + int2str(enum2int(str2Enum(dim, tmpSysTableField.FieldLabel)) + 1) + "]";
                    else
                        num = "";
                        
                    map.insert(tmpSysTableField.ExtendedFieldId, tmpSysTableField.FieldName + num + " (" + tmpSysTableField.FieldLabel + ")" );
                }
            }
        }
        return map.pack();
    }
  4. В методе init этого же класса добавить примерно такие строки (в блоке switch(sysPickListType)):
    X++:
            case SysPickListType::FieldsUsersLabels :
                imageRes    = #imageField;
                caption     = "Пользовательские поля с названием";
                designWidth = #designLargeWidth;
                if (!map)
                {
                    map = Map::create(sysPickList::fillFieldsUserLabesMap(parmTxt));
                }
                break;
  5. Вызываем метод:
    X++:
    Global::pickFieldUserLabel(tableNum(CustTable));

Для примера можно выбрать форму для изучения \Forms\PBATreeTable.

Пример Lookup метода:
X++:
void lookup()
{
    fieldId id;
//AnyUserTable  - таблица куда сохраняем поле
    ;

    id = pickFieldUserLabel(tableNum(CustTable));

    if (! id)
        return;

    AnyUserTable.FieldName = fieldid2name(tableNum(CustTable),id);

    AnyUserTable_ds.refresh();
}
P.S. Спасибо tricky , за хороший пост.
__________________

This posting is provided "AS IS" with no warranties, and confers no rights.
За это сообщение автора поблагодарили: mazzy (2), Lemming (5), lev (2), mallard (2), Proba (1).
Старый 17.09.2010, 18:00   #8  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
ну и в дагонку методам pick (может кому пригодится )..
в своё время нужны были методы, которые вываливают список EDT, Forms и MainMenu.
т.к. в стандарте таковых не нашел добавил следующие методы в класс Global:

Ax3.0 sp3

1. список EDT:
X++:
static int pickExtDataTypes()
{
    Object      formRun;
    container   names;
    int         i;
    Dictionary  dict = new Dictionary();
    DictType    dictType;
    #ResAppl
    ;

    formRun = classFactory.createPicklist();
    formRun.init();

    for (i=1; i <= dict.typeCnt(); i++)
    {
        dictType = new DictType(dict.typeCnt2Id(i));

        names   += dictType.name();
    }

    formRun.choices(names, #ImageEDT);
    formRun.caption("EDT");
    formRun.run();
    formRun.wait();

    if (formRun.choice())
    {
        return dict.typeName2Id(formRun.choice());
    }

    return 0;
}
2. Список форм.
X++:
static FormName pickForms()
{
    Object      formRun;
    container   names;
    TreeNode    treeNode;
    TreeNode    treeNodeChild;
    #ResAppl
    #AOT
    ;

    treeNode        = TreeNode::findNode(#FormsPath);
    treeNodeChild   = treeNode.AOTfirstChild();

    formRun = classFactory.createPicklist();
    formRun.init();

    while (treeNodeChild)
    {
        names   += treeNodeChild.treeNodeName();

        treeNodeChild = treeNodeChild.AOTnextSibling();
    }

    formRun.choices(names, #ImageForm);
    formRun.caption("Forms");
    formRun.run();
    formRun.wait();

    if (formRun.choice())
    {
        return formRun.choice();
    }

    return '';
}
3. Список пунктов главного меню
X++:
static MenuName pickMenusMain()
{
    Object      formRun;
    container   names;
    TreeNode    treeNode;
    TreeNode    treeNodeChild;
    SysDictMenu dictMenu;
    #ResAppl
    #AOT
    #Admin
    ;

    treeNode        = TreeNode::findNode(#MenusPath + '\\' + #MainMenu);
    treeNodeChild   = treeNode.AOTfirstChild();

    formRun = classFactory.createPicklist();
    formRun.init();

    while (treeNodeChild)
    {
        dictMenu    = SysDictMenu::newMenuName(#MainMenu + '\\' + treeNodeChild.treeNodeName());
        names      += dictMenu.label();

        treeNodeChild = treeNodeChild.AOTnextSibling();
    }

    formRun.choices(names, #ImageMenuMain);
    formRun.caption("MainMenu");
    formRun.run();
    formRun.wait();

    if (formRun.choice())
    {
        return formRun.choice();
    }

    return '';
}
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
За это сообщение автора поблагодарили: TasmanianDevil (4).
Теги
ax3.0, ax4.0, lookup, lookupfield, полезное, программно

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Как получить имена полей, которые есть у таблицы? 3oppo DAX: Программирование 2 22.12.2006 14:30
Свойство AllowEdit полей таблицы Lucky13 DAX: Программирование 4 29.07.2005 14:14
Список полей таблиц на базе конкретного EDT Владимир Максимов DAX: Программирование 10 06.10.2004 14:45
Изменение ID-ов полей таблицы somebody DAX: Программирование 5 02.02.2004 19:57
Объединить несколько полей таблицы в одном поле Grid-а на форме? storer DAX: Программирование 2 12.11.2003 14:08

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

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

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