New Trailhead Modules (and a badge!)

trailhead-bannerHave you checked out Trailhead lately?  Have you seen the new Star Wars movie?  The answer SHOULD be “yes” to both!


You like imaginary internet points right?  You also like BADGES too, right?

Again, the answer SHOULD be “yes” to both!

CaptureI just went through the new “Build a Battle Station App” Trailhead project and I have to admit it’s one of the best “learn the basics of Salesforce declarative setup” projects that I’ve seen so far.  This one takes you all the way from basic object setup to reporting and SF1 all within about 30-45 minutes of your afternoon.


Don’t stop there!  There’s a whole NEW TRAIL called “Admin Advanced” that yours truly actually helped shape via the “Advanced Formula” module.  Careful – SteveMo was a big one on here too, so you know you’re in for some learning…and owing him a beer when you’re done.

CaptureHungry for some hardcore Apex REST/SOAP callout magic?  There’s a module for you too!  A wonderful post that walks you through the crazy language of Apex callouts and how to master them!

Are you yeti to earn new badges?!


SOQL “Select *”

badideaSo, let me start off this post by saying how this is a bad idea for nearly all applications.  Wildcarding columns has performance impacts and kittens die when you do it.  There is a reason Salesforce doesn’t allow you to do this natively.

THAT SAID, I did happen to come across a scenario where I needed to export multiple records to an Excel file, and there were fields being added, removed, and changed on a quarterly basis.  Fieldset?  Sure, I could go that way, but I figure I try something new – a “set it and forget it” option.

So, I decided I needed to create a “Select *” option that:

  • Dynamically returned all fields in an sObject
  • Could reference and return any object
  • Could either reference a set of Ids or just pull the top 50 records
  • Can handle fields I do NOT want to return
  • Handle multi-level sorting of results

So after a little baby punching and kitten killing, I created a monster.  =)

You can check out my GitHub repo here, but this is the high-level explanation of what beast I just unleashed.

// Specify Record Ids
Set<Id> setRecordIds = new Set<Id>();

// Exclude Audit Fields
Set<String> setBlockedFields = UtilityMethods.setAuditFields;

// Set Sorts
Map<String, String> mapSort = new Map<String, String>();
mapSort.put('State', UtilityMethods.G_SORT_ASCENDING);
mapSort.put('Name', UtilityMethods.G_SORT_ASCENDING);
// Awaken the monster
Map<Id, SObject> mapRecordData = UtilityMethods.objRecordData('Account', setRecordIds, setBlockedFields, mapSort);

// Do stuff with the results

young-frankenstein-song-and-dance-menSo – please don’t abuse this.  I release this monster into the world as more of an academic exercise as well as ya know what – you may have a real need for this at some point.

Do NOT, by any means, use this in your day-to-day Apex coding.  It’s bad and if you use this, you should feel bad.

Now…if you flipped the purpose of this code to be an INCLUSIVE field set instead of an EXCLUSIVE field set, then I’ll give you a pat on the back.  =)

Discover Lightning on Trailhead!

Lightning-1024x512Unless you’ve been living under a rock lately in the Salesforce community, you’ve heard about the new Lightning Experience (“LEX”) due out in Winter ’16!  (queue elated yet half-scared applause and amazement)

Also, unless you’ve been living under a rock or have not read my previous posts, I’m a pretty rabid fan of Salesforce Trailhead as well – and they have come through with bright shiny colors on delivering FOUR NEW TRAILS all around migrating, administering, and developing around the initial release of LEX.  If you are a developer, administrator, or even end-user – there are trails for you!

My biggest questions have been around “what works and what doesn’t so I can accurately advise my clients”.  I’m slowly digesting the new Winter ’16 pre-release notes that dropped at the end of last week, but as I’ve said before – Trailhead content is written in a way to cut right to the quick; give me contextually-appropriate major chunks of information and test me to ensure I comprehended it right.  There are many times where a Trailhead challenge has given me information in JUST SLIGHTLY a different light that (full pun intended) sets off the light bulb in my brain.

Without further ado, I wanted to introduce you to the four new Trailhead trails and my take on each.  You’ll see some overlap between some of the trails – some modules and challenges cross trails to ensure maximum contextual assistance.

