• Chris760
  • NEWBIE
  • 240 Points
  • Member since 2012

  • Chatter
    Feed
  • 5
    Best Answers
  • 2
    Likes Received
  • 1
    Likes Given
  • 26
    Questions
  • 46
    Replies
Lets say you have an object in salesforce with 300 fields.  I then create two records, one where I only fill out 2 of the fields, and another record where I fill out all 100 of the fields.  My questions are: 1) Do both records take up the same amount of space in the database?  2) What determines the speed of a database on salesforce; the total size of how much space the database file takes up in MB?  Or is it based on the number of actual records (big or small) that are stored in the database file?

I have a salesforce org I'm working on with almost 300 fields and half a million records and it chugs like crazy (constantly times out when running queries and cant even open the tab view without timing out).  I think part of the problem is that the initial designer (a sales rep at the company) put every field he felt they could ever possibly need on the object (that only a couple records might ever use) instead of creating a seperate object to attach all these little bits and pieces of random information to.  As a result, there's always a ton of empty fields in the various records and I'm wondering if that might be a part of the problem.

Either way, any ideas or suggestions about working with objects containing millions of records would be hugely helpful.  We've already asked salesforce to add custom indexes to fields that get queried a lot, so I'm not sure what else can be done to speed things up.

Thanks.
I have a trigger that utilizes the Last Login field on the user record (you need to have logged in within a certain period of time to start getting a case load assigned to you), but I can't seem to figure out how to simulate a test user logging into salesforce on a test class.  I've tried inserting a UserLogin record manually to create the needed "Last Login" record, but no dice... the system wouldn't let me.  Is there some other way that I could simulate the act of a test user logging into salesforce after I've created that test user?

Any ideas would be welcome.
Hi everyone,
I need your help on the below.

I have got a requirment where I need to generate a report that should capture the total login time of users i.e.; Login Time - LogOut Time = total login hours.

Is there anyway we can achieve this, Please help. Thank You
For some reason, the test class I've written is failing and I'm not sure why.  It seems to be failing as a result of one of the methods that the trigger calls.  What's weird though is that the method works fine when I'm not running it in test mode (just normally in the sandbox).  So I'm not sure if test mode disables something from working or what it might be, so any insights would be helpful.  Below is the method that the trigger is calling and failing, and the failure seems to be occuring on the third line where the records from the "Case_Assignment_Settings__c" SOQL list gets copied to the single Case_Assignment_Settings__c settings object (the test error is saying "System.ListException: List index out of bounds: 0, Class.caseAssignmentMethods: line 3, column 1,Trigger.caseTriggers: line 18, column 1: []"

Here is the caseAssignmentMethods class:
public class caseAssignmentMethods {
    public static list<Case_Assignment_Settings__c> caseSettings = [SELECT Hours_Until_Stale__c,Assignment_Timeout_Cutoff__c,Case_Match_Set_Size__c,Case_Origin_All_Match_Points__c,Case_Origin_Exact_Match_Points__c,Case_Origin_Exact_Match_Required__c,Location_All_Match_Points__c,Location_Exact_Match_Points__c,Location_Exact_Match_Required__c,Sub_Type_All_Match_Points__c,Sub_Type_Exact_Match_Points__c,Sub_Type_Exact_Match_Required__c,Tier_All_Match_Points__c,Tier_Exact_Match_Points__c,Tier_Exact_Match_Required__c,Times_Skipped_Multiplier__c,Time_Elapsed_Multiplier__c,Type_All_Match_Points__c,Type_Exact_Match_Points__c,Type_Exact_Match_Required__c,User_Type_All_Match_Points__c,User_Type_Exact_Match_Points__c,User_Type_Exact_Match_Required__c FROM Case_Assignment_Settings__c];
    Public static Case_Assignment_Settings__c settings = caseSettings[0];
    Public static Integer samples = settings.Case_Match_Set_Size__c.intValue();
    Public static list<String> filters = new list<String>{'Case_Origin','Location','Sub_Type','Type','Tier','User_Type'};
    public static datetime loginCutoff = System.Now().addHours(0-settings.Assignment_Timeout_Cutoff__c.intValue());
    public static list<Group> groups = [SELECT Id FROM Group WHERE Type = 'Queue' AND Name = 'Unassigned Queue'];
    public static Id uq = groups.get(0).Id;

