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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 07.12.2007, 11:24   #1  
bJoker is offline
bJoker
Участник
 
7 / 11 (1) +
Регистрация: 06.11.2007
Программно вывести список отношений (Relation)
Как можно программно вывести список отношений?
Определить имеет ли определенное поле отношение с другим полем.
Если имеет, то вывести связанное поле и таблицу.
За это сообщение автора поблагодарили: Kuat (1).
Старый 07.12.2007, 11:50   #2  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Регистрация: 21.10.2004
См. класс DictRelation и методы dictTable.relation и dictType.relationObject
Старый 07.12.2007, 12:06   #3  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Если вам надо для анализа и собственного понимания, то я вот когда-то (когда еще совсем был не бум-бум в Dict* классах) использовал прямой запрос для СУБД Oracle.
Предварительно проверьте, что таблица XRefPaths у вас непустая. Если пустая, то сначала постройте "Перекрестные ссылки". Запрос такой:
Код:
SELECT
	path,      
	path_clear,
	TRIM(SUBSTR(path_clear, 1, end_table - 1)) AS table_name,
	TRIM(SUBSTR(path_clear, end_table + 1, end_relation - end_table - 1)) AS relation_name,
	TRIM(SUBSTR(path_clear, end_relation + 1, end_equal - end_relation - 1)) AS relation_left,
	TRIM(SUBSTR(path_clear, end_equal + 2, LENGTH(path_clear) - end_equal - 1)) AS relation_right