Trail 1:  “Admin Trail – Migrating to Lightning Experience”


Who:  Admins and Developers

What:  Four modules walk you through topics such as:

  • What is LEX and is it right for your organization?
    • Yes!  There are things that work and don’t work – this is “version 1” ya know…
  • How to enable LEX for discovery and testing
  • Navigating setup and new LEX-exclusive enhancements
  • Customizing the LEX UI and a re-introduction to Actions
    • Bye-bye URL hacks!
    • Bye-bye Javascript buttons!
    • Bye-bye raw URL navigation!
  • Setting yourself up for a successful deployment

When:  Do this one first.

Why:  Unless your users are a group of supermen and superwomen that can handle any blip that comes their way, LEX is going to be a tough rollout – specifically in user training and “Salesforce Classic” feature parity.  Start your education here.

Trail 2:  “Admin Trail – Starting with Lightning Experience”


Who:  Admins and Developers

What:  Three modules walk you through topics such as:

  • Introduction to Salesforce and Lightning
  • Diving into the new Opportunity Workspace
  • Customizing Layouts, Actions, Objects, and Fields
  • Executing a LEX education plan and strategy for your company
  • Dropping the hammer:  LEX Rollout

When:  Do this one second.

Why:  LEX is the #1 largest UI-based change in over a decade.  The underlying administration concepts and foundational abilities aren’t changing, but how you and your users access them are.  You need to learn the gaps that do exist in LEX v1 and how to appropriately mitigate or delay each area so you aren’t left high and dry.

NOTE!  This trail was originally designed for brand new admins who are walking into a Winter ’16 org with LEX enabled, but EVERYONE can learn from this module.

Trail 3:  “Developer Trail – Lightning Experience”


Who:  Developers primarily, but Admins can learn a LOT from this as well

What:  Five modules walk you through topics such as:

  • What is LEX and is it right for your organization?
    • Yes!  There are things that work and don’t work – this is “version 1” ya know…
  • How to enable LEX for discovery and testing
  • UI framework and approach
  • How LEX impacts Visualforce overall
  • How LEX impacts ISVs, Packaging, and the AppExchange
    • How to tell if your 3rd party packages are ready for LEX
  • What else is changing with development tools?
  • How to use Visualforce within the LEX framework
    • Overall expectations
    • Navigation
    • Styling
    • What NOT to do in LEX
  • How to use Lightning Components with the LEX framework
    • Components and Attributes
    • Standard and Components
    • Events and JavaScript handling
  • Lightning Design System (LDS)
    • Salesforce has released a Salesforce bootstrap framework
    • How to use it
    • How NOT to use it…

When:  Do this one third overall, or if you’re a dev – do it first just for LDS.

Why:  Because you’re a developer and have questions about how your knowledge will convert into the LEX world – flat out.  Salesforce does not have any delusions that LEX will be perfect on “day 1”, nor do they expect that everyone will be able to transition over even within the next few releases.  What they do expect is that you will take the lessons learned here and start making smart design decisions so that when you are ready to move, you can.

Trail 4:  “Sales Rep Trail – Using Lightning Experience”


Who:  Admins, Developers, and END USERS (yes!  I said END USERS!)

What:  Two modules walk you through concepts such as:

  • What is Salesforce?
  • What is LEX?
  • Working with your Admins
  • Working with Leads and Opportunities in LEX
  • Leveraging Reports & Dashboards (and more) in LEX

When:  This is a great follow-up to the other trails, or a must for your users as part of your rollout strategy – even if you have seasoned veteran users.

Why:  One thing that admins and devs often skip over is the user experience – or how users will be introduced and trained on the system.  We’re so often mired in the details of fields, triggers, and workflow that we completely space that someone will have to advance their Opportunity through the new Sales Path in LEX.  This module is KEY for getting some good ol’ fashioned context.  =)

