Monday, November 1, 2021

Move Reports from one folder to another using Apex

In many cases, moving reports from one folder to another was a problem that we faced at least once and resorted to manual modifications as the approaches available to do this are very limited and have high limitations.  Same applies for deleting a report too.

It is possible to move reports from one folder to another by using some migration tools. However, we will not cover those approaches in this post, since using migration tool requires lot of manual intervention to perform retrieval and deployment.  

Before we start with our process, we need to have the below mentioned two classes created in your org 

Let's understand by taking an example.  In my org, there are two reports
  • Report "Numeric Methods" in Folder "Economics" and 
  • Report "Quant" in Folder "Commerce".  

Now let's try to move both of the reports into folder "Aptitude".   Point to remember here is we need to make use of the the Full API Name of the report (i.e., Folder Developer Name + '/'+ Report Developer Name) to make use of it in apex.

Folder Developer Name can be fetched with the below SOQL
SELECT Id, DeveloperName FROM Folder

Report DeveleloperName can be fetched with the below SOQL
SELECT Id, Name, DeveloperName FROM Report

For the above mentioned reports, this is how the full name looks like
  • Commerce/Quant
  • Economics/Numeric_Methods
Execute the below logic in anonymous block of Dev Console and this will move the two reports mentioned into folder "Aptitude".

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
//Below variable to hold the list of Reports to be moved
List<String> lstStrRepNames = new List<String>();
lstStrRepNames.add('Commerce/Quant');
lstStrRepNames.add('Economics/Numeric_Methods');

//Below variable to hold the Developer Name of target Folder
String strTargetFolder = 'Aptitude';

MetadataService.MetadataPort service = new MetadataService.MetadataPort();
service.SessionHeader = new MetadataService.SessionHeader_element();
service.SessionHeader.sessionId = UserInfo.getSessionId();

List<MetadataService.Report> reportsToUpdate = (List<MetadataService.Report>) service.readMetadata('Report', lstStrRepNames).getRecords();
for(MetadataService.Report objRep : reportsToUpdate){
    //In full name replace source folder with targetFolder by using '/' as seperator
    objRep.fullName = objRep.fullName.replace(objRep.fullName.substringBeforeLast('/'), strTargetFolder);
}
List<MetadataService.SaveResult> results = service.updateMetadata(reportsToUpdate);

Now coming to the process of deleting reports, let's try to delete the reports which we just moved to the folder "Aptitude".  The developer names are like below
  • Aptitude/Quant
  • Aptitude/Numeric_Methods
Execute the below logic in Anonymous Block and that will do the job of deleting them.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
//Below variable to hold the list of Reports to be deleted
List<String> lstStrRepNames = new List<String>();
lstStrRepNames.add('Aptitude/Quant');
lstStrRepNames.add('Aptitude/Numeric_Methods');

MetadataService.MetadataPort service = new MetadataService.MetadataPort();
service.SessionHeader = new MetadataService.SessionHeader_element();
service.SessionHeader.sessionId = UserInfo.getSessionId();

List<MetadataService.DeleteResult> results = service.deleteMetadata('Report', lstStrRepNames);


For demonstration purpose, I wrote the core-logic.  To keep it generic enough, you may have to write the logic written in an apex method with parameters and enhance it as per your requirement.

PS : Keep in your thoughts that, above logic cannot process more than 10 records in a single transaction.  So if the count is greater than 10, batch apex has to be leveraged to achieve the same

Hope this helps.  

..Bazingaa..

No comments:

Post a Comment