In your case I would make a wrapper class that holds the info you want. Store the wrapper in the map, and then reference the wrapper.
public map<String, List<WrapperClass>> mapFYToList {get;private set;}
public SDGProgrammeController()
{
mapFYToList = new map<String, List<WrapperClass>>();
for(Site__c r : [SELECT StoreNo__c, Probability__c, Name, JS_Region__c,JS_Zone__c, Address__c, Postcode__c,
(SELECT MeetingDate__c,RecordType.name,Total_Sales_Area_Uplift__c, TU_Sales_Area_Uplift__c, TUSalesAreaPre__c,
TUSalesAreaPost__c, SalesAreaPreExcCO__c, SalesAreaPostExcCO__c, NonFoodSalesAreaUplift__c, NonFoodSalesAreaPre__c,
NonFoodSalesAreaPost__c, GMSalesAreaUplift__c, GMSalesAreaPre__c, GMSalesAreaPost__c, FoodSalesAreaUplift__c,
FoodSalesAreaPre__c, FoodSalesAreaPost__c
FROM Financial__r
WHERE MeetingDate__c != null AND Recordtype.Name IN('CCM','CCM Update','IB')
ORDER BY MeetingDate__c desc
LIMIT 1),
(SELECT Launch_date__c,Start_On_Site__c, Status__c,Store__c,ProjectName__c,Investment_Type__c,ProjectManager__c,
MainContractor__c,RetailHandover__c,Closure__c,Launch_FY__c,Launch_Period__c, Launch_Quarter__c
FROM Investment_Programs__r
WHERE Status__c IN('Live','Feasibility','Completed') AND RecordType.Name ='New Store' )
FROM Site__c
WHERE Recordtype.name = 'Supermarket' AND Probability__c IN('Open','Certain','Possible','Probable')
AND Id IN(SELECT Site__c FROM Financial__c WHERE MeetingDate__c != null AND Recordtype.Name IN('CCM','CCM Update','IB'))
AND Id IN(SELECT Site__c FROM InvestmentProgram__c WHERE Status__c IN('Live','Feasibility','Completed') AND RecordType.Name ='New Store')
ORDER BY Launch_Date__c asc LIMIT 999])
{
if(mapFYToList.get(r.Investment_Programs__r[0].Launch_FY__c) == null)
{
mapFyToList.put(r.Investment_Programs__r[0].Launch_FY__c, new List<WrapperClass>{new WrapperClass(r)};
}
else
{
mapFyToList.get(r.Investment_Programs__r[0].Launch_FY__c).add(new WrapperClass(r));
}
system.debug(mapFyToList);
}
}
public List<String> getKeys()
{
List<String> keys = new List<String>();
keys.AddAll(mapFYToList.KeySet());
keys.sort();
return keys;
}
public class WrapperClass
{
String name {get; set;}
String postCode {get; set;}
Stirng status {get; set;}
Integer probability {get; set;}
public WrapperClass(Site__c site)
{
name = site.Name;
postCode = site.Postcode__c;
status = site.Investment_Programs__r[0].Status__c;
probability = site.Probability__c;
}
}
}
And then in your VF Page
<apex:repeat value="{!keys}" var="fy">
<apex:pageBlockTable value="{!mapFYToList[fy]}" var="obj">
<apex:column value="{!obj.name}"/>
<apex:column value="{!obj.postCode}"/>
<apex:column value="{!obj.status}"/>
<apex:column value="{!obj.probability}"/>
</apex:pageBLockTable>
</apex:repeat>
I was able to get a very similar to piece of code to yours to work - but I found that I couldn't even compile the page using outputField
- You should only use outputField
for values that are directly tied to a sObject value.
Change to outputText
and also verify that wrapRec.T_Price__c
is in fact a number value.
Failing that, try wrapping the value to be added in a VALUE()
function.
EDIT Here is the code I used. I used a list of accounts in the controller.
<apex:pageBlock >
<apex:pageBlockSection columns="1" collapsible="false" >
<apex:pageBlockTable value="{!acctWrapper}" var="acct">
<apex:column value="{!acct.acctId}"/>
<apex:column value="{!acct.name}"/>
<apex:column >
<apex:variable var="total1" value="{!total1 + acct.num}" />
<apex:outputText value="{!total1}" />
</apex:column>
<apex:column >
<apex:variable var="total2" value="{!total2 + acct.num}" />
<apex:outputText value="{!total2}" />
</apex:column>
</apex:pageBlockTable>
</apex:pageBlockSection>
</apex:pageBlock>
Here is the wrapper code:
public class Wrapper {
public String name {get; set;}
public Id acctId {get; set;}
public Integer num {get; set;}
public Wrapper(String name, Id acctId, Integer num) {
this.name = name;
this.acctId = acctId;
this.num = num;
}
}
And here is where I build the wrapper list:
//defined at top of class
public Wrapper[] acctWrapper {get; set;}
accounts = [SELECT Name, Id From Account LIMIT 20];
acctWrapper = new Wrapper[]{};
Integer count = 0;
for (Account a : accounts){
acctWrapper.add(new Wrapper(a.Name, a.Id, count));
count+=1;
}
Best Answer
Wrapping the
ROUND()
output within aTEXT()
is what you need here.+
in this context expects appending two string values whereasROUND()
returns a number and thus the error.