FROM
(
SELECT
	path,       
	path_clear,
	INSTR(path_clear, '\', 1,1) AS end_table,
	INSTR(path_clear, '\', 1,2) AS end_relation,
	INSTR(path_clear, '==', 1,1) AS end_equal
FROM
(
SELECT 
	path,
	REPLACE(REPLACE(TRIM(path), '\Data Dictionary\Tables\', ''),'\Relations', '') AS path_clear
	-- REPLACE(REPLACE(TRIM(path), '\Data Dictionary\Extended Data Types\', ''),'\Relations', '') AS path_clear  
FROM XREFPATHS 
WHERE path LIKE '%Relations%==%' 
	AND path LIKE '\Data Dictionary\Tables\%'
--	AND path LIKE '\Data Dictionary\Extended Data Types\%'
ORDER BY path
)
)
В этом виде он выводит отношения на таблицах. Если раскомментировать закомментированные (--) строки и закомментировать строки над ними, то запрос выдаст отношения на EDT.
Старый 07.12.2007, 12:26   #4  
Russland is offline
Russland
MCTS
Аватар для Russland
MCBMSS
 
267 / 116 (4) +++++
Регистрация: 17.10.2005
Адрес: Донеччина, Україна
Analyzing table relations of a Query object
Не совсем то, конечно, но возможно это вам сможет помочь.
__________________

В глухомани, в лесу Несмотря на красу Дни проводит Лиса Патрикевна. Я никак не пойму Отчего, почему Не пускают куму На деревню

Последний раз редактировалось Russland; 07.12.2007 в 12:29.
Старый 07.12.2007, 12:29   #5  
bJoker is offline
bJoker
Участник
 
7 / 11 (1) +
Регистрация: 06.11.2007
Можно подробнее о Dict* классах.
Мне просто надо вывести информацию о всех полях выбранной таблицы (имя, формат, ссылки,и. т.д.)

И можно подробнее о line* в DictRelation.
Старый 07.12.2007, 12:29   #6  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Еще могу поделиться двумя методами ("AS IS") из своего недопиленного класса, всячески анализирующего словарь данных. Класс заточен на вывод информации в таблицы MS Access (структуры таблиц в методах имеются). Вы можете создать аналогичные по структуре таблички Аксапты или вывести данные, например, в Excel. В общем, с выводом при желании разберетесь, ну, а точность циклов перебора Dict-коллекций гарантирую (включая выстраданные комментарии )
X++:
void makeRelationsOnTables()
{
    #define.currTableName('ddRelationsOnTables')
    int i, j, L;

    TableId         tableId;
    DictTable       dictTable;

    FieldId         fieldId;
    DictField       dictField;

    EnumId          enumId;
    DictEnum        dictEnum;

    ExtendedTypeId  EDTypeId;
    DictType        dictEDType;

    DictRelation    dictRel;

    TableId         externTableId;
    DictTable       dictExternTable;

    ;

    this.recreateTable( #currTableName,
        ' rtTableId             LONG , ' +
        ' rtTableName           TEXT , ' +
        ' rtTableNameSQL        TEXT , ' +
        ' rtTableLabel          TEXT , ' +

        ' rtExternTableId       LONG , ' +
        ' rtExternTableName     TEXT , ' +
        ' rtExternTableNameSQL  TEXT , ' +
        ' rtExternTableLabel    TEXT , ' +

        ' rtRelationNum         LONG , ' +
        ' rtRelationName        TEXT , ' +
        ' rtRelationValidate    LONG , ' +

        ' rtRelationLine        LONG , ' +
        ' rtRelationLineTypeTxt TEXT , ' +

        ' rtFieldId             LONG , ' +
        ' rtFieldName           TEXT , ' +
        ' rtLineValue           LONG , ' +

        ' rtExternFieldId       LONG , ' +
        ' rtExternFieldName     TEXT , ' +
        ' rtExternLineValue     LONG   ' );


    this.openRecordset( #currTableName );

    // цикл по таблицам
    for (i=1; i<= dictionary.tableCnt(); i++)
    {
        tableId   = dictionary.tableCnt2Id(i);
        dictTable = new DictTable(tableId);

        dictRel = new DictRelation(tableId);

        // цикл по Relations для данной таблицы
        for (j=1; j<= dictTable.relationCnt(); j++)
        {
            //l_relationName = dictTable.relation(j);  // строковое имя релатион

            //relatedTableId =  dictRel.loadNameRelation(dictTable.relation(j)); // id связанной таблицы
            externTableId =  dictRel.loadNameRelation(dictTable.relation(j)); // id связанной таблицы

            // сюда вставить обработку !externTableId
            if (externTableId)
            {
                dictExternTable = new DictTable(externTableId); // связанная таблица
            }

            // цикл по ЛИНИЯМ Relations для данной таблицы
            for (L=1; L<= dictRel.lines(); L++)
            {

                //rstAxa.AddNew();
                adRstAccess.AddNew();

                    this.setFieldValue('rtTableId'      , tableId );
                    this.setFieldValue('rtTableName'    , dictTable.name() );
                    this.setFieldValue('rtTableNameSQL' , dictTable.name(DbBackend::SQL) );
                    this.setFieldValue('rtTableLabel'   , dictTable.label() );

                    if (externTableId)
                    {
                        this.setFieldValue('rtExternTableId'      , externTableId );
                        this.setFieldValue('rtExternTableName'    , dictExternTable.name() );
                        this.setFieldValue('rtExternTableNameSQL' , dictExternTable.name(DbBackend::SQL) );
                        this.setFieldValue('rtExternTableLabel'   , dictExternTable.label() );
                    }

                    this.setFieldValue('rtRelationNum'      , j );
                    this.setFieldValue('rtRelationName'     , dictTable.relation(j) );
                    this.setFieldValue('rtRelationValidate' , dictRel.validate() );

                    this.setFieldValue('rtRelationLine'        , L );
                    this.setFieldValue('rtRelationLineTypeTxt' , enum2str(dictRel.lineType(L)) );

                    if (dictRel.lineType(L) == TableRelation::Field)
                    {
                        // поле нашей таблицы
                        if (dictRel.lineTableValue(L))
                        {
                            dictField = dictTable.fieldObject(dictRel.lineTableValue(L) );
                            this.setFieldValue('rtFieldId'   , dictField.id() );
                            this.setFieldValue('rtFieldName' , dictField.name() );
                        }
                        else
                        {
                            this.setFieldValue('rtFieldName' , #meErrorIndicator );
                        }


                        // поле связанной таблицы
                        if (dictRel.lineExternTableValue(L))
                        {
                            dictField = dictExternTable.fieldObject(dictRel.lineExternTableValue(L) );
                            this.setFieldValue('rtExternFieldId'   , dictField.id() );
                            this.setFieldValue('rtExternFieldName' , dictField.name() );
                        }
                        else
                        {
                            this.setFieldValue('rtExternFieldName' , #meErrorIndicator );
                        }

                    }

                    if (dictRel.lineType(L) == TableRelation::ThisFixed)
                    {
                        // поле нашей таблицы фиксировано: ИМЯ НАШЕГО ПОЛЯ == (внешнее значение)
                        dictField = dictTable.fieldObject(dictRel.lineTableValue(L) );
                        if (dictField)
                        {
                            this.setFieldValue('rtFieldId'   , dictField.id() );
                            this.setFieldValue('rtFieldName' , dictField.name() );
                        }
                        else
                        {
                            this.setFieldValue('rtFieldName' , #meErrorIndicator );
                        }

                        // (внешнее значение)
                        this.setFieldValue('rtExternLineValue' , dictRel.lineExternTableValue(L) );
                    }

                    if (dictRel.lineType(L) == TableRelation::ExternFixed)
                    {
                        // поле ВНЕШНЕЙ таблицы фиксировано: (наше значение) == ИМЯ ВНЕШНЕГО ПОЛЯ
                        // (наше значение)
                        this.setFieldValue('rtLineValue' , dictRel.lineTableValue(L) );

                        // поле связанной таблицы
                        dictField = dictExternTable.fieldObject(dictRel.lineExternTableValue(L) );
                        if (dictField)
                        {
                            this.setFieldValue('rtExternFieldId'   , dictField.id() );
                            this.setFieldValue('rtExternFieldName' , dictField.name() );
                        }
                        else
                        {
                            this.setFieldValue('rtExternFieldName' , dictField.name() );
                        }

                    }

                adRstAccess.Update();

            }
        }
    }

    this.closeRecordset();
}

// ====================================================================================

void makeRelationsOnEDTypes()
{
    #define.currTableName('ddRelationsOnEDTypes')
    int i, j, L;

    TableId         tableId;
    DictTable       dictTable;

    FieldId         fieldId;
    DictField       dictField;

    EnumId          enumId;
    DictEnum        dictEnum;

    ExtendedTypeId  EDTypeId;
    DictType        dictEDType;

    DictRelation    dictRel;

    TableId         externTableId;
    DictTable       dictExternTable;

    ;

    this.recreateTable( #currTableName,
        ' reEDTypeId         LONG , ' +
        ' reEDTypeName       TEXT , ' +
        ' reEDTypeLabel      TEXT , ' +
        ' reEDTypeArraySize  LONG , ' +
        ' reEDTypeArrayIndex LONG , ' +

        ' reLine             LONG , ' +
        ' reLineType         LONG , ' +
        ' reLineTypeTxt      TEXT , ' +

        ' reTableId          LONG , ' +
        ' reTableName        TEXT , ' +

        ' reFieldId          LONG , ' +
        ' reFieldName        TEXT , ' +

        ' reLineValue        LONG   ' );

    this.openRecordset( #currTableName );

    // цикл по EDT
    for (i=1; i <= dictionary.typeCnt(); i++)
    {
        EDTypeId   = dictionary.typeCnt2Id(i);

        dictEDType = new DictType(EDTypeId);
        dictRel = dictEDType.relationObject();

        if (dictRel)
        {
            // цикл по Relations для данного EDT
            for (j = 1; j <= dictEDType.arraySize(); j++)
            {
                dictRel = dictEDType.relationObject(j);  // повторный вызов, потому что уже с учетом элементов массива

                for (L=1; L<= dictRel.lines(); L++)
                {
                    adRstAccess.AddNew();

                        this.setFieldValue('reEDTypeId'         , EDTypeId );
                        this.setFieldValue('reEDTypeName'       , dictEDType.name() );
                        this.setFieldValue('reEDTypeLabel'      , dictEDType.label(j) );

                        this.setFieldValue('reEDTypeArraySize'  , dictEDType.arraySize() );
                        this.setFieldValue('reEDTypeArrayIndex' , j );

                        this.setFieldValue('reLine' , L );

                        this.setFieldValue('reLineType'    , dictRel.lineType(L) );
                        this.setFieldValue('reLineTypeTxt' , enum2str(dictRel.lineType(L)) );

                        dictTable = new DictTable(dictRel.table()); // правая таблица

                        if (dictTable)
                        {
                            this.setFieldValue('reTableId'   , dictTable.id() );
                            this.setFieldValue('reTableName' , dictTable.name() );

                            dictField = dictTable.fieldObject(dictRel.lineExternTableValue(L) );

                            if (dictField)
                            {
                                this.setFieldValue('reFieldId'   , dictField.id() );
                                this.setFieldValue('reFieldName' , dictField.name() );
                            }
                        }

                        if (dictRel.lineType(L) == TableRelation::ExternFixed)
                        {
                            this.setFieldValue('reLineValue' , dictRel.lineTableValue(L) );

                            // dictRel.lineExternTableValue(k) дает здесь ID поля, т.е. RelatedFieldId
                            // вообще здесь как-то всё путанно, не сразу разобрался,
                            // потому что:
                            // dictRel.table()
                            //   -> dictRel.lineExternTableValue(k)
                            //     -> dictRel.lineType(k) == TableRelation::ExternFixed
                            //       -> dictRel.lineTableValue(k)
                            // т.е. "table" и "ExternTable" как-то туда-сюда мечутся... :(
                            // но в итоге выстроилась картина "как надо", можно забыть о переживаниях :))
                        }
                    adRstAccess.Update();
                }
            }
        }
    }

    this.closeRecordset();
}
За это сообщение автора поблагодарили: bJoker (1).
Старый 07.12.2007, 14:11   #7  
bJoker is offline
bJoker
Участник
 
7 / 11 (1) +
Регистрация: 06.11.2007
Спаисбо всем.
Помог последний пример.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
И снова про Relation Corsar DAX: Программирование 7 24.10.2008 14:19
Как работает список рассылки? fialka DAX: Функционал 2 26.06.2008 09:15
Сергей Герасимов: Майкрософт ежемесячно публикует список исправленных ошибок Blog bot DAX Blogs 1 16.01.2007 11:52
Relation на таблице и EDT Alex_K DAX: Программирование 2 15.12.2004 15:49
Список полей таблиц на базе конкретного EDT Владимир Максимов DAX: Программирование 10 06.10.2004 14:45

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

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

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