Saturday, December 21, 2024

Find all tables with relations to a given field

 Sometimes we need to know which tables are related to a given table on a given field.



Unfortunately, none of AI generative tools I tried was able to provide me with a working code. So, I wrote this code manually based on Microsoft doc and some articles.

static void findAllTablesWithRelations(TableId _tableId, FieldId _fieldId)
    {
        Dictionary      dict = new Dictionary();
        DictTable       dictTable;
        DictRelation    dictRelation;
        TableId         tableId;
        int             i, j;
        int             linesCnt;
        int             relationLine;
        int             c;
        int             numOfTables = dict.tableCnt();
        boolean         relationFound;

        // Loop through all tables in the system
        for (j=1 ; j<= numOfTables; j++)
        {
            relationFound   = false;
            tableId         = dict.tableCnt2Id(j);
            dictTable       = dict.tableObject(tableId);
// Uncomment the following to get specific table types
            //if( dictTable.isAbstract() || 
            //    dictTable.isDataEntity() || 
            //    dictTable.isMap() || 
            //    dictTable.isTempDb() || 
            //    dictTable.isTmp() || 
            //    dictTable.isView())
            //{
            //    continue;
            //}

            dictRelation    = new DictRelation(tableId);
            str tableName   = dictTable.name();
            
            // Loop through all table relations
            int relCount = dictTable.relationCnt();
            //info(strFmt("Number of relations %1", relCount));

            for (i = 1; i <= relCount; i++)
            {
                str relName     = dictTable.relation(i);
                dictRelation.loadNameRelation(relName);
                
                if (dictRelation && dictRelation.externTable() == _tableId)
                {
                    linesCnt = dictRelation.lines();
                    for (relationLine=1; relationLine <= linesCnt; relationLine++)
                    {
                        // Check if the relation is with AMDeviceTable.DeviceId
                        if (dictRelation.lineExternTableValue(relationLine) == _fieldId)
                        {
                            c++;
                            info(strFmt("%1 : %2 : %3", c, dictTable.name(), fieldId2Name(tableId, dictRelation.lineTableValue(relationLine))));
                            relationFound = true;
                            break;
                        }
                    }
                }
                // just one relation is enough
                if(relationFound)
                {
                    break;
                }
            }
        }
    }

You can replace tableId and fieldId with your own values. For example, for GroupId table:

internal final class GetRelatedTables
{
    public static void main(Args _args)
    {
        TableId tableId = tableNum(SuppItemGroup);
        FieldId fieldId = fieldNum(SuppItemGroup, GroupId);

        info(strFmt("Searching related tables for %1.%2 ", tableId2Name(tableId), fieldId2Name(tableId, fieldId)));
        GetRelatedTables::findAllTablesWithRelations(tableId, fieldId);
        info('Search completed');
    }
}

The output:

Search completed

7 : AMInventItemTemplate : PurchInventSuppItemGroupId

6 : AMInventItemTemplateStaging : PurchInventSuppItemGroupId

5 : InventTableModule : SuppItemGroupId

4 : SuppItemTable : AccountCode

3 : VendTable : SuppItemGroupId

2 : RetailMassUpdateWorksheetLine : Purch_SuppItemGroupId

1 : CustTable : SuppItemGroupId

Searching related tables for SuppItemGroup.GroupId