Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I have a situation where there is a text field on an object that is a text field. That field needs to be a Salesforce Id (It is a pseudo polymorphic relationship).

Is it possible to enforce this using a Validation Rule?

I was hoping CASESAFEID would return nothing so that I could compare Value_c != CASESAFEID(Value_c) but that didn't work.

Just to clarify, I am not trying to make sure the Value__c is a valid record Id in my Salesforce instance, just that it has the format of a Salesforce Id.

share|improve this question
1  
You could always use REGEX. The ID is always 15 or 18 alphanumeric characters. –  Michael Welburn Jan 23 '13 at 4:52
add comment

2 Answers

up vote 6 down vote accepted

Per the ID Field Type Docs:

ID fields in the Salesforce user interface contain 15-character, base-62, case-sensitive strings. Each of the 15 characters can be a numeric digit (0-9), a lowercase letter (a-z), or an uppercase letter (A-Z). Two unique IDs may only be different by a change in case.

So, any 15 digit alphanumeric value is valid. A simple REGEX can validate this.

For an 18 digit ID, the last 3 digits are a "calculated suffix" of the first 15 characters case sensitivity : ID Suffix Calculation

as referenced on 15 or 18 Character IDs in Salesforce.com as well as numerous other sites. We can use this logic, to verify if the 15 digit substring + the "calculated suffix" matches the full 18 digit value.

Piecing all of this together, gives you the following validation rule:

IF(
    REGEX(Polymorphic_ID__c, '^[a-zA-Z0-9]+$'), /** must be alphanumeric **/
    IF(
         LEN(Polymorphic_ID__c) == 18,
         CASESAFEID(LEFT(Polymorphic_ID__c, 15)) !=  Polymorphic_ID__c, /** if its 18 characters, verify that the 3 digit calculated suffix is valid **/
         IF (LEN(Polymorphic_ID__c) == 15, /** any 15 digit alphanumeric is valid **/
              false,
              true
          )
    )
    , true
)

I've tested this on a number of scenarios, and it appears to check out. One thing to note, per the docs "00100000000myidAAA" is a valid ID, and it passes the "calculated suffix" test, so this validation rule isn't preventing that.

share|improve this answer
    
I'd be reluctant to call the last three digits of the 18 character ID a checksum. They aren't really intended to verify the integrity of the prior characters. Only to, as you say, make the entire ID case insensitive. –  Daniel Ballinger Jan 23 '13 at 8:33
    
@DanielBallinger Good point. I've edited the answer to refer to this as a "calculated suffix" rather than a checksum. I don't think this is the best terminology, but I agree checksum isn't the best descriptor. If there's a better descriptor, edits are encouraged. :) –  Mikey Jan 23 '13 at 17:04
    
I'm supporting @Mikey's answer but I think it's still worth mentioning. For custom objects you can use VLOOKUP function to check if record with given Name value exists and the function can return Id or whatever you want. The tricky part is it has to be Name and preferably unique (first match is returned). Primary use of this is check for dictionary of valid values etc. Doesn't really apply to your situation, you have Id and not Name... but it's there ;) –  eyescream Jan 23 '13 at 17:13
    
I like Calculated Suffix :) Thanks for this answer, it is exactly what I was trying to do. –  Daniel Blackhall Jan 23 '13 at 22:33
add comment

You can use

Value_c = CASESAFEID(Value_c)

as the Validation Rule.

For CASESAFEID(Value_c), if the Value_c is not an effective ID, CASESAFEID() will do nothing but just return the value as the input value;

Therefore, CASESAFEID(Value_c) will only work when Value_c is an effective ID.

share|improve this answer
    
00100000000myidAAA = CASESAFEID(00100000000myidAAA) returns true which will cause the save to fail. –  Daniel Blackhall Jan 23 '13 at 5:08
    
I set the Value__c is as a 15-digit Text field. –  Jia Hu Jan 23 '13 at 5:17
    
If you set Value__c as 18-digit ID, you will never use CASESAFEID(Value_c) to do the decision, since whatever you input, you always get the same output! –  Jia Hu Jan 23 '13 at 5:25
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.