• Prachi S
  • NEWBIE
  • 75 Points
  • Member since 2015


  • Chatter
    Feed
  • 1
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 5
    Questions
  • 10
    Replies
Hi, 
I have implemented a visualforce page to upload a CSV file and batch apex that reads the CSV and loads data into multiple related custom objects. Now visualforce page allows me to load CSV upto 10 MB but when I try to parse this huge file in apex I run into heap size governor limits.

I have implemented the parsing of CSV file in batch apex exactly as per financialforce customization from below link:
https://developer.financialforce.com/customizations/importing-large-csv-files-via-batch-apex/

The post mentions:
You can create a batch process to read the file in chunks and define the number of lines to read for each chunk.
To do this, create a batch apex process where the scope size defines the number of records to read for each chunk. In the sample code that follows, lines from a CSV file are to be read rather than records. The start method returns an Iterable<String> that contains the lines to be processed in the execute method. Afterwards, the process reads the list of lines using the CSVReader in the same way as an online process.
 
global with sharing class ReadAndPopulateBatch implements Database.batchable<String>, Database.Stateful
{
   private String m_csvFile;
   private Integer m_startRow;
   private CSVParser m_parser;
   private static final Integer SCOPE_SIZE = 100;
   public ReadAndPopulateBatch(){....}
   public static ID run(){....}
   global Iterable<String> start(Database.batchableContext batchableContext)
   { 
       return new CSVIterator(m_csvFile, m_parser.crlf);
   }
   global void execute(Database.BatchableContext batchableContext, List<String> scope)  
   {
       //TODO: Create a map with the column name and the position.
       String csvFile = '';
       for(String row : scope)
       {
          csvFile += row + m_parser.crlf;
       }
       List<List<String>> csvLines = CSVReader.readCSVFile(csvFile,m_parser);
       //TODO: csvLines contains a List with the values of the CSV file.
       //These information will be used to create a custom object to
       //process it.
   }
   global void finish(Database.BatchableContext batchableContext){......}
}
Although this post recommends to read the file in chunks it doesnt explain how to do so. It defines a variable private static final Integer SCOPE_SIZE = 100; but doesnt really use it in the example provided.

The input my batch class constructor gets is a BLOB of size 10 MB. How do I read this file in chunks in my apex class so that the user doesnt have to split the file for the data load to work?

Any advice will be really helpful. Thanks!
 
Hi All,

In my apex code I need to check if an input string from CSV file is a valid number. It can be a integer or decimal value.
isNumeric only returns true if the input is integer but does not work for decimal.
Is there an easy way to determine if an input string from CSV file is a valid decimal or integer ?
 
String numeric = '1234567890';
system.debug(numeric.isNumeric());


String decimalPoint = '1.2';
system.debug(decimalPoint.isNumeric());

Logs Displays:

true
flase


 
Hi All,
I have a visualforce page that calls an Apex controller - DataLoadFileUploader which in turn calls an additional Apex Batch class-CSVReaderBatch.

Now both these classes have DML operations and I want to ensure if any of these DML operations fail a complete rollback happens and also an error displays on the page. To achieve this I have defined only 1 savepoint in as shown in below snippet:
 
public class DataLoadFileUploader {

    public Blob contentFile{get;set;} 
    public String nameFile{get;set;}  
    public Boolean IsWhatIfFile{get;set;}
    			
    /***This function calls a batch class that reads the input CSV file and creates records***/
    public Pagereference ReadFile()
    {
    	Savepoint spMain = Database.setSavepoint();
        try{
             //some records are inserted here

        	system.debug('Call CSVReader---');
        	CSVReaderBatch BatchObj = new CSVReaderBatch(contentFile,IsWhatIfFile);
        	Database.executeBatch(BatchObj,2000);                                	        
        }
        catch(Exception e){
        	Database.rollback(spMain);        	
        	ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.ERROR,'An error has occured reading the CSV file:' +e.getMessage());
        	ApexPages.addMessage(errormsg);
        }   
        return null;      
    }       
}
Is this the correct way of ensuring a complete rollback ?

Any advise will be greatly appreciated.