    public static void sendToUnassignedQueue(list<Case> casesNeedingUQ){
        for(Case c : casesNeedingUQ){
            c.OwnerId = uq;
        }
    }
    
    public static void reassignStaleCases(){
        list<Case> processed = new list<Case>();
        for(Case c : [SELECT Id, OwnerId from Case where Status = 'New' AND Hours_Since_Last_Modified__c > :settings.Hours_Until_Stale__c]){
            Case nc = new Case();
            nc.Id = c.Id;
            nc.OwnerId = uq;
            processed.add(nc);
        }
		update processed;
    }
    
	public static void assignCases(){
		map<Id,map<String,Integer>> scores = new map<Id,Map<String,Integer>>();
        map<Integer,Integer> keys = new map<Integer,Integer>();
        list<Case> cases = new list<Case>();
        list<Case> processed = new list<Case>();
        Integer totCases = 0;
        Boolean process = false;
        Boolean query = true;
        System.debug('samples: '+samples);

        for(User u : [SELECT Id, Name, Email, Type__c, Sub_Type__c, User_Type__c, Case_Origin__c, Tier__c, Location__c, Profile.Name, LastLoginDate FROM User WHERE LastLoginDate != null AND LastLoginDate > :loginCutoff AND Id NOT IN (SELECT OwnerId FROM CASE WHERE (Status = 'In Progress' OR Status = 'New') AND OwnerId != null) ORDER BY LastLoginDate DESC NULLS LAST]){
            
            String finalQuery = buildCaseQuery(u);
            cases = Database.query(finalQuery);
            totCases = cases.size();
            System.debug('totCases: '+totCases);
            if(totCases != 0){
                process=true;
            }
            System.debug('process: '+process);
            if(process){
                Integer i = 0;
                Integer topIdIter = -1;
                Double topScore = -1;
                while(i < samples && i < totCases){
                    Case c = cases.get(i);
                    System.debug('Case Origin: '+c.Id);
                    Double curScore = compareFields(c,u);
                    System.debug('curScore: '+curScore);
                    if(curScore >= 0 && curScore > topScore){
                        topScore = curScore;
                        topIdIter = i;
                    }
                    i++;
                }
                i = 0;
                if(topIdIter >= 0){
                    Boolean finalize = true;
                    while(i <= topIdIter && finalize && i<totCases){
                        if(i == topIdIter){
                            cases[i].inProcess__c = false;
                            cases[i].OwnerId = u.Id;
                            cases[i].Assignment_Points__c = topScore;
                            processed.add(cases.remove(i));
                            totCases--;
                            finalize = false;
                        }
                        else{
                            Integer ts = cases.get(i).Times_Skipped__c.intValue();
                            cases[i].Times_Skipped__c = ts+1;
                            cases[i].inProcess__c = true;
                        }
                        i++;
                    }
                }
                i = 0;
       		 	while(totCases > 0 && cases[i].inProcess__c == true){
            		cases[i].inProcess__c = false;
            		processed.add(cases.remove(i));
            		totCases--;
        		}
        		if(processed.size() > 0){
            		update processed;
        		}
            }
        }
        
    }
	
    public static Double compareFields(Case c,User u){
    	Double curScore = 0;
        Boolean potentialCase = true;
        for(String f : filters){
            String uf = String.valueOf(u.get(f+'__c'));
            String cf = String.valueOf(c.get(f+'__c'));
            Double exactMatchPoints = Double.valueOf(settings.get(f+'_Exact_Match_Points__c'));
            Double allMatchPoints = Double.valueOf(settings.get(f+'_All_Match_Points__c'));
            Boolean exactMatchrequired = Boolean.valueOf(settings.get(f+'_Exact_Match_Required__c'));
            if(uf !=null && cf !=null && uf.contains(cf)){
                curScore += exactMatchPoints;
            }
            else if(uf !=null && cf !=null && !uf.contains('All') && exactMatchrequired){
                potentialCase = false;
            }
            else if(uf !=null && cf !=null && uf.contains('All')){
                curScore += allMatchPoints;
            }
    	}
        curScore += c.Times_Skipped__c != null ? (c.Times_Skipped__c * settings.Times_Skipped_Multiplier__c) : 0;
        curScore += c.Hours_Old__c != null ? (c.Hours_Old__c * settings.Time_Elapsed_Multiplier__c) : 0;
        if(potentialCase){
        	return curScore;
        }
        else{
            return -1;
        }
    }
    
