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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 31.08.2018, 12:54   #1  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,936 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Форма SysSetupForm и отображение QueryFilter в дереве запроса
Всем привет.

Сегодня с удивлением обнаружил что формочка SysSetupForm в 2012-й аксапте не показывает на 3-й закладке QueryFilter в дереве запроса.

Все QueryBuildRange показывает, а QueryFilter - нет.
Какая-то подстава.

Дописал, чтобы выводила.
Смотреть методы
fillQueryTreeQueryDatasource
fillQueryTreeFormDatasource
Вложения
Тип файла: zip SysSetupForm_upgrade_2018_08_31__12_48.zip (5.9 Кб, 115 просмотров)
За это сообщение автора поблагодарили: sukhanchik (10).
Старый 26.10.2018, 15:56   #2  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,936 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Исправил ряд ошибок.
1. Падало при наличии Range.
2. Отображало Filters только 1-го датасорса.
Вложения
Тип файла: zip Admin_SysSetupForm_upgrade_2018_10_26__15_49.zip (6.0 Кб, 119 просмотров)
За это сообщение автора поблагодарили: sukhanchik (2), Jorj (1), iCloud (2).
Старый 27.05.2024, 16:28   #3  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,936 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Привет всем.

Оказывается на этом фичи формы персонализации не заканчиваются.

Для связей с типом PrimaryKey криво отображаются связи в запросе.

Пример :

1. Форма перекрестных ссылок "Чем используется" (\Forms\xRefReferencesUsedByTypedTree)
Связи датасорса xRefReferences с дочерними отображаются так
xRefPaths. == xRefReferences. Role: xRefPaths_1
xRefNames. == xRefReferences. Role: xRefNames

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

2. Форма проводок по расчетам с поставщиками (\Forms\VendTrans)
Связь датасорса VendTrans с дочерним VendTrans_W отображается так
VendTrans_W. == VendTrans. Role: VendTrans

3. Форма складских проводок в управлении запасами (\Forms\InventTrans)
Связь датасорса InventTrans с дочерним InventDim отображается так
InventDim. == InventTrans. Role: InventDim
а с DirPartyTable так
DirPartyTable. == InventTransOrigin. Role: DirPartyTable


Так получается потому, что при разборе запроса класс ядра QueryBuildLink для таких связей почему-то возвращает пустые значения методами
queryBuildLink.relatedField()
queryBuildLink.field()
и непустое методом
queryBuildLink.joinRelation()
(возвращается значение свойства RelatedTableRole для использованной при линке связи. А если оно пустое то значение, которое ядро автоматом генерирует - обычно это имя связанной таблички)

а форма персонализации никак этот факт не обрабатывает.


Не совсем понятно такое поведение класса QueryBuildLink. Зачем скрывать идентификаторы полей. Разработчик должен названия связей что ли помнить ?Ерунда какая-то. Во всяком случае пользоваться этим неудобно. Нужно чтобы было просто - посмотрел запрос на диалоге и все понятно. А так приходится лезть в AOT, чтобы понять как точно идет связь.


Или может я чего-то недопонимаю ?


Пока исправил так
на форме SysSetupForm
добавил метод

