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
Joe HayesJoe Hayes 

Missing variable in controller and recursion problem

Hi,

I am struggling with a button on a custom object called Certification_Candidate__c that collates various information and displays a vf page, rendered as pdf and then saves it as an attachment on the record.

At the moment I am getting an error in the controller Variable does not exist: Centre_Number__c at line 17 column 140
Centre_Number__c is a custom field within the accredited centre object and has a master relationship with Certification_Candidate__c so I am unsure why it cannot be seen with the SOQL.

I am also having a problem with recursion, when the vf page is loaded and the SavePDF() method is actioned it saves 5 copies to the record.
I guess what is happening is that the pdf.getContent() is calling another instance of SavePDF() and therefore it recurs.

Please can someone have a look down the code and give me some pointers where I am going wrong?

I don't write apex often enough so everytime I come to a project I have to re-learn a lot of stuff to jog my memory. It is very frustrating, I would love to out source some of the more advanced pieces but I dont think that will be the case unfortunately.

VF Page
<apex:page standardController="Certification_Candidate__c" extensions="AssessmentTableController" showHeader="false" applyHtmlTag="false" applyBodyTag="false" renderAs="pdf" action="{!SavePDF}">
<html>
<head>
<style type="text/css" media="print">
     ...various css...
</style>
</head>

<body style="font-size:12px">
<div class="header">
   <p style="font-weight:bold; text-align:center; font-size:16px">
   title
   </p>
   <apex:panelGrid columns="2" style="width:567px; font-size:16px; margin: auto,auto;">
   <apex:outputText value="Forename(s): {!Certification_Candidate__c.Forename__c}"/>
   <apex:outputText value="Surname: {!Certification_Candidate__c.Surname__c}"/>
   <apex:outputText value="Date of Birth: {!Certification_Candidate__c.Date_of_Birth__c}"/>
   <apex:outputText value="NI Number: {!Certification_Candidate__c.NI_Number__c}"/>
   </apex:panelGrid>
   </div>
                       
   <div class="footer">                      
<apex:panelGrid columns="2" width="568px" style="margin: 0px auto; font-weight:normal">
  <apex:outputText value="Date of Issue: {0, date, dd/MM/yyyy}"><apex:param value="{!NOW()}"/></apex:outputText>
    <apex:outputText value="Certificate Number: {0, date, YY}/{!Certification_Candidate__c.Accredited_Centre__r.Centre_Number__c}/{!certnum}"><apex:param value="{!NOW()}"/></apex:outputText>
</apex:panelGrid>
<apex:panelGrid columns="1" width="567px" style="margin: auto auto">
<apex:outputText value="text"/>
</apex:panelGrid>
<apex:panelGrid columns="2" width="567px" style="margin: auto auto; font-weight:normal">
  <apex:image value="https://c.eu1.content.force.com/servlet/servlet.FileDownload?file=015D00000048ZMN" alt="alt text" width="100px"/>
      <apex:outputText value=""/>
  <apex:outputtext value="text"/>
  <apex:outputtext value="text"/>
</apex:panelGrid>
<br/><br/>
<table style="font-size:8px;">
<tr>
<td width="60%"><apex:outputText value="text"/><br/><apex:outputText value="text"/><br/><apex:outputText value="tel:"/><br/><br/><br/><apex:outputtext value="address:"/><br/><apex:outputtext value="trading name"/>
</td>
<td width="30%"><apex:outputText value="text"/>
</td>
<td width="10%"><apex:image value="https://c.eu1.content.force.com/servlet/servlet.FileDownload?file=015D00000048ZMO" alt="text" width="50px"/>
</td>
</tr>
</table>
</div>

<div class="content">
<apex:dataTable value="{!AsstList}" var="item" border="0" cellpadding="5" cellspacing="1" width="567px" style="margin: auto auto;">

<apex:column width="20%" headerValue="Code">
<apex:outputText value="{!item.CodeTEXT__c}">
</apex:outputText>
</apex:column>

<apex:column width="60%" headerValue="Description">
<apex:outputText value="{!item.Description__c}">
</apex:outputText>
</apex:column>

<apex:column width="20%" headerValue="Expiry Date">
<apex:outputText value="{0, date, dd/MM/yyyy}">
       <apex:param value="{!item.Expiry_Date__c}" />
       </apex:outputText>
</apex:column>
</apex:dataTable>
</div>

</body>
</html>
</apex:page>

Controller
public class AssessmentTableController {
    public List <Assessment__c> asstList {get;set;}
    public String certnum;
    public String candid {get;set;}
    public String centnum;
    
    public AssessmentTableController(ApexPages.StandardController controller){
        Id candid = ApexPages.currentPage().getParameters().get('Id');
        asstList = new List<Assessment__c>();
        asstList = [select Candidate__c,codeTEXT__c,Expiry_Date__c, Description__c from Assessment__c where Expiry_Date__c > today and Candidate__r.id=:candid order by codeTEXT__c desc];

        certnum = [SELECT Description__c from Asstcodes__c WHERE name =: 'CertificateNumber' limit 1].Description__c;
    }
    
    public PageReference savePdf() {
    
    centnum = [SELECT Certification_Candidate__c.Accredited_Centre__r.Centre_Number__c from Certification_Candidate__c WHERE Id =: candid].Centre_Number__c;
    
    Attachment attachment = new Attachment();
    PageReference pdf = ApexPages.currentPage();
    Blob body;

    try {
        body = pdf.getContent(); 
    } catch (VisualforceException e) {
        body = Blob.valueOf('Some Text');
    }
    
    attachment.Body = body;
    attachment.Name = centnum + '-' + certnum + '-' + String.ValueOf(Date.Today().Year()).Right(2);
    attachment.IsPrivate = false;
    attachment.ParentId = candid;
    attachment.ContentType = 'application/pdf';
    insert attachment;
    
    String centnumNew = String.ValueOf(Integer.ValueOf(certnum)+1);
    certnum.description__c = centnumNew;
    update centnum;
    
    return null;
  }
}

Thanks for your help,

Joe​​
Alain CabonAlain Cabon
Hi,

Certification_Candidate__r.Accredited_Centre__r.Centre_Number__c

This is perhaps just a wrong "__c" instead of a right "__r".

Alain
Paul S.Paul S.
Also, Sf's documentation for apex:page indicates that you should NOT be performing DML operation via the action attribute of the component.  My guess is that what you're seeing is part of the reason why.  Could you use a commandButton component to call the savePDF method?
Joe HayesJoe Hayes
Got to the bottom of both,

Ended up with 
centnum = [SELECT Accredited_Centre__r.Centre_Number__c from Assessment__c WHERE Candidate__r.id=:candid limit 1].Accredited_Centre__r.Centre_Number__c;

That fixed my variable problem

The recursion came dome the getcontent() which called the action in my vf therefore kept going round and round.

Not sure how to combat the recursion issue as of yet.

Thanks