    public static String buildCaseQuery(User u){
        Integer i = 0;
        String queryString = 'SELECT Case_Origin__c,Hours_Old__c,inProcess__c,Assignment_Points__c,CreatedDate,Location__c,OwnerId, Status,Sub_Type__c,Tier__c,Times_Skipped__c,Type__c,User_Type__c FROM Case WHERE Status = \'New\' AND OwnerId = \''+uq+'\'';
            for(String f : filters){
            String ors = '';
            String uf = String.valueOf(u.get(f+'__c'));
            System.debug('Query: '+queryString);
            Boolean exactMatchRequired = Boolean.valueOf(settings.get(f+'_Exact_Match_Required__c'));
            if(uf != null && !uf.contains('All')){
                if(exactMatchRequired){
                    List<String> filterValues = uf.split(';',-2);
                    Integer j = 0;
                    for(String fv : filterValues){
                        if(j==0){
                        	ors+=('('+f+'__c = null OR ('+f+'__c != null AND ('+f+'__c = \''+fv+'\'');
                        }
                        else{
                            ors+=(' OR '+f+'__c = \''+fv+'\'');
                        }
                        j++;
                    }
                    ors+=(')))');
                    if(String.isNotBlank(ors)){
                        queryString+= ' AND '+ors;
                    }
                }
            }
        }
        queryString += ' ORDER BY CreatedDate ASC NULLS LAST LIMIT '+samples;
        System.debug('Query: '+queryString);
        return queryString;
    }
}

Here's the trigger that calls the above methods:

trigger caseTriggers on Case (before update, before insert, after insert, after update) {
    list<Case> cases = trigger.new;
    list<Case> assignedCases = new list<Case>();
    set<Id> userIds = new set<Id>();
    for(Case c : cases){
        userIds.add(c.OwnerId);
    }
    map<Id,User> userMap = new map<Id,User>([SELECT Id, Tier__c FROM User WHERE Id IN :userIds]);
    Boolean caseChanged = false;
    for(Case c : cases){
        if((c.Status == 'New' && (trigger.isInsert && trigger.isBefore || (trigger.isUpdate && trigger.isBefore && c.OwnerId == Trigger.oldMap.get(c.Id).OwnerId))) || (trigger.isUpdate && trigger.isBefore && c.isClosed == false && c.Tier__c != Trigger.oldMap.get(c.Id).Tier__c && !userMap.get(c.OwnerId).Tier__c.contains(c.Tier__c))){
            assignedCases.add(c);
        }
        if(trigger.isAfter){caseChanged = true;
        }
    }
    if(trigger.isBefore && !assignedCases.isEmpty()){
        caseAssignmentMethods.sendToUnassignedQueue(assignedCases);
    }
    if(true==true && triggerValidate.allowCaseUpdate && caseChanged){triggerValidate.allowCaseUpdate = false;caseAssignmentMethods.assignCases();triggerValidate.allowCaseUpdate = true;
    }
}

And lastly, here's my test class:

@isTest 
public class testAllCaseTrigger{

    static testMethod void testInactivityMethod() { 
    List<RecordType> rtypes = [Select Id From RecordType where Name='Person Account' and isActive=true];
    List<Account> accounts = new List<Account>{}; 
    List<Case> cases = new List<Case>{}; 
    
    test.startTest(); 
    
    for(Integer i = 0; i < 1; i++){ 
    Account newAcct = new Account(LastName='TestAcct'+ i,Phone='111',RecordTypeID=rtypes[0].ID);  
    accounts.add(newAcct); 
    } 
    
    insert accounts; 
    
    for(Integer i = 0; i < 1; i++){ 
    Case newCase = new Case(SuppliedName='TestAcct'+ i,Subject='111');  
    cases.add(newCase); 
    } 
    
    insert cases; 
    
    
    test.stopTest(); 
    
    }
    
