2

I am developing a Visualforce Page which is for configuring some User Settings. The Requirement is that when the page is saved it should redirect to where the user is able to edit the Settings of the next alphabetical user.

For example lets say all the users in the System are ordered alphabetically by LastName

  1. Kent Brockman
  2. Timothy Lovejoy
  3. Maud Flanders
  4. Frank Grimes
  5. Troy McClure
  6. Homer Simpson
  7. Marge Simpson
  8. Moe Szyslak

If I am editing "Frank Grimes" when I save I should be redirected to "Troy McClure".
If I edit "Moe Szyslak" I should be redirected back to "Kent Brockman"

I know it would be possible to just query every user ordered by LastName and loop through until I find the user after the current one, but this could potentially exhaust my governor limits.

What I am wondering is ther a more efficent way to query the next alphabetical user?

3
  • Could you not just query where LastName > : current limit 1?
    – Matt Lacey
    Jun 28 '13 at 7:20
  • 1
    @LaceySnr you have just made my day! I had no idea the < or > operators could be used on String types. Please write this up as an answer, it will certainly get my vote :) Jun 28 '13 at 7:46
  • Ah well, I was a bit late but there ya go. Gotta love it when you discover something like that!
    – Matt Lacey
    Jun 28 '13 at 12:07
3

I've just experimented with that names. It's realy funny :) So my solution based on the greater-than-or-equal sign. To my surprise the SOQL can perfectly compair "strings" and "Simpson" is realy greater than "Flanders". The only problem is that if you have uses with the same last name. Then we need to use the ID of the curren user in our SOQL query to exclude in the query result:

Select Id, FirstName, LastName
From User
Where LastName >= 'Flanders'
And Id != 'XXXXXXXXXX'
Order By LastName

Where 'Flanders' is the name of the current user and 'Id' is his User-Id.

For more precision (in case you have users with the same last and first names) you can create a new formula field and concatenate the last and first names to be able to compare them as one string in SOQL

Select Id, FirstName, LastName
From User 
Where LastFirstName__c >= 'SimpsonHomer' 
And ID != 'a08E000000TxH1g' 
Order BY LastFirstName__c  
Limit 1 

If you will get a zero result query then it means that you've edited the last of the users and need to get a very first from the list:

Select Id, FirstName, LastName
From User 
Order BY LastFirstName__c  
Limit 1 
1
  • Always good to get a question you've just solved. You know you'll answer it well :) This is a great answer, thanks Jun 28 '13 at 8:03
1

if you are using the same controller and dont setRedirect(true) on the pageReference, you could keep a list of user ids in the context and just us an index to determine the next user id

public class UserSettingsController {

  // id of the user to display
  Id userId;
  // index of the displayed user id
  Integer userAtIndex;
  // user ids sorted by last name   
  Id[] userIds;

  public UserSettingsController(){

     userId = (Id)ApexPages.currentPage().getParameters().get('user_id');

     for (Integer i=0;i<getUserIds();i++)
     {
        if (userIds[i] == userId)
        {
          userAtIndex = i;
          break;
        }
     }

     if (userAtIndex == null)
     {
        // HANDLE CASE WHERE USER COULDNT BE FOUND IN USERIDS
     }
  }

  // handle on save
  public PageReference onSave(){

    // YOUR SAVE LOGIC

    // index of the next userId
    Integer newIndex = userAtIndex <= userIds.size() - 1 ? userAtIndex + 1 : 0

    PageReference pref = new PageReference('--PAGE--');
    pref.getParameters().put('user_id',userIds[newIndex]);

    return pref;
  }

  // return list of user ids sorted by lastname
  Id[] getUserIds(){

    if (userIds == null)
    {
      userIds = new Id[]{};
      userIds.addAll(new Map<Id,User>([select Id from User order by LastName]).keySet());
    }
    return userIds;
  }
}
2
  • Interesting suggestions, but this still doesn't solve the efficiency problem. You've still queried every user in the database in your getUserIds method. Jun 28 '13 at 6:44
  • @DanielBlackhall yes I agree. but you could limit the query to the users with the same letter of the last name and once you finished the set of users you jump to the next letter. takes you an addl. query on initial load and every time you run out of users + an addl. query per letter for which no user exists
    – Seb Wagner
    Jun 28 '13 at 6:56

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.