+ Start a Discussion
ismyhcismyhc 

How to add values to custom pick list on opportunities

Hi all,

 

I've created a a cutsom field for opportunites which is the datatype picklist. I would like to be able to setup a batch class that will periodically do a web callout that returns a list of names which I would then like to use to update the picklist values available for the custom field. 

 

How would I insert these values into the custom field so that all opportunites have access to them?

 

Thanks!

 

 

ismyhcismyhc

So, one thing ive tried is the following. I schedule the following batch class to run, and while it does run I get these results..

 

It changes the value of the custom picklist to 'test value' in all opportunites. If you then change the value and save it, then it removes the value all together for that particular opportunity.

 

Below is the class...  Obviously once I am able to get this working, the list of values will be greater, but for now its just one static value.

global class xAdvertiserBatch implements Database.Batchable<sObject> {

    String query = 'select x_advertiser__c from Opportunity';
    String email = 'my@email.com';
    String newAdvs = 'test value';
    
    global database.querylocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator(query);
    }
    
    global void execute(Database.BatchableContext BC, List<sObject> scope) {
        List<Opportunity> opp = new List<Opportunity>();
    
        for(sObject s : scope) {
            Opportunity o = (Opportunity)s;
                o.x_advertiser__c = newAdvs;
                opp.add(o);
            }
            
        update opp;
    
    }
    
    global void finish(Database.BatchableContext BC) {
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    
    mail.setToAddresses(new String[] {email});
    mail.setReplyTo('my@email.com');
    mail.setSenderDisplayName('Batch Processing');
    mail.setSubject('Batch Process Completed');
    mail.setPlainTextBody('Batch Process has completed');
    
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }
    

}

 

willardwillard

two ways.

 

You can store the values in a custom object and then create a visualforce page that would show your field as a SelectList.  You would populate this SelectList via a method in your controller extension.  Here's an example: http://wiki.developerforce.com/index.php/Extended_Functionality_of_Visualforce_-_Part_1

 

Another way is by using the metadata api to load picklist values.  Here's the documentation for that:

http://www.salesforce.com/us/developer/docs/api_meta/Content/customfield.htm

You can see in there a property for Picklist

ismyhcismyhc

Okay, cool. Ill take a look at the second link.

 

In my situation this would be a custom picklist on the users standard Opportunity page.

 

Thanks!

ismyhcismyhc

Ive looked at the two links above and I believe that the best way would be to use the metadata api. I kindof understand the documentation, but I was wondering if there is some example code somehwere to demonstrate what I am trying to accomplish?

 

Also, could someone help explain why my above code behaves as explained? Am I even close?

 

Goal:

I want to dynamically populate the values on a custom picklist accross all opportunities. I would like to do this through a batch process as the values will be added to fairly frequently.

 

Thanks again for any help!

 

 

 

ismyhcismyhc

Also, does using the metadata api to load the picklist values require using a visualforce page to actually display the new values in the picklist?

 

Meaning, can I update picklist values of a customfield on at standard object and have the picklist show its updated values on the standard "Opportunities" page?

 

Ive searched the forums and documentation for hours and I am getting the feeling that what I want to do isnt possible??

willardwillard

you know - looks like the metadata api is actually not available in apex code.  I don't think you can update the picklist values via apex.  Sorry about that.  You still can call your webservice and insert the values into a custom object and then have it show up as a lookup field on a standard page.

 

You would have to create a VF page in order for it to show up as a dropdown.  If you want to go that route, let me know and I can share some code w/ you if the link above is not sufficient.

ismyhcismyhc

Ah.. Okay.

 

You know I think my best option is to create the custom object and then add a custom lookup field that relates to that custom object. I would like to then setup a batch process that calls my webservice to update the values of this custom object, maybe once a day. Okay.. I think I am back on the right track now.

 

I guess my next step is to read up on custom objects!

 

Thanks for you response!

willardwillard

This is just pseudo-code since i don't have a custom object called myCustomObject__c, but should work if there are no typos:

public void batchProcess() {
        // delete previous first - you can alternatively do some upserts, but you will have to specify an externalId
        List<id> coDeletes = [select id from myCustomObject__c];
        delete coDeletes;
        
        List<myCustomObject__c> cObjects = new List<myCustomObject__c>();
        
        List<String> newValues = getNewValuesFromWebCallout();
        for (Integer i = 0; i < newValues.size(); i++) {
            myCustomObject__c co = new myCustomObject__c();
            co.name = newValues[i];
            cObjects.add(co);
        }
        
        insert cObjects;
    }

 

ismyhcismyhc

Okay. I kindof understand what you are doing here, but Im getting an error...

 

Maybe Ive just been looking at it to long... anyways.. thanks for all of your help!!

 

Variable does not exist: x_Advertiser__c at line 13..

 

global class xBatch {

    public void batchProcess() {
    
        List<id> coDeletes = [select id from x_Advertiser__c];
        delete coDeletes;
        
        List<x_Advertiser__c> cObjects = new List<x_Advertiser__c>();
        
        List<String> newValues = 'dog';
        
        for (Integer i = 0; i < newValues.size(); i++) {
            x_Advertiser__c = new x_Advertiser__c();
            co.name = newValues[i];
            cObjects.add(co);
        }
        
        insert cObjects;
    }
}

 

willardwillard

You have to declare your variable in the for loop:

 

x_Advertiser__c co = new x_Advertiser__c();

ismyhcismyhc

ah.. that was a typo my part.

 

I was able to get the values added!

 

I did have one problem though. I had to comment out the part that deletes the current values.. or i assume thats what its doing.. Below is the code.

 

I get a compile error when un-commenting the those two lines.

 

Once again, thanks for you all of your help!

 





 

global class xBatch {

    public void batchProcess() {
    
      //  List<id> coDeletes = [select id from x_Advertiser__c];
      //  delete coDeletes;
        
        List<x_Advertiser__c> cObjects = new List<x_Advertiser__c>();
        
        string dog = 'dog';
        string bag = 'bag';
        
        List<String> newValues = new List<String>();
        
        newValues.add(dog);
        newValues.add(bag);
        
        for (Integer i = 0; i < newValues.size(); i++) {
            x_Advertiser__c co = new x_Advertiser__c();
            co.name = newValues[i];
            cObjects.add(co);
        }
        
        insert cObjects;
    }
}

 

Compile Error: Illegal assignment from LIST<x_Advertiser__c> to LIST<Id> 
 
willardwillard

ismyhc - you have to learn how to deal with these compile errors as these will come up every day that you code.

 

That error just means that the Type of List does not match.  The query is giving back a list of x_advertiser__c's, but I am assigning it to a list of Id's.  I'm sure you can figure out how to rectify the situation.