    static testMethod void testCaseAssignment() {
        list<Profile> profiles = [SELECT Id FROM Profile WHERE Name = 'Service Rep'];
        Id profile = profiles[0].Id;        
        
      	User u = new User();
        u.LastName = 'Test';
        u.FirstName = 'Test';
        u.Email = 'abc13@123.com';
        u.ProfileId = profile;
        u.Tier__c = 'Tier 1';
        u.Username = 'abc13@123.com';
        u.Alias = 'Test1';
        u.CommunityNickname = 'TestNick';
        u.TimeZoneSidKey = 'America/Los_Angeles';
        u.LocaleSidKey = 'en_US';
        u.EmailEncodingKey = 'ISO-8859-1';
        u.LanguageLocaleKey = 'en_US';
        Insert u;
        
        User u2 = new User();
        u2.LastName = 'Test2';
        u2.FirstName = 'Test2';
        u2.Email = 'abcd2@123.com';
        u2.ProfileId = profile;
        u2.Tier__c = 'Tier 2';
        u2.Username = 'abcd2@123.com';
        u2.Alias = 'Test2';
        u2.CommunityNickname = 'TestNick2';
        u2.TimeZoneSidKey = 'America/Los_Angeles';
        u2.LocaleSidKey = 'en_US';
        u2.EmailEncodingKey = 'ISO-8859-1';
        u2.LanguageLocaleKey = 'en_US';
        Insert u2;
        
        test.startTest(); 
        
        Case c = new Case();
        c.OwnerId = u.Id;
      	c.Status = 'New';
      	c.Tier__c = 'Tier 1';
   		Insert c;
        
        c.Status = 'In Progress';
        Update c;
        
        c.Tier__c = 'Tier 2';
        Update c;
        test.stopTest(); 
        
   	}

}

Thanks.

Lets say I wrote the following on the Account chatter feed: "@[Bob Jones] thanks for all the help you gave to @[Debbie Johnson] yesterday!  I'll make sure that @[John Smith] follows up with you guys tomorrow."

Where (or how) does chatter actually store the @[User] information for all the users mentioned in that post?  When I go to the FeedComment or FeedItem objects in the developers workbench (depending on whether the post is the first in a thread or not), the "Body" field in both objects always shows the above post as "@Bob Jones thanks for all the help you gave to @Debbie Johnson yesterday!  I'll make sure that @John Smith follows up with you guys tomorrow."

It appears that, when it gets saved to the database, it takes off the brackets.  But if I were to save either version of that post directly to salesforce using APEX (with or without the brackets), it somehow breaks the feature that allows the various users profiles (Bobs, Debbies, and Johns) to pop up when you mouse over their user hashtag.

So what I'm trying to figure out (with not much luck) is, how does the system store or create the relationship between the user hashtags in a message, and the users whom those hashtags reference?  My end goal is to be able to insert chatter posts via apex where I can add the @[User] hashtags and those users will actually have those posts show up in their chatter feeds.

I'm trying to figure out how to write a SOQL query to display the newest opportunity associated with every account, using the MIN() SOQL aggregate function.  Unfortunately, I can't seem to wrap my head around how to structure this since aggregate queries only let you include the field that you're grouping by and the field you're aggregating [Example: AccountId, MIN(CreatedDate) from Opportunity], however I also need to know the Id of each resulting opportunity so that I can utilize it in the trigger.  How would I need to structure the query so that I can also extract the opportunity ID?  Thanks!

I have a regular old PDF file on my desktop, and that same PDF file is attached to a record in Salesforce.  Now, when I change the PDF's extension on my computer to ".txt", I can then open it and read the texttual data that makes up the file.  I need to extract some data at the beginning of the ".txt" version of the file that details how many pages the PDF consists of, but I need to do this for many PDF files that are already in Salesforce.

I discovered the "String pdf = System.EncodingUtil.base64Encode(a.Body)" method, which apparently converts the base64 blob representation of the file into an unencoded string... but when I looked at the actual output, I realized that it was totally different compared to the ".txt" version of the PDF on my desktop.  It seems that I'm not encoding/decoding the attachment Body blob to the correct format, but I'm totally clueless as to what to convert it to, or what method I would need to use to convert it.

Does anyone have any ideas as to how I would convert the PDF data to whatever format it gets converted to when I just change the extension on my computer and view it in notepad?

Thanks!


Since programming in APEX, I've learned to use maps (as opposed to nested FOR loops) on pretty much everything.  But there's one scenario where I've never been able to figure out a "map" based solution and I wanted to get feedback from some of you more experience gurus about how you would approcah the following problem and see if I'm going about this situation in totally the wrong way.

 

So the problem occurs when I'm dealing with multiple *dynamic* filters in a given query.  Here's a real life example I'm dealing with right now...

 

