Wednesday, May 18, 2011

JavaScript Hack to Mass Delete Custom Picklist Values

As an extension of last night's efforts, I've created what appears to be a working JavaScript hack to delete all picklist values from a custom picklist. This simplifies maintenance of picklist values by allowing an admin to delete all the values and then simply re-add the ones that are desired.

The following code was tested in Chrome 11 on Windows 7.

javascript:

/* Gather all of the a elements on the page. */

var links = document.getElementsByTagName("a");

/* Pick out the Del links. */

var delLinks = new Array();
for (var i = 0; i < links.length; i++) {
  var link = links[i];
  
  if (link.innerHTML == "Del") {
    /*alert("Del link found!");*/
    /*alert(link.attributes['href'].value);*/
    delLinks[delLinks.length] = link;
  }
}

/* Open each Del link to delete the associated
   picklist value.
   
   This code can be augmented as desired
   to only delete certain values.
   
   However, for custom picklists it's probably
   easier to just delete all of the values
   and then re-add the desired values. */

for (var i = 0; i < delLinks.length; i++) {
  var delLink = delLinks[i];
  window.open(
      delLink.attributes['href'].value);
}

As with all hacks, please to use with caution, at your own risk.

Tuesday, May 17, 2011

Mass Deleting Picklist Values

Apparently, the only way one can (relatively) easily mass delete picklist values is by editing the object definition in the Force.com IDE.

To do this:
  1. Open the object definition (e.g., Contact.object).
  2. Delete the picklistValues elements that are no longer desired.

I had to prune a list of 485 picklist values in a language selection picklist to a more reasonable number.

Regardless of this workaround, it would be great if this feature was more easily accessible through the web UI, as per the following idea: "mass delete picklist values (setup)"


Apparently, all I succeeded in doing was shifting the order of the picklist values. At this point I am also at a loss as to how to mass delete picklist values, much to my chagrin.

However, I did eventually create a "sort of" workaround: "JavaScript Hack to Mass Delete Custom Picklist Values"

Thursday, May 12, 2011

Increasing Speed of Command Line Extract/Export with Apex Data Loader

I had a strange problem when I tried to automate a routine, daily export that I was performing with the Apex Data Loader (version 20.0 and 21.0): Exporting through the GUI only took 5 seconds, but exporting through the command line took anywhere from 30 minutes to 1 hour.

After 4 weeks, Salesforce Premier Support finally delivered a solution to the case I logged: Set the sfdc.debugMessages value to false. I'm very glad that Premier Support was able to find a simple solution to this problem.

Apparently, debug messages were so verbose for every record being exported that operation time increased by a ridiculous factor. Luckily for me, debug messages are not that important for an export.

Saturday, May 7, 2011

Bug (?) with ISNULL() Function in Validation Rules

I tried to setup a simple validation rule today in my sandbox to enforce the presence of a value in a Lookup field.

My first attempt for the error formula was:
ISNULL( Source_Program__c )

However, this turned out not to work at all. Whether a value was in the field or not, the formula never generated a validation error.

Then, I switched over to an even more basic formula:
Source_Program__c = null

This worked like a charm. Am I missing something here?

Friday, April 29, 2011

keeping Person Accounts on the roadmap

From a discussion on Person Accounts yesterday, a Salesforce Foundation representative said about Person Accounts, "we do not have a roadmap going forward but the current offering is going to continue". What does this mean to us as Salesforce customers and prospective customers? One school of thought says that having no roadmap indicates that the feature is on its way out. Another school of thought says that having no roadmap simply means that at the current time, the feature meets most if not all of users' needs and has no need to be on a roadmap.

But let's stop for a second and think, "Why is this feature important?" My thought on that is, "Should a database be structured to match the business model?" To me, the entities with which we do business dictate whether we should use Person Accounts or not. If we contract and transact with other businesses, then accounts with contacts would work. If we contract and transact with individual people, don't person accounts make more sense? A simple use case is managing individual donors and contributors for nonprofits. Another use case is managing students at an institution of learning.

But perhaps most importantly, what are some of the pros and cons of using Person Accounts? I'll admit that I'm probably biased because we use Person Accounts in two of our orgs, but I hope not to lie when I say that I would love to know all of the benefits and liabilities of using this feature.

Below are starters taken from an editable document shared with the public, in lieu of something more authoritative from Salesforce.

Some pros:
  • The model fits the B2C way of doing business.
  • You can contract with people instead of businesses using the standard Contract object.
  • Person accounts will show up on both account and contact reports, which would be accurate for a company that mixes B2B with B2C.
  • Person accounts can leverage both Account fields and Contact fields via a single sObject.
  • Contact fields are directly accessible for a Person Account via Apex through a single Account instance.

Some cons:
  • To convert a lead into an opportunity for a new person account, the lead cannot have a value in the standard Company field.
  • For person accounts, formula fields at the account level cannot reference contact fields.
  • Code may have to account for the fact that there are now two record types on the Account object.

Personally, I believe that Person Accounts make a great selling point and feature for the Salesforce products. If being off the roadmap is a fault, then maybe we just need to promote some of the ideas on the IdeaExchange that will make the feature even stronger and more compelling:

Tuesday, April 26, 2011

Bug (?) with Rerendering an apex:pageBlockSection When apex:inputFile Exists Elsewhere on Page

I can understand throwing an error if we rerender part of a page that contains an apex:inputFile component, but I'm a bit confused about why rerendering part of a page that has no apex:inputFile component should generate the following error:
apex:inputFile can not be used in conjunction with an action component, apex:commandButton or apex:commandLink that specifies a rerender or oncomplete attribute.

I've created a demo for getting the error message, although you can't see the exact error message unless you deploy the page in your own sandbox. The source code can be downloaded here.

What I expected was that my partial page refresh of "Dependent Section" would work just fine. However, when I change the value in my controlling picklist, the page just fails, with the error mentioned above.

Is this a bug? I'm not sure what Salesforce would say, but it certainly is puzzling and extremely frustrating to me.

Tuesday, April 12, 2011

DML error: Name not specified

When trying to upsert a list of records via Apex, I received a slew of "Name not specified" errors on every single one of the records.  The Database.Error.getStatusCode() instance method returned "MISSING_ARGUMENT", and the Database.Error.getMessage() instance method returned "Name not specified".

My upsert was constructed as follows:
upsertResults = Database.upsert(applications,
        Application__c.Unique_External_Application_ID__c, false);

Application__c is a custom object, and Unique_External_Application_ID__c is a custom field that is set to be an external ID. applications is my List that I was trying to upsert.

Basically, after a few hours of frustration and asking for help on #salesforce, I determined that the error came from the fact that I was trying to set a Lookup field by specifying an external ID on the related object. An example is shown below:
Application__c application = new Application__c();
application.Start_Term__r = new Term__c(Banner_Code__c = '201115');

I had simply assumed this would work, since I knew that a lookup field can be set by setting the custom field __r to new sObject(Name = recordName). Apparently I was 100% wrong.


But I did create an idea out of this whole mess: enable Apex DML to set Lookup or Master-Detail by external ID

I wish I could recall the idea, because apparently the error was the result of my putting a null value into the Name field when specifying the related record. Essentially, my code was trying to execute the following:
application.Program__r = new Program__c(Name = null);

Specifying an external ID in the following manner does work:
application.Term__r = new Term__c(Banner_Code__c = '201115');