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
SaraagSaraag 

Generic CSV reader- Dynamic casting

Hi,

 

I'm trying to create a generic CSV reader that will read from a Blob into list of records. This class would be called from a controller. This is my first draft. Arguments include file, fieldnames which sort of acts as the map and then the object name. I want to be able to detect what the object is and then read the CSV into a list of records of that type. Not sure what I have here would work (since I'm using PUT method on the generic sObject)

 

public List<sObject> readCSVRecords(Blob fileContent,List<String> fieldNames,String objName){
   	       Schema.SObjectType targetType = Schema.getGlobalDescribe().get(objName);
   	       
   	       List<sObject> returnList=new List<sObject>();	
   	   	    if(fileContent!=NULL&fileContent.size()<MAXFILESIZE){ //currently limited to 2MB
   	   	   
	   	   	    fileString=fileContent.toString();
	   		    fileLines=fileString.split('\n');
	   		    fileLinesSize=fileLines.size();	
			    for(Integer i=1;i<fileLinesSize;i++){ //leave out headings
			   	String[] inputvalues = filelines[i].split(',');
			        Integer y=0;
			        sObject rec=targetType.newSObject(objName); //How do I cast this dynamically?
			         for(String s:fieldNames){
			        	rec.put(s,inputvalues[y]);
			            	y++;
			         }
			         returnList[i-1].add(rec);
			            
			   }	
			   return returnList;
			   			   		
   	   	    }  
   	   	 else
   	return NULL; 	   
   }// end readCSVRecords

 

I would appreciate any help

 

Thank you

Best Answer chosen by Admin (Salesforce Developers) 
SaraagSaraag

Forgot about this post, I figured out the issue. I used newSObject incorrectly. Here is the correct code:

 

//---Method Name: readCVSRecords
// Arguments: file content as blob,filed names as list, objname as string,recordtypeid or NULL, boolean to indicate load default values on record.
// Return: List of SObjects
// Description: Call this method with a blob, objectname,fieldnames that correspond to the CSV as list, optional recordtypeid and boolean to indicate if default values are to be loaded.
// Note: fieldnames should follow the exact order of values in CSV. You can may be enhance this by reading fieldnames from the file itself (use fieldapi names as column headers)


public List<sObject> readCSVRecords(Blob fileContent,List<String> fieldNames,String objName,Id recTypeId,Boolean LoadDefaults){ Schema.SObjectType targetType = Schema.getGlobalDescribe().get(objName); List<sObject> returnList=new List<sObject>(); if(fileContent!=NULL&fileContent.size()<MAXFILESIZE){ //currently limited to 2MB fileString=fileContent.toString(); fileLines=fileString.split('\n'); fileLinesSize=fileLines.size(); for(Integer i=1;i<fileLinesSize;i++){ //leave out headings String[] inputvalues = filelines[i].split(','); Integer y=0; sObject rec=targetType.newSObject(recTypeId,LoadDefaults); for(String s:fieldNames){ try{ rec.put(s,inputvalues[y]); }catch(system.sObjectException se){ //Invalid fieldname for objName. Can either handle here or throw back to controller and display error in page. } y++; } returnList[i-1].add(rec); } return returnList; } else return NULL; }// end readCSVRecords

 

All Answers

SaraagSaraag

Forgot about this post, I figured out the issue. I used newSObject incorrectly. Here is the correct code:

 

//---Method Name: readCVSRecords
// Arguments: file content as blob,filed names as list, objname as string,recordtypeid or NULL, boolean to indicate load default values on record.
// Return: List of SObjects
// Description: Call this method with a blob, objectname,fieldnames that correspond to the CSV as list, optional recordtypeid and boolean to indicate if default values are to be loaded.
// Note: fieldnames should follow the exact order of values in CSV. You can may be enhance this by reading fieldnames from the file itself (use fieldapi names as column headers)


public List<sObject> readCSVRecords(Blob fileContent,List<String> fieldNames,String objName,Id recTypeId,Boolean LoadDefaults){ Schema.SObjectType targetType = Schema.getGlobalDescribe().get(objName); List<sObject> returnList=new List<sObject>(); if(fileContent!=NULL&fileContent.size()<MAXFILESIZE){ //currently limited to 2MB fileString=fileContent.toString(); fileLines=fileString.split('\n'); fileLinesSize=fileLines.size(); for(Integer i=1;i<fileLinesSize;i++){ //leave out headings String[] inputvalues = filelines[i].split(','); Integer y=0; sObject rec=targetType.newSObject(recTypeId,LoadDefaults); for(String s:fieldNames){ try{ rec.put(s,inputvalues[y]); }catch(system.sObjectException se){ //Invalid fieldname for objName. Can either handle here or throw back to controller and display error in page. } y++; } returnList[i-1].add(rec); } return returnList; } else return NULL; }// end readCSVRecords

 

This was selected as the best answer
Subramani_SFDCSubramani_SFDC
can u pls provide the full class??