Thank you!


 
Hi All,

I am trying to insert a list of related records in Apex and found the documentation that explains how to do so for inserting 1 parent and 1 child record. Here is the snippet I am talking about and link for the same:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_dml_foreign_keys.htm
public class ParentChildSample {
    public static void InsertParentChild() {
        Date dt = Date.today();
        dt = dt.addDays(7);
        Opportunity newOpportunity = new Opportunity(
            Name='OpportunityWithAccountInsert',
            StageName='Prospecting',
            CloseDate=dt);
        
        // Create the parent reference.
        // Used only for foreign key reference
        // and doesn't contain any other fields.
        Account accountReference = new Account(
            MyExtID__c='SAP111111');                
        newOpportunity.Account = accountReference;
        
        // Create the Account object to insert.
        // Same as above but has Name field.
        // Used for the insert.
        Account parentAccount = new Account(
            Name='Hallie',
            MyExtID__c='SAP111111');      
        
        // Create the account and the opportunity.
        Database.SaveResult[] results = Database.insert(new SObject[] {
            parentAccount, newOpportunity });
        
        // Check results.
        for (Integer i = 0; i < results.size(); i++) {
            if (results[i].isSuccess()) {
            System.debug('Successfully created ID: '
                  + results[i].getId());
            } else {
            System.debug('Error: could not create sobject '
                  + 'for array element ' + i + '.');
            System.debug('   The error reported was: '
                  + results[i].getErrors()[0].getMessage() + '\n');
            }
        }
    }
}

Now I want to replicate this functionality to insert a List of related records instead of a single record and I get an error when I just change the below line from documentation :

// Create the account and the opportunity.
Database.SaveResult[] results = Database.insert(new SObject[] { parentAccount, newOpportunity });

To:

// Create the account and the opportunity.
Database.SaveResult[] results = Database.insert(new SObject[] { parentAccountLIST, newOpportunityLIST });


Any help on what parameters change for inserting a list will be of great help.

Thank you!!


 
Hi All,
I am getting "Unknown property 'VisualforceArrayList.Name" error while trying to create a Visualforce email template on custom object Status__c.
I have narrowed down the line that is actually giving me the error which is:
{!relatedTo.Demand_Vs_Supply_Master__r.Name}

I do not get this error when I change the line to display the ID instead of Name:
{!relatedTo.Demand_Vs_Supply_Master__c}

I have checked my relationship name is correct and cant figure out why it wont traverse to the related object.

Any help will be really appreciated.

Thank you!
 
<messaging:emailTemplate subject="{!relatedTo.Name} {!$Label.Incident_Submit_For_Approval}" 
recipientType="User" 
relatedToType="Status__c" 
language="{!recipient.LanguageLocaleKey}">
<messaging:htmlEmailBody >        
        <html>
            <body>
            <p>Hi {!relatedTo.Owner.Name},</p>
            <p>{!$Label.Incident_Submit_Approval_Request} {!relatedTo.Name}.</p>
            <p>{!relatedTo.Name} details :</p>
            
            <table cellspacing="0" cellpadding="0">
                <tr style="height: 21px;">
                    <td style="width: 130px;text-align: right;">Name</td>
                    <td style="padding-left: 10px;">{!relatedTo.Name}</td>
                </tr>                                             
                 <tr style="height: 21px;">
                    <td style="width: 130px;text-align: right;">Demand vs Supply</td>
                    <td style="padding-left: 10px;">{!relatedTo.Demand_Vs_Supply_Master__r.Name}</td>
                </tr>                                           
            </table>
            <p>You can either approve or reject by typing APPROVE or REJECT in the first line and adding comments in the second line in reply to this email.</p>
            <br/>Thank You,
            <!--<br/>{!relatedTo.Demand_Vs_Supply_Master__r.Supplier_Site__r.Site__r.Company__r.Name}.<br/>          -->
            </body>
        </html>
    </messaging:htmlEmailBody> 
