0

I have a standard controller from which I get the object. How can I use this in a for loop?

Apex

...
    public ListToStringContact(ApexPages.StandardSetController controller)
    {
        setCon = controller;
        system.debug(setCon);
         obj = setCon.getRecord().getSObjectType();
    }
    public pageReference returnIds() {

      Sobject s = obj.newSobject();

        // do something with the selected records
        for ( s record : (s[])setCon.getSelected())
        {
...
        }
...
  • Is your class intended to be fully generic, or are you operating on a specific type of sObject? – David Reed Jul 2 at 15:35
  • @DavidReed it is intended to be generic – Thomas Jul 2 at 16:11
  • at some point, you will most likely need to cast into lists of concrete sobjects (Account, Opportunity, ...) – cropredy Jul 2 at 16:14
1

If you're intending your class to be fully generic and work with any kind of sObject, you'll need to declare the variables you wish to use as type sObject (or List<sObject>, Map<Id, sObject>, and so on). Your types must be concrete at compile time; in Apex, you can't get a dynamic reference to a type and then declare a variable as that type.

So in returnIds(), you'd do

public pageReference returnIds() {
    // do something with the selected records
    for (sObject record : setCon.getSelected())
    {
    }
}

You don't need to do any casting, because getSelected() already returns a List<sObject>.

As you operate on these values, you'll only be able to use properties and methods defined at the sObject level, like get() and put(). If your sObjects are really Opportunities, you won't be able to do record.CloseDate, but you can access field data with record.get('CloseDate'). Just bear in mind that those dynamic methods return untyped Object values, and you'll have to cast them.

You can, however, directly access the Id member of an sObject-typed variable, as all sObjects have that member.

  • Thanks for your explanation, I got it working – Thomas Jul 2 at 16:46
1

Here is the documentation

There is a method called getRecords() which will return the records for the first page of the set controller.

There is also a method called getHasNext() which will tell you if there is more then 1 page of records.

If you wanted to get all of the records from a given controller, you would do something like this:

List<Opportunity> records = new List<Opportunity>(); 
// Keep in mind that records are returned as SObjects and will need to be cast
// Otherwise, change this list to type SObject and remove the casting below

do {
    records.addAll((List<Opportunity>) setCon.getRecords());
    setCon.next(); // Tell the controller to get the next page.
} while (setCon.getHasNext());

That being said, you generally don't want to do that. In some cases, the number of records could be quite large and this can result in issues with the view state size.

Instead of getRecords you should try getSelected as it will only pull in the records that were selected via check box on the list. This will help keep your page view state under control and allow you to work with the records that you actually care about anyway.

While I'm not entirely proud of the component itself, it may help you learn more about set controllers. This is something I wrote a while back that uses set controllers in a slightly different way to take any given query, convert the results into a set controller and then use the set controller to display the results to a page and allow users to select and operate on records.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.