web
You’re offline. This is a read only version of the page.
close
Skip to main content
Community site session details

Community site session details

Session Id :
Microsoft Dynamics AX (Archived)

code to find relation to a table

(0) ShareShare
ReportReport
Posted on by 182

Hi Sir,

I am new to AX development. I want to write a job that checks any given table's relation with another specified table( in my case HCM Worker). I have tried the following code:

static void IndirectRelation(Args _args)
{
DictTable dictTable;
DictRelation dictRelation;
DictField Field;
DictField RelatedField;
int RelationIndex = 1;

str relationName;
int relationCnt;
int cnt;
int linesCnt;
int cnt2;
str externFieldName;
str fieldName;
str tab,exttab,tab1,exttab1,x,table;
;
dictTable = new DictTable(tableNum(HcmEmploymentDetail));
dictRelation = new DictRelation(tableNum(HcmEmploymentDetail));
dictRelation.loadTableRelation(tableNum(HcmWorker));
info(strFmt("%1", tableId2name(dictRelation.externTable())));
x=tableId2name(dictRelation.externTable());

if(dictRelation.externTable() != 0)

{
Field = new DictField(tableNum(HcmEmploymentDetail), dictRelation.lineTableValue(RelationIndex));
RelatedField = new DictField(tableNum(HcmWorker), dictRelation.lineExternTableValue(RelationIndex));
table = tableId2name(dictRelation.table());
info("RELATION FOUND");
info(strFmt("%1.%2==%3.%4",table,Field.name(),x,RelatedField.name()));
}
else
{


relationCnt = dictTable.relationCnt();
for(cnt = 1; cnt <= relationCnt; cnt++)
{
if(x=="HcmWorker")
{
break;
}
relationName = dictTable.relation(cnt);
info(relationName);
dictRelation.loadNameRelation(relationName);

linesCnt = dictRelation.lines();
for(cnt2 = 1; cnt2 <= linesCnt; cnt2++)
{
externFieldName = fieldId2Name(dictRelation.externTable(),dictRelation.lineExternTableValue(cnt2));
fieldName = fieldId2Name(dictRelation.table(),dictRelation.lineTableValue(cnt2));
tab = tableId2Name(dictRelation.table());
exttab = tableId2Name(dictRelation.externTable());
info(strfmt("%1.%2 = %3.%4",tab,fieldName,exttab,externFieldName));

//>>Checking direct relation
dictTable = new DictTable(tableName2Id(exttab));
dictRelation = new DictRelation(tableName2Id(exttab));
dictRelation.loadTableRelation(tableNum(HcmWorker));
x=tableId2name(dictRelation.externTable());

if(dictRelation.externTable() != 0)
{
Field = new DictField(tableNum(HcmEmploymentDetail), dictRelation.lineTableValue(RelationIndex));
RelatedField = new DictField(tableNum(HcmWorker), dictRelation.lineExternTableValue(RelationIndex));
table = tableId2name(dictRelation.table());
info("RELATION FOUND");
info(strFmt("%1.%2==%3.%4",table,Field.name(),x,RelatedField.name()));
break;
}
else
{
relationCnt = dictTable.relationCnt();
for(cnt = 1; cnt <= relationCnt; cnt++)
{
relationName = dictTable.relation(cnt);
info(relationName);
dictRelation.loadNameRelation(relationName);

linesCnt = dictRelation.lines();
for(cnt2 = 1; cnt2 <= linesCnt; cnt2++)
{
externFieldName = fieldId2Name(dictRelation.externTable(),dictRelation.lineExternTableValue(cnt2));
fieldName = fieldId2Name(dictRelation.table(),dictRelation.lineTableValue(cnt2));
tab1 = tableId2Name(dictRelation.table());
exttab1 = tableId2Name(dictRelation.externTable());
info(strfmt("%1.%2 = %3.%4",tab1,fieldName,exttab1,externFieldName));
}
}
}
}

}
}

}

