Показать сообщение отдельно
Старый 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).