</messaging:emailTemplate>



 
Hi All,
I have a field level security requirement around custom formula. If the user does not have read access for the custom formula field at the profile level, User should not be abe to see the value at all in the custom Lightning component page / VF page but whenever i do security check in apex code for the field and assign any value to it then it is throwing error saying "formula fields are not writeable".

Please take a snap of my code as below:

List<hed__Course_Offering__c> courseOfferingList = [Select Id,Course_ID__c from hed__Course_Offering__c where hed__Term__c IN :termList ];
for(Integer i=0; i<spProgramDetail.courseOfferingList.size();i++){
// Course_ID__c is a FORMULA Field.    
 if (!Schema.sObjectType.hed__Course_Offering__c.fields.Course_ID__c.isAccessible()){
    courseOfferingList[i].Course_ID__c = '';
    }
}

Any help would be appreciated.

Regards,
Pawan Kumar
Hello All,

I have written some code to insert Contact under Account based on text field which is common in both way..

for example : i have abc__c (text) field in Account and Contact, both have same value 'Text1'..if this is same for both way then insert that contact into that account which is matched with Account abc__c..

Please help me out and let me know if i need to go with another way..

Trigger Code :
trigger ContactInsertUnderAccount on Contact (after insert, after update)
{
    if (trigger.isAfter || trigger.isBefore)
    {
        List<Contact> toUpdate = new List<Contact>();
        for (Contact record : trigger.new)
            if (record.abc__c != null && record.AccountId == null)
                toUpdate.add(record);
        contactInsertUnderAccount.associateExternalAccount(toUpdate);
    }
}

Apex Class :
Public Class ContactInsertUnderAccount{
    public static void associateExternalAccount(List<Contact> contacts){
        List<Contact> toUpdate = new List<Contact>();
        for (Contact record : [select Id, abc__c from Contact])
        toUpdate.add(new Contact(Id=record.Id, Account = new Account(abc__c = record.abcl__c)));
        Database.update(toUpdate);
    }
}

Thanks..
Hi All,

I'm using custom Lookup lightning component which uses RequireJS, this is working smoothly, untill we have Locker Service deactivated. Once the Service is Activated it is throwing an Exception message as "Something has gone wrong. Error in $A.getCallback() [ReferenceError: define is not defined] Failing descriptor: {markup://c:CustomLookupComp}. Please try again.". Whereas define is defined already in teh RequireJS by default.

I have also refered some sites, where they mention to use the commments in the function to let the Aura to identify the variable/element.
http://jshint.com/docs/  
/* globals define */

Still No luck on this.

please let me know if you have any solution or alternative for this ?

Thanks

 
Hi All,

In my apex code I need to check if an input string from CSV file is a valid number. It can be a integer or decimal value.
isNumeric only returns true if the input is integer but does not work for decimal.
Is there an easy way to determine if an input string from CSV file is a valid decimal or integer ?
 
String numeric = '1234567890';
system.debug(numeric.isNumeric());


String decimalPoint = '1.2';
system.debug(decimalPoint.isNumeric());

Logs Displays:

true
flase


 
Hi All,
I have a visualforce page that calls an Apex controller - DataLoadFileUploader which in turn calls an additional Apex Batch class-CSVReaderBatch.

Now both these classes have DML operations and I want to ensure if any of these DML operations fail a complete rollback happens and also an error displays on the page. To achieve this I have defined only 1 savepoint in as shown in below snippet:
 
public class DataLoadFileUploader {

    public Blob contentFile{get;set;} 
    public String nameFile{get;set;}  
    public Boolean IsWhatIfFile{get;set;}
    			
    /***This function calls a batch class that reads the input CSV file and creates records***/
    public Pagereference ReadFile()
    {
    	Savepoint spMain = Database.setSavepoint();
        try{
             //some records are inserted here

        	system.debug('Call CSVReader---');
        	CSVReaderBatch BatchObj = new CSVReaderBatch(contentFile,IsWhatIfFile);
        	Database.executeBatch(BatchObj,2000);                                	        
        }
        catch(Exception e){
        	Database.rollback(spMain);        	
        	ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.ERROR,'An error has occured reading the CSV file:' +e.getMessage());
        	ApexPages.addMessage(errormsg);
        }   
        return null;      
    }       
}
Is this the correct way of ensuring a complete rollback ?