IN SUMMARY!  (Yes, I’m finally done!)

  • LEX is BIG.  Not like DF keynote/Benioff’s shoes big – like impacting your career big.
  • Trailhead = awesome.  I can’t pick a better word for it.
  • Salesforce has gifted you a fast-track with Trailhead.  Use it.
  • If you want a Winter ’16 LEX org before your sandbox window – you have to do these modules
    • Pre-release org activation is queued and prioritized based on your Trailhead progress
  • Sound off on Twitter!  Mention me (@andyboettcher) when you complete a badge!  I want to hear from all of you!

Come see me at Dreamforce ’15!

dreamforce_15_cloud_logotype_RGBIt’s almost time for Dreamforce ’15!  I’m going to be working my magic, meeting as many people as I can, and speaking at a good number of sessions this year.  Want to come see me?  Sign up for these sessions today!


9:30am-11:30am – Hands-on Workshop: Introduction to Point-And-Click App Building, Moscone West 2020

Are you a new Salesforce Admin or a Super User looking to understand the power of the creating an application with point-and-click tools on the platform? This session is for you! The goal of this session is to help familiarize you what tools exist on the platform and how you can use them to build an app without writing a single line of code. In addition, in between lessons you’ll get hands-on and build a sustainable app that you can put to work today. At the end of the workshop, you will feel empowered about point-and-click app building, confident in your ability to streamline business process, and be engaged with Salesforce.

NOTE!  We’ll be using one of the Trailhead Projects as the basis for this workshop – come ready to point-and-click your way to success!

12:00pm-12:30pm – Trailhead Gladiators, Moscone West Developer Theater

Watch customers go head-to-head in the DevZone arena as they face off on Trailhead challenges. Who will emerge victorious? Join us and find out.


11:30pm-12:00pm – Trailhead Gladiators, Moscone West Developer Theater

Watch customers go head-to-head in the DevZone arena as they face off on Trailhead challenges. Who will emerge victorious? Join us and find out.


12:00pm-1:00pm – Hands-on Training by MVP: Enhance Your Processes and Flows with Apex, Moscone West 2024

Processes and Flows are quickly becoming a go-to tool for both Administrators and Developers. Field updates, time-based actions, fast record lookups, and record creates are all possible declaratively. However, what happens when you need to take your process to the next step, and basic Processes and Flows cannot support your business logic? Join us to learn how developers can utilize Apex interfaces and annotations to customize and support Processes and Flows. You’ll leave with an understanding of how to use the ProcessPlugin interface and the InvocableMethod annotation for allowing Flows to make callouts, handle faults, and implement customized business processes. You should have some familiarity with writing Apex, along with a basic understanding of Processes and Flows to fully participate in this session.

1:30pm-2:00pm – Integrations with the Platform using Custom Apex REST Services, Moscone West Developer Theater (Innovation Theater)

Join us to learn how to create custom Apex REST web services to allow multiple external systems to integrate – more specifically, the architecture of such services to control and sanitize inputs, fully handle internal exception reporting, and return standard outputs that are able to be consumed and handled by any external programmatic solution.

3:00pm-3:30pm – Trailhead Gladiators, Moscone West Developer Theater

Watch customers go head-to-head in the DevZone arena as they face off on Trailhead challenges. Who will emerge victorious? Join us and find out.


9:00am-10:00am – Designing an interface users will actually want to use, Moscone West Community Campfire A

“Why won’t the users use my interface? It does exactly what they want it to do!” is a common frustration by developers. Change your mindset. Developers work like developers, users work like users. Let’s talk about how to think like a user.

Write your first APEX trigger – stream!

Well heck, that was pretty cool.  As part of Salesforce Developer Champions, I set up a streaming channel on Livecoding.TV – a new service dedicated to streaming developers developing stuff.

My first experience was pretty slick – I broadcast live to about 40 people how to create your first APEX trigger.  You can watch the recording (it’s in two parts because my connection dropped) at

Favorite my channel for more streams coming soon!

Passing Variables to Local Application from

shiftyCreating solutions for a living often puts you in situations where business needs sometimes just don’t align to “how technology normally works”.  One of these situations came up today.

Requirement:  We have information in that we need to pass to a local (on the Workstation) Access Database and then open it up.

My brain starts screaming “WHAT?!?!  You can’t do that…the browser won’t let you interact with the local file system!”  After some noodling around, my brain reaches WAAAAY back to VB6 days – Microsoft VBScript.  We could use old school ADO and VBScript commands to open up the Access Database, insert records, and then open that same database through a Shell Run command!

