With the upcoming release of Salesforce imminent for 2022, we will see the deprecation of API versions 7 through version 30. Now you can do a few things, you can check your Setup -> Apex Classes and sort by API version to see which ones are going to be out of date. This only shows you part of the problem. The other issue is Triggers. You also need to check them as well. And how about creating a report? How are you going to do that? Well fortunately we have Anonymous Apex. We can use the Execute Anonymous window to Execute statements and get results. Let’s look at what we have to do with the Apex Classes.

Internal to Salesforce is the ApexClass Object. This object contains all the information about the Apex code in your organization. So to extract what we need we just query the ApexClass Object using SOQL like so:

SELECT Id, ApiVersion, Name, NamespacePrefix FROM ApexClass WHERE Status='Active'

This will do several things, it will return a list of ALL the Apex classes that are active and it will include the NamespcePrefix. Why is the NamespacePrefix important? Because any value (generally speaking) in this column will represent a package vs internal code. So now we have the list, let’s think about how we further refine it. We only want classes below API version 31, but the ApiVersion field is a text and converting a text inline in SOQL to an integer won’t work… so lets just use the IN clause.

Now at this point if we are going to use the IN clause that means we’d need to create the list of ApiVersions … we could do this manually OR we could cheat and use Anonymous Apex. By outputting the list in a System.Debug() message we’d have our list of API versions.

Set setOfVersions = new Set();
for( Integer i = 7; i < 31; i++ )
{
// convert to string, put in list of versions to check
setOfVersions.add( Decimal.valueOf(i) );
}
System.debug('===> list:' + setOfVersions);

Once the versions are done running we can simply copy the list from the Debug Log. We can then append that to the SOQL query using the WHERE ApiVersion IN (list) like so:

SELECT Id, ApiVersion, Name, NamespacePrefix FROM ApexClass WHERE Status='Active' AND ApiVersion IN('7','8','9'...'30');

Thus the query will not return all classes that are version 30 or below.

Next we simply repeat the process with the other Object ApexTrigger.

SELECT Id, ApiVersion, Name, NamespacePrefix FROM ApexTrigger WHERE Status='Active' AND ApiVersion IN('7','8','9'...'30');

This will now give us both Apex Classes and Triggers of version 30 and below. It should be noted that while you can see all of this in the Salesforce.com UI you would need to filter and you have no way of creating a report for Management (short of cut & paste).

So now let’s revisit one of my earlier posts which explained how to create a CSV file and save it to your instance. By using Execute Anonymous AND my prior example code to create a CSV file we can create an Excel file which contains a list of all Apex Classes and Triggers of version 30 and below.

Set setOfVersions = new Set();
for( Integer i = 7; i < 31; i++ )
{
// convert to string, put in list of versions to check
setOfVersions.add( Decimal.valueOf(i) );
}

List listOfClasses = [
SELECT Id, ApiVersion, Name, NamespacePrefix
FROM ApexClass
WHERE Status='Active'
AND ApiVersion IN :setOfVersions
];

// Create a CSV File
String csv = 'Id,ApiVersion,Name,Type,Name Space\n';
for( ApexClass a : listOfClasses )
{
System.debug('Class ==> ' + a.Name + ' : ' + a.ApiVersion);
csv += a.id + ',' + a.ApiVersion + ',' + a.name.escapeCsv() + ', Class, ' + a.NamespacePrefix + '\n';
}
System.debug('===> Total Classes : ' + listOfClasses.size());

List listOfTriggers = [

SELECT Id, ApiVersion, Name, NamespacePrefix

FROM ApexTrigger

WHERE Status='Active'

AND ApiVersion IN :setOfVersions
];

for( ApexTrigger t : listOfTriggers )
{
System.debug('Trigger ==> ' + t.Name + ' : ' + t.ApiVersion);
csv += t.id + ',' + t.ApiVersion + ',' + t.name.escapeCsv() + ', Trigger, ' + t.NamespacePrefix + '\n';
}

System.debug('===> Total Triggers : ' + listOfTriggers.size());

ContentVersion file = new ContentVersion(title = ‘ApexClassesAndTriggersBelowV30.csv’,
versionData = Blob.valueOf( csv ),
pathOnClient = '/ApexClassesAndTriggersBelowV30.csv');

insert file;
System.debu
g(‘===> Content URL : /’ + file.Id);

And just like that … you have a list of all classes and triggers needing to be updated and you can download it and using Excel filter and do other things with the list. Enjoy!

[contact-form]