Any advise will be greatly appreciated.

Thank you!


 
Hi All,

I am trying to insert a list of related records in Apex and found the documentation that explains how to do so for inserting 1 parent and 1 child record. Here is the snippet I am talking about and link for the same:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_dml_foreign_keys.htm
public class ParentChildSample {
    public static void InsertParentChild() {
        Date dt = Date.today();
        dt = dt.addDays(7);
        Opportunity newOpportunity = new Opportunity(
            Name='OpportunityWithAccountInsert',
            StageName='Prospecting',
            CloseDate=dt);
        
        // Create the parent reference.
        // Used only for foreign key reference
        // and doesn't contain any other fields.
        Account accountReference = new Account(
            MyExtID__c='SAP111111');                
        newOpportunity.Account = accountReference;
        
        // Create the Account object to insert.
        // Same as above but has Name field.
        // Used for the insert.
        Account parentAccount = new Account(
            Name='Hallie',
            MyExtID__c='SAP111111');      
        
        // Create the account and the opportunity.
        Database.SaveResult[] results = Database.insert(new SObject[] {
            parentAccount, newOpportunity });
        
        // Check results.
        for (Integer i = 0; i < results.size(); i++) {
            if (results[i].isSuccess()) {
            System.debug('Successfully created ID: '
                  + results[i].getId());
            } else {
            System.debug('Error: could not create sobject '
                  + 'for array element ' + i + '.');
            System.debug('   The error reported was: '
                  + results[i].getErrors()[0].getMessage() + '\n');
            }
        }
    }
}

Now I want to replicate this functionality to insert a List of related records instead of a single record and I get an error when I just change the below line from documentation :

// Create the account and the opportunity.
Database.SaveResult[] results = Database.insert(new SObject[] { parentAccount, newOpportunity });

To:

// Create the account and the opportunity.
Database.SaveResult[] results = Database.insert(new SObject[] { parentAccountLIST, newOpportunityLIST });


Any help on what parameters change for inserting a list will be of great help.

Thank you!!


 
Hi All,
I am getting "Unknown property 'VisualforceArrayList.Name" error while trying to create a Visualforce email template on custom object Status__c.
I have narrowed down the line that is actually giving me the error which is:
{!relatedTo.Demand_Vs_Supply_Master__r.Name}

I do not get this error when I change the line to display the ID instead of Name:
{!relatedTo.Demand_Vs_Supply_Master__c}

I have checked my relationship name is correct and cant figure out why it wont traverse to the related object.

Any help will be really appreciated.

Thank you!
 
<messaging:emailTemplate subject="{!relatedTo.Name} {!$Label.Incident_Submit_For_Approval}" 
recipientType="User" 
relatedToType="Status__c" 
language="{!recipient.LanguageLocaleKey}">
<messaging:htmlEmailBody >        
        <html>
            <body>
            <p>Hi {!relatedTo.Owner.Name},</p>
            <p>{!$Label.Incident_Submit_Approval_Request} {!relatedTo.Name}.</p>
            <p>{!relatedTo.Name} details :</p>
            
            <table cellspacing="0" cellpadding="0">
                <tr style="height: 21px;">
                    <td style="width: 130px;text-align: right;">Name</td>
                    <td style="padding-left: 10px;">{!relatedTo.Name}</td>
                </tr>                                             
                 <tr style="height: 21px;">
                    <td style="width: 130px;text-align: right;">Demand vs Supply</td>
                    <td style="padding-left: 10px;">{!relatedTo.Demand_Vs_Supply_Master__r.Name}</td>
                </tr>                                           
            </table>
            <p>You can either approve or reject by typing APPROVE or REJECT in the first line and adding comments in the second line in reply to this email.</p>
            <br/>Thank You,
            <!--<br/>{!relatedTo.Demand_Vs_Supply_Master__r.Supplier_Site__r.Site__r.Company__r.Name}.<br/>          -->
            </body>
        </html>
    </messaging:htmlEmailBody> 
</messaging:emailTemplate>