I'm currently working on an insurance companies system where every time a doctor authorizes a patient to receive treatment but *doesn't* fax in the patents records along with the authorization, I need to query the database to look for past medical records for that patient where the patient ID (on the faxed authorization) matches the patient ID in the database, and the doctor ID on the authorization, matches the doctor ID in the database, and the number of times medicated per day, is a number that's greater than or equal to the number of times medicated on the patient record in the database.

 

In other words, unlike most situations where you'd just say "[select ID, Patient__c, Doctor__c, Times_Treated_Daily__c from Records__c where Patient__c IN: patientsWithRecords.keySet()]", the filters in this case are multiple, and different for every record being queried.  So (and PLEASE correct me if I'm wrong) if I wrote "select Id, Patient__c, Doctor__c, Times_Treated_Daily__c from Records__c where Patient__c IN: patientsWithRecords.keySet() and Doctor__c IN: doctorsWithRecords.keySet() and Times_Treated_Daily__c IN: (or >= ?) timesTreatedDaily.keySet()" (essentially doing a FOR loop to extract my filters into individual keysets ahead of time), the resulting query would be useless because a patient could have multiple matching doctors, a doctor can have multiple matching patients, and the times treated could be grater or less than anyone in the keyset.  So simply throwing the 3 filters that I need to query against (Patient, Doctor, and Times Treated Daily) into 3 maps/keysets and querying against it, won't necessarily return records that I could bind with because the "IN:" part of the query means that records could easily "mix and match" with a variety of doctors, patients, and times treated daily.

 

As a result, I'll make the 3 keySets, but then I'll still iterate through the records to do the final matching since I feel like there's no way to know if record X is actually the patient, doctor and times treated daily for the specific record I'm querying for.  Am I going about this in a totally wrong way and there's actually a way simpler way to do this?  Or do maps automatically somehow compensate for this when you map multiple variables?  Or is there a way to write your SOQL in order to account for multiple variables like that?  Or are nested FOR loops basically the only way?

 

I'm so curious to know how other people would tackle this problem.  Any ideas or experiences with it would be hugely apprecited.  Thanks!

In the standard salesforce view, you can use URL variables to populate certain list views on an tab.  For example, if you wanted to populate a certain list view on the Account, you'd set the URL to be "/001?fcf={List View Salesforce ID}.  As most on here know, you can use URL variables to select and prepopulate all kinds of things on list views and on records.

 

Then there's the standard Salesforce Console.  The Console seems to consist of a page called "DesktopPage", which is embedded with 3 iFrame windows (a list view, a main view, and a mini view).  Unfortunately, unlike the normal tab views, I can't seem to make the console do ANYTHING using URL variables.  Specifically, I'm trying to change the Tab/Object dropdown list to a specific object, and change the List View dropdown to a specific record.

 

Does anyone know of any URL variables or (if not URL variables) some kind of a way to accomplish the act of selecting the dropdowns you want when first opening the console?  If not, does anyone know of a way to execute a javascript "Mass Action" console button, or some other way to execute javascript on the console when the page first loads?

 

Any ideas or thoughts at all would be hugely appreciated.

Hi I am testing my triggers and getting problems to write test method for triggers as i am new to test methods. Here is my trigger. the problem that i facing is due to three different objects are used in my trigger. Please review this code for trigger that i wrote. Thanks in advance.

Trigger Code:

 

 trigger RiskConvInsert on JunctionRiskRiskSearch__c (after insert)
  {
          List<JunctionRiskSearchConvJunc__c> juncRRSCJ = new List<JunctionRiskSearchConvJunc__c>();
          for(JunctionRiskRiskSearch__c jrsc: Trigger.New)
          {
              List<Risk_Conversation__c> riskConv = [Select Id from Risk_Conversation__c where Risk_Search__c =: jrsc.Risk_Searches__c];
              for(Risk_Conversation__c riskConvRec: riskConv)
              {
                  JunctionRiskSearchConvJunc__c junRec = new JunctionRiskSearchConvJunc__c();
                  junRec.Risk_Conversations__c = riskConvRec.Id;
                  junRec.JunctionRiskSearch__c = jrsc.Id;
                  juncRRSCJ.add(junRec);
              }
              insert juncRRSCJ;
          }
      }

Is it possible to use a trigger to create a note on a object? have a text field value that I need to populate within Notes & Attachments on custom object. Any help is greatly appreciated.

