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
Roger WickiRoger Wicki 

visualforce controller for loop

Dear Community

I have struggles with a certain part of my visualforce controller. As far as I know there is no reason why after a loop execution should cause the data to be nilled or made inaccessible. But that's exactly what happens as far as I can see. below is the code snippet which iterates over a custom date format (yyyyMM) as Integer and within over a list of Opportunities to compare the dates.
opps = [ SELECT Close_Date_Month__c, CloseDateYear__c, Account.Name, CloseDate, RenewalDate__c, Name FROM Opportunity
              WHERE RenewalDate__c >= :dateFrom AND CloseDate <= :dateTo AND (StageName LIKE '%yes%' OR StageName LIKE '%Closed%') AND Account.Type LIKE '%Manufacturer%' ];
map<String, map<Integer, set<String>>> aMap = new map<String, map<Integer, set<String>>>();

for ( Integer i = getMonthYear(dateFrom); i <= getMonthYear(dateTo); i = getNextMonthYear(i) )
{
   ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.WARNING, 'YearMonth processed: ' + i));
   for ( Opportunity o : opps )
   {
      ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.WARNING, 'Opp processed: ' + o.Name));
      if ( getMonthYear(o.CloseDate) <= i && getMonthYear(o.RenewalDate__c) >= i )
      {
         ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.WARNING, 'Close Date: ' + getMonthYear(o.CloseDate)));
         ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.WARNING, 'Renewal Date: ' + getMonthYear(o.RenewalDate__c)));
         String s = getStringDate(i);
// Logic
       }
    }
}
I filled the code with ApexPage Message Warnings so as to see what happens. Here is the result:
User-added image
User-added image
The "Opp processed" message appears only once even though it should appear once per Opportunity (there are 4) per date (i). Close Date & Renewal Date outputs are correct where they appear, but they should appear much more often.

Here are my functions used to get the formats:
// Extracts the year out of the integer of format yyyyMM
private static Integer getYear(Integer i)
{
    return (Integer)i/100;
}

// Transforms a date into an integer representation of yyyyMM
private static Integer getMonthYear(Date d)
{
    return d.Year()*100 + d.Month();
}

// Returns the next month of the Integer representation yyyyMM
private static Integer getNextMonthYear(Integer i)
{
    return Math.mod(i, 100) == 12 ? i + 89 : i + 1;
}

// Returns a 3-character representation of a date Integer yyyyMM
private static String getStringDate(Integer i)
{
    map<Integer, String> mapping = new map<Integer, String>
    {
        1 => 'JAN',
        2 => 'FEB',
        3 => 'MAR',
        4 => 'APR',
        5 => 'MAY',
        6 => 'JUN',
        7 => 'JUL',
        8 => 'AUG',
        9 => 'SEP',
       10 => 'OCT',
       11 => 'NOV',
       12 => 'DEC'
    };
    System.assert(Math.mod(i, 100) >= 1 && Math.mod(i, 100) <= 12);
    return mapping.get(Math.mod(i, 100));
}

Do you have any insights on that strange behaviour?

Best
Best Answer chosen by Roger Wicki
AbdelhakimAbdelhakim
Hi,

I think its because you try to send the same message
this function "ApexPages.addMessage", check if its the same message, and try to not display it twice.

it better to put the result in string varial and print it when its done

All Answers

AbdelhakimAbdelhakim
Hi,

I think its because you try to send the same message
this function "ApexPages.addMessage", check if its the same message, and try to not display it twice.

it better to put the result in string varial and print it when its done
This was selected as the best answer
Roger WickiRoger Wicki
Hi Abdelhakim

Thanks for that input. I tested replacing the messages with a string debug as porposed and indeed it appears to show them the right way now. So I can use it for debugging.

Thanks