.ultrageek. Computers, Music, and Thoughts


Find the API Name from the Field Label

I recently had a use case where I was going to take a drop down value and use that to pull a value from a separate lookup object. I would have "Hourly" and my logic would return "Hourly__c" which I could then use dynamic SOQL and sObjects to do some magic. I did not want to use hardcoded values or a custom setting lookup table and I thought it would be easy to query the metadata...which turned out to be strangely harder than I thought it would be so here is a working solution:

There are a lot of examples of getting the Label from the API name but not really the other way around.


Salesforce.com Icons

No school like the old school. A quick way to give quick visual feedback in the Classic Salesforce.com UI is to use the built-in icons in conjunction with a formula field. A source that I have used forever seems to work and then not work so I found another URL that seems to work:

Does not work - look below for working links: http://blogforce9dev-developer-edition.ap1.force.com/salesforceicons

Basic Formula I used recently to let the user know that the future class had not updated the page with Approval Updates (Status/Step):

if(Update_Status_Text__c = "Future",
/* Page has not been updated by the future class */
IMAGE("/img/msg_icons/error16.png", "Refresh!") &
" Refresh Page",
/* All Good! */
IMAGE("/img/msg_icons/confirm16.png", "All Good!") &
" Page Good!"

This is the original page I've used for years (No Longer Works): http://www.force2b.net/index.php/2010/08/salesforce-icons/

Update (Mar 2019): And yet another good site: http://www.vermanshul.com/2017/10/quick-tips-salesforce-default-images.html

Update (Feb 2018): Here's another good site: http://salesforce-stuff.blogspot.com/2012/01/salesforce-images.html

Tagged as: , No Comments

Quick Tip: CSVFIX Duplicate Column

One tool I use to do bulk data loads in to Salesforce.com does not allow mapping one source to multiple destination fields. You can of course use workflows or code to backfill the data once it gets in but a cheaper/easier alternative if it is just one field is the following:

  • csvfix eval -e "if($1!='',$1,$1)" etl_temp.csv > etl_temp2.csv

It is a bit of a hack but basically as long as there is a value in the column it copies it to the last column. $1 is the field position of that row, != is the not equals, and two single quotes for 'Empty String'. The if statement uses double quotes for windows, use single quotes for non-windows.


Custom Settings Fun

Custom Settings are one of the great ways a developer can give admins power to update logic, settings, and the behaviour of code and really make code more flexible.

This is just a quick reference of all the cool ways you can pull those settings back out without having to use a SOQL statement.

This method loads all of the custom settings in to a list:
list<Customer_Setting_Name__c> buList =Customer_Setting_Name__c.getall().values();

This method loads a record using the name as a filter. This of course assumes you are not loading duplicate names:
Customer_Setting_Name__c aplo =Customer_Setting_Name__c.getValues(filter_string); // filter_string is just a string passed in

And finally, this method loads all of the custom settings in to a map with the name as the key:
Map<String,Customer_Setting_Name__c> buMap =Customer_Setting_Name__c.getAll();

The great thing is that these do not take a SOQL hit and admin can update these.

Some of the uses I use this for:

  • Mapping Business Unit settings for Lead Queue's, record types, groups, etc.
  • Multi-dimensional Pick lists that need to shared across objects, enabled/disabled (Global Picklists have taken the place of a lot of these), and that require additional attributes but maybe don't warrant the need for a full custom object IE security.
  • For 'quick disable' functionality for when I want to put code in production that might need to be quickly disabled



Test Classes with Global Picklists

Global Picklists or as Salesforce.com likes to refer to them, "Picklist Value Sets" from the menu or "Global Value Sets" in change sets, are not new but my dealings with them are. Specifically in Apex and test classes with a parent/child relationship using Global Picklists.

Global picklists btw do not have the same limitations normal picklists have in terms of the 1,000 character limitation that previous you had to use record types or a custom solution to get around.

So when you get the following error message in your test class testings: "INVALID_OR_NULL_FOR_RESTRICTED_PICKLIST, bad value for restricted picklist field". What this means is that under the user you are running the test under is not configured to use the values you have populated in the test class. Usually because the test is running under system and is using the master record type that does not have the field mappings. That is my guess at least.

Two ways to fix:

  • Set the RecordTypeId in the test data either statically or dynamically through a variable and a soql lookup using the name/developer name
  • Use the System.runAs(thisUser) method to either run as the user running the test or create a user with a specifically assigned profile that has the correct privileges and set up.

Below are examples:


Adding New Opportunity Record Type to Wave Sales App

We created a new Opportunity Type over the weekend and I assumed that it would just magically get added to the Opportunity dataset that the default Wave Sales App builds out but no, the dataflow/dataset was missing all the records related to the new record type. Creating a new dataset showed the data so I knew it was the dataflow somehow.

This is a braindead post to remind folks that if you create a new Opportunity record type and use the Salesforce.com default Wave App that you have to go in and update the dataflow JSON in about 4 places depending on the options you picked when you created the App.

These are the nodes:

  • Opportunity_Custom_Filter_Flag
  • Activity_Custom_Filter_Flag
  • Pipeline_Trending_Custom_Filter_Flag
  • Opportunity_Products_Custom_Filter_Flag

I recommend just downloading and updating the sections using a JSON editor like this one.


Embedding Wave Dashboard in to VisualForce page with Filters

This is a post on how to successfully embed a Wave dashboard in Visualforce with multiple datasource filters in Summer 17. If you found errors, fixes, or need help please comment and I'll respond/update the post, thanks!

Wave err...Einstein Analytics as Marketing has now re-branded Wave, is a little spotty on documentation. It assumes you drive the same way to and from work everyday so as you would expect it is a little lacking flexibility for the million other ways you could use the functionality. Recently I wanted to give users an Account Analysis dashboard without having to completely redo the Account Page since not everyone has a Wave license. One quick solution was to create a VisualForce page that was filtered on one Account with multiple data sources using a custom link from the Account Page to the custom VisualForce page. The challenge other than documentation that does not work in the live system was multiple datasets.

This is the documentation page that as of Summer 17 actually does not work (v40.0): https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_compref_wave_dashboard.htm

This is the page that provides the clue: https://success.salesforce.com/issues_view?id=a1p3A0000008gVeQAI

Couple of tips:

  • You do not need to create a list on the dashboard as the documentation states. It is nice to provide to your users in case they want to switch Accounts but is not critical for this working.
  • "Connect Data Sources" will not allow you to filter just one dataset and cascade to the other datasets.
  • Creating Links with "Apply Selections and Filters" checked will cause issues. When I tried under Summer 17 it will unfilter my parent dashboard or not work at all.

Results may vary and I'm hoping with hotfixes and releases this is fixed but for Summer 17 on July 9th 2017 this is how the system works.

And here's the details:

And here's the full example page. Since it uses a standard controller it does not need a test class (WOOHOO!)


Silly Admin Trick: Extracting Names and Emails from Groups and Permission Sets

Filed away in the "Why is this so hard?", extracting a list of users related to a Public Group, Queue, or Permission Set in Salesforce.com is harder than it should be. Not in reporting and a pain with Dataloader and XLS. There are lots of workarounds and methods for doing this but it should be easy!

So here's another workaround using public group as the example:

  1. Get the ID of the Group
  2. Fire up Workbench (https://workbench.developerforce.com/login.php)
  3. Queries drop down --> SOQL Queries
  4. Pick User to see the list of fields for reference
  5. Put the following in Notepad or whatever you use for scratch
  6. SELECT Name, FirstName, LastName, Business_Unit__c,Title, EMAIL FROM USER WHERE IsActive = TRUE AND ID IN (SELECT UserOrGroupId FROM GroupMember WHERE GroupId = 'Group_ID')
  7. If you get an error make sure your single quotes are not apostrophe's, Evernote loves to switch those on you without asking.
  8. Under 'View As' select Bulk CSV so you can easily download/export the entire list

Nothing to interesting but doing the SOQL join can be tricky, left inner join for those keeping score.


Fixing Salesforce.com Developer Console Jerking Back Up or Snapping Back

A strange issue I have had with Salesforce.com Developer Console on Chrome for a couple of (don't laugh) a couple of months is that as I scroll down the page will jerk back up to the previous page. In scanning altslash.org I saw this headline:

Chrome Now Uses Scroll Anchoring To Prevent Those Annoying Page Jumps

Ok, so fast forward through the usual blah blah blah. I disabled this in chrome (chrome://flags/#enable-scroll-anchoring) and either this issue got fixed or this setting fixed the issue I was having with the page jerking back or snapping back anytime I scrolled rapidly down the an apex class. Console is basically a streaming app that is constantly updating and listening for changes so it doesn't surprise me that it was impacted by this but what was so frustrating was that I just could not find anything on the Internets to point me in the direction of how to fix or even identify the problem until just now. Happy Days!

The work around in case someone has this issue is to not scroll with your mouse in the middle of the page but instead to position your mouse on right where the scroll bars are and the system will allow you to scroll with out snapping back to the previous page.


Wave Replication and Data Accuracy

In order to support custom dataflows you have to turn on 'Data Replication' and you want to create custom dataflows in order to allow better control over schedules, development, debugging, and insulation against dataflow failures due to changes, data, etc.

That being said you will want to disable incremental updates. Troubleshooting has several times come back to the Replication Object has stale data even though the data was changed hours or days before working the issue with replication and the dataflows running.

Some things to note:

  • New Records are picked up immediately
  • Changes could take an hour before getting picked up
  • Replication counts against the 24 dataflow limit

This might come across as negative but I am not sure why the replication settings give you the option to run hourly if it's going to cause a limits issue. I have 5 Dataflows plus replication and can only run a refresh once a day.

Use this resource to disable replication: Extract Data Incrementally in Replication

Or basically add this to your dataflows right before the fields: "incremental": false,