Now – only if Salesforce could be manipulated to build the VBScript file and then the user could just execute it!

After a little messing around, here’s the code!  This code generates the VBS, downloads it with a specific name, and the user can just execute it.

**NOTE – It works with one click in IE, but in Chrome and FF you have to execute the file manually from the downloaded location (clicking on the file via the browser throws an error for some reason)

Visualforce Page

<apex:page standardController="Account" extensions="VBScriptGeneratorController" showHeader="false" sidebar="false" contentType="application/vbs#OpenWord.vbs">
<apex:outputText escape="false" value="{!strOutput}" />


public VBScriptGeneratorController(ApexPages.StandardController scController) {
 // TODO
 this.soObject = (sObject)scController.getRecord();
Account acct = [SELECT Id, Name FROM Account WHERE Id = :(Id)this.soObject.get('Id')];
strOutput = '';
strOutput+= 'Set conn = CreateObject("ADODB.Connection") \r\n';
 strOutput+= 'conn.Open "Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:\\Users\\Andy\\TestADO.accdb;" \r\n';
 strOutput+= 'strSQL = "INSERT INTO tblData (Var1, Var2) VALUES (\'' + acct.Id + '\',\'' + acct.Name +'\')" \r\n';
 strOutput+= 'Set rs = conn.Execute(StrSQL) \r\n';
 strOutput+= 'conn.Close \r\n';
 strOutput+= 'CreateObject("WScript.Shell").Run "C:\\Users\\Andy\\TestADO.accdb" \r\n';

Flow and FinishLocation

pulling-hair-out-321x300Have you tried using Flows with Visualforce pages and tried to set the finishLocation to a dynamic value?  Odds are yes, and odds are even better that you had (or are having) no end of frustrations trying to get it to fire right.

The key to get your dynamic finishLocation to fire right is to factor your PageReference in such a way where as you are progressing through the flow and while the wrapper Visualforce page is rerendering, you can effectively capture and utilize Flow output variables.

To start, let’s embed a flow in a Visualforce page:

<apex:page controller="flowController">
<flow:interview name="DemoFlow" interview="{!flDemo}" finishLocation="{!prFinishLocation}" />

You’ll note that the “interview” attribute is in use.  That is one of the necessary steps to make this work – you need to link your Flow to the controller.

public class flowController{
// Instanciate the Flow for use by the Controller - linked by VF "interview" attribute
 public Flow.Interview.DemoFlow flDemo {get;set;}

 // Factor your PageReference as a full GET/SET
 public PageReference prFinishLocation {
 get {
 PageReference prRef = new PageReference('/your/page/location?var1= + strOutputVariable);
 return prRef;
 set { prFinishLocation = value; }

 // Factor your Flow output variable pull as a full GET / SET
 public String strOutputVariable {
 get {
 String strTemp = '';

 if(flDemo != null) {
 strTemp = string.valueOf(flDemo.getVariableValue('your flow output variable name');

 return strTemp;

 set { strOutputVariable = value; }


You’ll see that both the finishLocation’s PageReference as well as the variable that captures the Flow’s output variable are all in fully broken out GET/SET logic.  Factoring your code in this manner is the trick; as you move through the flow, the Visualforce page re-renders each time the user progresses through a Flow Screen.

**NOTE!  There is also a trick to how your actual Flow is set up.  For instance – if your Flow is creating a Contact and you want to direct the user to that Contact’s standard detail record upon completion of the Flow, you will need to have one last screen at the end to force the Visualforce page re-render so your controller can grab that Contact’s Id.

**ANOTHER NOTE!  You will NOT be able to get 100% test coverage when you link Flow to a controller like this.  Because Flow requires user-interaction, if you try and reference the “flDemo” variable from the example above without first checking to see if it’s null (which it will be in the Unit Test), your test will fail.  There is NO way right now (confirmed by Salesforce) to full test a Flow using this method…don’t pull your hair out trying.

Good luck!  Hit me up in the comments if you have other great Flow hacks or if you have issues getting this method to work.

Thanks for reading!