When you create a custom button that pre-populates various fields with values, you have to specify the salesforce record ID of the field itself in your button parameters and then put "=" (equals), and then follow that up with your merge field to specify the value of that parameter.

 

Normally I get the record ID by just using Google Chrome, right clicking on the field while in Edit view, clicking "Inspect Element" (which gives me the salesforce ID) and then pasting that ID in my button code as the parameter needing to be populated.  I know that other people go a longer route by going to the object in question, clicking on the field name itself, and copying the salesforce ID from the URL (after the "salesforce.com/" part) to extract the custom field salesforce ID.

 

Both of these methods seem rediculously inefficient.  More importantly though, you're hard-coding the field ID into the button itself.  That means, if your company ever moves orgs, OR if you're creating a packaged app, your button will essentially "break" once it's installed in a new org, because the field ID's in your button parameters will no longer match the ID's that salesforce assignes to those fields once you install that package somewhere else.

 

So my question is this... is there some special trick, either using the "URLFOR" function or something else (formula functon, action, etc), that allows you to dynamically generate the salesforce ID of a field that you need to include in your parameters?

 

Essentially, it would allow your buttons to look something like the following (this example would be a list button for Contacts, placed on the Account page layout):

 

{!URLFOR($Action.Contact.New,Account.Id,[FIELDID($ObjectType.Contact,"Contact_Status__c")="New",retURL=Account.Id],true)}

 

So in the above example, I invented a functon called "FIELDID", which takes the Sobject type and API name of the field on that object, does a DescribeSobject() call in the background, and spits out the salesforce ID of that particular field, as opposed to hard coding it perminantly.  No hunting around for salesforce ID's, no hacks, just using the tools available in the Custom Button section.

 

So... that being said, is there some way to do pretty much that, using the button functions available to salesforce users?  If not, then what is the "official" way that Salesforce recommends you use to go about extracting field ID's for the parameters you use in your custom buttons?

I have a field OpenedTaskDate__c on Task  this is date field.

i should need to display this date on contact field (TaskTestDate__c). so i have writtened a trigger like this

trigger updateTrig on Contact (before insert,after insert , before update) {
Task T =new Task();
for(contact c:Trigger.new)
c.TaskTestDate__c= t.OpenedTaskDate__c;


but it was not displaying the task field value on contact field.

I've created a trigger to copy field value "Status" (which is picklist) from "Opportunity Products" to "Opportunities". Here is what i came up to:

 

trigger UpdateStatus on OpportunityLineItem (after insert, after update) {

    List<Opportunity> oppp = new List<Opportunity>();

    for (OpportunityLineItem oppLnItem : trigger.new)
    {  
        
        
                
        oppp.add (new Opportunity (Id=oppLnItem.Opportunity_Id__c, Status__c=oppLnItem.Status__c));

        update oppp;
         
        
    } 
    }

 

Not sure if it works, but what I DO know is that i have absolutely no idea how to create a test class for this trigger :(((. Can you help? All the things I've googled about test classes seem so complicated, and i just cant find my way around.

Hi,

 

Document generated from Third party (other than salesforce) is saved under 'Notes & Attachments' in Opportunity.

When the saved file is viewed, dark grey line is added below the image which making the image blurred.

 

Can anyone please help me in resolving this issue.

 

Thanks in advance.

 

with sharing with out sharing, Which is the default in Apex class?????????

 

please help me....

I have an extremely basic trigger that is designed to delete any task with a blank subject when it's created:

 

trigger deleteBlankSubjects on Task (after insert){

  list<Task> records = trigger.new;
  list<Task> deletable = new list<Task>();
		
    for(Task t : records){
      if(t.Subject == null || isBlank(t.Subject)){
        deletable.add(t);					
      }
    }
  delete deletable;		
}

 

For some reason though, whenever I write out the isBlank() method, I get the error, "Save error: Method does not exist or incorrect signature: isBlank(String)".  

 

I've tried writing it a bunch of different ways now, and every time I get the same error.  What's worse, is that I can't seem to find any examples of people using the APEX .isBlank() method on google (where I usually turn when I'm stuck), even though the APEX Handbook says it's perfectly allowable.  What am I doing wrong here???  Totally confused.

 

I'm using Eclipse if it's of any help.  Any insight from any guru's out there would be HUGELY appreciated.