The problem with this code is that it is not looping properly. It will check relation of first table and it takes the first relation and displays all the relation of the second loop. But am not able to do recursive looping. Please help me with it.

Thank you

*This post is locked for comments

I have the same question (0)
  • Community Member Profile Picture
    on at
    RE: code to find relation to a table

    I don't understand

    Please rewrite solution step by step again.

    I am basic AX2012 Dev.

    Thank you _/\_

  • Martin Dráb Profile Picture
    236,160 Most Valuable Professional on at
    RE: code to find relation to a table

    RecId is a unique identification of a record - and a full record (all fields) is better than just a single string value such as worker name. But RecId are you talking about? "Some recId" doens't say where you get it nor what table it refers to. If it's a reference to a worker, you can easily find not only the name, but all attributes of the worker.

    Nevertheless I would expect you to look at SysDatabaseLog.CreatedBy.

  • Maverick Profile Picture
    182 on at
    RE: code to find relation to a table

    Hi Andre,

    I have already setup the database log function. But i want to add a little customization to that because if anybody changes the employee details like attendance or salary, it is not showing the worker name who have changed it, instead it shows some recId.

    Thank you,

    Pavan

  • Community Member Profile Picture
    on at
    RE: code to find relation to a table

    Is what you're doing one of these tools to find the relationship tables ?

    My example :

    Human-Resources.png

    Relations in Human Resources:

    Human-Resources.png

    good sucessful !

  • André Arnaud de Calavon Profile Picture
    298,570 Super User 2025 Season 2 on at
    RE: code to find relation to a table

    Hi Maverick,

    Can you explain "any changes to any details". The real requirement is not clear. If e.g. a timesheet has a relation to the worker table as the timesheet is created for a worker, this is not necessarily the person who changed any details. If it the worker that will be registered for the hour postings.

    What details needs to be audited? There is a database log function which can log the details changed for tables maintained in the Database log setup. It can then log what fields had been changed with the corresponding user ID of the worker.

    Forget a minute the coding and development part. Explain the requirement functionally.

  • Hariharans87 Profile Picture
    3 on at
    RE: code to find relation to a table

    "When there is direct relation to the HCMWorker,it will show the name, but when there is no direct relation, it is returning only recid."

    How you came to know that which record/field is created/modified?

    Because, i am sure that all tables are not enabled createdby, createddatetime, modifiedby and modifieddatetime fields.

  • Martin Dráb Profile Picture
    236,160 Most Valuable Professional on at
    RE: code to find relation to a table

    If you want a recursive function, create one. Your method isn't recursive, therefore it doesn't meet your own requirements. To be clear, a recursive function is a function calling itself (in this case, you would find related tables for a given table and call the function again for each of them, to process the whole tree), which you don't do in your code at all.

  • Maverick Profile Picture
    182 on at
    RE: code to find relation to a table

    Hi Martin,

    Sorry for not making my point clear.

    I want to write a recursive function, that checks a table's relation with HCMWorker table.

    There are some tables which have direct relation with HCMWorker, some tables that having indirect relations with 3 or 4 hirarchies and some tables that do not have any relation with HCMWorker.

    So what my need is that, I want to check whether a given table is having any sort of relation with HCMWorker. If there is no relation at all, it should show No Relation.

    PS:   Why am using this is, we are developing an audit report  which shows the name of the worker  that  has made any changes to any details.  When there is direct relation to the HCMWorker,it will show the name, but when there is no direct relation, it is returning only recid. So I want to check a given table's relation hirarchy with HCMWorker and follow it to find the worker name from the HCMWorker table.

    Hope this is made my point clear.

    Thanks in advance

  • Community Member Profile Picture
    on at
    RE: code to find relation to a table

    Hi Maverick ! you try the following code if you find a bug, please tell me if you succeed provision should tell me:

    Step 1: Create new  1 form in form have 2 Edit String , 1 Button and 1 GridView in Grid have 3 EditString. create new  a table regular, a table TempBP.

    Step 2: Insert all tables name in your table have create in step 1. Create 1 new Jobs and code.

    static void ListOfTables(Args _args)
    {
    UtilElements localEelmet;
    UtilEntryLevel LayerName = UtilEntryLevel::sys;
    TreeNode treeNode;
    BSDQueryRelation_Thanh _BSDQueryRelation_Thanh;
    //int CountTable =0 ;

    ;
    while select localEelmet
    where localEelmet.utilLevel == LayerName
    && localEelmet.recordType == UtilElementType::Table
    {

    // CountTable++;
    treeNode = xUtilElements::getNodeInTree(xUtilElements::parentElement(localEelmet));
    delete_from _BSDQueryRelation_Thanh;
    _BSDQueryRelation_Thanh.NameTable = localEelmet.name;
    _BSDQueryRelation_Thanh.insert();

    //info(strFmt("TableId: %1 ; Name: %2, %3",localEelmet.TableId,localEelmet.name, CountTable));

    }
    }

    Step 3: Code of Form program:

    class Declaration:

    public class FormRun extends ObjectRun

    {

       container allrelationTrace;

    }

    Query Relation method:

    public container QueryRelation(TableId _SourceTableId,TableId _TargetId)

    {

       int relationId, id, ccount ;

       int relationCnt;

       container relationTrace, allrelationtrace2;

       str name;

       str nameTableSource,nameTableTarget;

       SysDictTable dictTable;

       SysDictRelation dictRelation;

       nameTableSource = tableId2name(_SourceTableId);

       nameTableTarget = tableId2name(_TargetId);

       if(_SourceTableId ==_TargetId)

       {

           return [_TargetId];

       }

       dictTable = new DictTable(_SourceTableId);

       dictRelation = new DictRelation (_SourceTableId);

       relationCnt= dictTable.relationCnt();

               // vong lap kiem tra quan he cua Source Table

           for(relationId = 1; relationId <= relationCnt; relationId++)

               {

                   dictRelation.loadNameRelation(dictTable.relation(relationId));

                   if(dictRelation.externTable() == _TargetId)

                   {

                       relationTrace = conIns(relationTrace, conLen(relationTrace)+1,tableId2name(dictRelation.externTable()));

                       return relationTrace;

                   }

               }

           // vong lap chay tung quan he cua table Source

           for(relationId = 1; relationId <= relationCnt; relationId++)

               {

                   dictRelation.loadNameRelation(dictTable.relation(relationId));

                   // vong lap kiem tra cac quan he hien tai dang di qua ( tranh bi lap lai khi quan he xoay vong)

                       for(id =1; id <= conLen(allrelationTrace); id++)

                       {

                           name =tableId2name(dictRelation.externTable());

                           if(conPeek(allrelationTrace,id) == name)

                           {

                               ccount =1;

                               break;

                           }

                        }

                   allrelationtrace2 = conIns(allrelationtrace2, conLen(allrelationtrace2)+1,tableId2name(_SourceTableId));

                   // vonh lap kiem tra tat ca cac quan he di qua ma khong co ket qua tra ve ( tranh trung lap cac quan he ko co ket qua)

                       for(id =1; id <= conLen(allrelationtrace2); id++)

                       {

                           name =tableId2name(dictRelation.externTable());

                           if(conPeek(allrelationtrace2,id) == name)

                           {

                               ccount =1;

                               break;

                           }

                        }

                   // neu 2 dieu kien ben tren thoa man thi cho phep thuc thi vong lap de quy

                   if(ccount < 1 && _SourceTableId != dictRelation.externTable())

                       {

                           ccount=0;

                           allrelationtrace2 = conNull();

                           relationTrace = this.QueryRelation(dictRelation.externTable(),_TargetId);

                           if(relationTrace)

                           {

                               relationTrace = conIns(relationTrace, conLen(relationTrace)+1,tableId2name(dictRelation.externTable()));

                               return relationTrace;

                           }

                           else

                           {

                               allrelationTrace = conIns(allrelationTrace, conLen(allrelationTrace)+1,tableId2name(_SourceTableId));

                           }

                       }

                }

    return relationTrace ;

    }

    Write code action Click of Button:

    void clicked()

    {

       container conquery, conquery2 ;

       int i, j;

       SysDictTable dictTable;

       SysDictRelation dictRelation;

       int relationCnt;

       str name ;

       super();

       allrelationTrace = conNull();

        dictTable = new DictTable(tableName2id(txtSourceTable.valueStr()));

        dictRelation = new DictRelation (tableName2id(txtSourceTable.valueStr()));

        relationCnt= dictTable.relationCnt();

       for (j =1 ; j < relationCnt; j++)

       {

           if(j==1)

           {

              dictRelation.loadNameRelation(dictTable.relation(j));

              conquery = element.QueryRelation(tableName2id(txtSourceTable.valueStr())

                               ,tableName2id(txtTargetTable.valueStr()));

           }

           else

           {

              dictRelation.loadNameRelation(dictTable.relation(j-1));

              conquery = element.QueryRelation(dictRelation.externTable()

                               ,tableName2id(txtTargetTable.valueStr()));

               if(conLen(conquery) > 0)

               {

                   conquery = conIns(conquery,conLen(conquery)+1,tableId2name(dictRelation.externTable()));

               }

           }

           conquery2 = conIns(conquery2,conLen(conquery2)+1,conquery);

           conquery= conNull();

       }

       delete_from BsdRalationTable_Thanh;

       for (i = 1;i <= conLen(conquery2); i++)

       {

           conquery = conPeek(conquery2,i);

           BsdRalationTable_Thanh.clear();

           BsdRalationTable_Thanh.TableTargetName = txtTargetTable.valueStr();

           BsdRalationTable_Thanh.TableSourceName = txtSourceTable.valueStr();

           name ="--> ";

               for (j=conLen(conquery);j >1; j--)

               {

                       if(typeOf(conPeek(conquery,j)) == Types::Integer)

                            name +=int2str(conPeek(conquery,j)) +" --> ";

                       else

                            name +=conPeek(conquery,j) +" --> ";

                }

         if(conLen(conquery) >0)

          {

               BsdRalationTable_Thanh.TableRelationName = name;

               BsdRalationTable_Thanh.insert();

           }

                       BsdRalationTable_Thanh_DS.refresh();

               BsdRalationTable_Thanh_DS.research();

               name = "";

       }

    }

    Code lookup for 2 StringEdit:

    public void lookup()

    {

       Query query = new Query();

       QueryBuildDataSource queryBuildDataSource;

       QueryBuildRange queryBuildRange;

       SysTableLookup sysTableLookup = SysTableLookup::newParameters(tableNum(BSDQueryRelation_Thanh), this);

       sysTableLookup.addLookupField(fieldNum(BSDQueryRelation_Thanh,NameTable));

       queryBuildDataSource = query.addDataSource(tableNum(BSDQueryRelation_Thanh));

      // queryBuildDataSource.addGroupByField(fieldNum(BSDQueryRelation_Thanh,NameTable));

       sysTableLookup.parmQuery(query);

       sysTableLookup.performFormLookup();

       super();

    }

    Good luck ! replay for me, please !

  • Martin Dráb Profile Picture
    236,160 Most Valuable Professional on at
    RE: code to find relation to a table

    Please explain what you're intended to develop, instead of just showing code that doesn't do what you want. I don't understand what recursive looping are you talking about.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Andrés Arias – Community Spotlight

We are honored to recognize Andrés Arias as our Community Spotlight honoree for…

Leaderboard > 🔒一 Microsoft Dynamics AX (Archived)

#1
Martin Dráb Profile Picture

Martin Dráb 2 Most Valuable Professional

#1
Guy Terry Profile Picture

Guy Terry 2 Moderator

#1
Rahul Shah Profile Picture

Rahul Shah 2

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans