Moderator
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
|
Еще могу поделиться двумя методами ("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();
}
|