function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Starz26Starz26 

A Pattern for Obtaining all record in a Hierarchy

Greetings,

 

I wrote this little loop while trying to get a list of ALL accounts within a Hierachy regardless of there in the hierachy you start from.

 

For example

A

-----b

-----------b1

-----c

-----------c1

---------------c1.2

-----d

 

So if I start at b1, it will return all accounts up to A and back down thus including c1.2 as well.

 

Maybe someone will find it useful. You could refactor it to work with roles or only go up 1 level to find parent and siblings, etc...

 

 

Account theAccount = //Your SOQL Here
Set<ID> AllParents = new Set<ID>();
Boolean allDone;

AllParents.add(theAccount.ID);
      //If the account we are starting at has a Parent ID, add it
      //to the set of IDs
      if(theAccount.ParentID != Null){
        AllParents.add(theAccount.ParentID);
      }
      
      //Main loop to traverse through the Hierarchy
      do{
         //Set the flag to indicate loop should stop
         allDone = true;
        //Get a list of accounts with IDs or Parent IDs in the AllParents Set
        //This will produce 1 SOQL for each level in the Hierachy 
        //Max is then 99 levels deep which I believe no one will  have
        //You could add a check though
        for(Account a : [Select ID, ParentID From Account Where ID IN :AllParents OR ParentID IN :AllParents]){

          if(!AllParents.contains(a.ID) || ( !AllParents.contains(a.parentID) && a.parentID != null)){

            if(a.parentID != null)
              AllParents.add(a.parentID);

            AllParents.add(a.id);
            //Reset flag to find more parents / children
            allDone = false;

          }
          
        }
        
      } while(allDone == false); 
     

 

Marcelo CostaMarcelo Costa

Hi Starz26!

Thank you for your contribution. Have some suggestions for you though...

 1) Always use {} to deliniate blocks. It helps SO MUCH when we are reading the code...
 2) the soql inside the do while might be a bomb. You mentioned that the max is 99 lvls deep... this is probably because of the 101 SOQL in one execution context... You just have to remember that it probably more things are going to happen in the same context. You have triggers, flows, LWCs and all sort of components that will call methods... this might be a real bomb...

I have developed a similar solution with a completely different approach. The accounts that might have parents had their own record type (around 500 of them), and I would query for those accounts, and set up the hierarchy from there... this way, I only used one SOQL query.
3) The logic is a little bit confusing even with the comments. Some focus on naming conventions is appreciated too :)
Good Luck and Thanks...