X++:
// PKoz 21.05.2024
private boolean fillQueryTreeQueryDsRelation_MRC(
    QueryBuildLink  _queryBuildLink,
    int             _treeId,
    str             _queryBuildLinkNodeText,
    boolean         _general // по какой табличке перебираем связи
                             // true  - по основной  табличке линка (_queryBuildLink.table()),
                             // false - по связанной табличке линка (_queryBuildLink.relatedTable())
                             // метод вызывается последовательно для true и для false
    )
{
    FormTreeItem    formTreeItem;
    DictTable       dictTable;
    SysDictRelation dictRelationRelation;
    int             relationNum;
    int             relationLine;
    tableId         relatedTableId;
    str             linkStr;
    int             parentTreeId;
    str             xppRelationName;
    container       con;
    container       conRev;

    TableId     sourceTable  = _general ? _queryBuildLink.table()          : _queryBuildLink.relatedTable();
    TableId     relatedTable = _general ? _queryBuildLink.relatedTable()   : _queryBuildLink.table();

    str         relation     = _queryBuildLink.joinRelation();

    int addParentNode()
    {
        int     ret;
        ;

        // BP deviation documented
        formTreeItem = new FormTreeItem(_queryBuildLinkNodeText + strFmt('    [Table.XppRelationName:   %1.%2]', dictTable.name(), xppRelationName), imagelist.image(#ImageRelation), -1, null);
        ret = queryTree.addItem(_treeId, FormTreeAdd::Last, formTreeItem);
        return ret;
    }
    ;

    dictTable = new DictTable(sourceTable);
    if (!dictTable)
    {
        return false;
    }

    dictRelationRelation = new SysDictRelation(dictTable.Id());

    for (relationNum = dictTable.relationCnt(); relationNum; relationNum--)
    {
        relatedTableId = dictRelationRelation.loadNameRelation(dictTable.relation(relationNum));

        if (dictRelationRelation.relatedTableRole() == relation)
        {
            if (relatedTableId == relatedTable)
            {
                xppRelationName = dictTable.relation(relationNum);
                break;
            }
        }
    }
    if (!xppRelationName)
    {
        return false;
    }

    for (relationLine = dictRelationRelation.lines(); relationLine; relationLine--)
    {
        linkStr = dictRelationRelation.lineDescription(relationLine);

        if (linkStr)
        {
            if (_general)
            {
                // метод dictRelationRelation.lineDescription() возвращает нужное нам значение для _general = true, только нужно поменять местами операнды около символа "=="
                // меняем их местами :
                con = str2con_RU(linkStr, '==');
                conRev = con;
                conRev = conPoke(conRev, 1, conPeek(con, 2));
                conRev = conPoke(conRev, 2, conPeek(con, 1));
                linkStr = con2Str(conRev, ' == ');
            }
            if (dictRelationRelation.lineSubType(relationLine) != RelationshipSubType::Default)
            {
                // добавляем допинфу по типу связи
                linkStr += strFmt("     [LinkSubType = %1]", dictRelationRelation.lineSubType(relationLine));
            }

            if (!parentTreeId)
            {
                parentTreeId = addParentNode();
            }

            // BP deviation documented
            formTreeItem = new FormTreeItem(linkStr, imagelist.image(#ImageField), -1, null);
            queryTree.addItem(parentTreeId, FormTreeAdd::Last, formTreeItem);
        }
    }

    return true;
}
а в методе fillQueryTreeQueryDatasource
в конце поменять кусок кода

X++:
        // Relation

        if (queryBuildDataSource.linkCount())
        {
            formTreeItem = new FormTreeItem('Relation',imagelist.image(#ImageRelations),-1,null);
            treeId  = queryTree.addItem(sourceRootId,FormTreeAdd::Last,formTreeItem);

            for (i = 1; i <= queryBuildDataSource.linkCount(); i++)
            {
                queryBuildLink = queryBuildDataSource.link(i);

                nodeText = this.CalculateNodeTextForRelations(queryBuildLink.table(),
                    queryBuildLink.relatedTable(),
                    queryBuildLink.field(),
                    queryBuildLink.relatedField());

                // Add the context of the joinRelation name if it is specified.
                // This is for Surrogate Foreign Key scenarios where the fields aren't specified in the link.
                if (queryBuildLink.joinRelation())
                {
                    nodeText += ' Role: ' + queryBuildLink.joinRelation();
                }

                // BP deviation documented
                formTreeItem = new FormTreeItem(nodeText,imagelist.image(#ImageRelation),-1,null);
                queryTree.addItem(treeId,FormTreeAdd::Last,formTreeItem);
            }
        }

на такой

X++:
        // Relation

        if (queryBuildDataSource.linkCount())
        {
            formTreeItem = new FormTreeItem('Relation',imagelist.image(#ImageRelations),-1,null);
            treeId  = queryTree.addItem(sourceRootId,FormTreeAdd::Last,formTreeItem);

            for (i = 1; i <= queryBuildDataSource.linkCount(); i++)
            {
                queryBuildLink = queryBuildDataSource.link(i);

                nodeText = this.CalculateNodeTextForRelations(queryBuildLink.table(),
                    queryBuildLink.relatedTable(),
                    queryBuildLink.field(),
                    queryBuildLink.relatedField());

                // Add the context of the joinRelation name if it is specified.
                // This is for Surrogate Foreign Key scenarios where the fields aren't specified in the link.
                if (queryBuildLink.joinRelation())
                {
                    // nodeText += ' Role: ' + queryBuildLink.joinRelation();
                    nodeText += '    Role: ' + queryBuildLink.joinRelation();
                }

                // BP deviation documented
                formTreeItem = new FormTreeItem(nodeText,imagelist.image(#ImageRelation),-1,null);

                // PKoz 22.05.2024 -->
                if (!(queryBuildLink.joinRelation() &&
                        (
                            this.fillQueryTreeQueryDsRelation_MRC(queryBuildLink, treeId, nodeText, false) || // именно в таком порядке, сперва вызов false так как ядро сперва проверяет связи для подчиненной таблицы
                            this.fillQueryTreeQueryDsRelation_MRC(queryBuildLink, treeId, nodeText, true)
                        )
                     )
                   )
                // PKoz 22.05.2024 <--
                {
                    queryTree.addItem(treeId,FormTreeAdd::Last,formTreeItem);
                }
            }
        }
За это сообщение автора поблагодарили: Товарищ ♂uatr (4), sukhanchik (8), Manner (1).
Теги
dax2012, querybuildlink, queryfilter, syssetupform

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
АХ2012.Форма "Все накладные".Отображение накладных DaMa DAX: Функционал 7 10.07.2017 08:54
Зависает форма при выполнении executeQuery Vasiliusis DAX: Программирование 3 28.01.2016 11:42
Как класс->запрос->форма. Как такое создать? kitty DAX: Программирование 16 09.09.2014 12:52
Всегда ли правильно работает queryrun().query().dataSourceCount() при присоединении пользователем таблиц в настройках стандартного запроса? Aquarius DAX: Программирование 5 26.09.2013 09:52
Произвольная Lookup форма Maxim Gorbunov DAX: База знаний и проекты 0 30.11.2001 21:59

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

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

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